将阿里云上的RDS MySQL数据迁移到自建的服务器或者虚拟机,如果需要尽可能小的停机时间或者不停服务,那么至少需要做分两个步骤来完成:本地MySQL与RDS MySQL进行数据库同步及验证数据一致后将从库变成主库。其中比较麻烦的事情是本地MySQL与RDS做主从,因为与完整的MySQL主从同步相比,RDS 限制很多。因数据库角色切换比较简单,所以本文仅介绍主从同步


第一步:备份RDS数据

登录阿里云后台,执行数据库备份,得到诸如aaa.qp.xd这样的数据,并将其传输到目标MySQL数据库所在的系统。

从阿里云RDS MySQL在线迁移数据到本地MySQL_mysql

第二步:同步账号授权

任意系统用MySQL客户端连接阿里云RDS MySQL,用grant 指令创建同步账号,指令为” grant  REPLICATION SLAVE  on btcj.* to btcj@'172.18.28.%' with grant option;”.

grant  REPLICATION SLAVE  on btcj.* to btcj@'172.18.28.%' with grant option;

从阿里云RDS MySQL在线迁移数据到本地MySQL_数据_02

第三步:目标数据库安装软件

因数据库版本为MySQL 8.X,因此恢复软件的版本也必须为percona-xtrabackup

8.0以上的版本。为了能对备份文件.xb进行加压,还需要安装软件qpress。用系统工具yum就轻松地把qpgress安装在系统上。


yum install qpress



选择xtrabackup最麻烦,就是必须与MySQL版本相匹配,版本低了,再解压xb文件的时候,会因为报错而中断。由于目标数据库版本为MySQL-8.0.28,尝试了多个xtrabackup版本,最后试出xtrabackup-8.0.23可以满足需求。安装xtrabackup的指令如下:


yum localinstall percona-xtrabackup-80-8.0.23-16.1.el7.x86_64.rpm



第四步:备份数据解包并应用

1.    

目标系统命令行执行“cat btcj.qp.xb | xbstream -x -v -C 

/data/db_dir”。

cat btcj.qp.xb | xbstream -x -v -C /data/db_dir

其中目录/data/db_dir为手工创建,用来存储解包后的备份数据。

从阿里云RDS MySQL在线迁移数据到本地MySQL_mysql_03

2.    

解包qp文件。步骤“1”执行完以后,生成大量带“.qp”后缀的文件,需要用xtrabackup继续进行格式转换,在目标系统命令行下执行指令“xtrabackup decompress--remove-original --target-dir=/data/db_dir”。

xtrabackup --decompress --remove-original --target-dir=/data/db_dir

注意,这个指令带的选项、参数与低版本的innobackex有差异,如下图所示。

从阿里云RDS MySQL在线迁移数据到本地MySQL_mysql_04

第五步:备份数据恢复

一共两条指令,在目标系统的命令行下执行。如果报错,一般都是xtrabackup版本低,与MySQL版本不匹配,需要下载更高版本的xtrabackup。


xtrabackup --prepare --target-dir=/data/db_dir

xtrabackup --copy-back --target-dir=/data/db_dir --datadir=/var/lib/mysql


xtrabackup --prepare  --target-dir=/data/db_dir
xtrabackup --copy-back --target-dir=/data/db_dir --datadir=/var/lib/mysql

注意:数据源路径(--target-dir)与数据库实际存放路径(datadir)要分开,并且数据库实际存放路径必须是空目录。


第六步:启动目标数据库MySQL

备份数据恢复以后,在指定的恢复目录,存在文件“backup-my.cnf”。把这个文件的内容酌情复制到文件/etc/my.cnf。

从阿里云RDS MySQL在线迁移数据到本地MySQL_mysql_05

试着在命令行执行 service mysqld start启动MySQL服务,如果启动失败,根据错误日志提示修改MySQL选项文件 /etc/my.cnf ,一般情况下,注释掉某些行就可以正常启动MySQL服务,下边是一个正常启动的数据库选项文件/etc/my.cnf的完整内容,供大家参考。


[root@mysql182 db_dir]# more /etc/my.cnf

[mysqld]

datadir=/var/lib/mysql

socket=/var/lib/mysql/mysql.sock

replicate-do-db         = btcj

log-error=/var/lib/mysql/mysqld.log

pid-file=/var/run/mysqld/mysqld.pid

skip-grant-tables

slave-skip-errors=1236,1032


#innodb_undo_directory=.

#innodb_undo_tablespaces=0

# need for slave

server-id = 182

#master-info-repository = file

#relay-log-info_repository = file

binlog-format = ROW

gtid-mode = OFF

#enforce-gtid-consistency = true

log-bin = hostname-bin

relay-log = hostname-relay-bin

log-slave-updates=1

#plugin-load-add=validate_password.so

#validate-password=FORCE_PLUS_PERMANENT


lower_case_table_names=1

innodb_checksum_algorithm=crc32

innodb_log_checksums=1

innodb_data_file_path=ibdata1:200M:autoextend

innodb_log_files_in_group=2

innodb_log_file_size=1048576000

innodb_page_size=16384

innodb_undo_directory=./

innodb_undo_tablespaces=2

server_id=3170858970

innodb_log_checksums=ON

innodb_redo_log_encrypt=OFF

innodb_undo_log_encrypt=OFF

#server_uuid=01073793-7e65-11ec-8ac4-6c92bf3b5d07

#master_key_id=0

#innodb_encrypt_algorithm=aes_256_cbc


为了方便,暂时取消了MySQL登录密码,并且跳过错误1032等。


检查数据库数据存放目录”/var/lib/mysql”,确保其属主为mysql用户及组。再次启动MySQL,直到服务正常。


第七步:开始数据主从同步

目标系统登录本机MySQL,从数据库目录读取文件“xtrabackup_binlog_pos_innodb”获取RDS主库的二进制文件及偏移量位置。

切换到MySQL客户端,执行如下指令:


mysql> change master to master_host='rm-2zeex968rb5gv32q3fo.mysql.rds.aliyuncs.com',master_user='btcj',master_password='u9u6*5sdwd@23',master_log_file='mysql-bin.000445',master_log_pos=360595964;

mysql>start slave;



第八步:验证数据同步

目标系统MySQL客户端查看从库状态,只要不报错,就是正常。

从阿里云RDS MySQL在线迁移数据到本地MySQL_数据库_06


特别提示:阿里云的三节点RDS MySQL(非高可用型),默认情况下GTID是“OFF”关闭状态,不能被人为打开。因此只能是在远程客户端,以高权限账号用mysqldump  加选项 "--master-data"进行导出,再导入同步!套路真的是很深啊!