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 TABLE、OPTIMIZE TABLE和TRUNCATE 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功能開關。取值範圍如下:
|
loose_polar_nonblock_ddl_retry_times | Session | 設定擷取MDL-X鎖逾時重試的次數。取值範圍:0~31536000。預設值為0(由參數 說明 該參數值建議設定為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版本的叢集。
測試方法
使用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
通過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
在目標表
sbtest1
上開啟一個事務但不提交,該事務將持有目標表sbtest1
的MDL鎖。/* session 1 */ begin; select * from sbtest1;
在新會話中,開啟和關閉Nonblock DDL功能的條件下,分別對錶
sbtest1
進行加列操作,觀察TPS的變化情況。/* session 2 */ alter table sbtest1 add column d int;
使用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,TPS周期性下降,但未跌零。對使用者業務影響較小,能保證業務系統的穩定。
使用gh-ost進行表結構無鎖變更,TPS周期性跌零。對使用者業務影響很大,這是cut-over階段短暫鎖表造成的。
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工具耗時更少。
測試結論
Nonblock DDL功能在DDL執行期間能更好的規避新事務阻塞、TPS跌零等問題,從而儘可能的保證業務系統的穩定性。同時,能夠提供更高效的DDL變更能力。
聯絡我們
若您對DDL操作有任何疑問,請聯絡我們。