RDS MySQL支援DDL鎖等待逾時控制功能,其基於HINT靈活控制DDL線程等待MDL鎖的逾時時間,避免因長時間等待MDL鎖導致的會話阻塞和串連堆積。
功能說明
簡介:MySQL中使用lock_wait_timeout參數來控制MDL逾時時間,對於需要精確控制等待行為的DDL操作,使用者必須在執行前顯式修改該參數。RDS MySQL基於HINT提供了一種更簡單、直觀的方式來控制DDL語句的MDL鎖等待時間,支援通過/*+ WAIT(n) */和/*+ NO_WAIT() */直接在語句中指定MDL鎖等待時間。
優勢:相比引入新文法,使用HINT具有更好的相容性。HINT以注釋形式寫入Binlog,在不支援該特性的下遊執行個體或訂閱服務中,會被解析器自動忽略,視為普通注釋,不會導致SQL解析錯誤或複製中斷。
適用範圍
資料庫版本需滿足以下要求才能使用DDL鎖等待逾時控制功能,當版本不符合要求時,可以升級升級核心小版本或資料庫大版本:
MySQL 8.4
MySQL 8.0且核心小版本大於等於20250531
使用該功能時有以下限制:
僅支援
CREATE、DROP、ALTER、RENAME、TRUNCATE和OPTIMIZE操作。主節點同步至備節點或唯讀執行個體時,備節點或唯讀執行個體上本功能不生效。
設定MDL等待時間(
/*+ WAIT(n) */)時,n(等待時間)的取值範圍為[0, 31536000],單位:秒。
使用方法
在執行CREATE、DROP、ALTER、RENAME、TRUNCATE和OPTIMIZE操作時,您只需在上述關鍵字後添加/*+ WAIT(n) */ 或/*+ NO_WAIT() */,即可實現 MDL 鎖等待時間的控制。使用樣本如下:
-- 建立表t1並設定MDL逾時時間為10s。
CREATE /*+ WAIT(10) */ TABLE t1(a INT);
-- 為表t1添加列並設定MDL逾時不等待。
ALTER /*+ NO_WAIT() */ TABLE t1 ADD COLUMN b INT;
-- 刪除表 t1 添加列並設定 MDL 逾時時間為 1s
DROP /*+ WAIT(1) */ TABLE t1;功能效果
測試方法
開啟一個會話,建立表
t1並持有表MDL S鎖。CREATE TABLE t1(a INT); LOCK TABLE t1 READ;開啟另一個會話,使用
/*+ WAIT(n) */和/*+ NO_WAIT() */執行表結構變更和刪除操作,觀察語句執行情況。ALTER /*+ NO_WAIT() */ TABLE t1 ADD COLUMN b INT; DROP /*+ WAIT(1) */ TABLE t1;
測試結果
使用/*+ WAIT(n) */ 和/*+ NO_WAIT() */方式控制 MDL 逾時時間之後,表結構變更和刪除操作會在預期的時間內快速失敗。
mysql> ALTER /*+ NO_WAIT() */ TABLE t1 ADD COLUMN b INT;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql> DROP /*+ WAIT(1) */ TABLE t1;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction