+86 13541016684Mon. - Fri. 10:00-22:00

线上MySQL RDS实例迁移到AWS Aurora 教程

线上MySQL RDS实例迁移到AWS Aurora 教程

概述

Amazon Aurora与RDS MySQL相比,有一些显著的优点:性能更优,IO能力更强,磁盘容量会自动扩展无需手动管理等等。Aurora与MySQL几乎完全兼容,所以,用Aurora替代MySQL可以获得很多好处。

因为历史原因,我们运行着两个RDS MySQL实例,其中一个在AWS Classic环境中,我们希望把这两个数据库实例迁移到Aurora以获得更好的性能,但是怎么迁移就是个问题。

可选迁移方案

对于迁移,我们做过多种尝试,最简单的做法是:导出数据库的备份,基于该备份创建新的Aurora实例。具体来说,可以有两种做法。

  1. 应用下线,停止MySQL, 使用MySQLDump进行全量备份,创建Aurora,在Aurora中导入该备份。完成后应用接入Aurora重新上线。
  2. 应用下线,停止MySQL,对MySQL RDS实例进行手动快照,快照完成后,将该MySQL实例的快照迁移到Aurora。完成后应用接入Aurora重新上线。

两种做法都可以将MySQL迁移到Aurora,但是都需要停机维护,时间可能需要几个小时,甚至几天。而这对我们来说是不可接受的。

我们需要的迁移方案必须能够尽量不影响线上服务,平滑过渡到Aurora。

AWS提供了DMS(Database Migration Service)服务 ,但是试用之后,DMS在开始迁移数据之后,会经常出现SQL错误,而调试、排错非常的麻烦,只能够放弃。

直到在文档中发现AWS提供了基于MySQL BinLog的迁移方案,只需要最终阶段切换应用配置中的数据库连接时对线上服务有短时间影响。此方案终于使得我们的数据库迁移变得可行。

迁移过程 1

首先我们需要迁移的是在VPC中的MySQL RDS实例。文档对迁移过程给出了一些要求,如MySQL的版本建议为5.5以上,所有表需要转换为InnoDB等。

具体迁移步骤如下:

  1. 在RDS MySQL实例上创建只读副本。如果之前不存在只读副本,这个操作可以启用MySQL binlog。此外,如果数据库比较大,建议调整binlog保存的时间,以下示例将二进制日志文件的保留期设置为 6 天:
    CALL mysql.rds_set_configuration('binlog retention hours', 144);
  2. 只读副本创建完成后,等待只读副本跟上主实例,即Replica lag几乎为0时,停止只读副本的复制:
    CALL mysql.rds_stop_replication;
  3. 停止只读副本的复制之后,最好等待一段时间,比如10分钟,(重试10次之后的教训。)。
    在只读副本中执行:
    SHOW SLAVE STATUS
    记录结果中得到的Master_Log_FileRead_Master_Log_Pos的内容。
    对该只读副本进行手动快照。
  4. 对只读副本的快照,执行迁移快照,将快照转换为Aurora实例。注意:如果发现创建过程很久没响应(超过3小时),需要即时联系AWS确认有无异常。我碰到了很多次,卡在“正在准备数据”阶段。
  5. Aurora实例创建完成后,检查集群的安全组设置,确保能够联网。执行:
    CALL mysql.rds_set_external_master ('mysql master server host', 3306, 'repl_user', '<password>', 'mysql-bin-changelog.000031', 107, 0);
    CALL mysql.rds_start_replication;
    其中mysql-bin-changelog.000031107来自上述SHOW SLAVE STATUS的输出中的Master_Log_FileRead_Master_Log_Pos
  6. 在Aurora上执行SHOW SLAVE STATUS,确认复制过程正常执行。如果遇到类似以下错误:
    Error 'Table 'mysql.rds_monitor' doesn't exist' on query. Default database: 'mysql'. Query: 'DELETE from mysql.rds_monitor'
    Error 'Table 'mysql.rds_monitor' doesn't exist' on query. Default database: 'mysql'. Query: 'INSERT INTO mysql.rds_monitor(pid, table) values (5455,'abc/#sql-ib345-3892659999')'
    需要联系AWS,或者,直接执行CALL mysql.rds_skip_repl_error跳过复制错误,但是这个问题一旦出现,跳过之后一段时间还会再次出现。
  7. Aurora上执行SHOW SLAVE STATUS输出中的Seconds_Behind_Master可以得知复制落后于主实例的时间,一旦复制跟上进度,即可使用CALL mysql.rds_stop_replication;停止复制,然后在应用中切换写入节点。

迁移过程 2

经过上述迁移过程1,我们最终完成了VPC内的MySQL RDS实例到Aurora的迁移。我们另外一个RDS实例是在EC2 Classic环境中,AWS也有一篇文档描述如何进行这种情况下的数据库迁移。

具体的迁移步骤与上述过程只多了一个步骤:在VPC中创建一个新的EC2,开启Classic Link,配置为同时可以访问VPC中的Aurora(新创建的)与VPC外部Classic环境中的RDS MySQL实例,参考文档最后部分,配置nginx代理服务器,然后在mysql.rds_set_external_master中填写的主数据库为那台EC2的IP。其他步骤则完全一致。

经验教训

迁移到Aurora后需要注意以下几点:

  1. Aurora的Multi-AZ与RDS MySQL下的Multi-AZ完全不一样。MySQL下的Multi-AZ,只能有一个备机,而且备机是闲置的,而Aurora下可以创建最多15个副本,这些副本都可以按照设置的优先级按顺序进行Fail Over
  2. MySQL RDS下的只读副本,是可以改为可写的。但是Aurora下的只读副本是无法设置为可写的。
  3. Aurora下的权限也有些变化,导致oak-online-alter-table无法使用,但是Aurora的性能更强,升级实例类型后往往可以直接修改表结构而不影响线上服务。