2018-12-23 从aliyun的rds全备恢复数据库到do
因为要从生产环境导出一个数据库到测试环境做测试的原因,需要使用aliyun自动产生的全备文件,来恢复一个使用docker安装的mysql5.6实例。
1. 首先,是下载一个aliyun的rds的全备文件。
获取并下载rds全备文件的途径,可以参看 RDS for MySQL 物理备份文件恢复到自建数据库。问题是,这篇文章中的后半部分,说法不正确,这也是要写本文的原因之一。本文后面的章节会介绍。
2. 安装mysql-5.6版本
2.1 首先,从镜像市场 拉取mysql 5.6 版本。
$ docker pull msyql:5.6
拉取 5.6 版本而不是其他的原因,是aliyun的rds使用的就是mysql 5.6 版本。为了确保全备恢复能正常进行,暂时先使用mysql 5.6 版本。等后面测试确认新版本也可以恢复后,再更新本文。
2.2 然后,创建一个mysql容器。
在创建容器之前,需要先在宿主机器上创建好mysql的数据文件目录和备份文件目录。假设分别是:
- /dockers/mysql/data
- /dockers/mysql/backup
那么,我们的命令是:
$ docker run --name mysql -v /dockers/mysql/data:/var/lib/mysql -v /dockers/mysql/backup:/var/lib/mysqlbackup -p 3306:3306 -e MYSQL_ROOT_PASSWORD=xxx -e --character-set-server=utf8mb4 -e --collation-server=utf8mb4_unicode_ci -d mysql:5.6
这样就安装好mysql了。
可以通过:
$docker logs mysql
查看其日志来确认是否启动成功。
可以通过:
$ docker exec -it mysql bash
来进入容器内,然后就可以执行命令来直接查询数据了。
2.3 设置mysql时区
对于如何设置mysql时区,具体参看 设置mysql时区
2.4 安装xtrabackup
由于xtrabackup-2.3.×系列版本对应mysql-5.6系列版本,因此我们下载xtrabackup-2.3。
然后,解压出来的目录结构如下:
xtrabackup01.png
解压data.tar.xz后,得到的目录结果如下:
xtrabackup02.png
显然,要么将相关文件拷贝到系统环境对应目录,要么设置系统参数。我选择了拷贝文件到系统环境:
$ cp -R xtrabackup/data/usr /usr
接下来,执行命令测试是否安装成功:
$ xtrabackup --version
结果是得到一个关于libssl.so 找不到的报错,是因为docker容器内没有安装openssl导致的。可以这样解决:
$ apt-get -y update
$ apt-get -y install openssl
$ apt-get -y install vim
上述三个命令,分别是:更新操作系统、安装openssl、安装vim文本编辑工具。
2.5 好了,现在开始恢复mysql
首先,拷贝全备文件到mysql的备份目录:
$ mv hins_data_20181127005157.tar /dockers/mysql/backup
然后,解压该文件到 venus 目录。因为我们要回复的mysql实例,用于venus项目。
$ mkdir /dockers/mysql/backup/venus
$ tar xvf hins_data_20181127005157.tar -d /dockers/mysql/backup/venus
第三步,进入解压后的目录,查看备份数据的一些环境变量参数
$ vi /dockers/mysql/backup/venus/backup-my.cnf
其内容大概如下:
[mysqld]
innodb_checksum_algorithm=innodb
innodb_log_checksum_algorithm=innodb
innodb_data_file_path=ibdata1:200M:autoextend
innodb_log_files_in_group=2
innodb_log_file_size=524288000
innodb_fast_checksum=false
innodb_page_size=16384
innodb_log_block_size=512
innodb_undo_directory=.
innodb_undo_tablespaces=0
rds_encrypt_data=false
innodb_encrypt_algorithm=aes_128_ecb
我们看这段代码的原因,是其中这两句:
innodb_log_file_size=524288000
这段代码要黏贴到容器的mysql配置文件中,否则会因为mysql系统参数不一致而导致恢复失败:
$ vi /etc/mysql/mysql.conf.d/mysql.conf
最终,我们的mysql配置文件看起来像是这样的:
...
# add for xtrbackup
innodb_log_file_size=524288000
另外,还要在备份配置文件中显式指定数据目录,否则xtrbackup会报错说没有指定datadir参数。最终,看起来像是这样:
[mysqld]
innodb_checksum_algorithm=innodb
innodb_log_checksum_algorithm=innodb
innodb_data_file_path=ibdata1:200M:autoextend
innodb_log_files_in_group=2
innodb_log_file_size=524288000
innodb_fast_checksum=false
innodb_page_size=16384
innodb_log_block_size=512
innodb_undo_directory=.
innodb_undo_tablespaces=0
rds_encrypt_data=false
innodb_encrypt_algorithm=aes_128_ecb
# newly added
datadir=/var/lib/mysql
在这个地方,我还踩过一个小坑,当时给backup-my.cnf赋予了权限 777,结果结果恢复备份时xtrabackup报错:
Warning: World-writable config file '/var/lib/mysqlbackup/20181222/backup-my.cnf' is
原因是该配置文件的权限太大,谁都可以访问并修改,为了安全,mysql不允许读取这样的配置文件。将权限修改小就可以了:
$ chown root.root /var/lib/mysqlbackup/20181222/backup-my.cnf
$ chmod 754 /var/lib/mysqlbackup/20181222/backup-my.cnf
由于是全备恢复,因此必须移走原来的数据目录。由于使用了docker容器,我们无法在保持容器运行的情况下关闭mysql,因此我们只移走数据文件,但不关闭数据库了。
mv /dockers/mysql/data /dockers/mysql/backupold
- 先prepare数据
$ xtrabackup --defaults-file=/var/lib/mysqlbackup/20181222/back-my.cnf --apply-log /var/lib/mysqlbackup/20181222
现在,我们可以开始执行恢复了:
$ xtrabackup --defaults-file=/var/lib/mysqlbackup/20181222/back-my.cnf --copy-back /var/lib/mysqlbackup/20181222
最后,我们可以这样检查是否恢复成功:
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| ejabberd |
| mysql |
| performance_schema |
| test |
| venus |
+--------------------+
6 rows in set (0.00 sec)
mysql>
2.6 重置root密码
因为aliyun只允许添加新用户,不允许直接使用root登录(没有提供密码),也不允许登录rds机器。因此从rds产生的备份恢复出来的数据库,是不知道root密码的。然后我们使用了docker来安装的mysql,如果没有root密码,就无法修改数据库用户的授权,其他机器就无法通过宿主机器的端口,或docker容器的link来进行访问,因为授权通不过。
我们可以这样来取回root密码:
2.6.1 进入容器,然后修改mysql配置文件,允许暂时停用授权:
$ docker exec -it mysql bash
$ vi /etc/mysqsl/mysql.conf.d/mysqld.conf
给配置添加忽略授权的配置项:
[mysqld]
...
skip-grant-tables
2.6.2 接着,我们重启mysql,就可以无密码用root登录上去,然后给root重置密码了:
$ mysql -u root
mysql>
2.6.3 修改mysql的root密码有如下三种方法:
第一种,直接修改密码字段:
mysql> use mysql
Database changed
mysql> update user set password = password('xxxxxx') where user = 'root';
Query OK, 2 rows affected (0.00 sec)
Rows matched: 2 Changed: 2 Warnings: 0
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
mysql>
第二种,使用mysqladmin命令:
$ mysqladmin -u root password "newPass" oldpass 'oldPassword'
第三种,使用mysql重置密码专用sql语法:
mysql>set password for 'root'@'%' = password('xxxxxx');
2.6.4 修改配置文件并重启mysql,以便重新启用用户登录审计。
没有面裸奔当然时不行的,因此重置完毕root密码后,我们就要将用户登录审计功能重新打开了:
$ vi /etc/mysql/mysql.conf.d/mysqld.conf
$
$ [mysqld]
$ ...
$ skip-grant-tables
然后重启docker容器
$ docker restart mysql