【小宅按】 在日常的linux运维工作中,大数据量备份与还原,始终是个难点。关于mysql的备份和恢复,比较传统的是用mysqldump工具,今天推荐另一个备份工具innobackupex。

2.0 配置

2.1 准备工作

#系统环境

[root@master tools]# cat /etc/redhat-release CentOS release 6.8 (Final)
[root@master tools]# uname -r2.6.32-642.el6.x86_64

#主资料库版本

[root@master ~]# mysql -Vmysql Ver 14.14 Distrib 5.5.32, for Linux (x86_64) using readline 5.1

#检查资料库引擎

mysql> show engines;
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine | Support | Comment | Transactions | XA | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| CSV | YES | CSV storage engine | NO | NO | NO |
| InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES |
| PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO |
| BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO |
| MyISAM | YES | MyISAM storage engine | NO | NO | NO |
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO |
| MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO |
| FEDERATED | NO | Federated MySQL storage engine | NULL | NULL | NULL |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
8 rows in set (0.00 sec)

#主从资料库同步注意点 [mysqld]

#主从之间的id不能相同 server-id

#启用二进位日志 log-bin

#一般在从库开启(可选) read_only #推荐使用InnoDB并做好相关配置

#检查主从资料库状态

[root@master ~]# mysql -e "show global variables like server_id;"+---------------+-------+| Variable_name | Value |
+---------------+-------+| server_id | 241 |
+---------------+-------+

[root@slave01 ~]# mysql -e "show global variables like server_id;"+---------------+-------+| Variable_name | Value |
+---------------+-------+| server_id | 242 |
+---------------+-------+

2.2 安装percona-xtrabackup

官网安装包地址 - percona.com/downloads/X

2.2.1 源码安装Xtrabackup

将源码包下载到/usr/local/src下

源码包下载

cd /usr/local/src

yum -y install cmake gcc gcc-c++ libaio libaio-devel automake autoconf bzr bison libtool zlib-devel libgcrypt-devel libcurl-devel crypt* libgcrypt* python-sphinx openssl imake libxml2-devel expat-devel ncurses5-devel ncurses-devle vim-common libgpg-error-devel libidn-devel perl-DBI perl-DBD-MySQL perl-Time-HiRes perl-IO-Socket-SSL

wget http://www.percona.com/downloads/XtraBackup/XtraBackup-2.1.9/source/percona-xtrabackup-2.1.9.tar.gz

tar -zvxf percona-xtrabackup-2.1.9.tar.gz

cd percona-xtrabackup-2.1.9[root@master percona-xtrabackup-2.1.9]# ./utils/build.sh //执行该安装脚本,会出现下面信息Build an xtrabackup binary against the specified InnoDB flavor.Usage: build.sh CODEBASEwhere CODEBASE can be one of the following values or aliases:
innodb51 | plugin build against InnoDB plugin in MySQL 5.1
innodb55 | 5.5 build against InnoDB in MySQL 5.5
innodb56 | 5.6,xtradb56, build against InnoDB in MySQL 5.6
| mariadb100,galera56
xtradb51 | xtradb,mariadb51 build against Percona Server with XtraDB 5.1
| mariadb52,mariadb53
xtradb55 | galera55,mariadb55 build against Percona Server with XtraDB 5.5

根据上面提示和你使用的存储引擎及版本,选择相应的参数即可。因为我用的是MySQL 5.5版本,所以执行如下语句安装:

[root@master percona-xtrabackup-2.1.9]# ./utils/build.sh innodb55

以上语句执行成功后,表示安装完成。

最后,把生成的二进位文件拷贝到一个自定义目录下(本例中为/home/mysql/admin/bin/percona-xtrabackup-2.1.9),并把该目录放到环境变数PATH中。

mkdir -p /home/mysql/admin/bin/percona-xtrabackup-2.1.9/cp ./innobackupex /home/mysql/admin/bin/percona-xtrabackup-2.1.9/
mv /usr/local/src/percona-xtrabackup-2.1.9/src/xtrabackup_innodb55 xtrabackup_55
cp /usr/local/src/percona-xtrabackup-2.1.9/src/xtrabackup_55 /usr/local/src/percona-xtrabackup-2.1.9/src/xbstream /home/mysql/admin/bin/percona-xtrabackup-2.1.9/

vim /etc/profile

export PATH=$PATH:/home/mysql/admin/bin/percona-xtrabackup-2.1.9/

刷新profile并测试下innobackupex是否正常使用

source /etc/profile

测试下innobackupex是否正常使用

innobackupex --help

2.3 全量备份和恢复

2.3.1 全量备份操作

执行下面语句进行全备: mysql的安装目录是/application/mysql/ mysql的配置文件路径/etc/my.cnf 全量备份后的数据存放目录是/backup/mysql/data

mkdir -p /backup/mysql/data/innobackupex --defaults-file=/etc/my.cnf --user=root /backup/mysql/data/
170404 12:46:29 innobackupex: Waiting for log copying to finish

xtrabackup: The latest check point (for incremental): 1639325xtrabackup: Stopping log copying thread.
.>> log scanned up to (1639325)

xtrabackup: Creating suspend file /backup/mysql/data/2017-04-04_12-46-24/xtrabackup_log_copied with pid 21223xtrabackup: Transaction log of lsn (1639325) to (1639325) was copied.170404 12:46:30 innobackupex: All tables unlocked

innobackupex: Backup created in directory /backup/mysql/data/2017-04-04_12-46-24innobackupex: MySQL binlog position: filename mysql-bin.000019, position 967170404 12:46:30 innobackupex: Connection to database server closed170404 12:46:30 innobackupex: completed OK!

出现上面的信息,表示备份已经ok。

上面执行的备份语句会将mysql数据文件(即由my.cnf里的变数datadir指定)拷贝至备份目录下(/backup/mysql/data)

注意:如果不指定--defaults-file,默认值为/etc/my.cnf。 备份成功后,将在备份目录下创建一个时间戳目录(本例创建的目录为/backup/mysql/data/2017-04-04_12-46-24),在该目录下存放备份文件。

[root@master data]# ll /backup/mysql/data/总用量 4
drwxr-xr-x 6 root root 4096 4月 4 16:56 2017-04-04_16-56-35
[root@master data]# ll 2017-04-04_16-56-35/总用量 18468
-rw-r--r-- 1 root root 188 4月 4 16:56 backup-my.cnf
-rw-r----- 1 root root 18874368 4月 4 16:56 ibdata1
drwxr-xr-x 2 root root 4096 4月 4 16:56 mysql
drwxr-xr-x 2 root root 4096 4月 4 16:56 performance_schema
drwxr-xr-x 2 root root 4096 4月 4 16:56 test
-rw-r--r-- 1 root root 13 4月 4 16:56 xtrabackup_binary
-rw-r--r-- 1 root root 23 4月 4 16:56 xtrabackup_binlog_info
-rw-r----- 1 root root 89 4月 4 16:56 xtrabackup_checkpoints
-rw-r----- 1 root root 2560 4月 4 16:56 xtrabackup_logfile
drwxr-xr-x 2 root root 4096 4月 4 16:56 xtra_test

还可以在远程进行全量备份,命令如下:

innobackupex --defaults-file=/etc/my.cnf --user=root --host=127.0.0.1 --parallel=2 --throttle=200 /backup/mysql/data 2>/backup/mysql/data/bak.log 1>/backup/mysql/data/`data +%Y-%m-%d_%H-%M%S`.bak.log

参数解释:

--user=root 备份操作用户名,一般都是root用户 --host=127.0.0.1 主机ip,本地可以不加(适用于远程备份)。注意要提前在mysql中授予连接的许可权,最好备份前先测试用命令中的用户名、密码和host能否正常连接mysql。--parallel=2 --throttle=200 并行个数,根据主机配置选择合适的,默认是1个,多个可以加快备份速度。/backup/mysql/data 备份存放的目录2>/backup/mysql/data/bak.log 备份日志,将备份过程中的输出信息重定向到bak.log这种备份跟上面相比,备份成功后,不会自动在备份目录下创建一个时间戳目录,需要如上命令中自己定义。
[root@master src]# ll /backup/mysql/data/总用量 8
drwxr-xr-x 6 root root 4096 4月 4 12:46 2017-04-04_12-46-24
-rw-r--r-- 1 root root 106 4月 4 12:57 bak.log //备份信息都记录在这个日志里,如果备份失败,可以到这里日志里查询

2.3.2 全量备份后的恢复操作

[root@master data]# mysqlmysql> show databases;
+--------------------+| Database |
+--------------------+| information_schema |
| mysql |
| performance_schema |
| test || xtra_test |
+--------------------+5 rows in set (0.09 sec)

mysql> use xtra_test;
Database changed
mysql> show tables;
+---------------------+
| Tables_in_xtra_test |+---------------------+| I || M |
+---------------------+2 rows in set (0.04 sec)

mysql> drop database xtra_test;
Query OK, 2 rows affected (0.34 sec)mysql> show databases;
+--------------------+| Database |
+--------------------+| information_schema |
| mysql |
| performance_schema || test |
+--------------------+4 rows in set (0.00 sec)

注意:恢复之前

1)要先关闭资料库

2)要删除数据文件和日志文件(也可以mv移到别的地方,只要确保清空mysql数据存放目录就行)

[root@master data]# ps -ef|grep mysqld
root 10929 1 0 10:32 pts/0 00:00:00 /bin/sh /application/mysql/bin/mysqld_safe --datadir=/application/mysql/data --pid-file=/application/mysql/data/master.pid
mysql 11227 10929 0 10:32 pts/0 00:00:14 /application/mysql/bin/mysqld --basedir=/application/mysql --datadir=/application/mysql/data --plugin-dir=/application/mysql/lib/plugin --user=mysql --log-error=/application/mysql/data/master.err --pid-file=/application/mysql/data/master.pid --port=3306
root 21514 1896 0 13:55 pts/0 00:00:00 grep mysqld

由上面可以看出mysql的数据和日志存放目录是/application/mysql/data

[root@master data]# service mysqld stopShutting down MySQL.... SUCCESS!

[root@master data]# mv /application/mysql/data/* /tmp/[root@master data]# ls /application/mysql/data/[root@master data]#

恢复数据

[root@master data]# innobackupex --defaults-file=/etc/my.cnf --user=root --use-memory=1G --apply-log /backup/mysql/data/2017-04-04_13-04-05/[root@master data]# innobackupex --defaults-file=/etc/my.cnf --user=root --copy-back /backup/mysql/data/2017-04-04_13-04-05/[root@master ~]# chown -R mysql.mysql /application/mysql/data/

可能报错:

sh: xtrabackup: command not foundinnobackupex: Error: no mysqld group in MySQL options at /home/mysql/admin/bin/percona-xtrabackup-2.1.9/innobackupex line 4350.

解决:将xtrabackup_55复制成xtrabackup即可

[root@master src]# ls /home/mysql/admin/bin/percona-xtrabackup-2.1.9/innobackupex xbstream xtrabackup_55 xtrabackup_innodb55

[root@master src]# cd /home/mysql/admin/bin/percona-xtrabackup-2.1.9/[root@master percona-xtrabackup-2.1.9]# cp xtrabackup_55 xtrabackup[root@master percona-xtrabackup-2.1.9]# lsinnobackupex xbstream xtrabackup xtrabackup_55 xtrabackup_innodb55

检验:执行之后就OK了

[root@master percona-xtrabackup-2.1.9]# innobackupex --defaults-file=/etc/my.cnf --user=root --copy-back /backup/mysql/data/2017-04-04_13-04-05/

innobackupex: Copying /backup/mysql/data/2017-04-04_13-04-05/ib_logfile1 to /application/mysql/data/ib_logfile1
innobackupex: Copying /backup/mysql/data/2017-04-04_13-04-05/ib_logfile0 to /application/mysql/data/ib_logfile0
innobackupex: Finished copying back files.

170404 14:24:07 innobackupex: completed OK!

出现上面的信息,说明数据恢复成功了!!

从上面的恢复操作可以看出,执行恢复分为两个步骤:

1)第一步恢复步骤是应用日志(apply-log),为了加快速度,一般建议设置--use-memory(如果系统内存充足,可以使用加大内存进行备份 ),这个步骤完成之后,目录/backup/mysql/data/2017-04-04_13-04-05/下的备份文件已经准备就绪。

2)第二步恢复步骤是拷贝文件(copy-back),即把备份文件拷贝至原数据目录下。

最后,启动mysql,查看数据是否恢复回来了

[root@master ~]# /etc/init.d/mysqld start
Starting MySQL.. SUCCESS!

[root@master ~]# mysqlmysql> show databases;
+--------------------+| Database |
+--------------------+| information_schema |
| mysql |
| performance_schema |
| test || xtra_test |
+--------------------+5 rows in set (0.00 sec)

mysql> use xtra_test;
Database changed
mysql> show tables;
+---------------------+
| Tables_in_xtra_test |+---------------------+| I || M |
+---------------------+2 rows in set (0.00 sec)

2.4 增量备份和恢复

特别注意:

innobackupex 增量备份仅针对InnoDB这类支持事务的引擎,对于MyISAM等引擎,则仍然是全备。

2.4.1 增量备份操作

增量备份需要基于全量备份

先假设我们已经有了一个全量备份(如上面的/backup/mysql/data/2017-04-04_16-56-35),我们需要在该全量备份的基础上做第一次增量备份。

[root@master ~]# innobackupex --defaults-file=/etc/my.cnf --user=root --incremental-basedir=/backup/mysql/data/2017-04-04_16-56-35/ --incremental /backup/mysql/data

其中:

--incremental-basedir 指向全量备份目录 --incremental 指向增量备份的目录

上面语句执行成功之后,会在--incremental执行的目录下创建一个时间戳子目录(本例中为:/backup/mysql/data/2017-04-04_14-37-24),在该目录下存放著增量备份的所有文件。

[root@master data]# ll总用量 8
drwxr-xr-x 6 root root 4096 4月 4 16:56 2017-04-04_16-56-35 //全量备份目录drwxr-xr-x 6 root root 4096 4月 4 16:59 2017-04-04_16-58-58 //增量备份目录

在备份目录下,有一个文件xtrabackup_checkpoints记录著备份信息,其中可以查出

1)全量备份的信息如下:

[root@master data]# cd /backup/mysql/data/2017-04-04_16-56-35/[root@master 2017-04-04_16-56-35]# cat xtrabackup_checkpoints backup_type = full-backupedfrom_lsn = 0to_lsn = 1639436last_lsn = 1639436compact = 0

2)基于以上全量备份的增量备份的信息如下:

[root@master data]# cd /backup/mysql/data/2017-04-04_16-58-58/[root@master 2017-04-04_16-58-58]# cat xtrabackup_checkpoints backup_type = incrementalfrom_lsn = 1639436to_lsn = 1639436last_lsn = 1639436compact = 0

从上面可以看出,增量备份的from_lsn正好等于全备的to_lsn。

那么,我们是否可以在增量备份的基础上再做增量备份呢?

答案是肯定的,只要把--incremental-basedir执行上一次增量备份的目录即可,如下所示:

[root@master data]# innobackupex --defaults-file=/etc/my.cnf --user=root --incremental-basedir=/backup/mysql/data/2017-04-04_16-58-58/ --incremental /backup/mysql/data

[root@master ~]# ll /backup/mysql/data/总用量 12
drwxr-xr-x 6 root root 4096 4月 4 16:56 2017-04-04_16-56-35 //全量备份目录drwxr-xr-x 6 root root 4096 4月 4 16:59 2017-04-04_16-58-58 //增量备份目录1
drwxr-xr-x 6 root root 4096 4月 4 17:02 2017-04-04_17-02-35 //增量备份目录2

它的trabackup_checkpoints记录著备份信息如下:

[root@master ~]# cd /backup/mysql/data/2017-04-04_17-02-35/[root@master 2017-04-04_17-02-35]# cat xtrabackup_checkpoints backup_type = incrementalfrom_lsn = 1639436to_lsn = 1639436last_lsn = 1639436compact = 0

可以看到,第二次增量备份的from_lsn是从上一次增量备份的to_lsn开始的

2.4.2 增量备份后的恢复操作

增量备份的恢复要比全量备份复杂很多,增量备份与全量备份有著一些不同,尤其要注意的是:

1)需要在每个备份(包括完全和各个增量备份)上,将已经提交的事务进行「重放」。「重放」之后,所有的备份数据将合并到完全备份上。

2)基于所有的备份将未提交的事务进行「回滚」。于是,操作就变成了:不能回滚,因为有可能第一次备份时候没提交,在增量中已经成功提交

第一步是在所有备份目录下重做已提交的日志(注意备份目录路径要跟全路径)

其中:

一定要全路径

BASE-DIR 是指全量备份的目录

INCREMENTAL-DIR-1 是指第一次增量备份的目录

INCREMENTAL-DIR-2 是指第二次增量备份的目录,以此类推。

这里要注意的是:

1)最后一步的增量备份并没有--redo-only选项!回滚进行崩溃恢复过程

2)可以使用--use_memory提高性能。

以上语句执行成功之后,最终数据在BASE-DIR(即全量目录)下,其实增量备份就是把增量目录下的数据,整合到全变数目录下,然后在进行,全数据量的还原。

第一步完成之后,我们开始下面关键的第二步,即拷贝文件,进行全部还原!注意:必须先停止mysql资料库,然后清空资料库目录(这里是指/data/mysql/data)下的文件。

4)innobackupex --copy-back BASE-DIR

同样地,拷贝结束之后,记得检查下数据目录(这里指/data/mysql/data)的许可权是否正确(修改成mysql:mysql),然后再重启mysql。

接下来进行案例说明:

假设我们已经有了一个全量备份2017-04-04_16-56-35 删除在上面测试创建的两个增量备份

[root@master ~]# cd /backup/mysql/data/

[root@master data]# ll
drwxr-xr-x 6 root root 4096 4月 4 17:08 2017-04-04_16-56-35drwxr-xr-x 6 root root 4096 4月 4 17:08 2017-04-04_16-58-58drwxr-xr-x 6 root root 4096 4月 4 17:08 2017-04-04_17-02-35[root@master data]# rm -fr 2017-04-04_16-58-58 2017-04-04_17-02-35[root@master data]# ll
drwxr-xr-x 6 root root 4096 4月 4 17:08 2017-04-04_16-56-35

假设在全量备份后,mysql资料库中又有新数据写入

[root@master data]# mysql

mysql> create database ceshi;
Query OK, 1 row affected (0.00 sec)

mysql> use ceshi
Database changed
mysql> create table test1( -> id int3, -> name varchar(20) -> );Query OK, 0 rows affected (0.26 sec)

mysql> insert into test1 values(1,"chenbaojia");
Query OK, 1 row affected (0.05 sec)mysql> select * from test1;
+------+------------+| id | name |
+------+------------+| 1 | chenbaojia |
+------+------------+1 row in set (0.00 sec)mysql> show databases;
+--------------------+| Database |
+--------------------+| information_schema |
| ceshi |
| mysql |
| performance_schema || test |
+--------------------+5 rows in set (0.00 sec)

然后进行一次增量备份:

[root@master data]# innobackupex --defaults-file=/etc/my.cnf --user=root --incremental-basedir=/backup/mysql/data/2017-04-04_16-56-35/ --incremental /backup/mysql/data/

[root@master data]# ll总用量 8
drwxr-xr-x 6 root root 4096 4月 4 17:08 2017-04-04_16-56-35 //全量备份目录drwxr-xr-x 6 root root 4096 4月 4 17:28 2017-04-04_17-28-14 //增量备份目录

接著再在mysql资料库中写入新数据

[root@master data]# mysql

mysql> use ceshi;
Database changed

mysql> insert into test1 values(2,"pelosi");
Query OK, 1 row affected (0.11 sec)

mysql> insert into test1 values(3,"hiofo");
Query OK, 1 row affected (0.06 sec)

mysql> insert into test1 values(4,"mac");
Query OK, 1 row affected (0.09 sec)mysql> select * from test1;
+------+------------+| id | name |
+------+------------+| 1 | chenbaojia |
| 2 | pelosi |
| 3 | hiofo || 4 | mac |
+------+------------+4 rows in set (0.00 sec)

接著在增量的基础上再进行一次增量备份

--incremental-basedi 要写上次最后增量备份的目录

[root@master ~]# innobackupex --defaults-file=/etc/my.cnf --user=root --incremental-basedir=/backup/mysql/data/2017-04-04_17-28-14/ --incremental /backup/mysql/data

[root@master ~]# ll /backup/mysql/data/总用量 12
drwxr-xr-x 6 root root 4096 4月 4 17:08 2017-04-04_16-56-35 //全量备份目录drwxr-xr-x 6 root root 4096 4月 4 17:28 2017-04-04_17-28-14 //全量备份目录drwxr-xr-x 6 root root 4096 4月 4 17:38 2017-04-04_17-37-58 //全量备份目录

现在删除资料库ceshi 、 test

[root@master ~]# mysqlmysql> show databases;
+--------------------+| Database |
+--------------------+| information_schema |
| ceshi |
| mysql |
| performance_schema || test |
+--------------------+5 rows in set (0.00 sec)

mysql> drop database ceshi;
Query OK, 1 row affected (0.07 sec)

mysql> drop database test;
Query OK, 0 rows affected (0.00 sec)mysql> show databases;
+--------------------+| Database |
+--------------------+| information_schema |
| mysql |
| performance_schema |+--------------------+3 rows in set (0.00 sec)

接下来就开始进行数据恢复操作:

先恢复应用日志(注意最后一个不需要加--redo-only参数)

[root@master ~]# innobackupex --defaults-file=/etc/my.cnf --user=root --apply-log --redo-only /backup/mysql/data/2017-04-04_16-56-35/

[root@master ~]# innobackupex --defaults-file=/etc/my.cnf --user=root --apply-log --redo-only /backup/mysql/data/2017-04-04_16-56-35/ --incremental-dir=/backup/mysql/data/2017-04-04_17-28-14/

[root@master ~]# innobackupex --defaults-file=/etc/my.cnf --user=root --apply-log /backup/mysql/data/2017-04-04_16-56-35/ --incremental-dir=/backup/mysql/data/2017-04-04_17-37-58/

到此,恢复数据工作还没有结束!还有最重要的一个环节,就是把增量目录下的数据整合到全量备份目录下,然后再进行一次全量还原。

停止mysql资料库,并清空数据目录

[root@master ~]# /etc/init.d/mysqld stopShutting down MySQL. SUCCESS!
[root@master ~]# rm -fr /application/mysql/data/*

最后拷贝文件,并验证数据目录的许可权

[root@master ~]# innobackupex --defaults-file=/etc/my.cnf --user=root --copy-back /backup/mysql/data/2017-04-04_16-56-35/

[root@master ~]# chown -R mysql.mysql /application/mysql/data/*

[root@master ~]# /etc/init.d/mysqld startStarting MySQL.. SUCCESS!

[root@master ~]# mysqlmysql> show databases;
+--------------------+| Database |
+--------------------+| information_schema |
| ceshi |
| mysql |
| performance_schema |
| test || xtra_test |
+--------------------+6 rows in set (0.00 sec)mysql> select * from ceshi.test1;
+------+------------+| id | name |
+------+------------+| 1 | chenbaojia |
| 2 | pelosi |
| 3 | hiofo || 4 | mac |
+------+------------+4 rows in set (0.00 sec)

另外注意: 上面在做备份的时候,将备份目录和增量目录都放在了同一个目录路径下,其实推荐放在不同的路径下,方便管理!比如:

/backup/mysql/data/full 存放全量备份目录

/backup/mysql/data/daily1 存放第一次增量备份目录

/backup/mysql/data/daily2 存放第二次增量目录

以此类推

在恢复的时候,注意命令中的路径要跟对!

系列文章

【4-1】CentOS 6 MySQL 大数据备份方案之Percona XtraBackup 2.1

【4-2】CentOS 6 MySQL 大数据备份方案之Percona XtraBackup 2.1

【4-3】CentOS 6 MySQL 大数据备份方案之Percona XtraBackup 2.1

【4-4】CentOS 6 MySQL 大数据备份方案之Percona XtraBackup 2.1 完结

更多精彩内容,请滑至顶部点击右上角关注小宅哦~


来源:华为云社区原创 作者:陈宝佳


推荐阅读:
相关文章