MYSQL备份恢复知识:第六章:恢复原理
备份有两种方式,即逻辑备份和物理备份。逻辑备份时,仅保存了数据,没有保存结构。恢复前,需要初始化数据库并创建DATADIR。将mysqldump导出的数据导入到数据库,导入的结构按照数据库、表一一对应。因此逻辑备份的恢复比较简单,这里不需要进行单独的介绍。本章节主要介绍的是物理备份的恢复。
1. 恢复过程
1) 将所有数据文件拷贝到DATADIR目录中;
2) 将备份的redo归档日志(或redo日志)加载到buffer pool,并生成新的当前数据库的redo日志;
3) 将redo日志中的commit状态的交易apply到数据文件中,所有数据文件达到一致状态;
4) 达到一致状态的数据库,可以正常启动。但是这还不足够,因为它的交易状态不能与其它相关系统保持业务上的一致性。主要原因是应用在binary日志写完成后就会返回成功,但是这是时redo日志的状态有延后,不确定是commit状态;
5) 对比备份的binary日志和undo日志,找到binary提交但是undo状态显示未提交的交易。如果这些交易在redo日志中状态为prepared,将它们置成commit状态。至此,数据文件、binary日志和redo日志全部一致。
2. 物理备份数据的恢复
物理备份数据的恢复分为两个过程,一是恢复数据文件,二是恢复redo和binary日志。恢复数据文件比较简单,仅需要保存到指定位置即可。由于不是一致性备份,因此数据文件需要通过redo日志和binary日志保证一致性。恢复日志时,需要一个校验过程,比较复杂。
先了解一下数据写入的标准流程,也就是默认采用的两段式提交。数据库采用两段式提交时,需要同时对redo日志和binary日志进行校验。数据写入时,redo日志状态为prepare。如果写入操作成功,记录binary日志,客户端返回写入成功,在复制场景下会同步向备库传输。Binary日志完成后,状态同步到redo,完成redo commit。至此,一个完整的写入流程结束。
在数据恢复时,也会遵照数据写入规范。恢复前,首先从备份的redo日志中查找checkpoint lsn,也就是数据文件保持一致的最后时间点。从这个时间点以后,数据文件不能保证一致,需要通过日志提交来实现。首先,将redo日志中committed状态的交易提交到数据文件,使所有数据文件lsn达到redo日志中的最大lsn编号,并且成为一致状态;第二步,检测binary日志,获取已经完成提交的交易记录(XID),与undo对比,找到redo prepared状态的交易,并进行innodb级的提交。
3. 利用Binary日志增量恢复
通过MySQL内置工具mysqlbinlog,可将binary日志转换成ASCII文本,便于阅读,同时用于数据导入。
导入单个文件,
$ mysqlbinlog binlog.000028 | mysql --user=root --password=xxxxxx
导入多个文件,使用空格分开,导入将按照顺序进行,
$ mysqlbinlog binlog.000015 binlog.000016 | mysql --user=root --password=xxxxxx
导入多个文件,从000012到000015,
$ mysqlbinlog binlog.00001[2-5] | mysql --user=root --password=xxxxxx
Binary日志不具备唯一性,如果多次加载会生成重复的数据,专业术语称之为不具备“幂等性“。这依靠表结构的约束来避免。例如,表中存在主键或索引等,在Binary日志再次被导入时,会提示错误并停止执行。也可以通过视图判断,手工指定导入的起止位置,但是这种方式非常不可靠,操作失误的风险极大。或者,引入GTID,保证操作数据的“幂等性”。启用GTID,在my.cnf中添加两个参数:
gtid-mode = on
enforce-gtid-consistency = on
这样,每一次交易都会有一个唯一的GTID,它会记录在binary日志中。不论如何重复加载binary日志,数据都不会被叠加。
当物理备份恢复后,加载binary日志。可以加载全部备份的binary日志,但是为了效率,可以选择从备份结束前的某一个时间点来开始。
CSDN视频课程:
https://edu.csdn.net/lecturer/8135?spm=1002.2001.3001.4144