优点
快速进行完整,可靠的备份
在备份过程中不中断进行中的事务
节省备份空间及网络带宽
支持自动备份机制,备份后自动完成校验
快速恢复
支持Percona Server, MySQL MariaDB, Drizzle 版本的热备份,流备份,压缩备份及增量备份机制
支持InnoDB, XtraDB, HailDB 存储引擎的无堵塞(在线)备份机制
对于 MyISAM, Merge Archive, 分区表,触发器,备份过程中需对引擎执行只读锁定
可在两个服务器之间在线迁移表
支持压缩的流备份到另外一台服务器上
轻松建立 MySQL AB 复制
下载地址
http://www.percona.com/software/percona-xtrabackup
编译方法
tar xf percona-xtrabackup-2.1.6.tar.gz
cd percona-xtrabackup-2.1.6
参考
================== ========= =============================================
Value Alias Server
================== ========= =============================================
innodb51 plugin build against InnoDB plugin in MySQL 5.1
innodb55 5.5 build against InnoDB in MySQL 5.5
xtradb51 xtradb build against Percona Server with XtraDB 5.1
xtradb55 xtradb55 build against Percona Server with XtraDB 5.5
innodb56 5.6 build against InnoDB in MySQL 5.6
================== ========= =============================================
根据你当前的数据库版本进行编译,如,当前使用 innodb 5.5 版本, 则编译如下
AUTO_DOWNLOAD="yes" ./utils/build.sh innodb55
获得当前数据库版本方法
如, xtradb55 返回结果如下
select PLUGIN_DESCRIPTION, PLUGIN_VERSION from information_schema.plugins where plugin_name = 'Innodb';
+----------------------------------------------------------------------------+----------------+
| PLUGIN_DESCRIPTION | PLUGIN_VERSION |
+----------------------------------------------------------------------------+----------------+
| Percona-XtraDB, Supports transactions, row-level locking, and foreign keys | 5.5 |
+----------------------------------------------------------------------------+----------------+
1 row in set (0.00 sec)
如innodb55 返回结果如下
select PLUGIN_DESCRIPTION, PLUGIN_VERSION from information_schema.plugins where plugin_name = 'Innodb';
+------------------------------------------------------------+----------------+
| PLUGIN_DESCRIPTION | PLUGIN_VERSION |
+------------------------------------------------------------+----------------+
| Supports transactions, row-level locking, and foreign keys | 5.5 |
+------------------------------------------------------------+----------------+
1 row in set (0.00 sec)
当前编译版本
AUTO_DOWNLOAD="yes" ./utils/build.sh xtradb55
编译成功,会生成 innobackupex 及 xtrabackup_55 二进制文件, 复制文件至 /usr/local/bin 下
[root@db2 percona-xtrabackup-2.1.6]# cp innobackupex /usr/local/bin/.
[root@db2 percona-xtrabackup-2.1.6]# cp src/xtrabackup_55 /usr/local/bin/.
注: innobackup 文件是 perl 脚本,可看做是调用 xtrabackup 的工具
xtrabackup 是又 C 编译出来的二进制文件
常见编译错误
/usr/bin/ld: cannot find -laio
collect2: ld 返回 1
gmake: *** [xbstream] 错误 1
gmake: *** 正在等待未完成的任务....
xtrabackup.cc: In function ‘my_bool x
解决方法
yum install -y libaio libaio-devel
权限
备份过程中系统用户需要对存放备份数据的系统文件目录具备读写执行权限
而对数据库进行备份时候,建议具备下面的权限能力
RELOAD, LOCK TABLES (除非指定 --no-lock 参数) 以便具备 flush tables with read lock 能力
REPLICATION CLIENT 具备获得二进制日志文件备份能力
CREATE TABLESPACE 具备恢复整个表空间,并导入表的能力
SUPER 用于启动/关闭从服务器复制线程环境
全库完整备份方法
innobackupex --user=DBUSER --password=DBUSERPASS /path/to/BACKUP-DIR/
innobackupex --user=root --password=123 --socket=/var/run/mysqld/mysql5.socket /backup
备份过程中可以看到 innobackupex 调用了 xtrabackup 工具
131223 14:09:34 innobackupex: Starting ibbackup with command: xtrabackup_55 --defaults-group="mysqld" --backup --suspend-at-end --target-dir=/backup/2013-12-23_14-09-34 --tmpdir=/tmp
innobackupex: Waiting for ibbackup (pid=13829) to suspend
innobackupex: Suspend file '/backup/2013-12-23_14-09-34/xtrabackup_suspended_2'
备份过程中终止日志线程,并以上一次 checkpoint 作为日志备份时间点
xtrabackup: The latest check point (for incremental): '85727497'
xtrabackup: Stopping log copying thread.
.>> log scanned up to (85727497)
完成所有备份后,可以看到下面信息返回
innobackupex: Backup created in directory '/backup/2013-12-23_14-09-34'
131223 14:09:39 innobackupex: Connection to database server closed
131223 14:09:39 innobackupex: completed OK!
上述全库备份方法将会自动把备份信息存放到一个以当前年-月-日_时-分-秒的目录中
如果你希望自定义备份目录(注,目录需在备份过程中自动生成),可以增加 --no-timestamp 参数,如
innobackupex --user=root --password=123 --socket=/var/run/mysqld/mysql5.socket /backup/2013_12_23 --no-timestamp
则备份时候会自动创建 2013_12_23 目录并把备份集存放至该目录中
注意,当前全库备份只备份至上文提到 checkpoint '85727497' 序号的事务及已经完成同步至磁盘中的数据,而已经执行,但还没有提交的事务仍然存放在内存中(innodb buffer),导致当前数据文件处于非一致性状态
假设当前要对全备进行恢复,则我们却要利用回滚未提交的事务,使得数据文件处于一致状态,因此,我们再执行完整全备之后,切记要执行一次 --apply-log 操作,这点是十分重要的
当前参考文件 /backup/2013-12-23_14-09-34/xtrabackup_checkpoints
cat /backup/2013-12-23_14-09-34/xtrabackup_checkpoints
backup_type = full-backuped
from_lsn = 0
to_lsn = 85727497
last_lsn = 85727497
compact = 0
执行 --apply-log 时,必须要指定之前的备份目录(因为需要获得正确的 xtrabackup_checkpoints 文件)
cd /backup/2013-12-23_14-09-34
innobackupex --apply-log --defaults-file=/usr/local/mysql/etc/my.cnf --user=root --password=123 --socket=/var/run/mysqld/mysql5.socket ./
xtrabackup: starting shutdown with innodb_fast_shutdown = 1
131223 16:23:40 InnoDB: Starting shutdown...
131223 16:23:44 InnoDB: Shutdown completed; log sequence number 85728268
131223 16:23:44 innobackupex: completed OK!
参见最新后的 xtrabackup_checkpoints 文件信息
backup_type = full-prepared
from_lsn = 0
to_lsn = 85727826
last_lsn = 85727826
compact = 0
默认情况下,--apply-log 参数,只调用系统 100M 内存,如果当前 innodb buffer pool 比较大,则同步内存中数据时间可能会比较长,可以通过定义内存大小加快备份速度, 如参数 --use-memory=4G
恢复方法
要进行全库恢复,可调用参数 --copy-back
注: 当前全库恢复为离线恢复模式
需保证 datadir (/mdb) 数据库目录当前为空
需保证数据库处于关闭状态
数据恢复后,需对 datadir (/mdb) 目录重新修改文件所有者为 mysql 用户
innobackupex --copy-back --user=root --password=123 --socket=/var/run/mysqld/mysql5.socket /backup/2013-12-23_16-22-34
innobackupex: Starting to copy InnoDB log files
innobackupex: in '/backup/2013-12-23_16-22-34'
innobackupex: back to original InnoDB log directory '/mdb'
innobackupex: Copying '/backup/2013-12-23_16-22-34/ib_logfile1' to '/mdb/ib_logfile1'
innobackupex: Copying '/backup/2013-12-23_16-22-34/ib_logfile0' to '/mdb/ib_logfile0'
innobackupex: Finished copying back files.
131223 16:39:06 innobackupex: completed OK!
备份完成后需要对数据库文件目录授权 mysql 用户属性
[root@db2 /]# chown mysql:mysql /mdb -R
增量备份
注: 增量备份只支持 innodb 引擎, MyISAM 引擎无法实现增量,只会进行全表备份
innobackupex --incremental /data/backups --incremental-basedir=BASEDIR
备份恢复过程,先参考之前文档,执行一次全备份。(增量备份需建立在全备份之上)
全备
innobackupex --user=root --password=123 --socket=/var/run/mysqld/mysql5.socket /backup
apply-log 备份
innobackupex --user=root --password=123 --apply-log --socket=/var/run/mysqld/mysql5.socket /backup/2013-12-24_14-58-26/
检查当前 check-point 位置
cat 2013-12-24_14-58-26/xtrabackup_checkpoints
backup_type = full-prepared
from_lsn = 0
to_lsn = 85760880
last_lsn = 85760880
compact = 0
检查当前数据库的 lsn
---
LOG
---
Log sequence number 85760880
Log flushed up to 85760880
Last checkpoint at 85760880
Max checkpoint age 7782360
Checkpoint age target 7539162
为数据库插入数据.. (略)
增加数据后的 lsn
---
LOG
---
Log sequence number 85764524
Log flushed up to 85764524
Last checkpoint at 85764524
Max checkpoint age 7782360
Checkpoint age target 7539162
执行增量备份
innobackupex --user=root --password=123 --socket=/var/run/mysqld/mysql5.socket --incremental /backup --incremental-basedir=/backup/2013-12-24_14-58-26/
--incremental-basedir 需要指定之前完整备份的目录
--incremental 将会在改目录下生成新的目录用于存放增量备份数据
执行成功后, /backup 将会出现两个目录
2013-12-24_14-58-26 (完整备份) 2013-12-24_15-02-57 (增量备份)
查看当前增量备份 check-point 信息
cat /backup/2013-12-24_15-02-57/xtrabackup_checkpoints
backup_type = incremental
from_lsn = 85760880
to_lsn = 85764524
last_lsn = 85764524
compact = 0
完整备份 lsn 从 0 ~ 85760880, 增量备份 lsn 从 85760880 ~ 85764524 匹配当前数据库中的最后一次 lsn
分别按顺序(先全备再增量)对备份目录执行 --apply-log --redo-only 操作确保数据一致性(该操作只需要在恢复前执行)
innobackupex --user=root --password=123 --socket=/var/run/mysqld/mysql5.socket --apply-log --redo-only /backup/2013-12-24_14-58-26
innobackupex --user=root --password=123 --socket=/var/run/mysqld/mysql5.socket --apply-log --redo-only /backup/2013-12-24_14-58-26 --incremental-dir=/backup/2013-12-24_15-02-57
执行后再重新检验一次 check-point 文件, 发现全库备份的 checkpoint 已经包含了增量备份中的 lsn
[root@db4 backup]# cat 2013-12-24_14-58-26/xtrabackup_checkpoints
backup_type = full-prepared
from_lsn = 0
to_lsn = 85764524
last_lsn = 85764524
compact = 0
[root@db4 backup]# cat 2013-12-24_15-02-57/xtrabackup_checkpoints
backup_type = incremental
from_lsn = 85760880
to_lsn = 85764524
last_lsn = 85764524
compact = 0
恢复方法跟之前一样, 只需要指定全库备份位置则可
innobackupex --copy-back /backup/2013-12-24_14-58-26
时间点备份
全备恢复后,利用二进制日志进行时间点恢复,与 xtrabackup 无关, 纯 MYSQL 特点, 不详细讨论
备份压缩
利用 --compress 参数实现