开发者

MySQL系列连载之XtraBackup 备份原理解析

目录
  • mysql 系列连载之 XtraBackup 备份原理(1)
  • 导读
  • Xtrabackup简介
  • 原理
    • 1、MySQL主从同步原理
    • 2、XtraBackup备份原理
    • 3、备份的两个过程
    • 4、XtraBackup的优点
    • 5、Xtrabackup的两个工具
    • 6、Xtrabackup可以做什么
    • 7、Xtrabackup工具工作原理
    • 8、innobackupex备份mysql数据的流程
    • 9、innobackupex恢复mysql数据的流程
    • 10、innobackupex备份和恢复的工作原理
  • MySQL 系列连载之 XtraBackup 全量热备 or 恢复实践(2)
    • 1、准备工作
    • 2、安装percona-xtrabackup
    • 3、全量备份和恢复
  • MySQL 系列连载之 XtraBackup 增量热备 or 恢复实践(3)
    • FAQ
      • 1、可能报错1
      • 2、可能报错2

    MySQL 系列连载之 XtraBackup 备份原理(1)

    导读

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

    Xtrabackup简介

    innobackupex和mysqldump都可以对mysql进行热备份的,mysqldump对mysql的innodb的备份可以使用single-transaction参数来开启一个事务,利用innodb的mvcc来不进行锁表进行热备份,mysqldump备份是逻辑备份,备份出来的文件是sql语句,所以备份和恢复的时候很慢,但是备份和恢复时候很清楚。当MYSQL数据超过10G时,用mysqldump来导出备份就比较慢了,此种情况下用innobackupex这个工具就比mysqldump要快很多。利用它对mysql做全量和增量备份.

    Percona XtraBackup可以说是一个相对完美的免费开源数据备份工具,是使用perl语言完成的脚本工具,能够非常快速地备份与恢复mysql数据库,且支持在线热备份(备份时不影响数据读写)

    此工具调用xtrabackup和tar4ibd工具,实现很多对性能要求并不高的任务和备份逻辑,可以说它是innodb热备工具ibbackup的一个开源替代品。

    XtraBackup是目前首选的备份方案之一

    原理

    MySQL系列连载之XtraBackup 备份原理解析

    1、MySQL主从同步原理

    MySQL主从同步是在MySQL主从复制(Master-Slave Replication)基础上实现的

    通过设置在Master MySQL上的binlog(使其处于打开状态),Slave MySQL上通过一个I/O线程从Master MySQL上读取binlog,然后传输到Slave MySQL的中继日志中,然后Slave MySQL的SQL线程从中继日志中读取中继日志,然后应用到Slave MySQL的数据库中。这样实现了主从数据同步功能。

    2、XtraBackup备份原理

    innobackupex在后台线程不断追踪InnoDB的日志文件,然后复制InnoDB的数据文件。数据文件复制完成之后,日志的复制线程也会结束。这样就得到了不在同一时间点的数据副本和开始备份以后的事务日志。完成上面的步骤之后,就可以使用InnoDB崩溃恢复代码执行事务日志(redo log),以达到数据的一致性。

    3、备份的两个过程

    backup,备份阶段,追踪事务日志和复制数据文件(物理备份)。

    preparing,重放事务日志,使所有的数据处于同一个时间点,达到一致性状态。

    4、XtraBackup的优点

    1、可以快速可靠的完成数据备份(复制数据文件和追踪事务日志)

    2、数据备份过程中不会中断事务的处理(热备份)

    3、节约磁盘空间和网络带宽

    4、自动完成备份鉴定

    5、因更快的恢复时间而提高在线时间

    5、Xtrabackup的两个工具

    1)xtrabackup :只能用于热备份innodb,xtradb两种数据引擎表的工具,不能备份其他表。

    2)innobackupex:是一个对xtrabackup封装的perl脚本,提供了用于myisam(会锁表)和innodb引擎,及混合使用引擎备份的能力。主要是为了方便同时备份InnoDB和MyISAM引擎的表,但在处理myisam时需要加一个读锁。并且加入了一些使用的选项。如slave-info可以记录备份恢 复后,作为slave需要的一些信息,根据这些信息,可以很方便的利用备份来重做slave。 innobackupex比xtarbackup有更强的功能,它整合了xtrabackup和其他的一些功能,它不但可以全量备份/恢复,还可以基于时间的增量备份与恢复。innobackupex同时支持innodb,myisam。

    6、Xtrabackup可以做什么

    1)在线(热)备份整个库的InnoDB, XtraDB表

    2)在xtrabackup的上一次整库备份基础上做增量备份(innodb only)

    3)以流的形式产生备份,可以直接保存到远程机器上(本机硬盘空间不足时很有用)

    MySQL数据库本身提供的工具并不支持真正的增量备份,二进制日志恢复是point-in-time(时间点)的恢复而不是增量备份。

    7、Xtrabackup工具工作原理

    支持对InnoDB存储引擎的增量备份

    1)首先完成一个完全备份,并记录下此时检查点的LSN(Log Sequence Number)。

    2)在进行增量备份时,比较表空间中每个页的LSN是否大于上次备份时的LSN,如果是,则备份该页,同时记录当前检查点的LSN。首先,在logfile中找到并记录最后一个checkpoint(“last checkpoint LSN”),然后开始从LSN的位置开始拷贝InnoDB的logfile到xtrabackup_logfile;接着,开始拷贝全部的数据文件.ibd;在拷贝全部数据文件结束之后,才停止拷贝logfile。因为logfile里面记录全部的数据修改情况,所以,即时在备份过程中数据文件被修改过了,恢复时仍然能够通过解析xtrabackup_logfile保持数据的一致。

    8、innobackupex备份mysql数据的流程

    innobackupex首先调用xtrabackup来备份innodb数据文件,当xtrabackup完成后,innobackupex就查看文件xtrabackup_suspended ;然后执行“FLUSH TABLES WITH READ LOCK”来备份其他的文件。

    9、innobackupex恢复mysql数据的流程

    innobackupex首先读取my.cnf,查看变量(datadir,innodb_data_home_dir,innodb_data_file_path,innodb_log_group_home_dir)对应的目录是存在,确定相关目录存在后,然后先copy myisam表和索引,然后在copy innodb的表、索引和日志。

    10、innobackupex备份和恢复的工作原理

    (1)备份的工作原理

    MySQL 系列连载之 XtraBackup 备份原理(1)插图(2)

    1、备份开始时首先会开启一个后台检测进程,实时检测mysql

    redo的变化,一旦发现redo中有新的日志写入,立刻将日志记入后台日志文件xtrabackup_log中。

    2、之后复制innodb的数据文件和系统表空间文件ibdata1,待复制结束后。

    3、执行flush tables with read lock操作。

    4、复制.frm,MYI,MYD,等文件(执行flush tableswith read

    lock的目的是为了防止数据表发生DDL操作,并且在这一时刻获得binlog的位置)。

    5、最后会发出unlock tables,把表设置为可读可写状态。

    6、最终停止xtrabackup_log。

    (2)恢复的工作原理

    1、为了恢复一个备份,innobackupex需要以–copy-back选项启动。

    2、innobackupex将会首先通过my.cnf文件读取如下变量:datadir,innodb_data_home_dir,innodb_data_file_path,

    innodb_log_group_home_dir,并确定这些目录存在。

    3、接下来,此脚本将会首先拷贝MyISAM表、索引文件、其他类型的文件(如:.frm, .MRG, .MYD, .MYI, .TRG,

    .TRN, .ARM, .ARZ, .CSM, .CSV, par and .opt files)

    4、接下来拷贝InnoDB表数据文件,最后拷贝日志文件。

    5、拷贝执行时将会保留文件属性,在使用备份文件启动MySQL前,可能需要更改文件的owener(如从拷贝文件的user更改到mysql用户)。

    MySQL 系列连载之 XtraBackup 全量热备 or 恢复实践(2)

    1、准备工作

    #系统环境

    [root@master tools]# cat /etc/RedHat-release
    Centos release 6.8 (Final)
    [root@master tools]# uname -r
    2.6.32-642.el6.x86_64

    #主数据库版本

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

    #检查数据库引擎

    mysql> show engines;

    #主从数据库同步注意点 [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、安装percona-xtrabackup

    官网安装包地址 - https://www.percona.com/downloads/XtraBackup/LATEST/

    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 CODEBASE
    where 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

    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): '1639325'
    xtrabackup: 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 '21223'
    xtrabackup: 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-24'
    innobackupex: MySQL binlog position: filename 'mysql-bin.000019', position 967
    170404 12:46:30 innobackupex: Connection to database server closed
    170404 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
    

    参数解释:

    --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 备份日志,将备份js过程中的输出信息重定向到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)全量备份后的恢复操作
    
    #进入数据库
    [root@master data]# mysql
    
    #查看当前所有数据库
    mysql> show databases;
    +--------------------+
    | Database |
    +--------------------+
    | information_schema |
    | mysql |
    | performance_schema |
    | test |
    | xtra_test |
    +--------------------+
    5 rows in set (0.09 sec)
    
    #切换到 xtra_test数据库下
    mysql> use xtra_test;
    Database changed
    
    #查看当前数据库里的表
    mysql> show tables;
    +---------------------+
    | Tables_in_xtra_test |
    +---------------------+
    | I |
    | M |
    +---------------------+
    2 rows in set (0.04 sec)
    
    #删除整个 xtra_test库
    mysql> drop database xtra_test;
    Query OK, 2 rows affected (0.34 sec)
    
    #现在已经看不到 xtra_test库了
    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

    #关闭MySQL数据库服务
    [root@master data]# service mysqld stop
    Shutting down MySQL.... SUCCESS!
    
    #移动数据文件和日志文件到/tmp(当然删除也可以)
    [root@master data]# mv /application/mysql/data/* /tmp/
    
    [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 found innobackupex: 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]# ls
    innobackupex 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!
    
    #进入MySQL
    [root@master ~]# mysql
    
    #显示所有数据库(可以看到我们之前删除的xtra_test 库已经恢复了)
    mysql> show databases;
    +--------------------+
    | Database |
    +--------------------+
    | information_schema |
    | mysql |
    | performance_schema |
    | test |
    | xtra_test |
    +--------------------+
    5 rows in set (0.00 sec)
    
    #进入xtra_test 库
    mysql> use xtra_test;
    Database changed
    
    #查看xtra_test 库内表内容(已经全部恢复)
    mysql> show tables;
    +---------------------+
    | Tables_in_xtra_test |
    +---------------------+
    | I |
    | M |
    +---------------------+
    2 rows in set (0.00 sec)
    

    MySQL 系列连载之 XtraBackup 增量热备 or 恢复实践(3)

    增量备份和恢复

    特别注意:

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

    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-backuped
    from_lsn = 0
    to_lsn = 1639436
    last_lsn = 1639436
    compact = 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 = incrementReAntSqfbal
    from_lsn = 1639436
    to_lsn = 1639436
    last_lsn = 1639436
    compact = 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 = incremental
    from_lsn = 1639436
    to_lsn = 1639436
    last_lsn = 1639436
    compact = 0
    

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

    2)增量备份后的恢复操作

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

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

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

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

    其中:

    一定要全路径

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

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

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

    这里要注意的是:

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

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

    3)以上语句执行成功之后,最终数据在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-35
    drwxr-xr-x 6 root root 4096 4月 4 17:08 2017-04-04_16-58-58
    drwxr-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
    
    #创建一个叫做 ceshi 的数据库
    mysql> create database ceshi;
    Query OK, 1 row affected (0.00 sec)
    
    #切换到 ceshi 库下
    mysql> use ceshi
    Database changed
    
    #创建一个叫做 test1 的表
    mysql> create table test1(
    -> id int3,
    -> name varchar(20)
    -> );
    Query OK, 0 rows affected (0.26 sec)
    
    #往test1表中插入数据
    mysql> insert into test1 values(1,"chenbaojia");
    Query OK, 1 row affected (0.05 sec)
    
    #查看 test1 表中的内容
    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 ~]# mysql
    
    mysql> 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 stop
    Shutting 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 start
    Starting MySQL.. SUCCESS!
    
    [root@master ~]# mysql
    
    mysql> 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 | hiopythonfo |
    | 4 | mac |
    +------+------------+
    4 rows in set (0.00 sec)
    

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

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

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

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

    以此类推

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

    innobackupex 参数

    innobackupex全量、增量备份脚本

    可以根据自己线上数据库情况,编写全量和增量备份脚本,然后结合crontab设置计划执行。

    比如:每周日的1:00进行全量备份,每周1-6的1:00进行增量备份。

    还可以在脚本里编写邮件通知信息(可以用mail或sendemail)

    FAQ

    1、可能报错1

    Can't locate Time/HiRes.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at /home/mysql/admin/bin/percona-xtrabackup-2.1.9/innobackupex line 23.
    BEGIN failed--compilation aborted at /home/mysql/admin/bin/percona-xtrabackup-2.1.9/innobackupex line 23.

    解决方案:

    .pm实际上是Perl的包,只需安装perl-Time-HiRes即可:

    [root@test-huanqiu percona-xtrabackup-2.1.9]# yum install -y perl-Time-HiRes

    2、可能报错2

    Can't locate DBI.pm in @INC (@INC contains: /usr/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi /usr/lib/perl5/site_perl/5.8.8 /usr/lib/perl5/site_perl /usr/lib64/perl5/vendor_perl/5.8.8/x86_64-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.8 /usr/lib/perl5/vendor_perl /usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi /usr/lib/perl5/5.8.8 .) at /usr/local/webserver/mysql5.1.57/bin/mysqlhotcopy line 25.
    BEGIN failed--compilation aborted at /usr/local/webserver/mysql5.1.57/bin/mysqlhotcopy line 25.
    

    报错原因:系统没有按安装DBI组件。

    DBI(Database Interface)是perl连接数据库的接口。其是perl连接数据库的最优秀方法,他支持包括Orcal,Sybase,mysql,DB2等绝大多数的数据库。

    解决办法:

    安装DBI组件(Can't locate DBI.pm in @INC-mysql接口)
    或者单独装DBI、Data-ShowTable、DBD-mysql 三个组件
    [root@test-huanqiu percona-xtrabackup-2.1.9]# yum -y install perl-DBD-MySQL
    接着使用innobackupex命令测试是否正常
    [root@test-huanqiu percona-xtrabackup-2.1.9]# innobackupex --help
    Options:
    --apply-log
    Prepare a backup in BACKUP-DIR by applying the transaction log file
    named "xtrabackup_logfile" located in the same directory. Also,
    create new transaction logs. The InnoDB configuration is read from
    the file "backup-my.cnf".
    
    --compact
    Create a compact backup with all secondary index pages omitted. This
    option is passed directly to xtrabackup. See xtrabackup
    documentation for details.
    --compress
    This option instructs xtrabackup to compress backup copies of InnoDB
    data files. It is passed directly to the xtrabackup child process.
    Try 'xtrabackup --help' for more details.

    3、可能报错3

    161130 05:56:48 innobackupex: Connecting to MySQL server with DSN ‘dbi:mysql:;mysql_read_default_file=/usr/local/mysql/my.cnf;mysql_read_default_group=xtrabackup’ as ‘root’ (using password: YES).

    innobackupex: Error: Failed to connect to MySQL server as DBD::mysql module is not installed at /home/mysql/admin/bin/percona-xtrabackup-2.1.9/innobackupex line 2956.

    解决办法:

    [root@test-huanqiu ~]# yum -y install perl-DBD-MySQL.x86_64
    ......
    Package perl-DBD-MySQL-4.013-3.el6.x86_64 already installed and latest version //发现本机已经安装了
    
    [root@test-huanqiu ~]# rpm -qa|grep perl-DBD-MySQL
    perl-DBD-MySQL-4.013-3.el6.x86_64
    发现本机已经安装了最新版的perl-DBD-MYSQL了,但是仍然报出上面的错误!! 莫慌~~继续下面的操作进行问题的解决
    
    查看mysql.so依赖的lib库
    
    [root@test-huanqiu ~]# ldd /usr/lib64/perl5/auto/DBD/mysql/mysql.so
    linux-vdso.so.1 => (0x00007ffd291fc000)
    libmysqlclient.so.16 => not found //这一项为通过检查,缺失libmysqlclient.so.16库导致
    libz.so.1 => /lib64/libz.so.1 (0x00007f78ff9de000)
    libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007f78ff7a7000)
    libnsl.so.1 => /lib64/libnsl.so.1 (0x00007f78ff58e000)
    libm.so.6 => /lib64/libm.so.6 (0x00007f78ff309000)
    libssl.so.10 => /usr/lib64/libssl.so.10 (0x00007f78ff09d000)
    libcrypto.so.10 => /usr/lib64/libcrypto.so.10 (0x00007f78fecb9000)
    libc.so.6 => /lib64/libc.so.6 (0x00007f78fe924000)
    libfreebl3.so => /lib64/libfreebl3.so (0x00007f78fe721000)
    libgssapi_krb5.so.2 => /lib64/libgssapi_krb5.so.2 (0x00007f78fe4dd000)
    libkrb5.so.3 => /lib64/libkrb5.so.3 (0x00007f78fe1f5000)
    libcom_err.so.2 => /lib64/libcom_err.so.2 (0x00007f78fdff1000)
    libk5crypto.so.3 => /lib64/libk5crypto.so.3 (0x00007f78fddc5000)
    libdl.so.2 => /lib64/libdl.so.2 (0x00007f78fdbc0000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f78ffe1d000)
    libkrb5support.so.0 => /lib64/libkrb5support.so.0 (0x00007f78fd9b5000)
    libkeyutils.so.1 => /lib64/libkeyutils.so.1 (0x00007f78fd7b2000)
    libresolv.so.2 => /lib64/libresolv.so.2 (0x00007f78fd597000)
    libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f78fd37a000)
    libselinux.so.1 => /lib64/libselinux.so.1 (0x00007f78fd15a000)
    以上结果说明缺少libmysqlclient.so.16这个二进制包,找个官方原版的mysql的libmysqlclient.so.16替换了即可!
    
    [root@test-huanqiu~]# find / -name libmysqlclient.so.16 //查看本机并没有libmysqlclient.so.16库文件
    查看mysql/lib下的libmysqlclinet.so库文件
    
    [root@test-huanqiu~]# ll /usr/local/mysql/lib/
    total 234596
    -rw-r--r--. 1 mysql mysql 19520800 Nov 29 12:27 libmysqlclient.a
    lrwxrwxrwx. 1 mysql mysql 16 Nov 29 12:34 libmysqlclient_r.a -> libmysqlclient.a
    lrwxrwxrwx. 1 mysql mysql 17 Nov 29 12:34 libmysqlclient_r.so -> libmysqlclient.so
    lrwxrwxrwx. 1 mysql mysql 20 Nov 29 12:34 libmysqlclient_r.so.18 -> libmysqlclient.so.18
    lrwxrwxrwx. 1 mysql mysql 24 Nov 29 12:34 libmysqlclient_r.so.18.1.0 -> libmysqlclient.so.18.1.0
    lrwxrwxrwx. 1 mysql mysql 20 Nov 29 12:34 libmysqlclient.so -> libmysqlclient.so.18
    lrwxrwxrwx. 1 mysql mysql 24 Nov 29 12:34 libmysqlclient.so.18 -> libmysqlclient.so.18.1.0
    -rwxr-xr-x. 1 mysql mysql 8858235 Nov 29 12:27 libmysqlclient.so.18.1.0
    -rw-r--r--. 1 mysql mysql 211822074 Nov 29 12:34 libmysqld.a
    -rw-r--r--. 1 mysql mysql 14270 Nov 29 12:27 libmysqlservices.a
    drwxr-xr-x. 3 mysql mysql 4096 Nov 29 12:34 plugin
    将mysql/lib/libmysqlclient.so.18.1.0库文件拷贝到/lib64下,拷贝后命名为libmysqlclient.so.16
    
    [root@test-huanqiu~]# cp /usr/local/mysql/lib/libmysqlclient.so.18.1.0 /lib64/libmysqlclient.so.16
    
    [root@test-huanqiu~]# cat /etc/ld.so.conf
    include ld.so.conf.d/*.conf
    /usr/local/mysql/lib/
    /lib64/
    [root@test-huanqiu~]# ldconfig
    
    最后卸载perl-DBD-MySQL,并重新安装perl-DBD-MySQL
    [root@test-huanqiu~]# rpm -qa|grep perl-DBD-MySQL
    perl-DBD-MySQL-4.013-3.el6.x86_64
    [root@test-huanqiu~]# rpm -e --nodeps perl-DBD-MySQL
    [root@test-huanqiu~]# rpm -qa|grep perl-DBD-MySQL
    [root@test-huanqiu~]# yum -y install perl-DBD-MySQL
    待重新安装后,再次重新检查mysql.so依赖的lib库,发现已经都通过了
    
    [root@test-huanqiu~]# ldd /usr/lib64/perl5/auto/DBD/mysql/mysql.so
    linux-vdso.so.1 => (0x00007ffe3669b000)
    libmysqlclient.so.16 => /usr/lib64/mysql/libmysqlclient.so.16 (0x00007f4af5c25000)
    libz.so.1 => /lib64/libz.so.1 (0x00007f4af5a0f000)
    libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007f4af57d7000)
    libnsl.so.1 => /lib64/libnsl.so.1 (0x00007f4af55be000)
    libm.so.6 => /lib64/libm.so.6 (0x00007f4af533a000)
    libssl开发者_oracle.so.10 => /usr/lib64/libssl.so.10 (0x00007f4af50cd000)
    libcrypto.so.10 => /usr/lib64/libcrypto.so.10 (0x00007f4af4ce9000)
    libc.so.6 => /lib64/libc.so.6 (0x00007f4af4955000)
    libfreebl3.so => /lib64/libfreebl3.so (0x00007f4af4751000)
    libgssapi_krb5.so.2 => /lib64/libgssapi_krb5.so.2 (0x00007f4af450d000)
    libkrb5.so.3 => /lib64/libkrb5.so.3 (0x00007f4af4226000)
    libcom_err.so.2 => /lib64/libcom_err.so.2 (0x00007f4af4021000)
    libk5crypto.so.3 => /lib64/libk5crypto.so.3 (0x00007f4af3df5000)
    libdl.so.2 => /lib64/libdl.so.2 (0x00007f4af3bf1000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f4af61d1000)
    libkrb5support.so.0 => /lib64/libkrb5support.so.0 (0x00007f4af39e5000)
    libkeyutils.so.1 => /lib64/libkeyutils.so.1 (0x00007f4af37e2000)
    libresolv.so.2 => /lib64/libresolv.so.2 (0x00007f4af35c8000)
    libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f4af33aa000)
    libselinux.so.1 => /lib64/libselinux.so.1 (0x00007f4af318b000)
    

    4、可能报错4

    sh: xtrabackup_56: command not found

    innobackupex: Error: no ‘mysqld’ group in MySQL options at /home/mysql/admin/bin/percona-xtrabackup-2.1.9/innobackupex line 4350.

    有可能是percona-xtrabackup编译安装后,在编译目录的src下存在xtrabackup_innodb55,只需要其更名为xtrabackup_55,然后拷贝到上面的/home/mysql/admin/bin/percona-xtrabackup-2.1.9/下即可!

    参连接:

    http://www.yunweipai.com/13462.html

    到此这篇关于MySQL系列连载之XtraBackup 备份原理的文章就介绍到这了,更多相关MySQL XtraBackup 备份内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

    0

    上一篇:

    下一篇:

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新数据库

    数据库排行榜