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,表明数据已完整保留。
方案三
此方案使用阿里云的数据传输服务DTS(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同步整个数据库至新实例,适用于有实例升级需求,或者可以接受业务停机时间相对长一些的实例。