ALTER TABLE) need to obtain the MDL exclusive lock (MDL-X) on the target table. When there are uncommitted long-running transactions or large queries on the target table, these sessions hold the MDL shared read lock on the table, and the DDL operation will enter a waiting state.SELECT, INSERT, and UPDATE operations) will be blocked—they can neither acquire an MDL shared lock (because a higher-priority exclusive lock request exists in the waiting queue) nor bypass the exclusive lock request to execute directly.Level | Preemptive DDL | Non-blocking DDL |
Problems solved | DDL execution fails due to long transaction blocking | DDL blocks all new transactions during the waiting period |
Handling method | After timeout, terminate the session blocking DDL. | After timeout, DDL voluntarily yields, allowing new transactions to proceed. |
Impact on Existing Sessions | Sessions holding locks will be forcibly terminated. | Existing sessions are not affected. |
DDL Execution Result | DDL is guaranteed to succeed. | DDL may fail due to exhausted retry attempts. |
Use Cases | Long transactions can be interrupted, and DDL must succeed. | Business sessions cannot be interrupted, requiring zero awareness from the business. |
Parameter | Level | Description | Value Range | Default Value |
tdsql_ddl_block_mode | Session | The non-blocking DDL feature switch enables non-blocking DDL logic when set to nonblock. | preemptive nonblock default | preemptive |
tdsql_ddl_recovery_block_mode | Global | Controls the non-blocking DDL behavior of the recovery thread; takes effect when set to nonblock. Only GLOBAL-level settings are valid; Session-level settings are invalid. | preemptive nonblock default | preemptive |
tdsql_ddl_nonblock_lock_wait_timeout | Session | The timeout duration for a single attempt to obtain an MDL-X lock. If the lock is not acquired within this duration, the DDL operation will proactively abort the current request and allow new transactions to proceed. Unit: seconds. | 1 ~ 102410241024 | 1 |
tdsql_ddl_nonblock_retry_interval | Session | The wait interval between two lock acquisition attempts. Unit: seconds | 0 ~ 60 | 4 |
tdsql_ddl_nonblock_retry_times | Session | The maximum number of retries to obtain an MDL-X lock. Exceeding this limit will cause the DDL operation to fail. | 0 ~ ULONG_MAX | 10 |
Total duration ≈ tdsql_ddl_nonblock_retry_times × (tdsql_ddl_nonblock_lock_wait_timeout + tdsql_ddl_nonblock_retry_interval)
SET tdsql_ddl_block_mode = 'nonblock';
SET tdsql_ddl_nonblock_lock_wait_timeout = 2;SET tdsql_ddl_nonblock_retry_interval = 5;SET tdsql_ddl_nonblock_retry_times = 20;
SET GLOBAL tdsql_ddl_recovery_block_mode = 'nonblock';
ALTER TABLE orders ADD INDEX idx_status (status);
CREATE TABLE sbtest1 (id INT PRIMARY KEY,k INT NOT NULL DEFAULT 0,c CHAR(120) NOT NULL DEFAULT '',pad CHAR(60) NOT NULL DEFAULT '');-- Insert 1 million rows of test data (can be generated using tools such as SysBench)
sysbench oltp_read_write \\--mysql-host="connection address" \\--mysql-port=3306 \\--mysql-user="username" \\--mysql-password="password" \\--mysql-db="test" \\--tables=1 \\--table-size=1000000 \\--threads=8 \\--time=600 \\--report-interval=1 \\run
BEGIN;SELECT * FROM sbtest1 LIMIT 1;-- Uncommitted, holding a shared read MDL lock on sbtest1
ALTER TABLE sbtest1 ADD COLUMN d INT;-- DDL enters the MDL lock wait queue-- At this point, all new transactions are also blocked → business TPS drops to zero
SET tdsql_nonblock_ddl_mode = ON;SET tdsql_nonblock_ddl_lock_wait_timeout = 1;SET tdsql_nonblock_ddl_retry_interval = 5;SET tdsql_nonblock_ddl_retry_times = 50;ALTER TABLE sbtest1 ADD COLUMN d INT;-- DDL attempts to obtain the lock → aborts after 1 second → releases new transactions → waits 5 seconds → retries...-- When the transaction in Session 1 ended, the DDL successfully obtained the lock on the next retry attempt-- Query OK, 0 rows affected (23.15 sec)
Scenario | TPS performance | Business Impacts |
Disable non-blocking DDL | TPS continuously drops to zero until the lock is released. | Severe, business is completely interrupted. |
Enable non-blocking DDL | TPS exhibits periodic brief declines and does not drop to zero. | Minor, business remains available. |
-- Enable non-blocking DDL to avoid impacting online business operationsSET tdsql_ddl_block_mode = 'nonblock';SET tdsql_ddl_nonblock_lock_wait_timeout = 1;SET tdsql_ddl_nonblock_retry_interval = 3;SET tdsql_ddl_nonblock_retry_times = 100;ALTER TABLE orders ADD INDEX idx_create_time (create_time);
-- First attempt: non-blocking mode, without affecting business operationsSET tdsql_ddl_block_mode = 'nonblock';SET tdsql_ddl_nonblock_retry_times = 10;ALTER TABLE orders ADD COLUMN remark VARCHAR(255);-- If retry attempts are exhausted and it still fails...-- Second attempt: preemptive mode, force completionSET tdsql_ddl_block_mode = 'preemptive';SET tdsql_ddl_preempt_after_wait_seconds = 5;ALTER TABLE orders ADD COLUMN remark VARCHAR(255);
Feedback