mysql线上频出MySQL死锁问题!分享一下教科书般的排查和分析过程( 二 )


) ~[classes/:na]
Deadlock 非常显眼 , 说明业务上出现了死锁 , 肯定是业务上有问题 。 但是该业务代码一直运行了大半年 , 查看 Git 记录也发现最近没人动该业务相关代码 , 说明该业务之前就可能有问题 , 只是最近才达到了触发这种异常的条件 。
对该日志做个简单的总结:
1.这是什么错误日志?
8行:### SQL: UPDATE test_table SET money = money + ? WHERE user_id = ?9行:### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock try restarting transaction从第 8~9 行可以得知 , 该错误是数据库的错误 , 是死锁错误异常而导致的回滚 , 关键 SQL 是:UPDATE test_table SET money = money + ? WHERE user_id = ?
2.核心错误的调用方法是哪个 , 即事务开始的方法是哪个?
30行:at org.example.manager.impl.BizManagerImpl.transactionMoney(BizManagerImpl.java:25) ~[classes/:na] 31行:at org.example.manager.impl.BizManagerImpl$$FastClassBySpringCGLIB$$824241b9.invoke() ~[classes/:na]过滤了 jdk 类、spring 类、mybatis 类后 , 得到核心的业务错误代码(30~31 行) , 31 行为 Spring 的代理执行 , 30 行才是真正最开始执行业务代码:BizManagerImpl.transactionMoney
1.2 数据库死锁日志
接着去查看该库对应的数据库死锁日志 , 使用命令:show innodb engine status , 过滤掉非重要的日志后如下:
------------------------LATEST DETECTED DEADLOCK------------------------2020-07-14 23:34:29 0x7f958f1d5700*** (1) TRANSACTION:TRANSACTION 95146580, ACTIVE 2 sec starting index readmysql tables in use 1, locked 1LOCK WAIT 4 lock struct(s), heap size 1136, 5 row lock(s), undo log entries 2MySQL thread id 6264489, OS thread handle 140273305761536, query id 837446998 10.10.59.164 root updatingUPDATE test_table SET money = money + 5 WHERE user_id = 5*** (1) WAITING FOR THIS LOCK TO BE GRANTED:RECORD LOCKS space id 71816 page no 4 n bits 80 index idx_user_id of table `mall`.`test_table` trx id 95146580 lock_mode X locks rec but not gap waitingRecord lock, heap no 3 PHYSICAL RECORD: n_fields 2 compact format info bits 0 0: len 8 hex 8000000000000005 asc1: len 8 hex 8000000000000006 asc *** (2) TRANSACTION:TRANSACTION 95146581, ACTIVE 2 sec starting index readmysql tables in use 1, locked 14 lock struct(s), heap size 1136, 5 row lock(s), undo log entries 2MySQL thread id 6264490, OS thread handle 140280327919360, query id 837446999 10.10.59.164 root updatingUPDATE test_table SET money = money + 4 WHERE user_id = 4*** (2) HOLDS THE LOCK(S):RECORD LOCKS space id 71816 page no 4 n bits 80 index idx_user_id of table `mall`.`test_table` trx id 95146581 lock_mode X locks rec but not gapRecord lock, heap no 3 PHYSICAL RECORD: n_fields 2 compact format info bits 0 0: len 8 hex 8000000000000005 asc1: len 8 hex 8000000000000006 asc Record lock, heap no 5 PHYSICAL RECORD: n_fields 2 compact format info bits 0 0: len 8 hex 8000000000000001 asc1: len 8 hex 8000000000000002 asc *** (2) WAITING FOR THIS LOCK TO BE GRANTED:RECORD LOCKS space id 71816 page no 4 n bits 80 index idx_user_id of table `mall`.`test_table` trx id 95146581 lock_mode X locks rec but not gap waitingRecord lock, heap no 2 PHYSICAL RECORD: n_fields 2 compact format info bits 0 0: len 8 hex 8000000000000004 asc1: len 8 hex 8000000000000005 asc *** WE ROLL BACK TRANSACTION (2)


推荐阅读