0
点赞
收藏
分享

微信扫一扫

解决数据库MySQL查询超时的问题(奇技淫巧)

查拉图斯特拉你和他 2021-09-21 阅读 94
我的博客

系统中查询大数据量或者在业务高峰期,一些慢sql查询可能会拖垮数据库,因此需要在执行sql的时候设置sql最大执行时间,超过时间还没执行完的sql自动终止,抛错给用户让稍后重试.
解决方法:

  1. 使用MySQL提供的max_execution_time来显式制定max_execution_time. 参考https://dev.mysql.com/doc/refman/8.0/en/optimizer-hints.html#optimizer-hints-execution-time
    可以写死在mapper.xml中或者在Mybatis Interceptor中拦截sql加上max_execution_time.
  2. 上面的方法只能设置单条select的最大执行时间,如果想设置事务的最大执行时间,可以通过@Transational(timeout=xxx)指定事务的超时时间,事务超时机制是依赖于jdbc实现:启动一个定时任务,根据当前Connection复制一份Connection执行kill命令,参考https://www.cubrid.org/blog/3826470
  3. 如果不想每次执行带超时的sql都启动一个定时任务和复制connection,我们对spring事务做了代理,在新事务开启的时候,把事务的超时时间和当前时间放在ThreadLocal里,在拦截执行sql的时候可以根据当前时间算出即将执行的sql的max_exection_time,这样既能控制事务的超时时间也能控制每条sql的执行时间.
  4. 对非select sql,我们对Datasource进行了代理,在一个Connection从池里取出来的时候就根据超时时间设置一个定时任务(用时间轮存储和触发任务),如果sql在超时时间内还给池了,取消任务.如果时间超了,把connection close掉, 业务线程后续对这个connection进行操作会报错.

PS: 上面的方法都是治标不治本的方法.

举报

相关推荐

0 条评论