刚才有RD部门负责人在企业微信上问我他们的一个MYSQL实例Innodb_row_lock_waits在报警,这个是什么情况?
得益于我们把数据库的报警,发送给了RD负责人,每个负责人会对自己业务线的数据库性能比较关心,比DBA还要关心。 通常DBA收到这种row_lock报警只要不是连续的长时间报,一般会忽略。 这也是我们努力做数据库负责人制度的原因。
回归正题,处理Innodb_row_lock_waits或者Innodb_row_lock_current_waits报警。
报警判断
首先第一步这不是个严重的报警,如果没有其他并发报警. 但这个报警一般会对业务来说,行数增多,意味着更多的锁等待时长
行锁的报警规则设置如下:
<counter_node><counter>Innodb_row_lock_waits</counter><checkpoint>0,10,30,80,5000</checkpoint><weight>1</weight></counter_node>
报警排查
show engine innodb status \G
观察结果TRANSACTIONS 这一段:
TRANSACTIONS
Trx id counter 581112825 Purge done for trx’s n:o < 581112824 undo n:o < 0 state: running but idle History list length 34 LIST OF TRANSACTIONS FOR EACH SESSION: —TRANSACTION 421991409852768, not started 0 lock struct(s), heap size 1136, 0 row lock(s) —TRANSACTION 421991409917520, not started 0 lock struct(s), heap size 1136, 0 row lock(s) —TRANSACTION 421991409914784, not started 0 lock struct(s), heap size 1136, 0 row lock(s) —TRANSACTION 421991409911136, not started 0 lock struct(s), heap size 1136, 0 row lock(s)
一般会看到
RECORD LOCKS space id 161 page no 2405 n bits 80 index PRIMARY of table ***库名,表名*****trx id 579998817 lock_mode X insert intention waiting
类似的提示。把库名表名记下来。
如果上面的 show engine innodb status \G
看不到结果怎么办?
不慌, 开启锁监控(InnoDB Lock Monitor)
在早期Mysql版本里需要手动创建表(很2的方法)
CREATE TABLE innodb_lock_monitor (a INT) ENGINE=INNODB;
Mysql5.6 以后可以用系统变量来开关:
set GLOBAL innodb_status_output=ON;
set GLOBAL innodb_status_output_locks=ON;
开启锁监控以后可以在错误日志中每隔一段时间(一般是15秒)刷新一次锁信息
在实例上
tail -f mysql-error.log |grep "space id"
可以持续观察锁输出。找到高频率出现锁的库名和表名.
在慢日志里捞一下,基本都能具体的SQL,如果出不来,告诉给RD自己也能查出来。如果RD查得费劲,可以开下全日志或者调低下SLOW QUERY的阈值
补充
行锁相关的状态和监控说明
show global status like ‘Innodb_row_lock%’
- Innodb_row_lock_current_waits:当前正在等待锁定的数量;
- Innodb_row_lock_time:从系统启动到现在锁定总时间长度;
- Innodb_row_lock_time_avg:每次等待所花平均时间;
- Innodb_row_lock_time_max:从系统启动到现在等待最常的一次所花的时间;
- Innodb_row_lock_waits:系统启动后到现在总共等待的次数; ``
对于这5个状态变量,比较重要的主要是Innodb_row_lock_time_avg(等待平均时长),Innodb_row_lock_waits(等待总次数)以及Innodb_row_lock_time(等待总时长)这三项。尤其是当等待次数很高,而且每次等待时长也不小的时候,我们就需要分析系统中为什么会有如此多的等待,然后根据分析结果着手指定优化计划。
对于innodb中的latch,可以通过以下命令查看
show engine innodb mutex;