Mysql死锁发生如何排查和解决?

网上很多介绍死锁原理有排查方法,但是如何排查哪个事务阻塞导致死锁的发生,网上大佬的级别太高,我们新手看的是云里来雾里云的

以参考文档中的例子,环境准备也一样

1、数据库隔离级别

mysql> select @@tx_isolation;
+-----------------+
| @@tx_isolation  |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set, 1 warning (0.00 sec)

2、关闭事务自动提交

mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
|            1 |
+--------------+
1 row in set (0.00 sec)

mysql> set @@autocommit=0;
Query OK, 0 rows affected (0.01 sec)

mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
|            0 |
+--------------+
1 row in set (0.00 sec)

表结构:

//id是自增主键,name是非唯一索引,balance普通字段
CREATE TABLE `account` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `balance` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_name` (`name`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

insert into account values(null,'Z3',1);
insert into account values(null,'L4',1);

模拟并发制造死锁现场

事务A
mysql> update account set balance=2 where name='Z3';
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

事务B
mysql> mysql> update account set balance=2 where name='L4';

#事务A
mysql> insert into account values(null,'W5',1);


mysql> select * from information_schema.innodb_lock_waits\G
*************************** 1. row ***************************
requesting_trx_id: 5486
requested_lock_id: 5486:31:4:2
  blocking_trx_id: 5487
 blocking_lock_id: 5487:31:4:2
1 row in set, 1 warning (0.00 sec)

mysql> SELECT trx_mysql_thread_id FROM information_schema.innodb_trx where trx_id=5487;
+---------------------+
| trx_mysql_thread_id |
+---------------------+
|                  18 |
+---------------------+
1 row in set (0.00 sec)

kill阻塞进程
mysql> kill 18;


查询未提交的事务
select * from performance_schema.events_statements_current\G




上述的kill方案,还是存在一点没有连接上,能找到trx_mysql_thread_id,但是无法与events_statements_current表示的信息连,这样就无法快速的确认阻塞的sql

参考文档:Mysql死锁问题如何排查和解决? - 知乎

你可能感兴趣的:(数据库,mysql)