精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

MySQL 加鎖機制驗證記錄

數據庫 MySQL
MySQL 官方文檔 給出了不同類型語句的加鎖情形,但我覺得 這個總結 更到位,因此想結合文章的幾種情形,結合 InnoDB Monitor Output 做分析。文章是驗證過程的記錄,全文比較長,建議結合目錄查看感興趣的部分。

MySQL 官方文檔 給出了不同類型語句的加鎖情形,但我覺得 這個總結 更到位,因此想結合文章的幾種情形,結合 InnoDB Monitor Output 做分析。

文章是驗證過程的記錄,全文比較長,建議結合目錄查看感興趣的部分。

開啟 InnoDB Monitor

參考: 官方文檔

 

  1. SET GLOBAL innodb_status_output=ON-- 開啟輸出  
  2. SET GLOBAL innodb_status_output_locks=ON-- 開啟鎖信息輸出 

注意這些選項在 mysql 重啟后會恢復默認值。接下來使用命令查看信息:

  1. SHOW ENGINE INNODB STATUS\G 

樣例輸出,我們只關心鎖相關的內容:

 

  1. ---TRANSACTION 929632, ACTIVE 27 sec 
  2. 2 lock struct(s), heap size 1136, 1 row lock(s), undo log entries 1 
  3. MySQL thread id 1309, OS thread handle 123145430310912, query id 9179 localhost root 
  4. TABLE LOCK table `test`.`id_pk_rc` trx id 929632 lock mode IX 
  5. RECORD LOCKS space id 1813 page no 3 n bits 72 index PRIMARY of table `test`.`id_pk_rc` trx id 929632 lock_mode X locks rec but not gap 
  6. Record lock, heap no 4 PHYSICAL RECORD: n_fields 4; compact format; info bits 32 
  7.  0: len 4; hex 80000005; asc     ;; 
  8.  1: len 6; hex 0000000e2f60; asc     /`;; 
  9.  2: len 7; hex 4c000002222e83; asc L   ". ;; 
  10.  3: len 1; hex 63; asc c;; 
  • “page no 3 n bits 72” 代表在第 3 頁的記錄上,lock bitmap 共 72 位
  • “index PRIMARY of …” 代表鎖在某個索引上,PRIMARY 代表鎖在主鍵上
  • “lock_mode X” 鎖模式,X 代表互斥,鎖模式可以參數官方文檔 InnoDB Locking
  • “locks rec but not gap” 代表記錄鎖,“locks gap before rec” 代表間隙鎖,沒有說明則代表 Next Key Lock
  • “heap no 4” 代表記錄的序號,0 代表 infimum 記錄、1 代表 supremum 記錄,用戶記錄從 2 開始
  • PHYSICAL RECORD 后面的內容是索引記錄的內存結構,通常沒辦法直接閱讀

這個記錄里沒法直接看出鎖住了哪些記錄。一種方法是通過 select * from information_schema.innodb_locks \G; 查看搶鎖沒搶到的信息,為了查看記錄,在測試時可以另開一個會話,用諸如 SELECT * FROM ... WHERE ... FOR UPDATE 來搶鎖,這樣就可以看出鎖在哪個記錄上了。樣例輸出:

 

  1. lock_id     | 929771:1817:4:4 
  2. lock_trx_id | 929771 
  3. lock_mode   | X 
  4. lock_type   | RECORD 
  5. lock_table  | `test`.`id_si_rc` 
  6. lock_index  | id_si 
  7. lock_space  | 1817 
  8. lock_page   | 4 
  9. lock_rec    | 4 
  10. lock_data   | 5, 3 -- 注意這里是數據標識 

還有一個工具好用的工具 innodb_ruby 可以用來解析 MySQL 的靜態文件。Monitor 日志里我們知道是哪個頁的哪條記錄,可以使用innodb_ruby 來找到對應的記錄。(不過不建議在生產上使用)

不同情形下加鎖驗證

我們會考查 DELETE FROM t1 WHERE id = 5 語句在不同情形下的加鎖情況,通過構造數據、執行語句、查看 Monitor 日志來驗證加鎖的機制。

主鍵 + RC

結論:只對 ID = 5 這條記錄加 Record Lock

 

首先建表準備數據:

 

  1. -- 建表 
  2. CREATE TABLE id_pk_rc(id int primary keyname varchar(32)); 
  3.  
  4. -- 準備數據 
  5. INSERT INTO id_pk_rc values(1, 'a'); 
  6. INSERT INTO id_pk_rc values(3, 'b'); 
  7. INSERT INTO id_pk_rc values(5, 'c'); 
  8. INSERT INTO id_pk_rc values(7, 'c'); 
  9. INSERT INTO id_pk_rc values(9, 'b'); 

執行語句

 

  1. -- 設置為 RC 隔離級別 
  2. SET TRANSACTION ISOLATION LEVEL READ COMMITTED
  3. BEGIN-- 開啟事務 
  4. DELETE FROM id_pk_rc WHERE id = 5; 
  5. -- 先不結束事務,驗證 Monitor Output 再用 ROLLBACK; 回滾 

Monitor 輸出日志:

 

  1. ---TRANSACTION 929632, ACTIVE 27 sec 
  2. 2 lock struct(s), heap size 1136, 1 row lock(s), undo log entries 1 
  3. MySQL thread id 1309, OS thread handle 123145430310912, query id 9179 localhost root 
  4. TABLE LOCK table `test`.`id_pk_rc` trx id 929632 lock mode IX 
  5. RECORD LOCKS space id 1813 page no 3 n bits 72 index PRIMARY of table `test`.`id_pk_rc` trx id 929632 lock_mode X locks rec but not gap 
  6. Record lock, heap no 4 PHYSICAL RECORD: n_fields 4; compact format; info bits 32 
  7.  0: len 4; hex 80000005; asc     ;; 
  8.  1: len 6; hex 0000000e2f60; asc     /`;; 
  9.  2: len 7; hex 4c000002222e83; asc L   ". ;; 
  10.  3: len 1; hex 63; asc c;; 

看到輸出里有 lock_mode X locks rec but not gap ,可以確定持有的是記錄鎖。

唯一索引 + RC

結論:索引和聚簇索引/主鍵中都對 ID = 5 加 Record Lock

首先建表準備數據:

 

  1. -- 建表 
  2. CREATE TABLE id_ui_rc(pk int primary key, id intname varchar(32)); 
  3. CREATE UNIQUE INDEX id_ui ON id_ui_rc(id); 
  4.  
  5. -- 準備數據 
  6. INSERT INTO id_ui_rc values(1, 1, 'a'); 
  7. INSERT INTO id_ui_rc values(2, 3, 'b'); 
  8. INSERT INTO id_ui_rc values(3, 5, 'c'); 
  9. INSERT INTO id_ui_rc values(4, 7, 'c'); 
  10. INSERT INTO id_ui_rc values(5, 9, 'b'); 

執行語句:

 

  1. -- 設置為 RC 隔離級別 
  2. SET TRANSACTION ISOLATION LEVEL READ COMMITTED
  3. BEGIN-- 開啟事務 
  4. DELETE FROM id_ui_rc WHERE id = 5; 
  5. -- 先不結束事務,驗證 Monitor Output 再用 ROLLBACK; 回滾 

Monitor 輸出日志:

 

  1. ---TRANSACTION 929694, ACTIVE 6 sec 
  2. 3 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 1 
  3. MySQL thread id 1309, OS thread handle 123145430310912, query id 9241 localhost root 
  4. TABLE LOCK table `test`.`id_ui_rc` trx id 929694 lock mode IX 
  5. RECORD LOCKS space id 1815 page no 4 n bits 72 index id_ui of table `test`.`id_ui_rc` trx id 929694 lock_mode X locks rec but not gap 
  6. Record lock, heap no 4 PHYSICAL RECORD: n_fields 2; compact format; info bits 32 
  7.  0: len 4; hex 80000005; asc     ;; 
  8.  1: len 4; hex 80000003; asc     ;; 
  9.  
  10. RECORD LOCKS space id 1815 page no 3 n bits 72 index PRIMARY of table `test`.`id_ui_rc` trx id 929694 lock_mode X locks rec but not gap 
  11. Record lock, heap no 4 PHYSICAL RECORD: n_fields 5; compact format; info bits 32 
  12.  0: len 4; hex 80000003; asc     ;; 
  13.  1: len 6; hex 0000000e2f9e; asc     / ;; 
  14.  2: len 7; hex 7a0000059525c9; asc z    % ;; 
  15.  3: len 4; hex 80000005; asc     ;; 
  16.  4: len 1; hex 63; asc c;; 

可以看到分別對 index id_ui 和 index PRIMARY 加了 Record Lock。

非唯一索引 + RC

結論:會對所有 ID = 5 的索引記錄加 Record Lock,同時對主鍵加 Record Lock。

首先建表準備數據:

 

  1. -- 建表 
  2. CREATE TABLE id_si_rc(pk int primary key, id intname varchar(32)); 
  3. CREATE INDEX id_si ON id_si_rc(id); 
  4.  
  5. -- 準備數據 
  6. INSERT INTO id_si_rc values(1, 1, 'a'); 
  7. INSERT INTO id_si_rc values(2, 3, 'b'); 
  8. INSERT INTO id_si_rc values(3, 5, 'c'); 
  9. INSERT INTO id_si_rc values(4, 7, 'c'); 
  10. INSERT INTO id_si_rc values(5, 5, 'b'); 

執行語句:

 

  1. -- 設置為 RC 隔離級別 
  2. SET TRANSACTION ISOLATION LEVEL READ COMMITTED
  3. BEGIN-- 開啟事務 
  4. DELETE FROM id_si_rc WHERE id = 5; 
  5. -- 先不結束事務,驗證 Monitor Output 再用 ROLLBACK; 回滾 

Monitor 輸出日志(省略了 PHYSICAL RECORD 的內容):

 

  1. ---TRANSACTION 929779, ACTIVE 3 sec 
  2. 3 lock struct(s), heap size 1136, 4 row lock(s), undo log entries 2 
  3. MySQL thread id 1309, OS thread handle 123145430310912, query id 9325 localhost root 
  4. TABLE LOCK table `test`.`id_si_rc` trx id 929779 lock mode IX 
  5. RECORD LOCKS space id 1817 page no 4 n bits 72 index id_si of table `test`.`id_si_rc` trx id 929779 lock_mode X locks rec but not gap 
  6. Record lock, heap no 4 PHYSICAL RECORD: n_fields 2; compact format; info bits 32 
  7.  ... 
  8. Record lock, heap no 6 PHYSICAL RECORD: n_fields 2; compact format; info bits 32 
  9.  ... 
  10.  
  11. RECORD LOCKS space id 1817 page no 3 n bits 72 index PRIMARY of table `test`.`id_si_rc` trx id 929779 lock_mode X locks rec but not gap 
  12. Record lock, heap no 4 PHYSICAL RECORD: n_fields 5; compact format; info bits 32 
  13.  ... 
  14. Record lock, heap no 6 PHYSICAL RECORD: n_fields 5; compact format; info bits 32 
  15.  ... 

可以看到一共有 4 條記錄,首先可以看到索引 id_si 和 PRIMARY 分別鎖住了兩條記錄,加的鎖都是 X Record Lock No Gap,也就是記錄鎖。我們通過 select * from information_schema.innodb_locks \G; 查看是鎖住了 3, 5 這兩條記錄。

 

  1. lock_id     | 929779:1817:4:4 
  2. lock_trx_id | 929779 
  3. lock_mode   | X 
  4. lock_type   | RECORD 
  5. lock_table  | `test`.`id_si_rc` 
  6. lock_index  | id_si 
  7. lock_space  | 1817 
  8. lock_page   | 4 
  9. lock_rec    | 4 
  10. lock_data   | 5, 3  <- 注意這里 

無索引 + RC

結論:對所有記錄加 Record Lock 再釋放不匹配的記錄鎖

這個情形比較特殊,涉及兩個 知識點

  1. MySQL 加鎖時是對處理過程中“掃描”到的記錄加鎖,不管這條記錄最終是不是通過 WHERE 語句剔除了
  2. 對于 READ COMMITTED,MySQL 在掃描結束后,會違反 #1,釋放 WHERE 條件不滿足的記錄鎖

首先建表準備數據:

 

  1. -- 建表 
  2. CREATE TABLE id_ni_rc(pk int primary key, id intname varchar(32)); 
  3.  
  4. -- 準備數據 
  5. INSERT INTO id_ni_rc values(1, 1, 'a'); 
  6. INSERT INTO id_ni_rc values(2, 3, 'b'); 
  7. INSERT INTO id_ni_rc values(3, 5, 'c'); 
  8. INSERT INTO id_ni_rc values(4, 7, 'c'); 
  9. INSERT INTO id_ni_rc values(5, 5, 'b'); 

執行語句:

 

  1. -- 設置為 RC 隔離級別 
  2. SET TRANSACTION ISOLATION LEVEL READ COMMITTED
  3. BEGIN-- 開啟事務 
  4. DELETE FROM id_ni_rc WHERE id = 5; 
  5. -- 先不結束事務,驗證 Monitor Output 再用 ROLLBACK; 回滾 

Monitor 輸出日志(省略了 PHYSICAL RECORD 的內容):

 

  1. ---TRANSACTION 1446, ACTIVE 17 sec 
  2. 2 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 2 
  3. MySQL thread id 7, OS thread handle 123145446559744, query id 267 localhost root 
  4. TABLE LOCK table `test`.`id_ni_rc` trx id 1446 lock mode IX 
  5. RECORD LOCKS space id 27 page no 3 n bits 72 index PRIMARY of table `test`.`id_ni_rc` trx id 1446 lock_mode X locks rec but not gap 
  6. Record lock, heap no 4 PHYSICAL RECORD: n_fields 5; compact format; info bits 32 
  7.  ... 
  8. Record lock, heap no 6 PHYSICAL RECORD: n_fields 5; compact format; info bits 32 
  9.  ... 

看到 TABLE LOCK 的狀態是 IX 說明沒有加表鎖。同時看到最終鎖住的只有heap_no = 4 和 6 的兩條記錄。

主鍵 + RR

當 ID 為主鍵時,在 RR 隔離級別下,加鎖情況與一致,都是對主鍵記錄加 Record Lock。

唯一索引 + RR

當 ID 為唯一索引時,在 RR 隔離級別下,加鎖情況與一致,都是對索引記錄和聚簇索引/主鍵 Record Lock。

非唯一索引 + RR

結論:對索引記錄 Next Key Lock,末尾加 Gap Lock,同時對主鍵加 Record Lock

Repeatable Read 和 Read Committed 隔離級別的主要區別是 RR 要防止幻讀。幻讀指的是執行同一個 SQL 兩次得到的結果不同。考慮下面的場景:

 

  1. SELECT count(*) FROM t WHERE id = 5 FOR UPDATE 
  2. id = 5 
  3. SELECT count(*) FROM t WHERE id = 5 FOR UPDATE 

為了要避免這種情況,在 RR 隔離級別下,在 #1 執行時不僅要鎖住現有的 ID=5 的索引,還需要阻止 ID = 5 的記錄插入(即 #2)。而 Gap Lock 就是實現這個目的的一種手段。

考慮到索引是有序的,因此如果索引里有 [3, 5, 5, 7] 這幾個元素,則可以通過鎖住 (3, 5) 、 (5, 7) 這幾個區間,加上 [5] 這幾個已經存在的元素,就可以阻止 ID = 5 的記錄插入。Gap Lock(間隙鎖)的含義是鎖住區間,而如果加上右邊的閉區間,如 (3, 5] 就稱為記錄 5 的 Next-Key Lock。

InnoDB 在掃描行時會為掃到的行加上 Next-Key Lock,對于上面的數據,掃到記錄 5 時,會加上 (3, 5] 鎖,同時,還會對下一個記錄加上 Gap Lock,即 (5, 7) ,造成 (3, 7) 都無法插入的現象,驗證 MySQL 實現如下:

首先建表準備數據:

 

  1. -- 建表 
  2. CREATE TABLE id_si_rr(pk int primary key, id intname varchar(32)); 
  3. CREATE INDEX id_si ON id_si_rr(id); 
  4.  
  5.  
  6. -- 準備數據 
  7. INSERT INTO id_si_rr values(1, 1, 'a'); 
  8. INSERT INTO id_si_rr values(2, 3, 'b'); 
  9. INSERT INTO id_si_rr values(3, 5, 'c'); 
  10. INSERT INTO id_si_rr values(4, 7, 'c'); 
  11. INSERT INTO id_si_rr values(5, 5, 'b'); 

執行語句:

 

  1. -- 設置為 RC 隔離級別 
  2. SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
  3. BEGIN-- 開啟事務 
  4. DELETE FROM id_si_rr WHERE id = 5; 
  5. -- 先不結束事務,驗證 Monitor Output 再用 ROLLBACK; 回滾 

Monitor 輸出日志(省略 PHYSICAL RECORD 的內容):

 

  1. ---TRANSACTION 929891, ACTIVE 6 sec 
  2. 4 lock struct(s), heap size 1136, 5 row lock(s), undo log entries 2 
  3. MySQL thread id 1309, OS thread handle 123145430310912, query id 9442 localhost root 
  4. TABLE LOCK table `test`.`id_si_rr` trx id 929891 lock mode IX 
  5. RECORD LOCKS space id 1820 page no 4 n bits 72 index id_si of table `test`.`id_si_rr` trx id 929891 lock_mode X 
  6. Record lock, heap no 4 PHYSICAL RECORD: n_fields 2; compact format; info bits 32 
  7.  ... 
  8. Record lock, heap no 6 PHYSICAL RECORD: n_fields 2; compact format; info bits 32 
  9.  ... 
  10.  
  11. RECORD LOCKS space id 1820 page no 3 n bits 72 index PRIMARY of table `test`.`id_si_rr` trx id 929891 lock_mode X locks rec but not gap 
  12. Record lock, heap no 4 PHYSICAL RECORD: n_fields 5; compact format; info bits 32 
  13.  ... 
  14. Record lock, heap no 6 PHYSICAL RECORD: n_fields 5; compact format; info bits 32 
  15.  ... 
  16.  
  17. RECORD LOCKS space id 1820 page no 4 n bits 72 index id_si of table `test`.`id_si_rr` trx id 929891 lock_mode X locks gap before rec 
  18. Record lock, heap no 5 PHYSICAL RECORD: n_fields 2; compact format; info bits 0 
  19.  ... 

首先我們看到:

 

  1. id_si 
  2. id_si 

為什么唯一索引 + RR 就不需要 Gap Lock 呢?是因為我們的核心目的是不讓其它事務插入 ID = 5 的記錄,如果 ID 是唯一索引,鎖住記錄本身就能夠滿足要求了,不再需要 Gap Lock。

無索引 + RR

結論:對所有行都加記錄鎖,且索引前后都要加 Gap Lock

首先建表準備數據:

 

  1. -- 建表 
  2. CREATE TABLE id_ni_rr(pk int primary key, id intname varchar(32)); 
  3.  
  4. -- 準備數據 
  5. INSERT INTO id_ni_rr values(1, 1, 'a'); 
  6. INSERT INTO id_ni_rr values(2, 3, 'b'); 
  7. INSERT INTO id_ni_rr values(3, 5, 'c'); 
  8. INSERT INTO id_ni_rr values(4, 7, 'c'); 
  9. INSERT INTO id_ni_rr values(5, 5, 'b'); 

執行語句:

 

  1. -- 設置為 RC 隔離級別 
  2. SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
  3. BEGIN-- 開啟事務 
  4. DELETE FROM id_ni_rr WHERE id = 5; 
  5. -- 先不結束事務,驗證 Monitor Output 再用 ROLLBACK; 回滾 

Monitor 輸出日志(省略了部分信息):

 

  1. ---TRANSACTION 929980, ACTIVE 5 sec 
  2. 2 lock struct(s), heap size 1136, 6 row lock(s), undo log entries 2 
  3. MySQL thread id 1309, OS thread handle 123145430310912, query id 9529 localhost root 
  4. TABLE LOCK table `test`.`id_ni_rr` trx id 929980 lock mode IX 
  5. RECORD LOCKS space id 1822 page no 3 n bits 72 index PRIMARY of table `test`.`id_ni_rr` trx id 929980 lock_mode X 
  6. Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0 
  7.  0: len 8; hex 73757072656d756d; asc supremum;; 
  8.  
  9. Record lock, heap no 2 PHYSICAL RECORD: n_fields 5; compact format; info bits 0 
  10.  ... 
  11. Record lock, heap no 3 PHYSICAL RECORD: n_fields 5; compact format; info bits 0 
  12.  ... 
  13. Record lock, heap no 4 PHYSICAL RECORD: n_fields 5; compact format; info bits 32 
  14.  ... 
  15. Record lock, heap no 5 PHYSICAL RECORD: n_fields 5; compact format; info bits 0 
  16.  ... 
  17. Record lock, heap no 6 PHYSICAL RECORD: n_fields 5; compact format; info bits 32 
  18.  ... 

首先看到 TABLE LOCK 的狀態是 IX 說明沒有加表鎖。同時看到鎖住了 heap no 2~6的記錄,對應數據庫中的 5 條記錄。另外這里的鎖是 Next Key Lock,加上 heap no 為 1 的 “supremum” 記錄的 gap lock,鎖住了所有已經存在和不存在的行。因此如果執行 SELECT * FROM id_ni_rc WHERE id = 0 FOR UPDATE 也會阻塞,盡管 0 記錄不在數據庫中。

死鎖驗證

死鎖與獲取鎖的順序有關,一條語句(如 INSERT、DELETE)中對不同行、不同索引的加鎖存在先后,因此不同事務內的語句執行時,有可能產生死鎖。常見死鎖原因(摘自 MySQL InnoDB鎖和死鎖 ):

  • 同一索引上,兩個session相反的順序加鎖多行記錄
  • UPDATE/DELETE 通過不同的二級索引更新多條記錄,可能造成在 Primary key 上不同的加鎖順序
  • Primary key 和 Secondary index,通過 primary key 找到記錄,更新 Secondary index 字段與通過 Secondary index 更新記錄

樣例情形:

首先建表準備數據:

 

  1. CREATE TABLE deadlock(id int primary keyname varchar(32), reg int); 
  2. CREATE INDEX deadlock_name ON deadlock(name); 
  3. CREATE INDEX deadlock_reg ON deadlock(reg); 
  4.  
  5. -- 準備數據 
  6. INSERT INTO deadlock values(1, 'x', 5); 
  7. INSERT INTO deadlock values(2, 'b', 4); 
  8. INSERT INTO deadlock values(3, 'x', 3); 
  9. INSERT INTO deadlock values(4, 'd', 2); 
  10. INSERT INTO deadlock values(5, 'e', 1); 

兩個事務分別“同時”執行:

 

  1. -- Transaction A                       | -- Transaction B 
  2. DELETE FROM deadlock WHERE name = 'x'; | DELETE FROM deadlock WHERE reg >= 2; 

其中一個事務可能會檢測到死鎖而出錯。Monitor 日志里找到 “LATEST DETECTED DEADLOCK” 可以看到記錄的死鎖原因(這個示例復現出的問題與上圖不直接一致):

 

  1. ------------------------ 
  2. LATEST DETECTED DEADLOCK 
  3. ------------------------ 
  4. 2020-12-13 15:59:40 0x700007a56000 
  5. *** (1) TRANSACTION
  6. TRANSACTION 930064, ACTIVE 0 sec starting index read 
  7. mysql tables in use 1, locked 1 
  8. LOCK WAIT 3 lock struct(s), heap size 1136, 2 row lock(s) 
  9. MySQL thread id 1309, OS thread handle 123145430310912, query id 9616 localhost root updating 
  10. DELETE FROM deadlock WHERE name = 'x' 
  11. *** (1) WAITING FOR THIS LOCK TO BE GRANTED: 
  12. RECORD LOCKS space id 1825 page no 3 n bits 72 index PRIMARY of table `test`.`deadlock` trx id 930064 lock_mode X locks rec but not gap waiting 
  13. Record lock, heap no 2 PHYSICAL RECORD: n_fields 5; compact format; info bits 32 
  14.  ... 
  15.  
  16. *** (2) TRANSACTION
  17. TRANSACTION 930063, ACTIVE 0 sec updating or deleting 
  18. mysql tables in use 1, locked 1 
  19. 3 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 1 
  20. MySQL thread id 1308, OS thread handle 123145430589440, query id 9615 localhost root updating 
  21. DELETE FROM deadlock WHERE reg >= 2 
  22. *** (2) HOLDS THE LOCK(S): 
  23. RECORD LOCKS space id 1825 page no 3 n bits 72 index PRIMARY of table `test`.`deadlock` trx id 930063 lock_mode X 
  24. Record lock, heap no 2 PHYSICAL RECORD: n_fields 5; compact format; info bits 32 
  25.  ... 
  26.  
  27. *** (2) WAITING FOR THIS LOCK TO BE GRANTED: 
  28. RECORD LOCKS space id 1825 page no 4 n bits 72 index deadlock_name of table `test`.`deadlock` trx id 930063 lock_mode X locks rec but not gap waiting 
  29. Record lock, heap no 2 PHYSICAL RECORD: n_fields 2; compact format; info bits 0 
  30.  ... 
  31.  
  32. *** WE ROLL BACK TRANSACTION (1) 

我們看到:

  • 第一個事務在等待 PRIMARY 索引上 heap_no = 2 的記錄的 Record Lock
  • 第二個事務已經取得 PRIMARY 索引上 heap_no = 2 的 Next Key Lock
  • 同時第二個事務在等待 deadlock_name 索引上 heap_no = 2 的 Record Lock
  • MySQL 選擇回滾第一個事務

更新操作如 UPDATE/DELETE 加鎖的順序為: 查詢索引 > 主鍵索引 > 其它二級索引 。如上例中,第二個事務已經鎖住了主鍵索引,準備鎖住另一個二級索引 deadlock_name ,而第一個已經鎖住了 deadlock_name ,準備鎖主鍵索引,造成死鎖。

責任編輯:未麗燕 來源: lotabout.me
相關推薦

2010-11-15 13:47:13

oracle記錄加鎖

2025-09-16 07:09:32

2009-07-16 16:51:56

WebWork驗證機制

2017-05-15 18:00:43

MySQ加鎖處理

2020-11-08 14:32:01

JavaScript變量內存管理

2009-03-20 14:38:14

CAM介紹CAMXML結構驗證

2010-10-29 10:56:46

ORACLE用戶驗證

2022-12-29 09:49:06

輕量級架構決策

2017-08-30 18:15:54

MySql

2020-07-16 21:20:08

數據庫MySQL死鎖

2010-01-04 10:34:01

Silverlight

2021-06-08 09:41:26

MySQL加鎖范圍

2021-11-11 13:05:25

MySQLINSERT

2013-05-03 09:44:52

2012-02-20 09:55:41

ibmdw

2021-09-06 18:55:57

MySQLCheckpoint機制

2022-11-09 10:46:18

AQS加鎖機制

2021-06-06 13:03:53

MySQL普通索引

2023-03-27 17:58:34

MySQL加鎖間隙鎖

2021-06-05 18:02:20

MySQL加鎖范圍
點贊
收藏

51CTO技術棧公眾號

亚洲成人tv| a√中文在线观看| 国内精品伊人久久久久av一坑| www.日韩视频| 国产草草浮力影院| 99久久婷婷国产综合精品首页 | 亚洲av成人片色在线观看高潮 | 欧美日韩国产欧| 精品伊人久久97| 欧美又黄又嫩大片a级| 国产欧洲在线| 自拍偷拍国产精品| 欧美精品亚洲精品| 亚洲国产成人在线观看| 日本伊人精品一区二区三区观看方式| 啊v视频在线一区二区三区| 中文字幕乱码在线| 日韩精品一区二区三区免费视频| 色婷婷综合久久久中文字幕| av一区二区三区免费观看| 久草视频在线看| 丁香激情综合国产| 国产日韩精品入口| 一级黄色av片| 99在线观看免费视频精品观看| 久久精品夜夜夜夜夜久久| 波多野结衣办公室33分钟| jizz国产精品| 51午夜精品国产| 91最新在线观看| 三级中文字幕在线观看| 亚洲综合免费观看高清完整版在线| 亚洲精品白虎| 麻豆导航在线观看| 成年人网站91| 国产精品久久久久av福利动漫| 亚洲在线观看av| 免费看精品久久片| 国产精品久久久久久久久久久新郎| 日韩在线观看第一页| 欧美激情一级片一区二区| 日韩在线观看免费全集电视剧网站| 丝袜美腿中文字幕| 日韩精品免费一区二区夜夜嗨 | 成人高潮成人免费观看| 91亚洲精华国产精华精华液| 国产一区二区三区色淫影院| 成人高潮片免费视频| 国产精品18久久久久久久久久久久 | 美州a亚洲一视本频v色道| 成人的网站免费观看| 国产精品日韩欧美一区二区| av男人天堂av| 亚洲欧洲av| 亚洲国产精品t66y| 欧美性天天影院| 欧美日韩国产中文字幕在线| jlzzjlzz国产精品久久| 国内精品一区二区| 天天操天天干天天爱| 免费电影视频在线看 | 少妇户外露出[11p]| 亚洲午夜精品| 亚洲国产精品悠悠久久琪琪| 污片免费在线观看| 亚洲区小说区图片区qvod| 亚洲欧美制服第一页| 一区二区伦理片| 日韩国产综合| 久久成人这里只有精品| 麻豆亚洲av成人无码久久精品| 国产精品国码视频| 91成人天堂久久成人| 成年人av网站| 蜜桃久久av一区| 成人免费观看网址| 亚洲经典一区二区三区| 99精品视频一区| 日韩欧美在线观看强乱免费| 黄色成人影院| 午夜欧美大尺度福利影院在线看 | 韩日精品视频一区| 99久久伊人精品影院| 日韩在线视频免费| 中文字幕av资源一区| 国产av第一区| 性国裸体高清亚洲| 欧美日韩久久不卡| 人妻激情偷乱频一区二区三区| 亚洲国产最新| 久久网福利资源网站| 日产电影一区二区三区| 日韩黄色免费网站| 91传媒免费看| 国产美女视频一区二区三区| 亚洲另类春色国产| 欧美丰满熟妇bbbbbb百度| 开心久久婷婷综合中文字幕| 精品国产免费一区二区三区四区| 性高潮久久久久久久| 这里只有精品在线| 国产成人精品999| 国产高清第一页| 久久久精品2019中文字幕之3| 中文字幕久久综合| 中文字幕高清在线播放| 欧美一区二区三区不卡| www.av欧美| 影音先锋久久精品| 91精品在线国产| 精品久久久久一区二区三区 | 99国产精品久| 蜜桃网站在线观看| 小明成人免费视频一区| 亚洲高清久久久久久| 精品国产国产综合精品| 久久狠狠一本精品综合网| 97视频资源在线观看| 在线播放毛片| 色综合天天综合网天天狠天天| 日韩av成人网| 亚洲欧美偷拍自拍| 国产精品爽爽爽| 亚洲av成人无码网天堂| 亚洲激情自拍视频| 一级黄色片在线免费观看| 精品国产中文字幕第一页| 97av在线视频| 欧美一级在线免费观看| 亚洲精品乱码久久久久久久久| 三级a三级三级三级a十八发禁止| 亚洲盗摄视频| 91精品国产精品| 日本美女一级视频| 亚洲小说欧美激情另类| 激情久久综合网| 国产精品99在线观看| 国产精品热视频| 国产特黄在线| 91国在线观看| 欧美人与性囗牲恔配| 久久男女视频| 欧美连裤袜在线视频| 久草免费在线视频| 日韩av资源在线播放| 精品成人av一区二区在线播放| 成人黄页在线观看| 蜜臀av无码一区二区三区| 亚洲精品一二三**| 久久久久久久久久久免费精品| 亚洲国产av一区二区| 性感美女极品91精品| 在线看黄色的网站| 一本色道久久综合| 免费精品视频一区| 国产一区二区主播在线| 中文字幕日韩在线播放| 国产又粗又猛又黄又爽无遮挡| 国产精品萝li| 中文字幕55页| 精品999日本| 精品日本一区二区三区在线观看 | 欧美日韩中文| 国产精品一 二 三| 亚洲黄色免费看| 中文字幕av一区二区三区谷原希美| 日批视频免费观看| 亚洲欧美视频一区| 日本一区二区在线观看视频| 在线综合亚洲| 亚洲精品二区| 亚洲国产中文在线| 全亚洲最色的网站在线观看| h视频网站在线观看| 日韩欧美一区二区不卡| 在线观看 中文字幕| 久久精品一级爱片| 人妻换人妻仑乱| 国产日韩综合| 一区二区三区四区五区精品| 中文字幕一区二区三区日韩精品| 97视频在线观看视频免费视频 | 亚洲aaa级| 国产欧美日韩精品在线观看| 欧美人体视频xxxxx| 亚洲欧美精品中文字幕在线| 亚洲视频在线观看一区二区| 亚洲午夜三级在线| 99精品欧美一区二区| 国产黄人亚洲片| 99久久久无码国产精品6| 水蜜桃久久夜色精品一区| 高清国产在线一区| 福利视频一区| 国自在线精品视频| 欧美极品另类| 亚洲男人天堂久| а√中文在线资源库| 色婷婷久久久亚洲一区二区三区| 国产免费一区二区三区四区| 91麻豆6部合集magnet| 国模大尺度视频| 视频一区国产视频| 三上悠亚久久精品| 亚洲欧美在线专区| 日韩av不卡在线播放| 伊人久久大香线蕉av超碰| 国产成人一区三区| 美女网站在线看| 久久亚洲综合国产精品99麻豆精品福利| 天堂在线免费av| 精品处破学生在线二十三| 国产绿帽一区二区三区| 色婷婷av一区二区三区软件| 久草视频在线资源| 亚洲视频免费观看| 麻豆视频免费在线播放| 久久亚洲春色中文字幕久久久| 无码人妻丰满熟妇区毛片蜜桃精品| 日韩成人午夜精品| 欧美丰满熟妇bbbbbb百度| 欧美网站在线| 国产一区一区三区| 日韩专区精品| 五月天国产一区| 国产精品免费不| 久久综合伊人77777麻豆| 99国产精品免费网站| 亚洲a成v人在线观看| 日本电影久久久| 国产精品美女久久久久av超清| 成人亚洲欧美| 青草成人免费视频| 午夜影视一区二区三区| 韩国视频理论视频久久| 黄色美女视频在线观看| 欧美激情视频三区| 中文字幕中文字幕在线十八区 | 中文字幕另类日韩欧美亚洲嫩草| 国产精品美女久久久久久久久久久| 51妺嘿嘿午夜福利| 国产日产亚洲精品系列| 亚洲AV无码成人精品区明星换面 | 精精国产xxxx视频在线野外| 欧美激情综合色综合啪啪五月| 制服丝袜在线播放| 欧美美女18p| 蜜臀av国内免费精品久久久夜夜| 久久国产精品网站| 日本动漫理论片在线观看网站| 欧美大尺度在线观看| 午夜小视频在线观看| 欧美日韩xxxxx| 波多野结衣在线高清| 8050国产精品久久久久久| 婷婷电影在线观看| 国产精品久久久久久久久久免费| 男人亚洲天堂| 99国产在线观看| 欧美三级午夜理伦三级在线观看| 蜜桃视频成人| 欧美亚洲精品在线| 麻豆传媒网站在线观看| 激情婷婷久久| 少妇高清精品毛片在线视频| 轻轻草成人在线| 成人性生交视频免费观看| 国产成人av电影在线| 手机在线成人av| 国产欧美一区二区精品婷婷| 美女视频久久久| 亚洲国产美女搞黄色| 三级视频在线观看| 欧美精品成人一区二区三区四区| 亚洲国产精品久久久久爰性色 | xvideos国产在线视频| 国语自产偷拍精品视频偷| 日韩免费小视频| 97超碰最新| 黑丝美女一区二区| 草草草视频在线观看| 亚洲欧美日韩国产一区二区| 色婷婷综合网站| 成人午夜私人影院| 手机看片日韩av| 亚洲一区二区精品3399| 欧美人一级淫片a免费播放| 欧美一区二区日韩一区二区| 日本人妖在线| 欧美www在线| 欧美与亚洲与日本直播| 99精品国产高清一区二区| 国产va免费精品观看精品视频| 亚洲综合激情五月| 免费亚洲网站| 中文字幕欧美视频| 国产欧美精品一区二区三区四区| 精品无码人妻一区二区三| 欧美视频一区二区三区在线观看| 亚洲乱色熟女一区二区三区| 伊人伊成久久人综合网小说| 超黄网站在线观看| 成人欧美一区二区三区黑人孕妇| 伊人成综合网yiren22| 日韩精品手机在线观看| 日本色综合中文字幕| 艳妇乳肉亭妇荡乳av| 亚洲美女区一区| 国产成人麻豆免费观看| 亚洲国产欧美一区| 性欧美ⅴideo另类hd| 国产精品男人的天堂| 亚洲高清极品| av免费看网址| 国产寡妇亲子伦一区二区| 美国黄色特级片| 欧美性生交xxxxx久久久| 亚洲精品无码久久久| 久久这里有精品视频| 国产成人a视频高清在线观看| 免费看污久久久| 国产欧美丝祙| 看全色黄大色黄女片18| 亚洲精品国产成人久久av盗摄 | 亚洲精品动漫久久久久| 日本一本在线免费福利| 成人网页在线免费观看| 91久久夜色精品国产按摩| 天天爽天天爽夜夜爽| 国产亚洲污的网站| 久久久精品毛片| 亚洲视频一区二区| 欧美精品资源| 日韩亚洲视频| 免费观看在线综合| 99久久久无码国产精品不卡| 欧美系列在线观看| 岛国最新视频免费在线观看| 2019中文字幕全在线观看| 欧美精品国产白浆久久久久| 精品少妇在线视频| av日韩在线网站| 久久久久久少妇| 亚洲欧美精品一区二区| free欧美| 亚洲乱码一区二区三区 | 国产日韩欧美一二三区| 欧美电影一区| 亚洲理论中文字幕| 亚洲蜜臀av乱码久久精品| www.天堂av.com| 欧美极品欧美精品欧美视频| 丁香一区二区| 国模吧无码一区二区三区| 久久久综合激的五月天| 午夜精品免费观看| 最近2019好看的中文字幕免费| 四虎国产精品免费久久| 热久久最新网址| 亚洲精品成a人在线观看| 国产手机视频在线| 欧美久久久精品| 精品网站aaa| 国产第一页视频| 欧美国产日本韩| 国产女人18毛片水真多| 欧美国产第一页| 奇米777国产一区国产二区| aaa毛片在线观看| 国产精品久久久久久久久快鸭| 国产麻豆免费视频| 97av在线影院| 欧美美女视频| 天天操夜夜操很很操| 午夜视黄欧洲亚洲| 国产黄色在线| 91成人理论电影| 亚洲综合精品| 久久精品在线观看视频| 日韩一级片在线播放| 欧美aaaaa性bbbbb小妇| 天堂√在线观看一区二区| 国产一区二区免费视频| 久久免费激情视频| 精品激情国产视频| 久久久久久毛片免费看| 艹b视频在线观看| 午夜精品免费在线| 日本中文在线观看| 国产精品久久久久免费| 青青草97国产精品免费观看| 免费一级肉体全黄毛片| 亚洲天堂男人天堂| 成人台湾亚洲精品一区二区| 亚洲精品高清无码视频| 亚洲一区二区三区免费视频| 日本在线人成| 免费电影一区| 国产91精品精华液一区二区三区 | av一区二区三区四区电影|