原理:
在InnoDB内部会维护一个redo日志文件,我们也可以叫做事务日志文件。事务日志会存储每一个InnoDB表数据的记录修改。当InnoDB启动时,InnoDB会检查数据文件和事务日志,并执行两个步骤:它应用(前滚)已经提交的事务日志到数据文件,并将修改过但没有提交的数据进行回滚操作。
Xtrabackup在启动时会记住log sequence number(LSN),并且复制所有的数据文件。复制过程需要一些时间,所以这期间如果数据文件有改动,那么将会使数据库处于一个不同的时间点。这时,xtrabackup会运行一个后台进程,用于监视事务日志,并从事务日志复制最新的修改。Xtrabackup必须持续的做这个操作,是因为事务日志是会轮转重复的写入,并且事务日志可以被重用。所以xtrabackup自启动开始,就不停的将事务日志中每个数据文件的修改都记录下来。上面就是xtrabackup的备份过程。
接下来是准备(prepare)过程。在这个过程中,xtrabackup使用之前复制的事务日志,对各个数据文件执行灾难恢复(就像mysql刚启动时要做的一样)。当这个过程结束后,数据库就可以做恢复还原了。
过程是备份---->准备。就是说:先将文件全部复制过来,再根据事务日志对部分操作进行回滚。
以上的过程在xtrabackup的编译二进制程序中实现。程序innobackupex可以允许我们备份MyISAM表和frm文件从而增加了便捷和功能。
Innobackupex会启动xtrabackup,直到xtrabackup复制数据文件后,然后执行FLUSH TABLES WITH READ LOCK来阻止新的写入进来并把MyISAM表数据刷到硬盘上,之后复制MyISAM数据文件,最后释放锁。
备份MyISAM和InnoDB表最终会处于一致,在准备(prepare)过程结束后,InnoDB表数据已经前滚到整个备份结束的点,而不是回滚到xtrabackup刚开始时的点。这个时间点与执行FLUSH TABLES WITH READ LOCK的时间点相同,所以myisam表数据与InnoDB表数据是同步的。
类似oracle的,InnoDB的prepare过程可以称为recover(恢复),myisam的数据复制过程可以称为restore(还原)。
xtrabackup的安装:
官网下载rpm包或者tar.gz包解压就能用,此外需要通过epel的yum安装依赖包libev
# yum install libev -y
# rpm -ivh percona-xtrabackup-24-2.4.3-1.el6.x86_64.rpm
rpm包释放的可执行文件如下:
/usr/bin/innobackupex # 封装过的perl脚本
/usr/bin/xbcloud
/usr/bin/xbcloud_osenv
/usr/bin/xbcrypt
/usr/bin/xbstream
/usr/bin/xtrabackup # 主程序
xtrabackup的使用:
1、完全备份
# innobackupex --user=DBUSER --password=SECRET /path/to/backup/dir/
生成的是一个以当前日期命名的文件夹。
如果要使用一个最小权限的用户进行备份,则可基于如下命令创建此类用户:
> GRANT PROCESS, RELOAD, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'bkpuser'@'localhost' IDENTIFIED BY '123456';
> 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目录来存储备份数据。
完全备份\恢复示例:
备份:
在node1上执行:
# /etc/init.d/mysqld stop
# innobackupex --user=root --password=xxxx --no-timestamp /backups/
# scp -rp /backups/ root@node2:/tmp
恢复:
在node2上执行恢复:
1、node2上停止mysql服务(如果启动的话),并删除mysql的数据目录下所有文件:
# /etc/init.d/mysqld stop
# rm -fr /data/mysql/*
2、在node2上执行整理操作:
# innobackupex --apply-log /tmp/backups/
3、在node2上执行恢复操作,并修改文件属主属组:
# innobackupex --copy-back /tmp/backups/
# chown -R mysql.mysql /data/mysql/*
4、在node2上启动mariadb服务:
# /etc/init.d/mysqld start
2、增量备份
每个InnoDB的页面都会包含一个LSN信息,每当相关的数据发生改变,相关的页面的LSN就会自动增长。这正是InnoDB表可以进行增量备份的基础,即innobackupex通过备份上次完全备份之后发生改变的页面来实现。
要实现第一次增量备份,可以使用下面的命令进行:
# innobackupex --user=root --password=xxxx --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
其中BASE-DIR指的是完全备份所在的目录,而INCREMENTAL-DIR-1指的是第一次增量备份的目录,INCREMENTAL-DIR-2指的是第二次增量备份的目录,其它依次类推,即如果有多次增量备份,每一次都要执行如上的操作;
增量备份、恢复示例:
1、先做一个完全备份
# innobackupex --user=root /backups/ 会在/backups/下生成一个以当前时间命名的文件夹。如下图:
2、对数据表执行些修改等操作
【数据表的修改操作略过】
3、执行增量备份
# innobackupex --incremental /backups/ --incremental-basedir=/backups/2015-11-08_19-24-05
说明:
有时候查看增量备份的文件中的xtrabackup_checkpoints发现其数值没变化,可能是LSN变化太小了。执行大量的数据表修改等操作后,会发现其LSN是会变化的,有时候不变也是正常的。
补充个脚本的方式执行全备份、增量备份:
全备份:
innobackupex --user=root --password=123456 /backups/
增量备份:
innobackupex --user=root --password=123456 --incremental /backups/ --incremental-basedir=/backups/$(ls -l /backups| awk '{print $NF}'|tail -1)
# 将上面的2个添加到cron计划任务即可,备份的路径是/backups/目录下。
4、合并备份文件
# innobackupex --user=root --password=123456 --apply-log-only --redo-only /backups/2015-11-08_19-57-53/
# innobackupex --user=root --password=123456 --apply-log-only --redo-only /backups/2015-11-08_19-57-53/ --incremental-dir=/backups/2015-11-08_19-59-31/
# cat /backups/2015-11-08_19-57-53/xtrabackup_checkpoints # 检验是否合并成功
5、执行恢复数据到数据库的操作
# innobackupex --user=root --password=123456 --copy-back /backups/2015-11-08_19-57-53/ 【注意这里填的应该是basedir的路径】
# ls -lh /data/mysql/ 查看文件是否恢复
# chown -R mysql.mysql /data/mysql/ 修改文件权限
6、启动MySQL查看是否数据已恢复
# /etc/init.d/mysqld start