全部產品
Search
文件中心

PolarDB:非阻塞DDL

更新時間:Jul 06, 2024

PolarDB新增非阻塞DDL(Nonblock DDL)功能。Nonblock DDL規避了執行DDL過程中MDL鎖長時間擷取不成功導致的串連堆積和阻塞,有效地解決了DDL導致的鎖表問題。

背景資訊

使用者在執行DDL操作的時候,若目標表存在未提交的長事務或大查詢,DDL將持續等待擷取MDL-X鎖。在PolarDB中由於MDL-X鎖具有最高優先順序,DDL在等待MDL-X鎖的過程中,將阻塞目標表上所有的新事務,這將導致Business Connectivity的堆積和阻塞,可能會造成整個業務系統崩潰的嚴重後果。PolarDB提供的Nonblock DDL功能,可以保證即使在無法獲得MDL-X鎖的情況下,依然允許新事務進入目標表,從而保證整個業務系統的穩定。

前提條件

PolarDB MySQL版叢集需滿足如下條件之一:

  • PolarDB MySQL版8.0.1版本且Revision version為8.0.1.1.29及以上。

  • PolarDB MySQL版8.0.2版本且Revision version為8.0.2.2.12及以上。

您可以通過查詢版本號碼來確認叢集版本。

注意事項

開啟Nonblock DDL功能會導致DDL的優先順序降低,同時因MDL鎖擷取失敗從而導致執行DDL的失敗機率也會相應增大。

使用限制

  • PolarDB MySQL版8.0.1版本且Revision version為8.0.1.1.29及以上,以及8.0.2.2.12版本:

    • ALTER TABLE語句支援Nonblock DDL功能,應用於ALTER TABLE table_name ADD INDEX index_name ( `column1`, `column2`, `column3` )語句效果更佳。

    • 對於在InnoDB引擎上建立的表,需要使用ALTER TABLE table_name engine=innodb命令來代替 OPTIMIZE TABLE table_name 命令進行磁碟重組。

  • PolarDB MySQL版8.0.2版本且Revision version為8.0.2.2.13及以上:

    ALTER TABLEOPTIMIZE TABLETRUNCATE TABLE語句支援Nonblock DDL功能。

使用方法

您可以先通過loose_polar_nonblock_ddl_mode參數開啟Nonblock DDL功能,並通過loose_polar_nonblock_ddl_retry_times參數設定擷取MDL-X鎖逾時重試的次數、loose_polar_nonblock_ddl_retry_interval參數設定擷取MDL-X鎖逾時重試的時間間隔、loose_polar_nonblock_ddl_lock_wait_timeout參數設定擷取MDL-X鎖逾時的時間。具體操作請參見設定叢集參數和節點參數。參數說明如下:

參數

層級

說明

loose_polar_nonblock_ddl_mode

Session

Nonblock DDL功能開關。取值範圍如下:

  • ON:開啟Nonblock DDL功能。

  • OFF(預設):關閉Nonblock DDL功能。

loose_polar_nonblock_ddl_retry_times

Session

設定擷取MDL-X鎖逾時重試的次數。取值範圍:0~31536000。預設值為0(由參數lock_wait_timeout計算得到的值)。

說明

該參數值建議設定為4194304。

loose_polar_nonblock_ddl_retry_interval

Session

設定擷取MDL-X鎖逾時重試的時間間隔。取值範圍:1~31536000。單位為秒。預設值為6。

loose_polar_nonblock_ddl_lock_wait_timeout

Session

設定擷取MDL-X鎖逾時的時間。取值範圍:1~31536000。單位為秒。預設值為1。

效能對比

本文檔對比了開啟和關閉Nonblock DDL功能對業務的影響情況,同時與使用外部工具gh-ost進行表結構變更也進行了效能對比。

測試載入器

SysBench是一個跨平台且支援多線程的模組化基準測試載入器,用於評估系統在運行高負載的資料庫時相關核心參數的效能表現。使用SysBench是為了繞過複雜的資料庫基準設定,甚至在沒有安裝資料庫的前提下,快速瞭解資料庫系統的效能。關於如何使用SysBench,請參見效能測試方法(OLTP)

測試環境

一個規格為8核64 GB的標準版PolarDB MySQL版8.0版本的叢集。

測試方法

  1. 使用SysBench建立1個測試表sbtest1,並插入1000000行資料。

    ./oltp_read_write.lua --mysql-host="叢集地址" --mysql-port=“連接埠號碼” --mysql-user=“使用者名稱” --mysql-password=“使用者密碼” --mysql-db="sbtest" --tables=1 --table-size=1000000 --report-interval=1 --percentile=99 --threads=8 --time=6000 prepare
  2. 通過SysBench中的oltp_read_write.lua類比使用者業務。

    ./oltp_read_write.lua --mysql-host="叢集地址" --mysql-port=“連接埠號碼” --mysql-user=“使用者名稱” --mysql-password=“使用者密碼” --mysql-db="sbtest" --tables=1 --table-size=1000000 --report-interval=1 --percentile=99 --threads=8 --time=6000 run
  3. 在目標表sbtest1上開啟一個事務但不提交,該事務將持有目標表sbtest1的MDL鎖。

    /* session 1 */
    begin;
    select * from sbtest1;
  4. 在新會話中,開啟和關閉Nonblock DDL功能的條件下,分別對錶sbtest1進行加列操作,觀察TPS的變化情況。

    /* session 2 */
    alter table sbtest1 add column d int;
  5. 使用gh-ost工具進行加列操作,觀察TPS的變化情況(開啟Binlog)。

    ./gh-ost --assume-rbr --user="使用者名稱" --password="使用者密碼" --host="叢集地址" --port="連接埠號碼" --database="sbtest" --table="sbtest1"  --alter="ADD COLUMN d INT" --allow-on-master --aliyun-rds --initially-drop-old-table --initially-drop-ghost-table --execute;

測試結果

  • 關閉Nonblock DDL,TPS持續跌零。預設逾時時間為31536000,嚴重影響使用者業務。關閉Nonblock DDL

  • 開啟Nonblock DDL,TPS周期性下降,但未跌零。對使用者業務影響較小,能保證業務系統的穩定。開啟Nonblock DDL

  • 使用gh-ost進行表結構無鎖變更,TPS周期性跌零。對使用者業務影響很大,這是cut-over階段短暫鎖表造成的。使用gh-ost進行結構變更

Nonblock DDL與gh-ost工具效能對比

開啟Nonblock DDL並使用傳統的加列方式(INSTANT、INPLACE、COPY)與使用gh-ost工具分別對100萬行資料的表進行加列操作的效能對比如下:

  • 在無負載的情況下,通過下圖可以看出開啟Nonblock DDL並使用傳統的加列方式(INSTANT、INPLACE、COPY)比使用gh-ost工具耗時更少。無負載

  • 使用SysBench的oltp_read_write類比業務負載,通過下圖可以看出開啟Nonblock DDL並使用傳統的加列方式(INSTANT、INPLACE、COPY)比使用gh-ost工具耗時更少。read_write.

測試結論

Nonblock DDL功能在DDL執行期間能更好的規避新事務阻塞、TPS跌零等問題,從而儘可能的保證業務系統的穩定性。同時,能夠提供更高效的DDL變更能力。