MySQL是一个常用的数据库管理系统,有时候运行程序时出现死锁的问题。那么如何检查MySQL数据库中出现了死锁呢?下面将通过SQL语句来介绍。
SHOW ENGINE INNODB STATUS
使用以上命令可以查看MySQL当前的状态。在返回的结果中,会有关于死锁的信息。下面是一个简要的示例:
------------------------
LATEST DETECTED DEADLOCK
------------------------
2019-01-01 10:26:42
*** (1) TRANSACTION:
TRANSACTION 589172, ACTIVE 0 sec fetching rows
mysql tables in use 1, locked 1
LOCK WAIT 3 lock struct(s), heap size 360, 2 row lock(s)
MySQL thread id 17048, OS thread handle 0x12345, query id 12345678 localhost root preparing
SELECT * FROM table1 WHERE column1 = 'abc' FOR UPDATE
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 1221 page no 4 n bits 72 index idx_column1 of table `database`.`table1` trx id 589172 lock_mode X waiting
Record lock, heap no 2 PHYSICAL RECORD: n_fields 10; compact format; info bits 32
*** (2) TRANSACTION:
TRANSACTION 589174, ACTIVE 0 sec setting auto-inc lock
mysql tables in use 1, locked 1
6 lock struct(s), heap size 1248, 3 row lock(s), undo log entries 1
MySQL thread id 17049, OS thread handle 0x12345, query id 12345679 localhost root auto_increment
INSERT INTO table1 (column2, column3) VALUES ('def', 'ghi')
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 1221 page no 4 n bits 72 index idx_column1 of table `database`.`table1` trx id 589174 lock_mode X
Record lock, heap no 1 PHYSICAL RECORD: n_fields 10; compact format; info bits 32
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
TABLE LOCK table `database`.`table2` trx id 589174 lock mode AUTO-INC waiting
在上面的结果中,我们可以看到"DETECTED DEADLOCK"的标题,表明了死锁的存在。接着我们可以看到其中两个事务,分别是TRANSACTION 589172和TRANSACTION 589174,同时它们之间也出现了死锁。
对于TRANSACTION 589172,可知它在SELECT语句中使用了FOR UPDATE关键字,语句为"SELECT * FROM table1 WHERE column1 = 'abc' FOR UPDATE"。同时在输出中还显示了record lock,这表明此时它正在等待另一个事务的commit操作。
对于TRANSACTION 589174,可以看到它的情况就复杂一些。它在执行"INSERT INTO table1 (column2, column3) VALUES ('def', 'ghi')"语句,并拥有着一个record lock。同时,它还在等待表table2的auto-increment锁。
从以上结果分析我们不但可以了解死锁的存在,而且还可以查看具体的事务信息和我们执行的库表和语句等。尽管这并不是一个完整的步骤来避免死锁的问题,但它可以帮助我们确定在哪些地方可能会出现死锁,这样我们就可以对代码进行相应的优化。