# 41. MySQL 迁移 RDS 总结

Date: 2017-07-17

## Status

Accepted

## Context

1. 当前数据库为 Master, Slave 模式；
2. Master 实例上创建了 16 个数据库，全部需要迁移；
3. 部分业务存在跨库查询；
4. 有一个数据库被近 10 个业务进行查询等数据库操作；
5. 当前数据库为 MySQL 5.1，存在主从同步性能问题；
6. RDS 仅支持 MySQL 5.5, 5.6, 5.7 版本；

## Decision

1. 调研 MySQL 5.1 与 5.5 之间的差异，并周知各个项目组成员；
2. 将数据库与业务之间的引用关系用二维表列举出来；
3. 选出被业务单独或少量引用的数据库，先通过将对应测试数据库进行迁移，并交由测试人员进行测试；
4. 测试完成后对正式环境直接进行迁移；
5. 针对被10多个业务引用的数据库迁移，我们不止要做测试环境的迁移，还要做线上环境的测试
	1. 为了保证线上测试可回滚，我们需限定只有测试人员进行操作；
		1. 限制我们的服务器安全组，外网只能通过办公网络访问；
		2. 限制我们的入口 slb，只能通过办公网络访问。
	2. 我们的服务之间存在调用关系，部分业务走的外网域名；
		1. 准备我们所有外网业务的域名及其内网 ip 映射，通过 ansible 分发并追加其至所有的线上机器 hosts
	3. 所有业务准备好分支 feature/db-config-update-to-rds，此分支与 master 分支差异只有数据库配置改动，冻结 master 新代码合入，如此确保随时可上线，随时可回滚；
	4. 创建数据库迁移任务： 结构迁移+整体数据+增量数据迁移；
	5. 停止并备份任务计划调度(/etc/crontab，cron.d，/var/spool/cron)；
	6. 停止所有业务服务；
	7. 停止所有 nginx；
	8. 脚本验证所有机器上的服务和任务计划，确保无运行中相关程序；
	9. 验证无数据库连接；
	10. 锁定原数据库写操作(验证确认确实不可写)
	11. 网络隔离；
	12. 检查源数据库与目的数据库 数据一致性；
	13. 停止数据迁移任务；
	14. 停止主db数据库服务；
	15. 启动RDS到从库的数据同步任务；
	16. 重启所有服务；
	17. 重启 nginx；
	18. 测试团队开始全面验证；
	19. 网络隔离解除；
	20. 恢复任务计划；
	21. 重新执行停服期间计划任务。

## Consequences

1. RDS 磁盘预留过低，导致同步中途停止，无法进行写操作；
2. 一些业务需要回调，测试不完整；
3. 如果有完整的预发布环境，可保证服务零停机时间；