xtrabackup备份工具使用详解


innobackupex全局备份,恢复


mysqld的数据储存路径

[root@nb0001 mydata]# grep datadir /etc/my.cnf
datadir= /mydata/data

备份
innobackupex --user=root -password=asset /home/20160222.mysql_page.back/

恢复
rm -rf /mydata/data/*
innobackupex --apply-log /home/20160222.mysql_page.back/2016-02-22_13-09-40/
innobackupex --copy-back /home/20160222.mysql_page.back/2016-02-22_13-09-40/
chown -R mysql:mysql /mydata/data/

启动
service mysqld restart





innobackupex: 需要MySQL服务处于运行状态


【percona】下载

wget https://www.percona.com/downloads/XtraBackup/XtraBackup-2.1.8/RPM/rhel6/x86_64/percona-xtrabackup-2.1.8-733.rhel6.x86_64.rpm
wget https://www.percona.com/downloads/percona-toolkit/2.2.4/RPM/percona-toolkit-2.2.4-1.noarch.rpm

【安装】

 [root@pc0003 Percona]# yum install ./*.rpm

【如果要使用一个最小权限的用户进行备份,则可基于如下命令创建此类用户】:

mysql> CREATE USER 'haha'@'localhost' IDENTIFIED BY 's3cret';
mysql> GRANT RELOAD, LOCK TABLES, REPLICATION CLIENT ON*.*TO'bkpuser'@'localhost';
mysql> FLUSH PRIVILEGES;

 

 

使用innobakupex备份时,其会调用xtrabackup备份所有的InnoDB表,复制所有关于表结构定义的相关文件(.frm)、以及MyISAM、MERGE、CSV和ARCHIVE表的相关文件,同时还会备份触发器和数据库配置信息相关的文件。这些文件会被保存至一个以时间命令的目录中。


在备份的同时,innobackupex还会在备份目录中创建如下文件:

(1)xtrabackup_checkpoints —— 备份类型(如完全或增量)、备份状态(如是否已经为prepared状态)和LSN(日志序列号)范围信息;


每个InnoDB页(通常为16k大小)都会包含一个日志序列号,即LSN。LSN是整个数据库系统的系统版本号,每个页面相关的LSN能够表明此页面最近是如何发生改变的。


(2)xtrabackup_binlog_info —— mysql服务器当前正在使用的二进制日志文件及至备份这一刻为止二进制日志事件的位置。


(3)xtrabackup_binlog_pos_innodb —— 二进制日志文件及用于InnoDB或XtraDB表的二进制日志文件的当前position。


(4)xtrabackup_binary —— 备份中用到的xtrabackup的可执行文件;


(5)backup-my.cnf —— 备份命令用到的配置选项信息;


在使用innobackupex进行备份时,还可以使用--no-timestamp选项来阻止命令自动创建一个以时间命名的目录;如此一来,innobackupex命令将会创建一个BACKUP-DIR目录来存储备份数据。




备份前的准备:
修改配置文件,创建备份文件的路径,备份演示,查看备份信息

[root@pc0003 Percona]# cp /etc/my.cnf /etc/my.cnf.0915.1701
[root@nb0001 home]# vim /etc/my.cnf
把log-bin=改为新的binlogs
log-bin=/mydata/binlogs/master-bin
[root@pc0003 Percona]# service mysqld stop
[root@pc0003 Percona]# chown -R mysql:mysql /mydata/binlogs/
[root@pc0003 Percona]# service mysqld start
mysql> show binary logs;
+-------------------+-----------+
| Log_name          | File_size |
+-------------------+-----------+
| master-bin.000001 |       107 |
+-------------------+-----------+
创建备份的为文件路径 /mybackups
[root@pc0003 data]# mkdir /mybackups
【开始完全备份。。。。。。。。】
[root@pc0003 data]# innobackupex --user=root -password=lcl /mybackups/
提示 : 150915 17:09:08  innobackupex: completed OK! 备份完成
会生成一个时间日期的文件夹
[root@pc0003 mybackups]# cd /mybackups/2015-09-15_17-09-04/
【mysqld的配置信息 备份】
[root@pc0003 2015-09-15_17-09-04]# cat backup-my.cnf 
# This MySQL options file was generated by innobackupex.
# The MySQL server
[mysqld]
innodb_data_file_path=ibdata1:10M:autoextend
innodb_log_files_in_group=2
innodb_log_file_size=5242880
innodb_fast_checksum=0
innodb_page_size=16384
innodb_log_block_size=512
【mysql的版本】
[root@pc0003 2015-09-15_17-09-04]# cat xtrabackup_binary
【所备份的文件在哪个日志哪个位置上】
[root@pc0003 2015-09-15_17-09-04]# cat xtrabackup_binlog_info 
master-bin.000001107
xtrabackup_binlog_info  xtrabackup_logfile      
[root@pc0003 2015-09-15_17-09-04]# cat xtrabackup_checkpoints 
backup_type = full-backuped
from_lsn = 0
to_lsn = 1727800
last_lsn = 1727800
compact = 0





=======   备份方式二 易用   ====================
【临时关闭日志,新增的hellodb数据库不写入日志】
mysql> set sql_log_bin=0;
【删除其他数据库,导入hellodb数据库,与教程保持一致,mysql】
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| test               |
+--------------------+
mysql> source /home/hellodb.sql
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| hellodb            |
| mysql              |
| performance_schema |
| test               |
+--------------------+
mysql> set sql_log_bin=1;
mysql> use hellodb;
Database changed
mysql> 
mysql> create table t1(Name char(20));
Query OK, 0 rows affected (0.24 sec)
#############################################################################
 【开始备份】 
[root@pc0003 home]# innobackupex --user=root -password=lcl /mybackups/
如果是MyISAM的引擎,仅仅是把原来的数据库文件复制出来
**********************************************************
【每个innodb都使用独立的数据存放文件】
[root@pc0003 mybackups]# vim /etc/my.cnf
thread_concurrency = 4
datadir= /mydata/data
innodb_file_per_table = ON
[root@pc0003 mybackups]# service mysqld restart
修改ENGINE=MyISAM为ENGINE=InnoDB
[root@pc0003 home]# vim hellodb.sql
:%s/ENGINE=MyISAM/ENGINE=InnoDB/g
mysql> set sql_log_bin=0;
mysql> drop database hellodb;
mysql> source /home/hellodb.sql
mysql> set sql_log_bin=1;
mysql> show table status from hellodb \G
Name: classes
Engine: InnoDB
Name: coc
Engine: InnoDB
Name: courses
Engine: InnoDB
Name: scores
Engine: InnoDB
Name: students
Engine: InnoDB
Name: teachers
Engine: InnoDB
Name: toc
Engine: InnoDB
 
[root@pc0003 mybackups]# rm -rf /mybackups/2015-09-22_09-17-11/
[root@pc0003 mybackups]# innobackupex --user=root -password=lcl /mybackups/
###################################################
模拟恢复 【不需要mysql 处于启动状态】
先停掉mysql,删除所有库文件
[root@pc0003 mybackups]# service mysqld stop
[root@pc0003 mybackups]# ls -1 /mydata/data/
hellodb
ibdata1
ib_logfile0
ib_logfile1
mysql
pc0003.err
pc0003.log
pc0003-slow.log
performance_schema
test
删除所有,模拟故障,此时mysql不能启动
[root@pc0003 mybackups]# rm -rf /mydata/data/*
整理准备【注意,备份时不要整理,还原的时候才需要整理】
[root@pc0003 mybackups]# innobackupex --apply-log /mybackups/2015-09-22_09-30-04/
150922 09:47:15  innobackupex: completed OK
【恢复】
[root@pc0003 mybackups]# innobackupex --copy-back /mybackups/2015-09-22_09-30-04/
[root@pc0003 mybackups]# chown -R mysql:mysql /mydata/data/
[root@pc0003 mybackups]# service mysqld start
Starting MySQL... SUCCESS! 
【效果】
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| hellodb            |
| mysql              |
| performance_schema |
| test               |
+--------------------+
5 rows in set (0.00 sec)
mysql> use hellodb;
Database changed
mysql> show tables;
+-------------------+
| Tables_in_hellodb |
+-------------------+
| classes           |
| coc               |
| courses           |
| scores            |
| students          |
| teachers          |
| toc               |
+-------------------+
7 rows in set (0.00 sec)

数据恢复完成!
#########   增量备份    #########################################################
【已经恢复好了,再备份一次】 作为下面增量的基本库
[root@pc0003 mybackups]# innobackupex --user=root -password=lcl /mybackups/
150922 10:04:10  innobackupex: completed OK!
[root@pc0003 ~]# ls /mybackups/ -1
2015-09-22_10-04-07
【发生点改变】增量1
mysql> create table t1 (id int);
mysql> insert into t1 values (1),(2);
Query OK, 2 rows affected (0.06 sec)
【相对上次增量备份1】,注意后面的--incremental-basedir
[root@pc0003 ~]# innobackupex --user=root -password=lcl --incremental  /mybackups/ --incremental-basedir=/mybackups/2015-09-22_10-04-07/
[root@pc0003 ~]# ls /mybackups/ -1
2015-09-22_10-04-07
2015-09-22_10-17-37
【再来点改变】增量2
[root@pc0003 ~]# mysql -p
 mysql> use hellodb;
Database changed
mysql> create table test1 (Name char(10));
Query OK, 0 rows affected (0.08 sec)
【相对上次增量备份2】注意后面的--incremental-basedir
[root@pc0003 ~]# innobackupex --user=root -password=lcl --incremental  /mybackups/ --incremental-basedir=/mybackups/2015-09-22_10-17-37/
[root@pc0003 ~]# ls /mybackups/ -1
2015-09-22_10-04-07
2015-09-22_10-17-37
2015-09-22_10-22-42
[root@pc0003 ~]# cat /mybackups/2015-09-22_10-22-42/xtrabackup_checkpoints 
backup_type = incremental
from_lsn = 1761306
to_lsn = 1763036
last_lsn = 1763036
compact = 0
【本次备份截至到490,下次意外故障,可以基于二进制文件,从490之后恢复】
[root@pc0003 ~]# cat /mybackups/2015-09-22_10-22-42/xtrabackup_binlog_info 
master-bin.000007490

增量备份完成


#######   增量备份的数据恢复  ##################################
【模拟故障】
1,会有新的数据
[root@pc0003 ~]# mysql -p
mysql> use hellodb;
mysql> insert into t1 values (3),(4);
mysql> \q
[root@pc0003 ~]# service mysqld stop
删除所有数据库文件,二进制日志文件不在这里面
[root@pc0003 ~]# rm -rf /mydata/data/*
####### 增量备份须知 ##########
4、使用innobackupex进行增量备份
每个InnoDB的页面都会包含一个LSN信息,每当相关的数据发生改变,相关的页面的LSN就会自动增长。这正是InnoDB表可以进行增量备份的基础,即innobackupex通过备份上次完全备份之后发生改变的页面来实现。
要实现第一次增量备份,可以使用下面的命令进行:
# innobackupex --incremental /backup --incremental-basedir=BASEDIR
其中,BASEDIR指的是完全备份所在的目录,此命令执行结束后,innobackupex命令会在/backup目录中创建一个新的以时间命名的目录以存放所有的增量备份数据。另外,在执行过增量备份之后再一次进行增量备份时,其--incremental-basedir应该指向上一次的增量备份所在的目录。
需要注意的是,增量备份仅能应用于InnoDB或XtraDB表,对于MyISAM表而言,执行增量备份时其实进行的是完全备份。
“准备”(prepare)增量备份与整理完全备份有着一些不同,尤其要注意的是:
(1)需要在每个备份(包括完全和各个增量备份)上,将已经提交的事务进行“重放”。“重放”之后,所有的备份数据将合并到完全备份上。
(2)基于所有的备份将未提交的事务进行“回滚”。
于是,操作就变成了:
# innobackupex --apply-log --redo-only BASE-DIR
接着执行:
# innobackupex --apply-log --redo-only BASE-DIR --incremental-dir=INCREMENTAL-DIR-1
而后是第二个增量:
# innobackupex --apply-log --redo-only BASE-DIR --incremental-dir=INCREMENTAL-DIR-2
################################
[root@pc0003 ~]# ls /mybackups/ -1
2015-09-22_10-04-07
2015-09-22_10-17-37
2015-09-22_10-22-42
【基于基本库,做准备,开始整理】
[root@pc0003 ~]# innobackupex --apply-log --redo-only /mybackups/2015-09-22_10-04-07/ 
合并第一次的增量,不会新的文件夹数据,而是合并到基本库里面来
[root@pc0003 ~]# innobackupex --apply-log --redo-only /mybackups/2015-09-22_10-04-07/ --incremental-dir=/mybackups/2015-09-22_10-17-37/
150922 11:02:40  innobackupex: completed OK!
合并第一次的增量,不会新的文件夹数据,而是合并到基本库里面来
[root@pc0003 ~]# innobackupex --apply-log --redo-only /mybackups/2015-09-22_10-04-07/ --incremental-dir=/mybackups/2015-09-22_10-22-42/
150922 11:04:21  innobackupex: completed OK!
【查看一下】
[root@pc0003 ~]# cat /mybackups/2015-09-22_10-04-07/xtrabackup_checkpoints 
backup_type = full-prepared
from_lsn = 0
to_lsn = 1763036
last_lsn = 1763036
compact = 0
[root@pc0003 ~]# cat /mybackups/2015-09-22_10-17-37/xtrabackup_checkpoints 
backup_type = incremental
from_lsn = 1759244
to_lsn = 1761306
last_lsn = 1761306
compact = 0
[root@pc0003 ~]# cat /mybackups/2015-09-22_10-22-42/xtrabackup_checkpoints 
backup_type = incremental
from_lsn = 1761306
to_lsn = 1763036
last_lsn = 1763036
compact = 0
很明显,后面的两次增量备份,已经合并OK!现在基本库/mybackups/2015-09-22_10-04-07/可以作为数据恢复来用。
【恢复数据】 
[root@pc0003 ~]# ll /mydata/data/
[root@pc0003 ~]# innobackupex --copy-back /mybackups/2015-09-22_10-04-07/
150922 11:14:31  innobackupex: completed OK!
[root@pc0003 mybackups]# chown -R mysql:mysql /mydata/data/
[root@pc0003 mybackups]# service mysqld start
Starting MySQL... SUCCESS! 
[root@pc0003 ~]# ls /mydata/data/ -1
hellodb
ibdata1
mysql
performance_schema
test
增量数据已经恢复
【再来做二进制时间点的恢复,查看最后一次的增量备份数据】
[root@pc0003 ~]# cat /mybackups/2015-09-22_10-22-42/xtrabackup_binlog_info 
master-bin.000007490
[root@pc0003 ~]# mysqlbinlog --start-position=490 /mydata/binlogs/master-bin.000007 > /home/master-bin.000007-490.sql
mysql> set session sql_log_bin=0;
mysql> source /home/master-bin.000007-490.sql
mysql> set session sql_log_bin=1;
【效果,显示第一次的增量操作】
mysql> select * from t1;
+------+
| id   |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
+------+
【效果,显示第二次的增量操作】
mysql> show tables;
+-------------------+
| Tables_in_hellodb |
+-------------------+
| classes           |
| coc               |
| courses           |
| scores            |
| students          |
| t1                |
| teachers          |
| test1             |
| toc               |
+-------------------+
9 rows in set (0.00 sec)
mysql> select * from test1;
Empty set (0.00 sec)
基于二进制恢复,完成!


###############################################################



注意

1、将数据和备份放在不同的磁盘设备上;异机或异地备份存储较为理想;

2、备份的数据应该周期性地进行还原测试;

3、每次灾难恢复后都应该立即做一次完全备份;

4、针对不同规模或级别的数据量,要定制好备份策略;

5、二进制日志应该跟数据文件在不同磁盘上,并周期性地备份好二进制日志文件;


从备份中恢复应该遵循步骤:

1、停止MySQL服务器;

2、记录服务器的配置和文件权限;

3、将数据从备份移到MySQL数据目录;其执行方式依赖于工具;

4、改变配置和文件权限;

5、以限制访问模式重启服务器;mysqld的--skip-networking选项可跳过网络功能;

方法:编辑my.cnf配置文件,添加如下项:

skip-networking

socket=/tmp/mysql-recovery.sock

6、载入逻辑备份(如果有);而后检查和重放二进制日志;

7、检查已经还原的数据;

8、重新以完全访问模式重启服务器;

注释前面在my.cnf中添加的选项,并重启;