MySQL 8.0 リファレンスマニュアル


15.15.2.1 InnoDB トランザクションの使用および情報のロック

注記

このセクションでは、MySQL 8.0 内の INFORMATION_SCHEMA INNODB_LOCKS および INNODB_LOCK_WAITS テーブルよりも優先される、パフォーマンススキーマ data_locks および data_lock_waits テーブルによって公開されるロック情報について説明します。 古い INFORMATION_SCHEMA テーブルに関して記述されている同様の説明は、MySQL 5.7 Reference ManualUsing InnoDB Transaction and Locking Information を参照してください。

ブロックしているトランザクションの識別

どのトランザクションが別のトランザクションをブロックしているかを識別すると役立つ場合があります。 InnoDB トランザクションおよびデータロックに関する情報を含むテーブルを使用すると、どのトランザクションが別のトランザクションを待機しているか、およびどのリソースがリクエストされているかを判別できます。 (これらのテーブルの詳細は、セクション15.15.2「InnoDB INFORMATION_SCHEMA トランザクションおよびロック情報」 を参照してください。)

3 つのセッションが同時に実行されているとします。 各セッションは 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 値がレポートされる場合は、発行セッションがアイドル状態になった後のブロッキングクエリーの識別 を参照してください。

waiting trx id waiting thread waiting query blocking trx id blocking thread blocking query
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 (trx id A4、スレッド 6) とセッション C (trx id A5、スレッド 7) はどちらもセッション A (trx id A3、スレッド 5) を待機しています。

  • セッション C はセッション B およびセッション A を待機しています。

基礎となるデータは、INFORMATION_SCHEMA INNODB_TRX テーブルおよびパフォーマンススキーマの data_locks および data_lock_waits テーブルに表示されます。

次のテーブルに、INNODB_TRX テーブルのサンプルコンテンツを示します。

trx id trx state trx started trx requested lock id trx wait started trx weight trx mysql thread id trx query
A3 RUN­NING 2008-01-15 16:44:54 NULL NULL 2 5 SELECT SLEEP(100)
A4 LOCK WAIT 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 LOCK WAIT 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 テーブルのサンプルコンテンツを示します。

lock id lock trx id lock mode lock type スキーマのロック lock table lock index lock data
A3:1:3:2 A3 X RECORD test t PRIMARY 0x0200
A4:1:3:2 A4 X RECORD test t PRIMARY 0x0200
A5:1:3:2 A5 X RECORD test t PRIMARY 0x0200

次のテーブルに、data_lock_waits テーブルのサンプルコンテンツを示します。

requesting trx id requested lock id blocking trx id blocking lock 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. ブロッキングトランザクションのプロセスリスト ID を識別します。 sys.innodb_lock_waits テーブルでは、ブロッキングトランザクションのプロセスリスト ID は blocking_pid 値です。

  2. blocking_pid を使用して、MySQL パフォーマンススキーマの threads テーブルをクエリーし、ブロックしているトランザクションの THREAD_ID を判別します。 たとえば、blocking_pid が 6 の場合は、次のクエリーを発行します:

    SELECT THREAD_ID FROM performance_schema.threads WHERE PROCESSLIST_ID = 6;
  3. THREAD_ID を使用して、パフォーマンススキーマ events_statements_current テーブルをクエリーし、スレッドによって最後に実行されたクエリーを確認します。 たとえば、THREAD_ID が 28 の場合は、次のクエリーを発行します:

    SELECT THREAD_ID, SQL_TEXT FROM performance_schema.events_statements_current
    WHERE THREAD_ID = 28\G
  4. スレッドによって実行された最後のクエリーが、ロックが保持されている理由を判断するのに十分な情報でない場合は、パフォーマンススキーマ 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 テーブル、パフォーマンススキーマ data_locks および data_lock_waits テーブルからの次の出力は、ある程度ロードされたシステムから取得されます。 表示されているように、複数のトランザクションが実行されています。

次の data_locks テーブルおよび data_lock_waits テーブルは、次のことを示しています:

  • トランザクション 77F (INSERT を実行中) は、トランザクション 77E77D,、および 77B がコミットするのを待機しています。

  • トランザクション 77E (INSERT を実行) は、トランザクション 77D および 77B のコミットを待機しています。

  • トランザクション 77D (INSERT を実行) は、トランザクション 77B のコミットを待機しています。

  • トランザクション 77B (INSERT を実行) は、トランザクション 77A のコミットを待機しています。

  • トランザクション 77A は実行中であり、現在 SELECT を実行しています。

  • トランザクション E56 (INSERT を実行中) は、トランザクション E55 がコミットするのを待機しています。

  • トランザクション E55 (INSERT を実行中) は、トランザクション 19C がコミットするのを待機しています。

  • トランザクション 19C は実行中であり、現在 INSERT を実行しています。

注記

INFORMATION_SCHEMA PROCESSLIST テーブルと INNODB_TRX テーブルに表示されるクエリーの間に不整合がある可能性があります。 詳細は、セクション15.15.2.3「InnoDB トランザクションおよびロック情報の永続性と一貫性」 を参照してください。

次のテーブルに、重い workload を実行しているシステムの PROCESSLIST テーブルの内容を示します。

ID USER HOST DB COMMAND TIME STATE INFO
384 root localhost test Query 10 update INSERT INTO t2 VALUES …
257 root localhost test Query 3 update INSERT INTO t2 VALUES …
130 root localhost test Query 0 update INSERT INTO t2 VALUES …
61 root localhost test Query 1 update INSERT INTO t2 VALUES …
8 root localhost test Query 1 update INSERT INTO t2 VALUES …
4 root localhost test Query 0 preparing SELECT * FROM PROCESSLIST
2 root localhost test Sleep 566 NULL

次のテーブルに、重い workload を実行しているシステムの INNODB_TRX テーブルの内容を示します。

trx id trx state trx started trx requested lock id trx wait started trx weight trx mysql thread id trx query
77F LOCK WAIT 2008-01-15 13:10:16 77F 2008-01-15 13:10:16 1 876 INSERT INTO t09 (D, B, C) VALUES …
77E LOCK WAIT 2008-01-15 13:10:16 77E 2008-01-15 13:10:16 1 875 INSERT INTO t09 (D, B, C) VALUES …
77D LOCK WAIT 2008-01-15 13:10:16 77D 2008-01-15 13:10:16 1 874 INSERT INTO t09 (D, B, C) VALUES …
77B LOCK WAIT 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 RUN­NING 2008-01-15 13:10:16 NULL NULL 4 872 SELECT b, c FROM t09 WHERE …
E56 LOCK WAIT 2008-01-15 13:10:06 E56:743:6:2 2008-01-15 13:10:06 5 384 INSERT INTO t2 VALUES …
E55 LOCK WAIT 2008-01-15 13:10:06 E55:743:38:2 2008-01-15 13:10:13 965 257 INSERT INTO t2 VALUES …
19C RUN­NING 2008-01-15 13:09:10 NULL NULL 2900 130 INSERT INTO t2 VALUES …
E15 RUN­NING 2008-01-15 13:08:59 NULL NULL 5395 61 INSERT INTO t2 VALUES …
51D RUN­NING 2008-01-15 13:08:47 NULL NULL 9807 8 INSERT INTO t2 VALUES …

次のテーブルに、重い workload を実行しているシステムの data_lock_waits テーブルの内容を示します。

requesting trx id requested lock id blocking trx id blocking lock 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

次のテーブルに、重い workload を実行しているシステムの data_locks テーブルの内容を示します。

lock id lock trx id lock mode lock type スキーマのロック lock table lock index lock data
77F:806 77F AUTO_INC TABLE test t09 NULL NULL
77E:806 77E AUTO_INC TABLE test t09 NULL NULL
77D:806 77D AUTO_INC TABLE test t09 NULL NULL
77B:806 77B AUTO_INC TABLE test t09 NULL NULL
77B:733:12:1 77B X RECORD test t09 PRIMARY supremum pseudo-record
77A:733:12:1 77A X RECORD test t09 PRIMARY supremum pseudo-record
E56:743:6:2 E56 S RECORD test t2 PRIMARY 0, 0
E55:743:6:2 E55 X RECORD test t2 PRIMARY 0, 0
E55:743:38:2 E55 S RECORD test t2 PRIMARY 1922, 1922
19C:743:38:2 19C X RECORD test t2 PRIMARY 1922, 1922

関連キーワード:  InnoDB, テーブル, トランザクション, trx, lock, 実行, ロック, INSERT, セッション, 構成