前提
本エントリーは、tidb_enable_metadata_lock が ON であることを前提としています。
mysql> SELECT @@transaction_isolation, @@tidb_enable_metadata_lock, @@version; +-------------------------+-----------------------------+--------------------+ | @@transaction_isolation | @@tidb_enable_metadata_lock | @@version | +-------------------------+-----------------------------+--------------------+ | REPEATABLE-READ | 1 | 8.0.11-TiDB-v8.1.2 | +-------------------------+-----------------------------+--------------------+ 1 row in set (0.00 sec)
DDLをブロックしているトランザクションの調査方法
TiDB にも MySQL 同様に metadata lock があり、DDLがクエリによってブロックされることがあります。
mysql.tidb_mdl_view でブロックしているトランザクションを確認できます。
metadata lock が競合せず、ブロックが発生していない場合は、何も表示されません。
tidb_mdl_view は、実行済みのクエリも含めて、ブロックしているトランザクションに含まれる全てのクエリを SQL_DIGESTS に出力してくれます。これは非常に便利ですね。
start_time も、直近のクエリの開始時間ではなく、トランザクションの開始時間です。
mysql> SELECT * FROM mysql.tidb_mdl_view; +--------+---------+------------+--------------------------------+------------+----------------------------+-------------------------------------------+ | job_id | db_name | table_name | query | session_id | start_time | SQL_DIGESTS | +--------+---------+------------+--------------------------------+------------+----------------------------+-------------------------------------------+ | 108 | t | t | ALTER TABLE t ADD INDEX idx(a) | 3212836870 | 2025-09-11 21:01:30.919000 | ["begin","select `a` , now ( ) from `t`"] | +--------+---------+------------+--------------------------------+------------+----------------------------+-------------------------------------------+ 1 row in set (0.00 sec)
さて、ここで、追加のトランザクションを実行します。 なお、MySQL では MDL 待ち状態で、追加のトランザクションを実行すると、そのトランザクションは待たされますが、TiDB では DDL を追い越して、トランザクションを実行することができます(その代わり、後続のトランザクションが先行するDDLをブロックします)。
mysql> BEGIN; Query OK, 0 rows affected (0.00 sec) mysql> SELECT a, NOW() AS 2ndtry FROM t; +------+---------------------+ | a | 2ndtry | +------+---------------------+ | 1 | 2025-09-11 21:04:27 | +------+---------------------+ 1 row in set (0.00 sec)
tidb_mdl_view にも行が追加されることがわかりました。
mysql> mysql> SELECT * FROM mysql.tidb_mdl_view; +--------+---------+------------+--------------------------------+------------+----------------------------+-----------------------------------------------+ | job_id | db_name | table_name | query | session_id | start_time | SQL_DIGESTS | +--------+---------+------------+--------------------------------+------------+----------------------------+-----------------------------------------------+ | 108 | t | t | ALTER TABLE t ADD INDEX idx(a) | 3212836870 | 2025-09-11 21:01:30.919000 | ["begin","select `a` , now ( ) from `t`"] | | 108 | t | t | ALTER TABLE t ADD INDEX idx(a) | 3212836876 | 2025-09-11 21:04:26.073000 | ["select `a` , now ( ) as `2ndtry` from `t`"] | +--------+---------+------------+--------------------------------+------------+----------------------------+-----------------------------------------------+ 2 rows in set (0.00 sec)
トランザクションをコミット/ロールバックすると、tidb_mdl_view から消えます(そしてDDLの実行が開始されます)。