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

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 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
相关文章
|
1月前
|
SQL 关系型数据库 MySQL
MySQL死锁及源码分析!
MySQL死锁及源码分析!
MySQL死锁及源码分析!
|
1月前
|
SQL 关系型数据库 MySQL
案例剖析:MySQL唯一索引并发插入导致死锁!
案例剖析:MySQL唯一索引并发插入导致死锁!
108 0
案例剖析:MySQL唯一索引并发插入导致死锁!
|
1月前
|
SQL 关系型数据库 MySQL
案例剖析,MySQL共享锁引发的死锁问题!
案例剖析,MySQL共享锁引发的死锁问题!
|
3月前
|
关系型数据库 MySQL
MySQL自增ID用完会怎样?
MySQL自增ID用完会怎样?
|
3月前
|
SQL 关系型数据库 MySQL
遇到mysql数据库死锁,你会怎么排查?
遇到mysql数据库死锁,你会怎么排查?
257 0
|
12天前
|
监控 关系型数据库 MySQL
MySQL自增ID耗尽应对策略:技术解决方案全解析
在数据库管理中,MySQL的自增ID(AUTO_INCREMENT)属性为表中的每一行提供了一个唯一的标识符。然而,当自增ID达到其最大值时,如何处理这一情况成为了数据库管理员和开发者必须面对的问题。本文将探讨MySQL自增ID耗尽的原因、影响以及有效的应对策略。
38 3
|
12天前
|
存储 监控 关系型数据库
MySQL自增ID耗尽解决方案:应对策略与实践技巧
在MySQL数据库中,自增ID(AUTO_INCREMENT)是一种特殊的属性,用于自动为新插入的行生成唯一的标识符。然而,当自增ID达到其最大值时,会发生什么?又该如何解决?本文将探讨MySQL自增ID耗尽的问题,并提供一些实用的解决方案。
19 1
|
17天前
|
SQL 算法 关系型数据库
面试:什么是死锁,如何避免或解决死锁;MySQL中的死锁现象,MySQL死锁如何解决
面试:什么是死锁,死锁产生的四个必要条件,如何避免或解决死锁;数据库锁,锁分类,控制事务;MySQL中的死锁现象,MySQL死锁如何解决
|
27天前
|
关系型数据库 MySQL 数据库
一个 MySQL 数据库死锁的案例和解决方案
本文介绍了一个 MySQL 数据库死锁的案例和解决方案。
57 3
|
2月前
|
监控 关系型数据库 MySQL
MySQL锁机制与解决死锁问题
MySQL锁机制与解决死锁问题
285 5