架构
备份IP:172.17.100.103(5.6.39)
还原IP:172.17.100.104(5.6.39)
线上备份:阿里云RDS(5.6.16)
还原IP:172.17.100.101(5.7.22)
###################################################
实验一:完成Xtrabackup的安装,以及测试环境下的备份和还原
###################################################
Xtrabackup的安装
(CentOS6)前置依赖条件
#在centos6.6和6.8的版本上直接安装会提示缺少一个依赖条件,因此需要先打上这个rpm包
wget http://ftp.tu-chemnitz.de/pub/linux/dag/redhat/el6/en/x86_64/rpmforge/RPMS/libev-4.15-1.el6.rf.x86_64.rpm
yum install -y libev-4.15-1.el6.rf.x86_64.rpm
yum安装xtrabackup
wget https://www.percona.com/downloads/Percona-XtraBackup-2.4/Percona-XtraBackup-2.4.14/binary/redhat/6/x86_64/percona-xtrabackup-24-2.4.14-1.el6.x86_64.rpm
yum -y install perl perl-devel libaio libaio-devel perl-Time-HiRes perl-DBD-MySQL perl-Digest-MD5
yum install -y percona-xtrabackup-24-2.4.14-1.el6.x86_64.rpm
CentOS7下的xtrabackup安装
centos7在执行到上面的 “yum install percona-xtrabackup-24 -y” 这一步时会提示报错,证明CentOS6下面的版本无法通用于7
yum install -y libev
yum -y install perl perl-devel libaio libaio-devel perl-Time-HiRes perl-DBD-MySQL perl-Digest-MD5
wget https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.4.8/binary/redhat/7/x86_64/percona-xtrabackup-24-2.4.8-1.el7.x86_64.rpm
yum install -y percona-xtrabackup-24-2.4.8-1.el7.x86_64.rpm
单机备份(172.17.100.103)
#创建备份路径
mkdir -p /data/Xtrabackup
#执行备份
(innobackupex -S /tmp/mysql3306.sock -uroot -p密码 /data/Xtrabackup/)
#上面一条执行备份时出现过报错,最好指定一下参数文件
innobackupex --defaults-file=/data/mysql/mysql3306/my3306.cnf --user=root --password=beacon /data/Xtrabackup/
#将备份拷贝到目的IP
scp -r /data/Xtrabackup/2018-06-26_09-27-15/ 172.17.100.104:/data/Xtrabackup/
单机还原(172.17.100.104)
#删除datadir下的数据文件(2台测试机没有开启binlog)
cd /usr/local/mysql/data
rm -rf *
#执行还原
innobackupex --apply-log /data/Xtrabackup/2018-06-26_09-27-15/
innobackupex --copy-back /data/Xtrabackup/2018-06-26_09-27-15/
#更改权限
chown -R mysql.mysql /usr/local/mysql/data
遇到的问题
问题①
104的mysql没有执行关闭,直接执行的数据还原,完成之后可以登陆,也可以查看到有多少表被恢复过来,但是在执行表内容查询时,提示该表不存在
并且无法用service mysqld stop去关闭mysql
#通过mysqladmin关闭mysql
mysqladmin -uroot -p shutdown
完成重启后,可以正常使用数据库
问题②
备份时报错InnoDB: File ./ib_logfile2: 'open' returned OS error 71. Cannot continue operation
解决方法:在备份时指定cnf文件
innobackupex --defaults-file=/data/mysql/mysql3306/my3306.cnf --user=root --password=beacon /data/Xtrabackup/
###################################################
实验二:线上RDS库(5.6.16)还原到本地(5.6.39)
###################################################
下载阿里云解压脚本
wget http://oss.aliyuncs.com/aliyunecs/rds_backup_extract.sh
chmod +x rds_backup_extract.sh
将RDS的备份文件拷贝到本地
./rds_backup_extract.sh -f hins4334903_data_20180625233726.tar.gz -C /usr/local/mysql/data/
#执行恢复
innobackupex --defaults-file=/usr/local/mysql/data/backup-my.cnf --apply-log /usr/local/mysql/data
#修改数据路径的权限
chown -R mysql.mysql /usr/local/mysql/data
#对数据目录(/usr/local/mysql/data)下之前解压出的backup-my.cnf进行修改,注释掉一堆RDS特有的设置
综合来说能留下的就是这3个设置
innodb_data_file_path=ibdata1:200M:autoextend
innodb_log_files_in_group=2
innodb_log_file_size=1048576000
因为我本地5.6并没有按照标准规范去安装,所以这里并不像我5.7MySQL库设置得那样严谨
我直接把这3行拷贝到了/etc/my.cnf的[mysqld]下
然后用service mysqld start启动了数据库
#在RDS里创建的用户,是不会被恢复到本地的,因此采用下列方式即可完成登陆
mysql -uroot
检查确认所有库都可以打开,数据恢复完成;
根据阿里云的指导文档,在新建用户前还需要完成下面这个操作
delete from mysql.db where user<>'root' and char_length(user)>0;delete from mysql.tables_priv where user<>'root' and char_length(user)>0;flush privileges;
读取mysql.user可以发现账号只有root@localhost等3个空密码的账号,对其修改密码时,出现了下图的错误
ERROR 1558 (HY000): Column count of mysql.user is wrong. Expected 43, found 42. Created with MySQL 50518, now running 50639. Please use mysql_upgrade to fix this error.
通过mysql_upgrade来解决该问题
完成升级后该问题得以解决
执行完mysql_update之后关键的一步:一定要重启!!!
否则在打开performance_schema相关表的时候,仍然会有报错!!!
至此RDS(5.6)恢复到本地(5.6)完成,但是有一个遗留问题
在此次恢复过程中,只是用了apply-log,没有用copy-back就完成了恢复,那么copy-back的意义何在呢?(本机需要copy-back,异机不需要)
###################################################
实验三:线上RDS库(5.6.16)还原到本地(5.7.22)
###################################################
--------------------------------------------------------------------------------------
写在最前:阿里云RDS恢复到本地踩到的坑
在执行恢复的时候,遇到了一个gone away的报错
通过tail -f error.log可以发现是一个参数造成的恢复中断
将参数max_allowed_packet设置为与线上库相同的值后解决该问题(截图参见实验四)
在阿里云生产环境上这个值设置的是1024M
官网下载的5.7.22该值默认仅为4M(4194304Byte/1024/1024)
--------------------------------------------------------------------------------------
总体来说把RDS跨版本恢复到5.7与恢复到5.6没有太多差异,相同之处直接复制实验二的字段,差异之处加粗处理
5.7.22的数据目录路径为/data/mysql/mysql3306/data
下载阿里云解压脚本
wget http://oss.aliyuncs.com/aliyunecs/rds_backup_extract.sh
chmod +x rds_backup_extract.sh
将RDS的备份文件拷贝到本地
./rds_backup_extract.sh -f hins4334903_data_20180625233726.tar.gz -C /data/mysql/mysql3306/data
把恢复到本地的backup-my.cnf中的
innodb_data_file_path=ibdata1:200M:autoextend
复制到我的defaults-file中(我本地设置的是100M)
#执行恢复(生成ibdata)
innobackupex --defaults-file=/data/mysql/mysql3306/my3306.cnf --apply-log /data/mysql/mysql3306/data
#修改数据路径的权限
chown -R mysql.mysql /data/mysql/mysql3306/data
#一切准备妥当,启动MySQL
/usr/local/mysql/bin/mysqld --defaults-file=/data/mysql/mysql3306/my3306.cnf &
在另一个会话中读取error.log,可以发现如下报错
毫无疑问仍然需要upgrade
执行mysql_upgrade -S /tmp/mysql3306.sock -uroot
完成之后,log中已经没有error
#修改账户的密码
delete from mysql.db where user<>'root' and char_length(user)>0;delete from mysql.tables_priv where user<>'root' and char_length(user)>0;flush privileges;
alter user user() identified by '密码';
flush privileges;
据说跨版本升级如果配置不当会造成索引失效,我们这里只是一个迁移工作,确认一下索引是否安好
确认表都可以正常打开,恢复完成!
执行完mysql_update之后关键的一步:一定要重启!!!
否则在打开performance_schema相关表的时候,仍然会有报错!!!
###################################################
实验四:恢复线上RDS最新的数据到本地
###################################################.
--------------------------------------------------------------------------------------
写在最前:阿里云RDS恢复到本地踩到的坑
在执行恢复的时候,遇到了一个gone away的报错
通过tail -f error.log可以发现是一个参数造成的恢复中断
将参数max_allowed_packet设置为与线上库相同的值后解决该问题
在阿里云生产环境上这个值设置的是1024M
官网下载的5.7.22该值默认仅为4M(4194304Byte/1024/1024)
--------------------------------------------------------------------------------------
参照实验三,完成RDS数据的恢复
针对线上活跃的某张表核对数据记录,线下通过innobackupex恢复(不加binlog)行数为1546286,线上为1560004(6月27日19点左右的数据)
对恢复的xtrabackup_binlog_info进行查看,可以发现当前恢复的数据在binlog中使用的log为mysql-bin.000336,位置点为13090077
也就是说恢复所需要的起始binlog为mysql-bin.000336
到线上下载336到现在产生的所有binlog(336-346),并传到/data/mysql/mysql3306/logs下
快速传送windows小文件工具:lrzsz工具安装使用参考
cd ~
cp mysql-bin.0003* /data/mysql/mysql3306/logs
chown -R mysql.mysql /data/mysql/
#探寻末尾位置点
cd /data/mysql/mysql3306/logs
#将最后一个binlog导出成文本文件
mysqlbinlog -v --base64-output=DECODE-ROWS mysql-bin.000346 > 346.log
tail -10f 346.log
可以获知最后一个binlog的最后一个end_pos为86242654
将需要还原的binlog排列全部列出,第一个binlog为336,最后一个为346;(中间的是否需要按顺序没有测试,我采取了顺序排列)
start-position为第一个binlog的相应的end_log_pos:13090077
stop-position为最后一个binlog的最后一个end_log_pos:86242654
#我是切换到/data/mysql/mysql3306/logs下执行的,在其他路径下执行,需要把binlog的位置写全
mysqlbinlog --start-position=13090077 --stop-position=86242654 mysql-bin.000336 mysql-bin.000337 mysql-bin.000338 mysql-bin.000339 mysql-bin.000340 mysql-bin.000341 mysql-bin.000342 mysql-bin.000343 mysql-bin.000344 mysql-bin.000345 mysql-bin.000346 |mysql -uroot
完成恢复后没有报错,重新启动mysql
在启动的log中可以看到recovery的相关log
重启完成后,在binlog路径下可以看到新生成的binlog,同时在binlog.index里面可以看到新生成的binlog已经加入
验证数据,已经完全超越了昨晚的数据量
--2019.8.2华为云RDS恢复到线下
1.下载qpress并解压
cd ~
wget http://www.quicklz.com/qpress-11-linux-x64.tar
tar -xf qpress-11-linux-x64.tar
mv qpress /usr/bin/
2.下载线上qp备份文件到需要恢复的服务器(假设路径为/home/run)
cd /home/run
3.删除原数据库的数据和日志文件(确定数据库可以处理,否则请做好备份)
rm -rf /data/mysql/mysql3306/data/*
rm -rf /data/mysql/mysql3306/logs/*
4.还原
xbstream -x < *.qp -C /data/mysql/mysql3306/data/
innobackupex --decompress /data/mysql/mysql3306/data/
find /data/mysql/mysql3306/data/ -name "*.qp" | xargs rm -f
innobackupex --defaults-file=/data/mysql/mysql3306/my3306.cnf --apply-log /data/mysql/mysql3306/data
chown -R mysql.mysql /data/mysql
5.华为的和阿里恢复不同,不会清理线上的密码,而且在华为的表里面是没有root@localhost这个用户的,华为云具备super权限的账户是rdsAdmin
sed -i 's/#skip-grant-tables=1/skip-grant-tables=1/g' /data/mysql/mysql3306/my3306.cnf
/usr/local/mysql/bin/mysqld --defaults-file=/data/mysql/mysql3306/my3306.cnf &
#修改密码,同时对root@'%'授权
mysql -urdsAdmin << EOF
update mysql.user set authentication_string=password('密码') where user='rdsAdmin';
grant all privileges on *.* to root@'%' with grant option;
flush privileges;
shutdown;
EOF
#关闭免密登录
sed -i 's/skip-grant-tables=1/#skip-grant-tables=1/g' /data/mysql/mysql3306/my3306.cnf
/usr/local/mysql/bin/mysqld --defaults-file=/data/mysql/mysql3306/my3306.cnf &
#执行登陆即可
mysql -uroot -p'密码'
#脚本如下(首先确认innobackup装完,qp文件拷贝到了/home/run路径下,且只有1个qp文件)
#!/bin/bash
# 2019.8.5
# FlyDido
# 物理恢复华为RDS的全量备份
pid=`ps -ef|grep '/usr/local/mysql/bin/mysqld --defaults-file=/data/mysql/mysql3306/my3306.cnf'|grep -v grep|awk '{print $2}'`
if [ -z "$pid" ]; then
echo "mysql is down" > /tmp/dump.log
else
kill -9 $pid
fi
rm -rf /data/mysql/mysql3306/data/*
rm -rf /data/mysql/mysql3306/logs/*
cd /home/run
#解压
xbstream -x < *.qp -C /data/mysql/mysql3306/data/
innobackupex --decompress /data/mysql/mysql3306/data/
find /data/mysql/mysql3306/data/ -name "*.qp" | xargs rm -f
#应用日志
innobackupex --defaults-file=/data/mysql/mysql3306/my3306.cnf --apply-log /data/mysql/mysql3306/data
chown -R mysql.mysql /data/mysql
sed -i 's/#skip-grant-tables=1/skip-grant-tables=1/g' /data/mysql/mysql3306/my3306.cnf
/usr/local/mysql/bin/mysqld --defaults-file=/data/mysql/mysql3306/my3306.cnf &
#判定mysql启动情况
while((1<100))
do
tail -10 /data/mysql/mysql3306/data/error.log |grep 'ready for connections' &>> /tmp/dump.log
if [ $? == 0 ];then
echo -e "mysql启动完成\n"
break
else
echo -e "mysql启动中...\n"
sleep 10
fi
done
#mysql_upgrade -uroot &>> /tmp/dump.log &&
mysql -urdsAdmin << EOF
update mysql.user set authentication_string=password('密码') where user='rdsAdmin';
grant all privileges on *.* to root@'%' with grant option;
flush privileges;
shutdown;
EOF
sed -i 's/skip-grant-tables=1/#skip-grant-tables=1/g' /data/mysql/mysql3306/my3306.cnf
/usr/local/mysql/bin/mysqld --defaults-file=/data/mysql/mysql3306/my3306.cnf &
echo -e "恢复完成,密码为XXXX"