【原创】查找原始MySQL死锁ID

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介:

如果遇到死锁了,怎么解决呢?找到原始的锁ID,然后KILL掉一直持有的那个线程就可以了, 但是众多线程,可怎么找到引起死锁的线程ID呢? MySQL 发展到现在,已经非常强大了,这个问题很好解决。 直接从数据字典连查找。

 
我们来演示下。

线程A,我们用来锁定某些记录,假设这个线程一直没提交,或者忘掉提交了。 那么就一直存在,但是数据里面显示的只是SLEEP状态。
 
 
 
 
  1. mysql> set @@autocommit=0; 
  2. Query OK, 0 rows affected (0.00 sec) 
  3.  
  4. mysql> use test; 
  5. Reading table information for completion of table and column names 
  6. You can turn off this feature to get a quicker startup with -A 
  7.  
  8. Database changed 
  9. mysql> show tables; 
  10. +----------------+ 
  11. | Tables_in_test | 
  12. +----------------+ 
  13. | demo_test      | 
  14. | t3             | 
  15. +----------------+ 
  16. rows in set (0.00 sec) 
  17.  
  18. mysql> select * from t3; 
  19. +----+--------+--------+------------+----+----+----+ 
  20. | id | fname  | lname  | birthday   | c1 | c2 | c3 | 
  21. +----+--------+--------+------------+----+----+----+ 
  22. | 19 | lily19 | lucy19 | 2013-04-18 | 19 |  0 |  0 | 
  23. | 20 | lily20 | lucy20 | 2013-03-13 | 20 |  0 |  0 | 
  24. +----+--------+--------+------------+----+----+----+ 
  25. rows in set (0.00 sec) 
  26.  
  27. mysql> update t3 set birthday = '2022-02-23' where id = 19; 
  28. Query OK, 1 row affected (0.00 sec) 
  29. Rows matched: 1  Changed: 1  Warnings: 0 
  30.  
  31. mysql> select connection_id(); 
  32. +-----------------+ 
  33. | connection_id() | 
  34. +-----------------+ 
  35. |              16 | 
  36. +-----------------+ 
  37. 1 row in set (0.00 sec) 
  38.  
  39. mysql>  
 
线程B, 我们用来进行普通的更新,但是遇到问题了,此时不知道是哪个线程把这行记录给锁定了?
 
 
 
  1. mysql> use test; 
  2. Reading table information for completion of table and column names 
  3. You can turn off this feature to get a quicker startup with -A 
  4.  
  5. Database changed 
  6. mysql> select @@autocommit; 
  7. +--------------+ 
  8. | @@autocommit | 
  9. +--------------+ 
  10. |            1 | 
  11. +--------------+ 
  12. 1 row in set (0.00 sec) 
  13.  
  14. mysql> update t3 set birthday='2018-01-03' where id = 19; 
  15. ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction 
  16. mysql> select connection_id(); 
  17. +-----------------+ 
  18. | connection_id() | 
  19. +-----------------+ 
  20. |              17 | 
  21. +-----------------+ 
  22. 1 row in set (0.00 sec) 
  23.  
  24. mysql> show processlist; 
  25. +----+------+-----------+------+---------+------+-------+------------------+ 
  26. | Id | User | Host      | db   | Command | Time | State | Info             | 
  27. +----+------+-----------+------+---------+------+-------+------------------+ 
  28. | 10 | root | localhost | NULL | Sleep   | 1540 |       | NULL             | 
  29. | 11 | root | localhost | NULL | Sleep   |  722 |       | NULL             | 
  30. | 16 | root | localhost | test | Sleep   |  424 |       | NULL             | 
  31. | 17 | root | localhost | test | Query   |    0 | init  | show processlist | 
  32. | 18 | root | localhost | NULL | Sleep   |    5 |       | NULL             | 
  33. +----+------+-----------+------+---------+------+-------+------------------+ 
  34. rows in set (0.00 sec) 
  35.  
  36. mysql> show engine innodb status\G 
  37.  
  38.  
  39. ------------ 
  40. TRANSACTIONS 
  41. ------------ 
  42. Trx id counter 189327 
  43. Purge done for trx's n:o < 189323 undo n:o < 0 state: running but idle 
  44. History list length 343 
  45. LIST OF TRANSACTIONS FOR EACH SESSION: 
  46. ---TRANSACTION 0, not started 
  47. MySQL thread id 11, OS thread handle 0x7f70a0c98700, query id 994 localhost root init 
  48. show engine innodb status 
  49. ---TRANSACTION 189326, ACTIVE 2 sec starting index read 
  50. mysql tables in use 1, locked 1 
  51. LOCK WAIT 2 lock struct(s), heap size 376, 1 row lock(s) 
  52. MySQL thread id 17, OS thread handle 0x7f70a0bd5700, query id 993 localhost root updating 
  53. update t3 set birthday='2018-01-03' where id = 19 
  54. ------- TRX HAS BEEN WAITING 2 SEC FOR THIS LOCK TO BE GRANTED: 
  55. RECORD LOCKS space id 529 page no 3 n bits 72 index `PRIMARYof table `test`.`t3` trx id 189326 lock_mode X waiting 
  56. Record lock, heap no 2 PHYSICAL RECORD: n_fields 9; compact format; info bits 0 
  57.  0: len 2; hex 3139; asc 19;; 
  58.  1: len 6; hex 00000002e38c; asc       ;; 
  59.  2: len 7; hex 7e00000d2827c9; asc ~   (' ;; 
  60.  3: len 6; hex 6c696c793139; asc lily19;; 
  61.  4: len 6; hex 6c7563793139; asc lucy19;; 
  62.  5: len 3; hex 8fcc57; asc   W;; 
  63.  6: len 4; hex 80000013; asc     ;; 
  64.  7: len 4; hex 80000000; asc     ;; 
  65.  8: len 4; hex 80000000; asc     ;; 
  66.  
  67. ------------------ 
  68. ---TRANSACTION 189324, ACTIVE 641 sec 
  69. 2 lock struct(s), heap size 376, 3 row lock(s), undo log entries 1 
  70. MySQL thread id 16, OS thread handle 0x7f70a0b94700, query id 985 localhost root cleaning up 
  71. Trx read view will not see trx with id >= 189325, sees < 189325 
 
上面的信息很繁多,也看不清楚到底哪里是哪里。
 
不过现在,我们只要从数据字典里面拿出来这部分信息就OK了。
 
 
 
  1. mysql> SELECT * FROM information_schema.INNODB_TRX\G 
  2. *************************** 1. row *************************** 
  3.                     trx_id: 189324 
  4.                  trx_state: RUNNING 
  5.                trx_started: 2013-04-18 17:48:14 
  6.      trx_requested_lock_id: NULL 
  7.           trx_wait_started: NULL 
  8.                 trx_weight: 3 
  9.        trx_mysql_thread_id: 16 
  10.                  trx_query: NULL 
  11.        trx_operation_state: NULL 
  12.          trx_tables_in_use: 0 
  13.          trx_tables_locked: 0 
  14.           trx_lock_structs: 2 
  15.      trx_lock_memory_bytes: 376 
  16.            trx_rows_locked: 3 
  17.          trx_rows_modified: 1 
  18.    trx_concurrency_tickets: 0 
  19.        trx_isolation_level: REPEATABLE READ 
  20.          trx_unique_checks: 1 
  21.     trx_foreign_key_checks: 1 
  22. trx_last_foreign_key_error: NULL 
  23.  trx_adaptive_hash_latched: 0 
  24.  trx_adaptive_hash_timeout: 10000 
  25.           trx_is_read_only: 0 
  26. trx_autocommit_non_locking: 0 
  27. 1 row in set (0.01 sec) 
  28.  
  29. mysql>  
 
原来是线程16忘掉COMMIT了。



本文转自 david_yeung 51CTO博客,原文链接:http://blog.51cto.com/yueliangdao0608/1180917 ,如需转载请自行联系原作者
相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
18天前
|
关系型数据库 MySQL
MySQL自增ID用完会怎样?
MySQL自增ID用完会怎样?
|
22天前
|
SQL 关系型数据库 MySQL
遇到mysql数据库死锁,你会怎么排查?
遇到mysql数据库死锁,你会怎么排查?
61 0
|
29天前
|
存储 SQL 关系型数据库
深入MySQL锁机制:原理、死锁解决及Java防范技巧
深入MySQL锁机制:原理、死锁解决及Java防范技巧
|
29天前
|
SQL JavaScript 关系型数据库
Mysql索引不当引发死锁问题
本文通过真实案例解析了MySQL在高并发环境下出现死锁的问题。数据库表`t_award`包含多个索引,但在执行特定SQL语句时遭遇索引失效,导致更新操作变慢并引发死锁。分析发现,联合索引`(pool_id, identifier, status, is_redeemed)`因`identifier`允许为空值而导致索引部分失效。此外,`pool_id`上的普通索引产生的间隙锁在高并发下加剧了死锁风险。为解决此问题,文中提出了调整索引顺序至`(pool_id, status, is_redeemed, identifier)`等方案来优化索引使用,进而减轻死锁现象。
|
1月前
|
Oracle 关系型数据库 MySQL
Mysql和Oracle数据库死锁查看以及解决
【8月更文挑战第11天】本文介绍了解决MySQL与Oracle数据库死锁的方法。MySQL可通过`SHOW ENGINE INNODB STATUS`查看死锁详情,并自动回滚一个事务解除死锁;也可手动KILL事务。Oracle则通过查询V$LOCK与V$SESSION视图定位死锁,并用`ALTER SYSTEM KILL SESSION`命令终止相关会话。预防措施包括遵循ACID原则、优化索引及拆分大型事务。
|
19天前
|
监控 关系型数据库 MySQL
MySQL死锁是什么
【8月更文挑战第26天】MySQL死锁是指两个或多个事务在执行过程中,因争夺锁资源而造成的相互等待的现象,若无外力干涉,它们都将无法继续执行。这种相互等待的情况会导致整个系统陷入停滞状态,影响数据库的性能和稳定性。
35 0
|
2月前
|
SQL 存储 关系型数据库
细说 MySQL 死锁
【7月更文挑战第26天】MySQL 死锁
28 4
|
2月前
|
SQL 存储 关系型数据库
细说 MySQL 死锁
死锁检查在MySQL 8.0中涉及三个主要步骤:构造锁等待图、初始化事务权重和提升权重。首先,当事务进入锁等待状态时,信息会被记录到内存中的`waiting_threads`,形成快照数组。接着,对这个数组进行排序,构造出锁等待图,表示事务间的等待关系。然后,初始化所有等待事务的权重为1,如果一个事务在其他事务等待后进入等待,其权重会被提升,以避免长时间等待。最后,根据锁等待图,提升那些同时阻塞其他事务的权重,但不包括参与死锁的事务。权重更新后,死锁检查线程将依据这些信息来检测和解决死锁。
65 15
|
2月前
|
SQL 算法 关系型数据库
(十)全解MySQL之死锁问题分析、事务隔离与锁机制的底层原理剖析
经过《MySQL锁机制》、《MySQL-MVCC机制》两篇后,咱们已经大致了解MySQL中处理并发事务的手段,不过对于锁机制、MVCC机制都并未与之前说到的《MySQL事务机制》产生关联关系,同时对于MySQL锁机制的实现原理也未曾剖析,因此本篇作为事务、锁、MVCC这三者的汇总篇,会在本章中补全之前空缺的一些细节,同时也会将锁、MVCC机制与事务机制之间的关系彻底理清楚。
|
2月前
|
缓存 监控 关系型数据库
MySQL PXC 集群死锁分析案例
前不久一个系统死锁导致部分业务受到影响,今次补上详细的节点日志分析过程。
52 1