RDS for MySQL在2019年8月1日后将不再支持TokuDB引擎,本文介绍如何将TokuDB引擎转换为InnoDB引擎。

背景信息

由于Percona已经不再对TokuDB提供支持,很多已知BUG无法修正,极端情况下会导致业务受损,因此RDS for MySQL在2019年8月1日后将不再支持TokuDB引擎。由于直接进行引擎转换会阻塞DML操作,影响并发,建议您尽快对业务评估后选择以下其中一种方案对引擎进行转换。

TokuDB引擎下线时间

2019年8月1日

适用范围

存储引擎为TokuDB的实例。

说明 您可以使用show engines;命令查看实例当前默认引擎,或者使用show create table <表名>;命令查看表的存储引擎。


注意事项

  • 转换存储引擎后空间占用会增大,在操作期间需要预留出的空间大约为:并行操作的TokuDB表容量*2。操作期间请随时关注空间使用情况。
  • 转换引擎后,CPU使用率会下降,但IOPS会上升。这是由于数据页没有压缩,所以读取相同的数据量,IOPS会有所上升。
  • 全库迁移时,由于需要切换连接地址,请在业务低峰期进行操作。
  • 全库迁移时,如果变更了数据库版本,建议提前进行兼容性测试。

方案建议

  • 实例中的表较小(100M以下),且业务可接受短时阻塞时,可以使用方案一,锁表时间短,而且免去各种工具配置流程。
  • 实例中的表较大(大于5G)时,建议使用方案二或方案三。
  • 实例中的所有表都需要转换时,建议使用方案三或方案四。
  • 切换引擎后请修改实例参数default_storage_engineInnoDB

方案一

此方案为直接转换引擎,最简单直接,但过程中会全程阻塞DML操作,且大表转换时间比较久。

操作步骤

  1. 通过DMS登录RDS数据库
  2. 在上方选择SQL操作 > SQL窗口
  3. 执行如下命令:
    Alter table test.testfs engine innodb

    直接修改

方案二

此方案为使用第三方工具进行转换。支持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。

操作步骤

  1. 在本地主机或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" --execute


  2. 通过DMS登录RDS数据库
  3. 在左侧查看表,会发现存在以_gho、_ghc结尾的临时表。
    生成临时表
  4. 执行rm /tmp/ghostpost.postpone命令开始切换表。结果如下。
    开始切换表
    说明 忽略显示的error,实际已经切换完成。
  5. 检查表并验证数据。
    说明 验证数据没有问题后删除_del表即可。

    切换成功

方案三

此方案使用阿里云的数据传输服务DTS(Data Transmission Service)实时同步原表数据到临时表,在业务低峰期锁原表并交换表名。该方案可以大量的表同时操作。

操作步骤

  1. 通过DMS登录RDS数据库
  2. 在上方选择SQL操作 > SQL窗口
  3. 使用如下命令创建临时表。
    CREATE TABLE `testfs_tmp` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `vc` varchar(8000) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=innodb  DEFAULT CHARSET=utf8
    					
  4. 购买数据同步作业
    说明 数据同步作业需要收费,详细价格请参见数据传输
  5. 在数据传输控制台左侧单击数据同步
  6. 找到购买的数据同步作业,在右侧单击配置同步链路
  7. 配置如下参数。
    类别 参数 说明
    源实例信息 实例类型 选择RDS实例
    实例ID 选择需要切换引擎的RDS实例。
    连接方式 非加密传输SSL安全连接两种连接方式。选择SSL安全连接,需要提前开启SSL加密,会显著增加CPU消耗。
    目标实例信息 实例类型 选择RDS实例
    实例ID 选择需要切换引擎的RDS实例。
    连接方式 非加密传输SSL安全连接两种连接方式。选择SSL安全连接,需要提前开启SSL加密,会显著增加CPU消耗。


  8. 单击授权白名单并进入下一步
  9. 等待创建同步账号,然后单击下一步

  10. 将左侧的表testfs移动到右侧,单击编辑

  11. 修改数据库名为之前创建的testfs_tmp,单击确定

  12. 单击下一步
  13. 仅勾选全量数据初始化,单击预检查并启动

  14. 等待预检查完成,单击关闭

  15. 等待数据同步延迟为0ms。

  16. 在DMS的SQL窗口执行切换表名命令:
    rename table `testfs` to `testfs_del`,`testfs_tmp` to `testfs`;
    说明
    • 切换后DTS同步会报错,是正常现象。
    • 验证数据后请尽快释放同步作业,避免继续收费。



方案四

此方案使用DTS同步整个数据库至新实例,适用于有实例升级需求,或者可以接受业务停机时间相对长一些的实例。

操作步骤

  1. 源实例导出所有结构脚本,将脚本中关于引擎部分删除或修改。
    说明 例如将create table t1(id int,name varchar(10)) engine=tokudb;修改为create table t1(id int,name varchar(10)) engine=innodb;
  2. 新建RDS实例,用修改过的脚本创建库、表。
  3. 将源实例数据库使用DTS同步至新实例上。
    说明 在同步初始化时,仅勾选全量数据初始化


  4. 确认同步无延迟后,切换应用连接地址到新实例即可。