TiDB の DDL の挙動を確認した。
まとめ
tidb_enable_metadata_lock
が有効だと、DDLは先行のトランザクションによって待たされることがある- metadata lock 待ちが発生していても、(MySQL と違って) DMLは影響を受けない
- metadata lock の状況は
mysql.tidb_mdl_view
で観測できる- (MySQL と違って) SHOW PROCESSLIST では表示されない
環境
TiDB 8.0.11 / tidb_enable_metadata_lock = ON で試します。tidb_enable_metadata_lock
はデフォルト で ON
です。
mysql> SHOW GLOBAL VARIABLES LIKE 'version'; +---------------+--------------------+ | Variable_name | Value | +---------------+--------------------+ | version | 8.0.11-TiDB-v8.0.0 | +---------------+--------------------+ 1 row in set (0.02 sec) mysql> SHOW GLOBAL VARIABLES LIKE 'tidb_enable_metadata_lock'; +---------------------------+-------+ | Variable_name | Value | +---------------------------+-------+ | tidb_enable_metadata_lock | ON | +---------------------------+-------+ 1 row in set (0.03 sec)
検証
ロングトランザクションを実行開始し、ALTER TABLE
を別セッションで実行します。
mysql> BEGIN; Query OK, 0 rows affected (0.02 sec) mysql> UPDATE t1 SET c1 = 'updated' WHERE pk = 1; Query OK, 1 row affected (0.08 sec) Rows matched: 1 Changed: 1 Warnings: 0
mysql> ALTER TABLE t1 MODIFY COLUMN c2 INT NULL;
ALTER TABLE
は先行するトランザクションが終わるまで、metadata lock 待ちで待たされます。
metadata lock で待たされている様子は、(MySQL と違って) SHOW PROCESSLIST
には表示されません。
-- ALTER TABLE は待たされているが、SHOW PROCESSLIST では観測できない mysql> SHOW PROCESSLIST; +------------+------+-----------------+------+---------+------+----------------------------+------------------------------------------+ | Id | User | Host | db | Command | Time | State | Info | +------------+------+-----------------+------+---------+------+----------------------------+------------------------------------------+ | 1497366540 | root | 127.0.0.1:38330 | test | Sleep | 76 | in transaction; autocommit | NULL | | 1497366538 | root | 127.0.0.1:49314 | test | Query | 6 | autocommit | ALTER TABLE t1 MODIFY COLUMN c2 INT NULL | | 1497366546 | root | 127.0.0.1:50144 | test | Query | 0 | autocommit | SHOW PROCESSLIST | +------------+------+-----------------+------+---------+------+----------------------------+------------------------------------------+ 3 rows in set (0.01 sec)
tidb_mdl_view
で、metadata lock 待ちを観測できます。SQL_DIGESTS
でブロックしているトランザクションの内容が見れるのは便利ですね。
mysql> SELECT * FROM mysql.tidb_mdl_view \G *************************** 1. row *************************** job_id: 120 db_name: test table_name: t1 query: ALTER TABLE t1 MODIFY COLUMN c2 INT NULL session_id: 1497366540 start_time: 2024-05-01 03:41:18.621000 SQL_DIGESTS: ["begin","update `t1` set `c1` = ? where `pk` = ?"] 1 row in set (0.20 sec)
ALTER TABLE
が待たされている状態で、後続のDML が ALTER TABLE
の完了を待つかどうかを確認します。
mysql> UPDATE t1 SET c1 = 'updated' WHERE pk = 10; Query OK, 1 row affected, 1 warning (0.22 sec) Rows matched: 1 Changed: 1 Warnings: 1
→ 待たされませんでした。
先行するトランザクションを COMMIT
すると、ALTER TABLE
が開始されます。
なお、ALTER TABLE
が開始されても、DMLはブロックされることなくオンラインで実行可能です。