文件首頁
MySQL 8.4 參考手冊
相關文件 下載本手冊
PDF (美式信紙) - 39.9Mb
PDF (A4) - 40.0Mb
Man Pages (TGZ) - 258.5Kb
Man Pages (Zip) - 365.5Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


17.15.2.1 使用 InnoDB 交易與鎖定資訊

本節說明如何使用效能綱要 data_locksdata_lock_waits 資料表所公開的鎖定資訊。

識別封鎖交易

有時識別哪個交易封鎖另一個交易很有幫助。包含 InnoDB 交易與資料鎖定相關資訊的資料表可讓您判斷哪個交易正在等待另一個交易,以及正在請求哪個資源。(這些資料表的描述請參閱第 17.15.2 節,「InnoDB INFORMATION_SCHEMA 交易與鎖定資訊」。)

假設有三個工作階段同時執行。每個工作階段對應一個 MySQL 執行緒,並依序執行一個接一個的交易。考量這些工作階段已發出下列陳述式,但尚未提交其交易時系統的狀態

  • 工作階段 A

    BEGIN;
    SELECT a FROM t FOR UPDATE;
    SELECT SLEEP(100);
  • 工作階段 B

    SELECT b FROM t FOR UPDATE;
  • 工作階段 C

    SELECT c FROM t FOR UPDATE;

在此情境中,使用下列查詢來查看哪些交易正在等待,以及哪些交易正在封鎖它們

SELECT
  r.trx_id waiting_trx_id,
  r.trx_mysql_thread_id waiting_thread,
  r.trx_query waiting_query,
  b.trx_id blocking_trx_id,
  b.trx_mysql_thread_id blocking_thread,
  b.trx_query blocking_query
FROM       performance_schema.data_lock_waits w
INNER JOIN information_schema.innodb_trx b
  ON b.trx_id = w.blocking_engine_transaction_id
INNER JOIN information_schema.innodb_trx r
  ON r.trx_id = w.requesting_engine_transaction_id;

或者,更簡單地說,使用 sys 綱要 innodb_lock_waits 檢視

SELECT
  waiting_trx_id,
  waiting_pid,
  waiting_query,
  blocking_trx_id,
  blocking_pid,
  blocking_query
FROM sys.innodb_lock_waits;

如果封鎖查詢報告 NULL 值,請參閱在發出工作階段變成閒置狀態之後識別封鎖查詢

正在等待的交易 ID 正在等待的執行緒 正在等待的查詢 正在封鎖的交易 ID 正在封鎖的執行緒 正在封鎖的查詢
A4 6 SELECT b FROM t FOR UPDATE A3 5 SELECT SLEEP(100)
A5 7 SELECT c FROM t FOR UPDATE A3 5 SELECT SLEEP(100)
A5 7 SELECT c FROM t FOR UPDATE A4 6 SELECT b FROM t FOR UPDATE

在上表中,您可以使用「正在等待的查詢」或「正在封鎖的查詢」欄位來識別工作階段。如您所見

  • 工作階段 B (交易 ID A4,執行緒 6) 和工作階段 C (交易 ID A5,執行緒 7) 都在等待工作階段 A (交易 ID A3,執行緒 5)。

  • 工作階段 C 正在等待工作階段 B 以及工作階段 A。

您可以在 INFORMATION_SCHEMA INNODB_TRX 資料表和效能綱要 data_locksdata_lock_waits 資料表中查看基礎資料。

下表顯示 INNODB_TRX 資料表的一些範例內容。

交易 ID 交易狀態 交易開始時間 交易請求鎖定 ID 交易等待開始時間 交易權重 交易 MySQL 執行緒 ID 交易查詢
A3 執行中 2008-01-15 16:44:54 NULL NULL 2 5 SELECT SLEEP(100)
A4 鎖定等待 2008-01-15 16:45:09 A4:1:3:2 2008-01-15 16:45:09 2 6 SELECT b FROM t FOR UPDATE
A5 鎖定等待 2008-01-15 16:45:14 A5:1:3:2 2008-01-15 16:45:14 2 7 SELECT c FROM t FOR UPDATE

下表顯示 data_locks 表格的一些範例內容。

鎖定 ID 鎖定交易 ID 鎖定模式 鎖定類型 鎖定綱要 鎖定表格 鎖定索引 鎖定資料
A3:1:3:2 A3 X 記錄 測試 t 主要 0x0200
A4:1:3:2 A4 X 記錄 測試 t 主要 0x0200
A5:1:3:2 A5 X 記錄 測試 t 主要 0x0200

下表顯示 data_lock_waits 表格的一些範例內容。

請求交易 ID 請求鎖定 ID 正在封鎖的交易 ID 封鎖鎖定 ID
A4 A4:1:3:2 A3 A3:1:3:2
A5 A5:1:3:2 A3 A3:1:3:2
A5 A5:1:3:2 A4 A4:1:3:2
識別發布工作階段閒置後的封鎖查詢

在識別封鎖交易時,如果發出查詢的工作階段已閒置,則會針對封鎖查詢回報 NULL 值。在這種情況下,請使用以下步驟來判斷封鎖查詢

  1. 識別封鎖交易的 processlist ID。在 sys.innodb_lock_waits 表格中,封鎖交易的 processlist ID 為 blocking_pid 值。

  2. 使用 blocking_pid,查詢 MySQL Performance Schema threads 表格,以判斷封鎖交易的 THREAD_ID。例如,如果 blocking_pid 為 6,請發出此查詢

    SELECT THREAD_ID FROM performance_schema.threads WHERE PROCESSLIST_ID = 6;
  3. 使用 THREAD_ID,查詢 Performance Schema events_statements_current 表格,以判斷執行緒執行的最後一個查詢。例如,如果 THREAD_ID 為 28,請發出此查詢

    SELECT THREAD_ID, SQL_TEXT FROM performance_schema.events_statements_current
    WHERE THREAD_ID = 28\G
  4. 如果執行緒執行的最後一個查詢不足以判斷鎖定為何被持有,您可以查詢 Performance Schema events_statements_history 表格,以檢視執行緒執行的最後 10 個陳述式。

    SELECT THREAD_ID, SQL_TEXT FROM performance_schema.events_statements_history
    WHERE THREAD_ID = 28 ORDER BY EVENT_ID;
將 InnoDB 交易與 MySQL 工作階段關聯

有時將內部 InnoDB 鎖定資訊與 MySQL 維護的工作階段層級資訊關聯會很有用。例如,您可能想知道,對於給定的 InnoDB 交易 ID,對應的 MySQL 工作階段 ID 以及可能持有鎖定,從而封鎖其他交易的工作階段名稱。

以下來自 INFORMATION_SCHEMA INNODB_TRX 表格以及 Performance Schema data_locksdata_lock_waits 表格的輸出,取自一個負載較重的系統。如您所見,有數個交易正在執行。

以下 data_locksdata_lock_waits 表格顯示:

  • 交易 77F (執行 INSERT) 正在等待交易 77E77D77B 提交。

  • 交易 77E (執行 INSERT) 正在等待交易 77D77B 提交。

  • 交易 77D (執行 INSERT) 正在等待交易 77B 提交。

  • 交易 77B (執行 INSERT) 正在等待交易 77A 提交。

  • 交易 77A 正在執行,目前正在執行 SELECT

  • 交易 E56 (執行 INSERT) 正在等待交易 E55 提交。

  • 交易 E55 (執行 INSERT) 正在等待交易 19C 提交。

  • 交易 19C 正在執行,目前正在執行 INSERT

注意

INFORMATION_SCHEMA PROCESSLISTINNODB_TRX 表格中顯示的查詢之間可能存在不一致之處。如需說明,請參閱 第 17.15.2.3 節「InnoDB 交易和鎖定資訊的持久性和一致性」

下表顯示執行大量 工作負載的系統的 PROCESSLIST 表格內容。

ID 使用者 主機 資料庫 指令 時間 狀態 資訊
384 根目錄 localhost 測試 查詢 10 更新 INSERT INTO t2 VALUES …
257 根目錄 localhost 測試 查詢 3 更新 INSERT INTO t2 VALUES …
130 根目錄 localhost 測試 查詢 0 更新 INSERT INTO t2 VALUES …
61 根目錄 localhost 測試 查詢 1 更新 INSERT INTO t2 VALUES …
8 根目錄 localhost 測試 查詢 1 更新 INSERT INTO t2 VALUES …
4 根目錄 localhost 測試 查詢 0 準備中 SELECT * FROM PROCESSLIST
2 根目錄 localhost 測試 睡眠 566 NULL

下表顯示執行大量 工作負載的系統的 INNODB_TRX 表格內容。

交易 ID 交易狀態 交易開始時間 交易請求鎖定 ID 交易等待開始時間 交易權重 交易 MySQL 執行緒 ID 交易查詢
77F 鎖定等待 2008-01-15 13:10:16 77F 2008-01-15 13:10:16 1 876 INSERT INTO t09 (D, B, C) VALUES …
77E 鎖定等待 2008-01-15 13:10:16 77E 2008-01-15 13:10:16 1 875 INSERT INTO t09 (D, B, C) VALUES …
77D 鎖定等待 2008-01-15 13:10:16 77D 2008-01-15 13:10:16 1 874 INSERT INTO t09 (D, B, C) VALUES …
77B 鎖定等待 2008-01-15 13:10:16 77B:733:12:1 2008-01-15 13:10:16 4 873 INSERT INTO t09 (D, B, C) VALUES …
77A 執行中 2008-01-15 13:10:16 NULL NULL 4 872 SELECT b, c FROM t09 WHERE …
E56 鎖定等待 2008-01-15 13:10:06 E56:743:6:2 2008-01-15 13:10:06 5 384 INSERT INTO t2 VALUES …
E55 鎖定等待 2008-01-15 13:10:06 E55:743:38:2 2008-01-15 13:10:13 965 257 INSERT INTO t2 VALUES …
19C 執行中 2008-01-15 13:09:10 NULL NULL 2900 130 INSERT INTO t2 VALUES …
E15 執行中 2008-01-15 13:08:59 NULL NULL 5395 61 INSERT INTO t2 VALUES …
51D 執行中 2008-01-15 13:08:47 NULL NULL 9807 8 INSERT INTO t2 VALUES …

下表顯示執行大量 工作負載的系統的 data_lock_waits 表格內容。

請求交易 ID 請求鎖定 ID 正在封鎖的交易 ID 封鎖鎖定 ID
77F 77F:806 77E 77E:806
77F 77F:806 77D 77D:806
77F 77F:806 77B 77B:806
77E 77E:806 77D 77D:806
77E 77E:806 77B 77B:806
77D 77D:806 77B 77B:806
77B 77B:733:12:1 77A 77A:733:12:1
E56 E56:743:6:2 E55 E55:743:6:2
E55 E55:743:38:2 19C 19C:743:38:2

下表顯示執行大量 工作負載的系統的 data_locks 表格內容。

鎖定 ID 鎖定交易 ID 鎖定模式 鎖定類型 鎖定綱要 鎖定表格 鎖定索引 鎖定資料
77F:806 77F 自動遞增 表格 測試 t09 NULL NULL
77E:806 77E 自動遞增 表格 測試 t09 NULL NULL
77D:806 77D 自動遞增 表格 測試 t09 NULL NULL
77B:806 77B 自動遞增 表格 測試 t09 NULL NULL
77B:733:12:1 77B X 記錄 測試 t09 主要 上界虛擬記錄
77A:733:12:1 77A X 記錄 測試 t09 主要 上界虛擬記錄
E56:743:6:2 E56 S 記錄 測試 t2 主要 0, 0
E55:743:6:2 E55 X 記錄 測試 t2 主要 0, 0
E55:743:38:2 E55 S 記錄 測試 t2 主要 1922, 1922
19C:743:38:2 19C X 記錄 測試 t2 主要 1922, 1922