【停售/下线】TokuDB引擎转换为InnoDB引擎

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_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. 确认同步无延迟后,切换应用连接地址到新实例即可。