- 文档首页
云数据库 MySQL 版
内核功能
功能
支持 NOWAIT 语法
支持 NOWAIT 语法
本文介绍云数据库 MySQL 版提供的 NOWAIT 语法的相关信息。
DDL 支持“NO_WAIT”和“WAIT N”语法,可在无法获取表的 MDL 锁时立即报错或者等待 N 秒后报错。在实际的生产环境中,常常出现 DDL 阻塞业务的情况,例如,当 DDL 被一个长事务阻塞,无法获取 MDL 锁时,由于 DDL 的锁优先级高于业务的锁优先级,会导致后续业务持续被阻塞。
锁定读 SQL 支持“NOWAIT”和“SKIP LOCKED”语法,即获取锁失败后立即报错,或者跳过当前记录,以避免工作线程被阻塞,从而防止浪费线程池资源。执行“SKIP LOCKED”语法时,被跳过的行不会出现在结果集中。
由于历史原因,DDL 使用的是“NO_WAIT”关键字,而锁定读使用的是“NOWAIT”关键字。 这一点需要特别注意。
- MySQL 5.7 版本,内核小版本为 MySQL 5.7.32_20250615 及以上。
- MySQL 8.0 版本,内核小版本为 MySQL 8.0.32_20250615 及以上。
- MySQL 8.4 版本,内核小版本为 MySQL 8.4.7_20260415 及以上。
- 生产业务中可能存在长事务,若不希望 DDL 长时间阻塞业务 SQL,可尝试使用 DDL 的 NO_WAIT/WAIT N 语法。
- 在秒杀、抢购场景下,某些行存在大量的并发修改或加锁情况,导致大量事务线程阻塞,此时可使用锁定读的 NOWAIT/SKIP LOCKED 语法。
- 需要谨慎使用 DDL 的 NO_WAIT 语法。如果从库一直有读事务访问表,会导致从库持续回放失败,进而造成主从延迟。建议尽量使用 WAIT N 语法,根据业务流量进行评估 N 的取值。
- DDL 的 NO_WAIT 语法为新增语法,非社区语法,需留意下游的版本能否消费 binlog。锁定读的 NOWAIT 语法是从 MySQL 8.0 迁移到 MySQL 5.7的,需要注意 binlog的类型,确认是否能消费。
- DDL 的 NO_WAIT/WAIT N 语法的格式如下:
ALTER TABLE `table` [NO_WAIT | WAIT [n]] `command`;
DROP TABLE `table` [NO_WAIT | WAIT [n]];
TRUNCATE TABLE `table` [NO_WAIT | WAIT [n]];
OPTIMIZE TABLE `table` [NO_WAIT | WAIT [n]];
RENAME TABLE `table_src` [NO_WAIT | WAIT [n]] TO `table_dst`;
CREATE INDEX `index` ON `table.columns` [NO_WAIT | WAIT [n]];
CREATE FULLTEXT INDEX `index` ON `table.columns` [NO_WAIT | WAIT [n]];
CREATE SPATIAL INDEX `index` ON `table.columns` [NO_WAIT | WAIT [n]];
DROP INDEX `index` ON `table` [NO_WAIT | WAIT [n]];
- 锁定读 NOWAIT/SKIP LOCKED 语法的格式如下:
SELECT ... [FOR UPDATE [OF table] [NOWAIT | SKIP LOCKED]];
SELECT ... [FOR SHARE [OF table] [NOWAIT | SKIP LOCKED]];
锁定读 NOWAIT/SKIP LOCKED 语法使用示例如下:
Query OK, 0 rows affected (0.000 sec)
MySQL [t]> select count(1) from t for update;
1 row in set (0.001 sec)
MySQL [t]> select count(1) from t for update nowait;
ERROR 3282 (HY000): Do not wait for lock.
MySQL [t]> select count(1) from t for update skip locked;
1 row in set (0.001 sec)
最近更新时间:2026.05.28 11:52:21