Skip to main content

Xtrabackup

Xtrabackup

yum安装Xtrabackup

  1. 从percona官网查找可用yum源。
    https://www.percona.com/doc/percona-xtrabackup/2.2/installation/yum_repo.html
  1. 安装yum
yum install http://www.percona.com/downloads/percona-release/redhat/0.1-3/percona-release-0.1-3.noarch.rpm  
  1. 安装Xtrabackup和压缩支持
yum install -y percona-xtrabackup-24  
yum install -y qpress  
  1. 如果安装中出现缺少libev的问题,是因为epel源的问题。在rpmfind上找到对应版本下载安装即可
http://rpmfind.net/linux/rpm2html/search.php  
比如centos7查找
libev-4.15-3.el7.x86_64.rpm  
  1. 如果没有使用yum源从percona官方安装Xtrabackup,则qpress支持可以通过源码编译进行
wget http://www.quicklz.com/qpress-11-source.zip  
unzip qpress-11-source  
make  
cp qpress /usr/local/bin  

编译的过程中可能出现(mac必定出现):

qpress.cpp:1039:18: error: use of undeclared identifier 'isatty'  
    tty_stderr = isatty(fileno(stderr));
                 ^

此时在qpress.h或者qpress.cpp文件中引入unistd.h再次编译:

#include <unistd.h>

Xtrabackup常用参数

--defaults-file

mysql配置文件路径,需要放在第一个参数,优先于其他所有参数

--apply-log

生成一致性快照。如果不指定defaults-file参数,会从backup-my.cnf读取Innodb的相关配置

--redo-only

准备数据,合并事务,但是跳过回滚的事务(skip rollback)。

--copy-back

使用复制的方法恢复数据。

--move-back

使用移动的方法恢复数据(推荐)

--slave-info

备份的服务器是从服务器的时候使用。他会将主服务器信息写入备份记录并且记录change master命令。

--incremental

表示创建的是增量备份。需要制定--incremental-basedir命令告知基础备份的数据位置。

--incremental-basedir

增量备份基础备份位置。

--no-lock

关闭FLUSH TABLES WITH READ LOCK命令。不锁表。

--no-timestamp

不建立时间戳命名的子文件夹,直接备份。

--no-backup-locks

不进行FLUSH TABLES WITH READ LOCK操作。

--decompress

解压缩

--user=name

指定mysql用户名

--host=name

tcp模式下指定远程主机ip或者域名

--port=

tcp模式下指定远程主机端口

--password=name'

mysql密码

--socket=name

mysql的socket连接符文件

--databases=name

指定Xtrabackup需要备份的数据库或者表。
--databases=node_blog novaskii.test novaskii.hels

--compress

压缩备份文件

--compress-threads=

压缩备份线程数量

--parallel=

备份时候使用的线程数

--tables-file=name

要备份的表文件列表。

--tmpdir=name

备份过程中临时文件保存目录

--use-memory=

指定备份最大可用的内存。(e.g. 1MB, 1GB)

使用Xtrabackup进行全库备份

备份

innobackupex --defaults-file=配置文件 --no-timestamp --socket=Socket文件 备份目标目录 --parallel=备份线程数 --use-memory=使用内存 --user=用户名 --password='密码'  
innobackupex --defaults-file=my.cnf --no-timestamp --socket=my3306.sock /Users/fangyuan/mysql/3306_bak --parallel=2 --use-memory=512MB --user=root --password='password'  

恢复

在恢复之前,首先要停掉现有的mysql,并且做好备份工作。然后合并apply log,恢复文件。
备份完成的目录如下:

fangdeMac:3306_bak fangyuan$ ls -al  
total 204848  
drwxr-xr-x   15 fangyuan  staff        510  8 22 20:13 .  
drwxr-xr-x    5 fangyuan  staff        170  8 22 20:10 ..  
-rw-r-----    1 fangyuan  staff        434  8 22 20:13 backup-my.cnf
drwxr-x---   19 fangyuan  staff        646  8 22 20:12 cloak_server  
-rw-r-----    1 fangyuan  staff        678  8 22 20:13 ib_buffer_pool
-rw-r-----    1 fangyuan  staff  104857600  8 22 20:12 ibdata1
drwxr-x---   77 fangyuan  staff       2618  8 22 20:12 mysql  
drwxr-x---   90 fangyuan  staff       3060  8 22 20:13 performance_schema  
drwxr-x---    3 fangyuan  staff        102  8 22 20:13 student  
drwxr-x---   23 fangyuan  staff        782  8 22 20:13 student_db  
drwxr-x---  108 fangyuan  staff       3672  8 22 20:13 sys  
-rw-r-----    1 fangyuan  staff         61  8 22 20:13 xtrabackup_binlog_info
-rw-r-----    1 fangyuan  staff        113  8 22 20:13 xtrabackup_checkpoints
-rw-r-----    1 fangyuan  staff        631  8 22 20:13 xtrabackup_info
-rw-r-----    1 fangyuan  staff       2560  8 22 20:13 xtrabackup_logfile
fangdeMac:3306_bak fangyuan$  

首先要合并apply log:
注意检查备份出来的配置文件的完整性

innobackupex --defaults-file=备份出来的配置文件 --apply-log 备份文件目录  
innobackupex --defaults-file=backup-my.cnf --apply-log ./  

关闭要恢复的服务器:

mysqladmin --defaults-file=3306/my.cnf -S 3306/my3306.sock -u root -p  shutdown  

恢复数据:
恢复数据有两种方式,复制回去和移动回去,一般建议使用移动回去的方法减少磁盘读写并且速度会比较快,备份数据可以自己在其他时候去复制保存。
注意恢复文件的data目录必须为空

移动:
innobackupex --defaults-file=my.cnf --move-back /Users/fangyuan/mysql/3306_bak/  
复制:
innobackupex --defaults-file=my.cnf --move-back /Users/fangyuan/mysql/3306_bak/  

重建目录:

fangdeMac:3306 fangyuan$ ls ./../3306_or/  
binlog        data        errlog      genlog      my.cnf      relaylog    slowlog     tmp  
fangdeMac:3306 fangyuan$ ls  
data  
fangdeMac:3306 fangyuan$ mkdir binlog  
fangdeMac:3306 fangyuan$ mkdir errlog  
fangdeMac:3306 fangyuan$ mkdir genlog  
fangdeMac:3306 fangyuan$ mkdir relaylog  
fangdeMac:3306 fangyuan$ mkdir slowlog  
fangdeMac:3306 fangyuan$ mkdir tmp  

重新启动mysql:

mysqld --defaults-file=my.cnf &  

使用Xtrabackup进行增量备份

有些时候我们不能定期做完整的数据库备份,所以会采用全备份+增量备份互补的方法进行。

备份

在进行增量备份之前,需要完成一次全备份。全备份过程略。
我们将第一次全备份的文件备份到文件夹3306bakfull。


创建增量备份1:

innobackupex --defaults-file=my.cnf --socket=my3306.sock --no-timestamp --incremental /Users/fangyuan/mysql/3306_bak_incr01 --incremental-basedir=/Users/fangyuan/mysql/3306_bak_full --user=root --password='password'  

创建增量备份2:

innobackupex --defaults-file=my.cnf --socket=my3306.sock --no-timestamp --incremental /Users/fangyuan/mysql/3306_bak_incr02 --incremental-basedir=/Users/fangyuan/mysql/3306_bak_incr01 --user=root --password='password'  

恢复

同样的,先停掉服务器。
然后从q备份开始全,逐个进行apply-log,直到合并到需要恢复的增量备份为止。注意此时不要进行提交事务的回滚(redo only)

恢复全备份
innobackupex --apply-log --redo-only ./  
恢复增量备份1
innobackupex --apply-log --redo-only ./ --incremental-dir=./../3306_bak_incr01  
恢复增量备份2
innobackupex --apply-log --redo-only ./ --incremental-dir=./../3306_bak_incr02  
再次备份全备份,提交事务的回滚
innobackupex --defaults-file=my.cnf --apply-log ./  
创建目录
mkdir binlog  
mkdir errlog  
mkdir data  
mkdir genlog  
mkdir relaylog  
mkdir tmp  
mkdir slowlog  
恢复数据
innobackupex --defaults-file=my.cnf --move-back /Users/fangyuan/mysql/3306_bak_full/  
启动mysql

使用Xtrabackup压缩备份

Xtrabackup的compress参数压缩的数据需要使用decompress参数解压
decompress参数依赖于qpress这个工具

备份

备份就是使用了compress参数来实现压缩。而使用compress-threads来实现多线程压缩。

innobackupex --defaults-file=my.cnf --compress --compress-threads=2 --no-timestamp --socket=my3306.sock --user=root --password='password' --parallel=2 --use-memory=512MB ./../compress_bak/  

恢复

解压缩使用decompress参数,同样提供了decompress-threads进行多线程的解压。

解压缩文件
innobackupex --decompress --decompress-threads=2 ./  
生成一致性快照
innobackupex --defaults-file=./../3306/my.cnf --apply-log ./  
恢复数据库
mkdir binlog  
mkdir errlog  
mkdir data  
mkdir genlog  
mkdir relaylog  
mkdir tmp  
mkdir slowlog  
恢复数据
innobackupex --defaults-file=my.cnf --move-back /Users/fangyuan/mysql/compress_bak/  

Xtrabackup快速建立主从

利用Xtrabackup可以在需要的时候快速将数据库部署到其他服务器上建立主从关系或者将某个数据库单独分离出来放置在别的服务器上使用。
为了启用GTID同步,主库和从库配置中都必须包含以下内容:

gtid_mode=ON  
enforce-gtid-consistency  

如果是mysql5.6而非mysql5.7,还需要开启如下配置:

log-slave-updates  

Master Database:

检查主从复制模式:
show variables like '%gtid%'  
创建同步用户:
grant replication slave on *.* to repluser@'172.4.17.%' identified by 'password';  
刷新权限:
flush privileges;  

备份Mysql:

innobackupex --defaults-file=cnf/3306.cnf --socket=3306/my3306.sock --user=root --no-timestamp back/3306/  
压缩并传输到远程服务器:
tar zcvf master.tar.gz back  
scp master.tar.gz root@172.4.17.129:~  

Slave Server:
恢复Mysql:

innobackupex --defaults-file=/mysql/cnf/3306.cnf --apply-log ./3306  
innobackupex --defaults-file=/mysql/cnf/3306.cnf --move-back ./  
mysqld --defaults-file=/mysql/cnf/3306.cnf &  

进入Mysql执行主从关系:

设置主服务器
change master to master_host="172.4.17.144",master_port=3306,master_user='repluser',master_password='password',master_auto_position=1;  
跳过已经执行过的gtid(注意在使用之前gtid_executed必须为空,否则不能执行)
SET @@GLOBAL.GTID_PURGED='f8055cc6-69aa-11e6-83e7-00163e2c627f:1-3';  
启动从库
start slave;  
检查从库状态
show slave status\G;  

检查从库状态结果:

mysql> show slave status\G  
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 172.4.17.144
                  Master_User: repluser
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: 3306-mysql-bin.000003
          Read_Master_Log_Pos: 1768
               Relay_Log_File: 3306-relay-bin.000002
                Relay_Log_Pos: 1780
        Relay_Master_Log_File: 3306-mysql-bin.000003
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 1768
              Relay_Log_Space: 1983
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No  
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 71493306
                  Master_UUID: 599aace9-6920-11e6-805f-00163e405856
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 599aace9-6920-11e6-805f-00163e405856:1-3:5-8
            Executed_Gtid_Set: 599aace9-6920-11e6-805f-00163e405856:1-8,
f8055cc6-69aa-11e6-83e7-00163e2c627f:1-3  
                Auto_Position: 1
1 row in set (0.00 sec)  

此时已经搭建好了主从同步关系。

错误和解决

Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1, but the master has purged binary logs containing GTIDs that the slave requires.'

需要设置slave的gtidpurge属性,保证其知道master的gtidexecute值或开始同步的gtid数据

set global GTID_purged='927a597c-6cd2-11e6-b309-3274ad061969:1-3,fcf5cb46-6cce-11e6-a297-ccfa81956745:1-133:138';  
ERROR 1840 (HY000): GTID_PURGED can only be set when GTID_EXECUTED is empty.  

因为slave被启动过,已经从服务器同步了gtid_execute参数,所以此时不能使用purge参数设置,重置master即可

stop slave;  
reset master;  

线上机器损坏或者误操作的时候利用Xtrabackup和binlog恢复

先上机器进行误操作或者磁盘损坏的时候,需要进行Xtrabackup+binlog进行线上的数据恢复。
首先备份原始的数据库文件,防止恢复的时候数据库记录被清除,如果没有停机,则刷新binlog文件,flush logs。然后恢复Xtrabackup备份并启动mysql。

mysqladmin -u root -S my3306.sock shutdown  
mv 3306 3306_bro  
innobackupex --defaults-file=./../3306.cnf --apply-log ./  
innobackupex --defaults-file=./../3306.cnf --move-back ./  
mysqld --defaults-file=/mysql/cnf/3306.cnf &  

进入mysql检查数据:

mysql> select * from test;  
+----+----------+
| id | name     |
+----+----------+
|  1 | fangyuan |
|  2 | xiaocan  |
+----+----------+
2 rows in set (0.00 sec)

mysql>  

此时可以发现数据是旧数据,我们需要从binlog中恢复数据。
检查xtrabackupbinlogpos_innodb中binlog所在文件和位置,确定恢复的起始位置。

[root@localhost 3306]# cat xtrabackup_binlog_pos_innodb 
3306-mysql-bin.000003    1513  

检查原始数据库binlog文件

[root@localhost 3306_bro]# ls
3306-mysql-bin.000001  auto.cnf        ib_logfile0  node_blog  
3306-mysql-bin.000002  error.log       ib_logfile1  novaskii  
3306-mysql-bin.000003  ib_buffer_pool  ib_logfile2  performance_schema  
3306-mysql-bin.index   ibdata1         mysql        xiaocan  
[root@localhost 3306_bro]# 

从这里我们可以看出来Xtrabackup的备份binlog到了000003的1513。所以我们从000003的1513这个binlog位置开始往后恢复,直到所有binlog恢复完毕或者恢复到所需要的binlog位置。
如果需要核查binlog,可以用mysqlbinlog导出binlog

导入binlog:  
ysqlbinlog 3306-mysql-bin.000003 --set-charset=UTF8 --base64-output=decode-rows -v --start-position=1513 > output.log | mysql -u root -S /mysql/3306/my3306.sock  

此时再检查mysql数据库可以发现数据已经恢复一致。