2018-12-23 从aliyun的rds全备恢复数据库到docker的mysql。

因为要从生产环境导出一个数据库到测试环境做测试的原因,需要使用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。
然后,解压出来的目录结构如下:


2018-12-23 从aliyun的rds全备恢复数据库到docker的mysql。 xtrabackup01.png

解压data.tar.xz后,得到的目录结果如下:


2018-12-23 从aliyun的rds全备恢复数据库到docker的mysql。 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
上一篇:云数据库RDS存储能力进化解析!


下一篇:云数据库RDS存储能力进化解析!