mirror of
https://github.com/CyC2018/Interview-Notebook.git
synced 2026-11-06 04:54:09 +00:00
Update 计算机操作系统 - 死锁.md
补充按线程 ID 查询更早执行的语句,附录 A3 补实测输出。
This commit is contained in:
+22
-1
@@ -262,7 +262,15 @@ INSERT INTO payment VALUES (1025, 50); -- 同样等待事务 1
|
||||
|
||||
读 MySQL 8.0 的死锁日志时,两个事务的情况下 (2) 是最后开始等待、使等待关系形成环的事务,(1) 是它在等的事务;(1) HOLDS THE LOCK(S) 列出的就是 (2) 在等的那把锁,反之亦然。
|
||||
|
||||
每个事务只显示当时正在执行的语句,持有的锁可能是更早的语句加的,例如附录 A3 中两个事务显示的都是 INSERT,间隙锁却来自之前的 SELECT ... FOR UPDATE。
|
||||
每个事务只显示当时正在执行的语句,持有的锁可能是更早的语句加的,例如附录 A3 中两个事务显示的都是 INSERT,间隙锁却来自之前的 SELECT ... FOR UPDATE。要找出更早的语句,可以按日志中的 MySQL thread id 查 performance_schema.events_statements_history,它默认为每个连接保留最近 10 条语句(MySQL 8.0 实测,见[附录 A3](#a3-先查后插的间隙锁死锁)):
|
||||
|
||||
```sql
|
||||
SELECT h.EVENT_ID, h.SQL_TEXT
|
||||
FROM performance_schema.events_statements_history h
|
||||
JOIN performance_schema.threads t ON t.THREAD_ID = h.THREAD_ID
|
||||
WHERE t.PROCESSLIST_ID = 4136 -- 死锁日志中的 MySQL thread id
|
||||
ORDER BY h.EVENT_ID;
|
||||
```
|
||||
|
||||
lock_mode X locks gap before rec 是间隙锁,后面再有 insert intention 的是插入意向锁,在 data_locks 中分别显示为 X,GAP 和 X,GAP,INSERT_INTENTION。
|
||||
|
||||
@@ -354,6 +362,19 @@ INSERT INTO payment VALUES (1025, 50)
|
||||
ERROR 1062 (23000) at line 1: Duplicate entry '1024' for key 'payment.PRIMARY'
|
||||
```
|
||||
|
||||
死锁发生后,按事务 2 的 MySQL thread id 查 events_statements_history(history_size 为 10,这个 consumer 默认开启),能看到它在 INSERT 之前执行的 SELECT ... FOR UPDATE(节选,省略了客户端连接时执行的语句):
|
||||
|
||||
```text
|
||||
*** (2) TRANSACTION:
|
||||
MySQL thread id 4136, OS thread handle 6157561856, query id 4812446 localhost root update
|
||||
INSERT INTO payment VALUES (1025, 50)
|
||||
|
||||
EVENT_ID SQL_TEXT
|
||||
3 BEGIN
|
||||
5 SELECT * FROM payment WHERE order_id = 1025 FOR UPDATE
|
||||
6 INSERT INTO payment VALUES (1025, 50)
|
||||
```
|
||||
|
||||
执行 SET GLOBAL innodb_print_all_deadlocks = ON 后,再执行一遍可重复读的例子,错误日志中同样记录了两个事务持有的间隙锁和等待的插入意向锁(lock_mode X locks gap before rec insert intention waiting)。
|
||||
|
||||
### A4 死锁线程的状态与 CPU 时间
|
||||
|
||||
Reference in New Issue
Block a user