sql慢排查

查看慢查询日志的方式,一般如果你的项目配备了完善的监控系统,通常情况下会自动去读取磁盘中的慢查询日志,然后可直接通过监控系统的大屏来观察。但如若未具备完善的监控系统,也可以通过cat这类命令去查看本地的日志文件,慢查询日志的磁盘文件默认位于MySQL的安装目录下,也可以通过slow_query_log_file=/xxx/xxx/xx.log的方式去手动指定。

从上面日志中记录的查询信息来看,可以得知几个信息:

  1. 执行慢查询SQL的用户:root,登录IP为:localhost[127.0.0.1]。
  2. 慢查询执行的具体耗时为:0.014960s,锁等待时间为0s。
  3. 本次SQL执行后的结果集为4行数据,累计扫描6行数据。
  4. 本次慢查询发生在db_zhuzi这个库中,发生时间为1667466932(2022-11-03 17:15:32)。
  5. 最后一行为具体的慢查询SQL语句。

读取慢查询日志后,能够让咱们精准定位到发生慢查询SQL的用户、客户端机器、执行耗时、锁阻塞耗时、结果集行数、扫描行数、发生的库和时间、以及具体的慢查询SQL语句,得到了这些信息后,其实排查引起慢查询的原因就比较简单了。步骤如下:

  1. 先根据本地慢查询日志文件中的记录,得到具体慢查询SQL执行的相关信息。
  2. 查看Look_time的耗时,判断本次执行缓慢,是不是由于并发事务导致的长时间阻塞。
  3. 如果不是,则通过《SQL优化篇》中说的explain索引分析工具,先判断索引的使用情况。

一般来说在开发环境中没有问题的SQL语句,放到线上环境出现执行缓慢的情况,多半原因是由于并发事务抢占锁,造成当前事务长时间无法获取锁资源,因此导致当前事务执行的SQL出现超时,这种情况下需要去定位操作相同行数据的大事务,一般长时间的阻塞是由于大事务持有锁导致的,找出对应的大事务并拆解或优化掉即可。

通过show status like 'innodb_row_lock_%';命令可以查询MySQL整体的锁状态,如下:

  1. Innodb_row_lock_current_waits:当前正在阻塞等待锁的事务数量。
  2. Innodb_row_lock_time:MySQL启动到现在,所有事务总共阻塞等待的总时长。
  3. Innodb_row_lock_time_avg:平均每次事务阻塞等待锁时,其平均阻塞时长。
  4. Innodb_row_lock_time_max:MySQL启动至今,最长的一次阻塞时间。
  5. Innodb_row_lock_waits:MySQL启动到现在,所有事务总共阻塞等待的总次数。

如果你在慢查询日志中,看到了大量由于锁阻塞导致执行超出慢查询阈值的SQL,那可以执行上述这条指令看看整个MySQL的锁状态,如果这些值都比较大时,就意味着你当前这个MySQL节点承载的并发压力过高,此时就急需进行《MySQL架构优化》

posted @ 2024-02-29 09:09  恨铁不成钢2  阅读(14)  评论(0)    收藏  举报