MySQL备份之Xtrabackup

本文深入探讨了Xtrabackup作为一款开源的MySQL数据库备份工具的优势,详细介绍了其在线热备份、增量备份、流式备份等功能,并解析了其备份原理和实现细节。包括如何通过命令行实现完全备份、准备、恢复和增量备份等操作,以及如何在生产环境中进行数据恢复。此外,文章还介绍了如何使用Xtrabackup进行单张表的导入或导出,提供了关键步骤和注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、简介与安装
1、优势

  • 备份过程快速、可靠;
  • 备份过程不会打断正在执行的事务;
  • 能够基于压缩等功能节约磁盘空间和流量;
  • 自动实现备份检验;
  • 还原速度快;

A、Xtrabackup是什么
  Xtrabackup是由percona提供的一款开源mysql数据库备份工具,支持在线热备份(备份时不影响数据读写),是商业备份工具InnoDB Hotbackup的一个很好的替代品。
  Xtrabackup有两个主要的工具:xtrabackup、innobackupex
1、xtrabackup只能备份InnoDB和XtraDB两种数据表,而不能备份MyISAM数据表
2、innobackupex是参考了InnoDB Hotbackup的innoback脚本修改而来的,innobackupex是一个封装了xtrabackup的perl脚本。主要是为了方便同时备份InnoDB和MyISAM引擎的表,但在处理MyISAM时需要加一个读锁。并且加入了一些使用的选项。如slave-info可以记录备份恢复后,作为slave需要的一些信息,根据这些信息可以很方便的利用备份来重做slave。
B、Xtrabackup可以做什么

  • 在线(热)备份整个库的InnoDB、 XtraDB表
  • 在xtrabackup的上一次整库备份基础上做增量备份(innodb only)
  • 以流的形式产生备份,可以直接保存到远程机器上(本机硬盘空间不足时很有用)

MySQL数据库本身提供的工具并不支持真正的增量备份,二进制日志恢复是point-in-time(时间点)的恢复而不是增量备份。Xtrabackup工具支持对InnoDB存储引擎的增量备份,工作原理如下:
(1)首先完成一个完全备份,在logfile中找到并记录此时检查点的最后一个checkpoint(Log Sequence Number LSN),然后开始从LSN的位置开始拷贝InnoDB的logfile到xtrabackup_logfile;接着,开始拷贝全部的数据文件.ibd;在拷贝全部数据文件结束之后,才停止拷贝logfile。因为logfile里面记录全部的数据修改情况,所以,即时在备份过程中数据文件被修改过了,恢复时仍然能够通过解析xtrabackup_logfile保持数据的一致。
(2)在进程增量备份时,比较表空间中每个页的LSN是否大于上次备份时的LSN,如果是,则备份该页,同时记录当前检查点的LSN  
C、Xtrabackup备份原理 
  XtraBackup基于InnoDB的crash-recovery功能。它会复制innodb的data file,由于不锁表,复制出来的数据是不一致的,在恢复的时候使用crash-recovery,使得数据恢复一致。
  InnoDB维护了一个redo log,又称为transaction log,事务日志,它包含了innodb数据的所有改动情况。当InnoDB启动的时候,它会先去检查data file和transaction log,并且会做二步操作:
  XtraBackup在备份的时候, 一页一页地复制innodb的数据,而且不锁定表,与此同时,XtraBackup还有另外一个线程监视着transactions log,一旦log发生变化,就把变化过的log pages复制走。为什么要急着复制走呢? 因为transactions log文件大小有限,写满之后,就会从头再开始写,所以新数据可能会覆盖到旧的数据。在prepare过程中, XtraBackup使用复制到的transactions log对备份出来的innodb data file进行crash recovery。
D、实现细节
   XtraBackup以read-write模式打开innodb的数据文件,然后对其进行复制。运行 XtraBackup的用户,必须对innodb的数据文件具有读写权限。之所以采用read-write模式是因为XtraBackup采用了其内置的 innodb库来打开文件,而innodb库打开文件的时候就是rw的。

  XtraBackup要从文件系统中复制大量的数据,所以它尽可能地使用posix_fadvise(),来告诉OS不要缓存读取到的数据,从而提升性能。因为这些数据不会重用到了,OS却没有这么聪明。如果要缓存一下的话,几个G的数据,会对OS的虚拟内存造成很大的压力,其它进程,比如 mysqld很有可能被swap出去,这样系统就会受到很大影响了。

  在备份innodb page的过程中,XtraBackup每次读写1MB的数据,1MB/16KB=64个page。这个不可配置。读1MB数据之 后,XtraBackup一页一页地遍历这1MB数据,使用innodb的buf_page_is_corrupted()函数检查此页的数据是否正常, 如果数据不正常,就重新读取这一页,最多重新读取10次,如果还是失败,备份就失败了,退出。在复制transactions log的时候,每次读写512KB的数据。同样不可以配置。

2、安装
其最新版的软件可从 https://www.percona.com/downloads/XtraBackup/LATEST/获得。本文基于CentOS6.5的系统,因此,直接下载相应版本的rpm包安装即可。
解决依赖关系:挂载本地光盘安装perl-DBD-MySQL
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
3、innobackupex相关参数说明
–defaults-file:指定my.cnf参数文件的位置
–apply-log:同xtrabackup的–prepare参数,一般情况下,在备份完成后,数据尚且不能用于恢复操作,因为备份的数据中可能 会包含尚未提交的事务或已经提交但尚未同步至数据文件中的事务。因此,此时数据 文件仍处理不一致状态。–apply-log的作用是通过回滚未提交的事务及同步已经提交的事务至数据文件使数据文件处于一致性状态。
–copy-back:做数据恢复时将备份数据文件拷贝到MySQL服务器的datadir
–remote-host=HOSTNAME: 通过ssh将备份数据存储到进程服务器上
–stream=[tar]:备份文件输出格式, 该文件可在XtarBackup binary文件中获得. 在使用参数stream=tar备份的时候,你的xtrabackup_logfile可能会临时放在/tmp目录下,如果你备份的时候并发写入较大的 话,xtrabackup_logfile可能会很大(5G+),很可能会占满你的/tmp目录,可以通过参数–tmpdir指定目录来解决这个问题.
–tmpdir=DIRECTORY:当有指定–remote-host or –stream时, 事务日志临时存储的目录, 默认采用MySQL配置文件中所指定的临时目录tmpdir
–redo-only –apply-log:强制备份日志时只redo,跳过rollback,这在做增量备份时非常必要
–use-memory=*:该参数在prepare的时候使用,控制prepare时innodb实例使用的内存
–databases=LIST:列出需要备份的databases,如果没有指定该参数,所有包含MyISAM和InnoDB表的database都会被备份
–slave-info:备份从库, 加上–slave-info备份目录下会多生成一个xtrabackup_slave_info 文件, 这里会保存主日志文件以及偏移, 文件内容类似于:CHANGE MASTER TO MASTER_LOG_FILE=”, MASTER_LOG_POS=0
–socket=SOCKET:指定mysql.sock所在位置,以便备份进程登录mysql。
二、备份的实现
1、完全备份

# innobackupex --user=DBUSER --password=DBUSERPASS  /path/to/BACKUP-DIR/
[root@DQ ~]# innobackupex --user=root --password=123456 --socket=/tmp/mysql.sock cleanup/weekly/
由于系统上mysql是源码编译安装所有指定了mysql.sock路径,否则备份过程会报错

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

mysql> CREATE USER 'bkuser'@'localhost'  IDENTIFIED BY  'secret';
mysql> REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'bkuser';
mysql> GRANT RELOAD, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'bkuser'@'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_info
这里写图片描述
(4)xtrabackup_logfile 数据文件
这里写图片描述
(5)backup-my.cnf —— 备份命令用到的配置选项信息;
这里写图片描述
在使用innobackupex进行备份时,还可以使用–no-timestamp选项来阻止命令自动创建一个以时间命名的目录;如此一来,innobackupex命令将会创建一个BACKUP-DIR目录来存储备份数据。
2、准备(prepare)一个完全备份
一般情况下,在备份完成后,数据尚且不能用于恢复操作,因为备份的数据中可能会包含尚未提交的事务或已经提交但尚未同步至数据文件中的事务。因此,此时数据文件仍处理不一致状态。“准备”的主要作用正是通过回滚未提交的事务及同步已经提交的事务至数据文件也使得数据文件处于一致性状态。
innobakupex命令的–apply-log选项可用于实现上述功能。如下面的命令:

# innobackupex --apply-log  /path/to/BACKUP-DIR

这里写图片描述
如果执行正确,其最后输出的几行信息通常如下:
这里写图片描述
在实现“准备”的过程中,innobackupex通常还可以使用–use-memory选项来指定其可以使用的内存的大小,默认通常为100M。如果有足够的内存可用,可以多划分一些内存给prepare的过程,以提高其完成速度。

接下来连接到mysql服务器对数据进行一些读写操作,用于后面的测试二进制即时点还原
完全备份还原course表应回到A状态,之后做即时点还原应回到B状态
这里写图片描述
接下来备份二进制日志文件,先滚动日志,否则备份正在使用的二进制日志文件会报错

[root@DQ ~]# mysql -e 'flush logs'
[root@DQ ~]# cd /mnt/SQLData/
[root@DQ SQLData]# mysqlbinlog --start-position 203 mysql-bin.000002 >/root/cleanup/binlog`date +%F`.sql

模拟数据损坏
这里写图片描述
3、从一个完全备份中恢复数据
innobackupex命令的–copy-back选项用于执行恢复操作,其通过复制所有数据相关的文件至mysql服务器DATADIR目录中来执行恢复过程。innobackupex通过backup-my.cnf来获取DATADIR目录的相关信息。

# innobackupex --copy-back  /path/to/BACKUP-DIR
[root@DQ ~]# innobackupex --copy-back cleanup/weekly/2015-07-30_05-09-13/

如果执行正确,其输出信息的最后几行通常如下:请确保信息的最行一行出现“innobackupex: completed OK!”
这里写图片描述
当数据恢复至DATADIR目录以后,还需要确保所有数据文件的属主和属组均为正确的用户,如mysql,否则,在启动mysqld之前还需要事先修改数据文件的属主和属组。如:
这里写图片描述
查看完全备份courses表恢复到A状态
这里写图片描述
进行即时点还原后再次查看表恢复到B状态
这里写图片描述
4、使用innobackupex进行增量备份
每个InnoDB的页面都会包含一个LSN信息,每当相关的数据发生改变,相关的页面的LSN就会自动增长。这正是InnoDB表可以进行增量备份的基础,即innobackupex通过备份上次完全备份之后发生改变的页面来实现。
由于刚才的实现已经对mysql进行了一次还原,所以当前时刻数据库的状态已经没有完全备份,每次还原之后都要重新做一次完全备份,在新完全备份的基础上做增量备份
这里写图片描述
然后对数据进行读写操作
这里写图片描述
使用下面的命令要实现第一次增量备份:其中,BASEDIR指的是完全备份所在的目录,此命令执行结束后,innobackupex命令会在/rootcleanup/ 目录中创建一个新的以时间命名的目录以存放所有的增量备份数据。
这里写图片描述
再进行一些读写操作
这里写图片描述
在执行过增量备份之后再一次进行增量备份时,其–incremental-basedir应该指向上一次的增量备份所在的目录。
这里写图片描述
这里写图片描述
需要注意的是,增量备份仅能应用于InnoDB或XtraDB表,对于MyISAM表而言,执行增量备份时其实进行的是完全备份。
“准备”(prepare)增量备份与整理完全备份有着一些不同,尤其要注意的是:

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

于是,操作就变成了:

[root@DQ ~]# innobackupex --apply-log --redo-only cleanup/weekly/2015-07-30_07-03-20/

接着执行:

[root@DQ ~]# innobackupex --apply-log --redo-only cleanup/weekly/2015-07-30_07-03-20/ 
--incremental-dir=/root/cleanup/2015-07-30_07-27-09/

而后是第二个增量:

[root@DQ ~]# innobackupex --apply-log --redo-only cleanup/weekly/2015-07-30_07-03-20/ 
--incremental-dir=/root/cleanup/2015-07-30_08-05-18/

其中BASE-DIR指的是完全备份所在的目录,而INCREMENTAL-DIR-1指的是第一次增量备份的目录,INCREMENTAL-DIR-2指的是第二次增量备份的目录,其它依次类推,即如果有多次增量备份,每一次都要执行如上操作;
接下来模拟数据损坏,首先备份二进制日志
(生产环境中二进制日志应该是与数据目录分开存储,且最好存放在RAID1类似的设备上)

[root@DQ ~]# mysql -e 'flush logs'
[root@DQ ~]# cd /mnt/SQLData/
[root@DQ SQLData]# mysqlbinlog  mysql-bin.000001 >/root/cleanup/binlog`date +%F`.sql
[root@DQ ~]# service mysqld stop
Shutting down MySQL.                                     [  OK  ]
[root@DQ ~]# cd /mnt/SQLData/
[root@DQ SQLData]# rm -rf *

进行数据恢复

[root@DQ SQLData]#  innobackupex --copy-back /root/cleanup/weekly/2015-07-30_07-03-20/
[root@DQ SQLData]# chown -R mysql.mysql ./*
[root@DQ SQLData]# service mysqld start
Starting MySQL.........                                  [  OK  ]

成功恢复到第二次增量日志之前状态
这里写图片描述
5、导入或导出单张表
默认情况下,InnoDB表不能通过直接复制表文件的方式在mysql服务器之间进行移植,即便使用了innodb_file_per_table选项。而使用Xtrabackup工具可以实现此种功能,不过,此时需要“导出”表的mysql服务器启用了innodb_file_per_table选项(严格来说,是要“导出”的表在其创建之前,mysql服务器就启用了innodb_file_per_table选项),并且“导入”表的服务器也启用了innodb_file_per_table

system variables available in Percona Server 5.5 are no longer present in Percona Server 5.6
http://dev.mysql.com/doc/refman/5.6/en/tablespace-copying.html
这里写图片描述
(1)在目标服务器上创建一个跟源服务器上要导出的表表结构一致的表,而后才能实现将表导入:
这里写图片描述
这里写图片描述
选择导入scores表
这里写图片描述
(2)在目标服务器,丢弃现有的表空间(在表空间可以被导入前,InnoDB必须丢弃接收表的表空间 )
这里写图片描述
(3)在源服务器上,执行以下命令设置要导出的表状态为静默模式并创建.cfg元数据文件
这里写图片描述
FLUSH TABLES … FOR EXPORT is available as of MySQL 5.6.6。
该语句确保已刷新到磁盘的更改,以便在服务器正在运行时进行二进制表复制。
(.cfg)文件在InnoDB数据目录下要导出表的数据库目录中创建,文件包含用于导入表空间文件时进行模式验证的元数据
这里写图片描述
(4)将来自于“导出”表的服务器的scores表的.ibd和.exp文件复制到目标服务器的数据目录
这里写图片描述
这里写图片描述
(5)在源服务器上,使用解锁表释放FLUSH TABLES … FOR EXPORT获得的锁出口:

mysql> UNLOCK TABLES;

(6)在目标服务器上,导入表空间:

mysql> use jiaowu;
mysql> ALTER TABLE scores IMPORT TABLESPACE;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值