RDS MySQL在2019年08月01日後將不再支援TokuDB引擎,本文介紹如何將TokuDB引擎轉換為InnoDB引擎。
背景資訊
由於Percona已經不再對TokuDB提供支援,很多已知BUG無法修正,極端情況下會導致業務受損,因此RDS MySQL在2019年08月01日後將不再支援TokuDB引擎。由於直接進行引擎轉換會阻塞DML操作,影響並發,建議您儘快對業務評估後選擇以下其中一種方案對引擎進行轉換。
TokuDB引擎下線時間
2019年08月01日
適用範圍
儲存引擎為TokuDB的執行個體。
您可以使用show engines;命令查看執行個體當前預設引擎,或者使用show create table <表名>;命令查看錶的儲存引擎。
注意事項
-
轉換儲存引擎後空間佔用會增大,在操作期間需要預留出的空間大約應為並行操作的TokuDB表容量的2倍。操作期間請隨時關注空間使用方式。
-
轉換引擎後,CPU使用率會下降,但IOPS會上升。這是由於資料頁沒有壓縮,所以讀取相同的資料量,IOPS會有所上升。
-
全庫遷移時,由於需要切換串連地址,請在業務低峰期進行操作。
-
全庫遷移時,如果變更了資料庫版本,建議提前進行相容性測試。
方案建議
-
執行個體中的表較小(100M以下),且業務可接受短時阻塞時,可以使用方式情節一,鎖表時間短,而且免去各種工具配置流程。
-
執行個體中的表較大(大於5G)時,建議使用方式情節二或方案三。
-
執行個體中的所有表都需要轉換時,建議使用方式情節三或方案四。
-
切換引擎後請修改執行個體參數default_storage_engine為InnoDB。
方案一
此方案為直接轉換引擎,最簡單直接,但過程中會全程阻塞DML操作且大錶轉換時間比較久。
-
在上方選擇。
-
執行如下命令:
Alter table test.testfs engine innodb【執行SQL:(1)】 Alter table test.testfs engine innodb 執行成功, 耗時: [18185ms.]
方案二
此方案為使用第三方工具進行轉換。支援Online DDL的第三方工具很多,例如Percona開發的pt-osc、Git-hub開發的gh-ost等,這裡以gh-ost為例進行轉換說明,詳細說明請參見gh-ost。
原理說明
gh-ost進行轉換的基本原理是建立一個與原表結構相同的暫存資料表,然後同步原表資料,全量完成後通過類比Slave進程讀取Binlog,即時同步資料到暫存資料表。最後在業務低峰時間段重新命名表進行切換。此方案主要壓力來自全量資料初始化時的IO,但是可以通過修改參數限制IO。
-
優點:機動性強,可以自訂時間,同步過程可控。
-
缺點:每一個表都要用命令同步一次,如果表很多的話操作比較繁瑣。
參數說明
|
參數 |
說明 |
|
--initially-drop-old-table |
檢查並刪除已經存在的舊錶。 |
|
--initially-drop-ghost-table |
檢查並刪除已經存在的ghost中間表。 |
|
--aliyun-rds |
在阿里雲RDS上執行。 |
|
--assume-rbr |
設定gh-ost為rbr binlog模式。 |
|
--allow-on-master |
在主庫上執行gh-ost。 |
|
--assume-master-host |
主庫的地址。 |
|
--user |
資料庫帳號名稱。 |
|
--password |
資料庫密碼。 |
|
--host |
串連地址,與主庫地址相同即可。 |
|
--database |
資料庫名稱。 |
|
--table |
表名。 |
|
--alter |
動作陳述式。 |
|
--chunk-size |
行拷貝的batch大小。 |
|
--postpone-cut-over-flag-file |
切換檔案。指定時間刪除此檔案立刻進行表切換。 |
|
--panic-flag-file |
產生此檔案,ghost進程立刻停止。 |
|
--serve-socket-file |
用於接收互動命令。 |
|
--execute |
直接執行。 |
前提條件
-
已在本地主機或ECS安裝gh-ost。
-
已在RDS執行個體的IP白名單中添加本地主機或ECS的IP。
操作步驟
-
在本地主機或ECS上執行如下命令進行轉換,等待轉換完成。
gh-ost --user="test01" --password="Test123456" --host="rm-bpxxxxx.mysql.rds.aliyuncs.com" --database="test" --table="testfs" --alter="engine=innodb" --initially-drop-old-table --initially-drop-ghost-table --aliyun-rds --assume-rbr --allow-on-master --assume-master-host="rm-bpxxxxx.mysql.rds.aliyuncs.com" --chunk-size=500 --postpone-cut-over-flag-file="/tmp/ghostpost.postpone" --panic-flag-file="/tmp/stop.flag" --serve-socket-file="/tmp/ghost.sock" --execute2019/06/13 17:22:51 binlogsyncer.go:79: [info] create BinlogSyncer with config {999 2019/06/13 17:22:51 binlogsyncer.go:246: [info] begin to sync binlog from position 2019/06/13 17:22:51 binlogsyncer.go:139: [info] register slave for master server rm 2019/06/13 17:22:51 binlogsyncer.go:573: [info] rotate to (mysql-bin.000014, 241268 # Migrating `test`.`testfs`; Ghost table is `test`.`_testfs_gho` # Migrating `xxx`.`xxx`; xxx xxx rds.aliyuncs.com:3306; inspecting xxx # Migration started at Thu Jun 13 17:22:50 +0800 2019 # chunk-size: 500; max-lag-millis: 1500ms; dml-batch-size: 10; max-load: ; critical # throttle-additional-flag-file: /tmp/gh-ost.throttle # postpone-cut-over-flag-file: /tmp/ghostpost.postpone [set] # panic-flag-file: /tmp/stop.flag # Serving on unix socket: /tmp/ghost.sock Copy: 0/100000 0.0%; Applied: 0; Backlog: 0/1000; Time: 0s(total), 0s(copy); stream Copy: 0/100000 0.0%; Applied: 0; Backlog: 0/1000; Time: 1s(total), 1s(copy); stream Copy: 1500/100000 1.5%; Applied: 0; Backlog: 0/1000; Time: 2s(total), 2s(copy); str Copy: 3000/100000 3.0%; Applied: 0; Backlog: 0/1000; Time: 3s(total), 3s(copy); str Copy: 5500/100000 5.5%; Applied: 0; Backlog: 0/1000; Time: 4s(total), 4s(copy); str Copy: 7500/100000 7.5%; Applied: 0; Backlog: 0/1000; Time: 5s(total), 5s(copy); str Copy: 9000/100000 9.0%; Applied: 0; Backlog: 0/1000; Time: 6s(total), 6s(copy); str Copy: 10500/100000 10.5%; Applied: 0; Backlog: 0/1000; Time: 7s(total), 7s(copy); s Copy: 13500/100000 13.5%; Applied: 0; Backlog: 0/1000; Time: 8s(total), 8s(copy); s Copy: 15500/100000 15.5%; Applied: 0; Backlog: 0/1000; Time: 9s(total), 9s(copy); s Copy: 17500/100000 17.5%; Applied: 0; Backlog: 0/1000; Time: 10s(total), 10s(copy); -
在左側查看錶,會發現存在以_gho、_ghc結尾的暫存資料表。登入後在 test 資料庫的表列表中可看到 gh-ost 產生的暫存資料表
_testfs_ghc和_testfs_gho,表示轉換進行中中。 -
執行
rm /tmp/ghostpost.postpone命令開始切換表。結果如下。Copy: 100000/100000 100.0%; Applied: 0; Backlog: 0/1000; Time: 9m0s(total), 56s(copy); streamer: mysql-bin.000015:520562237; Copy: 100000/100000 100.0%; Applied: 0; Backlog: 0/1000; Time: 9m30s(total), 56s(copy); streamer: mysql-bin.000015:520674422; # Migrating `test`.`testfs`; Ghost table is `test`.`_testfs_gho` # Migrating xxx xxx xxx mysql.rds.aliyuncs.com:3306; inspecting xxx xxx xxx xxx mysql.rds.aliyuncs.com:3306 # Migration started at Thu Jun 13 17:22:50 +0800 2019 # chunk-size: 500; max-lag-millis: 1500ms; dml-batch-size: 10; max-load: ; critical-load: ; nice-ratio: 0.000000 # throttle-additional-flag-file: /tmp/gh-ost.throttle # postpone-cut-over-flag-file: /tmp/ghostpost.postpone # panic-flag-file: /tmp/stop.flag # Serving on unix socket: /tmp/ghost.sock Copy: 100000/100000 100.0%; Applied: 0; Backlog: 0/1000; Time: 9m31s(total), 56s(copy); streamer: mysql-bin.000015:520681377; 2019/06/13 17:32:23 binlogsyncer.go:107: [info] syncer is closing... 2019/06/13 17:32:23 binlogstreamer.go:47: [error] close sync with err: sync is been closing... 2019/06/13 17:32:23 binlogsyncer.go:122: [info] syncer is closed說明請忽略顯示的error(錯誤),實際已經切換完成。
-
檢查表並驗證資料。
說明驗證資料沒有問題後刪除_del表即可。
執行
show create table `testfs`;查看錶結構,確認AUTO_INCREMENT值為100001,表明資料已完整保留。
方案三
此方案使用阿里雲的Data Transmission Service即時同步原表資料到暫存資料表,在業務低峰期鎖原表並交換表名。該方案可以大量的表同時操作。
-
在上方選擇。
-
使用如下命令建立暫存資料表。
CREATE TABLE `testfs_tmp` ( `id` int(11) NOT NULL AUTO_INCREMENT, `vc` varchar(8000) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=innodb DEFAULT CHARSET=utf8 -
說明
資料同步作業為計費項目,詳細價格請參見資料轉送。
-
在資料轉送控制台左側單擊数据同步。
-
找到已購買的資料同步執行個體,在右側單擊配置同步鏈路。
-
配置如下參數。
類別
參數
說明
源執行個體資訊
執行個體類型
選擇RDS執行個體。
執行個體ID
選擇需要切換引擎的RDS執行個體。
串連方式
有非加密傳輸和SSL安全連線兩種串連方式。選擇SSL安全連線,需要提前開啟SSL加密,會顯著增加CPU消耗。
目標執行個體資訊
執行個體類型
選擇RDS執行個體。
執行個體ID
選擇需要切換引擎的RDS執行個體。
串連方式
有非加密傳輸和SSL安全連線兩種串連方式。選擇SSL安全連線,需要提前開啟SSL加密,會顯著增加CPU消耗。
頁面還包含同步作業名稱輸入框及執行個體地區下拉選擇(如華東1杭州)。配置完成後單擊授權白名單並進入下一步。
-
單擊授權白名單並進入下一步。
-
等待建立同步帳號,然後單擊下一步。
-
將左側的表testfs移動到右側,並單擊編輯。
配置同步對象:同步架構選擇單向同步(DML+DDL),目標已存在表的處理模式選擇預檢查並報錯攔截。在左側源庫對象中選擇 test002 資料庫下的 testfs 表,移至右側已選擇對象面板,然後將滑鼠移到該對象上,單擊編輯按鈕。
-
修改資料庫名為之前建立的testfs_tmp,並單擊確定。
將資料庫表名稱修改為
testfs_tmp,單擊確定。 -
單擊下一步。
-
僅勾選全量資料初始化,並單擊預檢查並啟動。
勾選全量資料初始化,不勾選結構初始化,然後單擊預檢查並啟動。
-
等待預檢查完成,單擊關閉。
-
等待資料同步延遲為 0ms。同步任務狀態變為同步中,表示資料同步已開始。
-
在DMS的SQL視窗執行切換表名命令:
rename table `testfs` to `testfs_del`,`testfs_tmp` to `testfs`;說明-
切換後DTS同步會報錯,屬於正常現象。
-
驗證資料後請儘快釋放同步作業,避免繼續產生計費。
-
方案四
此方案使用DTS同步整個資料庫至新執行個體,適用於有執行個體升級需求,或者可以接受業務停機時間相對長一些的執行個體。