Xtrabackup 只能备份和恢复 InnoDB 表,而且只有 ibd 文件,frm 文件它不管,恢复时就需要 DBA 提供 frm。innobackupex 可以备份和恢复 MyISAM 表以及 frm 文件,并且对 xtrabackup 也做了很好的封装,所以可以使用 innobackupex 来备份 MySQL 数据库。还有一个问题,就是 innobackupex 备份 MyISAM 表之前要对全库进行加 READ LOCK,阻塞写操作,若备份是在从库上进行的话会影响主从同步,造成延迟。对 InnoDB 表备份不会阻塞读写。
Xtrabackup 增量备份的原理是:
1) 首先完成一个完全备份,并记录下此时检查点 LSN;
2) 然后增量备份时,比较表空间中每个页的 LSN 是否大于上次备份的 LSN,若是则备份该页并记录当前检查点的 LSN。
具体来说,首先在 logfile 中找到并记录最后一个 checkpoint(“last checkpoint LSN”),然后开始从 LSN 的位置开始拷贝 InnoDB 的 logfile 到 xtrabackup_logfile;然后开始拷贝全部的数据文件.ibd;在拷贝全部数据文件结束之后,才停止拷贝 logfile。
所以 xtrabackup_logfile 文件在并发写入很大时也会变得很大,占用很多空间,需要注意。另外当我们使用 –stream=tar 或者远程备份 –remote-host 时默认使用 /tmp,但最好显示用参数 –tmpdir 指定,以免把 /tmp 目录占满影响备份以及系统其它正常服务。
因为 logfile 里面记录全部的数据修改情况,所以即使在备份过程中数据文件被修改过了,恢复时仍然能够通过解析 xtrabackup_logfile 保持数据的一致。
Xtrabackup 的增量备份只能用于 InnoDB 表,不能用在 MyISAM 表上。采用增量备份 MySQL 数据库时 xtrabackup 会依据上次全备份或增量备份目录对 InnoDB 表进行增量备份,对 MyISAM 表会进行全表复制。
流备份(streaming)可以将备份直接保存到远程服务器上。
当执行恢复时,由于复制是不锁表的所以此时数据文件都是不一致的,xtrabackup 使用之前保存的 redo log 对各个数据文件检查是否与事务日志的 checkpoint 一致,执行恢复:
1) 根据复制数据文件时以及之后已提交事务产生的事务日志进行前滚;
2) 将未提交的事务进行回滚。
这个过程就是 MySQL 数据库宕机之后执行的 crash recovery。
增量备份
在 InnoDB 中,每个 page 中都记录 LSN 信息,每当相关数据发生改变,page 的 LSN 就会自动增加,xtrabackup 的增量备份就是依据这一原理进行的。Xtrabackup 将上次备份(完全备份集或者也是一个增量备份集)以来 LSN 改变的 page 进行备份。
所以,要做增量备份第一次就要做一个完全备份(就是将 MySQL 实例或者说要备份的数据库表做一个完全复制,同时记录 LSN),之后可以基于此进行增量备份以及恢复。
增量备份优点:
1) 数据库太大没有足够的空间全量备份,增量备份能有效节省空间,并且效率高。
2) 支持热备份,备份过程不锁表(针对 InnoDB 而言),不阻塞数据库的读写。
3) 每日备份只产生少量数据,也可采用远程备份,节省本地空间。
4) 备份恢复基于文件操作,降低直接对数据库操作风险。
5) 备份效率更高,恢复效率更高。
恢复与还原
backup 的恢复过程中包括恢复和还原两个部分。
我们前面已经说了 xtrabackup 只备份 InnoDB 表的 ibd 文件,而 innobackupex 可以备份包括 InnoDB 表在内的其他存储引擎的表的所有数据文件。由于不同引擎表备份时的不同,也会让恢复过程看起来不一样。
先来看看完全备份集的恢复。
在 InnoDB 表的备份或者更直接的说 ibd 数据文件复制的过程中,数据库处于不一致的状态,所以要将 xtraback_logfile 中尚未提交的事务进行回滚,以及将已经提交的事务进行前滚,
使各个数据文件处于一个一致性状态,这个过程叫做“准备 (prepare)”。
如果你是在一个从库上执行的备份,那说明你没有东西需要回滚,只是简单的 apply redo log 就可以了。另外在 prepare 过程中可以使用参数 –use-memory 增大使用系统内存量从而提高恢复速度。
之后,我们就可以根据 backup-my.cnf 中的配置把数据文件复制回对应的目录了,当然你也可以自己复制回去,但 innobackupex 都会帮我们完成。在这里,对于 InnoDB 表来说是完成“后准备”动作,我们称之为“恢复 (recovery)”,而对于 MyISAM 表来说由于备份时是采用锁表方式复制的,所以此时只是简单的复制回来,不需要 apply log,这个我们称之为“还原 (restore)”。
注:本文档里之所以使用恢复和还原,也是和其他数据库比如 Oracle 看起来一样。
对于增量备份的恢复过程,与完全备份集的恢复类似,只是有少许不同:
1) 恢复过程需要使用完全备份集和各个增量备份集,各个备份集的恢复与前面说的一样(前滚和回滚),之后各个增量备份集的 redo log 都会应用到完全备份集中;
2) 对于完全备机集之后产生的新表,要有特殊处理方式,以便恢复后不丢表;
3) 要以完全备份集为基础,然后按顺序应用各个增量备份集。
流备份和压缩
提到流备份 (streaming) 就要说远程备份和备份压缩,先说流备份吧。
流备份是指备份的数据通过标准输出 STDOUT 传输给 tar 程序进行归档,而不是单纯的将数据文件保存到指定的备份目录中,参数 –stream=tar 表示开启流备份功能并打包。同时也可以利用流备份到远程服务器上。
举例来说,
$ innobackupex --stream=TAR ${BACKUP_DIR}/base | gzip > ${BACKUP_DIR}/base.tar.gz $ innobackupex --stream=TAR ${BACKUP_DIR}/base|ssh somebackupaddr “cat > ${DIR}/base.tar”
当然了,如果你使用了流备份,那么增量备份也就不能用了,因为增量备份需要参考次备份情况,而上次备份却被打包或者压缩了。
在我们现实使用中,更多的使用增量备份,至于归档压缩我们可以通过脚本自主完成。
部分备份和恢复
Xtrabackup 可以只备份 / 恢复部分库表,可以正则模式匹配或者是你想备份库表的列表,但 InnoDB 表必须是独立表空间,同时不能使用流备份功能。
1) 使用正则模式匹配备份部分库表,需要使用参数 –include,语句类似如下:
$ innobackupex --include=’^qb.*’ ${BACKUP_DIR}/part-base
2) 使用数据库列表备份部分库,需要使用参数 –databases,语句类似如下:
$ innobackupex --databases=qb0 qb1 qb2 qb3 ${BACKUP_DIR}/part-base
3) 使用表列表备份部分表,需要使用参数 –tables-file,语句类似如下:
$ innobackupex --tables-list=${CONF_DIR}/tab.conf ${BACKUP_DIR}/part-base
注:在我们的现实应用中,很少会只备份集群中部分库表,所以只是了解此功能即可,若有现实需要可以参考 percona 官方资料以获取更多信息。
能备份部分库表,也就能根据完全备份集进行部分库表的恢复,在现实中很少会用到,但还是说一下吧。
首先在“准备 prepare”的过程中,使用参数 –export 将表导出,这个导出会将每个 InnoDB 表创建一个以.exp 结尾的文件,这些文件为之后的导入过程服务。
$ innobackupex --apply-log --export ${BACKUP_DIR}/base
然后将你需要恢复的表的 ibd 和 exp 文件复制到目标机器,在目标机器上执行导入:
mysql> create table t() engine=innodb; // 此处需要 DBA 手动创建一个同结构的表或表已存在 mysql> ALTER TABLE t DISCARD TABLESPACE; $ cp t.ibd t.exp ${DATA_DIR}/${DB}/ mysql> ALTER TABLE t IMPORT TABLESPACE;
这样的导出导入就可以保住恢复的表可以与数据库其他表保持一致性了。
并行备份
Xtrbackup 还支持并行备份,默认情况下 xtrabackup 备份时只会开启一个进程进行数据文件的备份,若配置参数 –parallel=N 可以让 xtrabackup 开启 N 个子进程对多个数据文件进行并发备份,这样可以加快备份的速度。当然服务器的 IO 处理能力以及对服务器的影响也是要考虑的,所以另一个参数 –throttle=IOS 会与它同时使用,这个参数用来限制备份过程中每秒读写的 IO 次数,对服务器的 IO 是一个保护。
这两个参数 xtrabackup 和 innobackupex 都支持,举例如下:
$ innobackupex --parallel=4 --throttle=400 ${BACKUP_DIR}/part-base
注意:对同一个数据文件只会有一个进程在备份。
其他
Xtrabackup 在备份时主要的工作是做数据文件复制,它每次只会读写 1MB 的数据(即 64 个 page,不能修改),xtrabackup 逐页访问 1MB 数据,使用 innodb 的 buf_page_is_corrupted() 函数检查此页的数据是否正常,如果数据不正常,就重新读取这一页,最多重新读取 10 次,如果还是失败,备份就失败了,退出。
在复制事务日志的时候,每次读写 512KB 的数据,同样不可以配置。