You need to enable JavaScript to run this app.
文档中心
云数据库 MySQL 版

云数据库 MySQL 版

复制全文
下载 pdf
功能
支持 NOWAIT 语法
复制全文
下载 pdf
支持 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 语法使用示例如下:​
​
// session 1​
MySQL [t]> begin;​
Query OK, 0 rows affected (0.000 sec)​
​
MySQL [t]> select count(1) from t for update;​
+----------+​
| count(1) |​
+----------+​
| 6 |​
+----------+​
1 row in set (0.001 sec)​
​
MySQL [t]>​
​
// session 2​
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;​
+----------+​
| count(1) |​
+----------+​
| 0 |​
+----------+​
1 row in set (0.001 sec)​
​
​
最近更新时间:2026.05.28 11:52:21
这个页面对您有帮助吗?
有用
有用
无用
无用