更多精彩内容关注公众哈:爱可生开源社区
本文转载自公众号:图解MySQL
XtraBackup 在 MySQL 备份场景中被广泛使用,大家一定不陌生。我们也在之前的两篇文章中分享了其备份的原理。(详见 [原理解析] XtraBackup全量备份还原& [原理解析] XtraBackup增量备份还原)本文想要描述的是 XtraBackup 恢复时参数 apply-log-only 的作用,不知道大家有没有注意到,这个参数如果不设置,可能会产生数据不一致的惨剧。
使用 XtraBackup 对数据库做备份,实际上就是拷贝 MySQL 的数据文件,为了保证备份数据的最终一致,也会同时拷贝备份过程中的 Redo log。
![041e656767c3d7e7775fdd61ad1d1594.png](https://i-blog.csdnimg.cn/blog_migrate/f936e85492555959a66ed1ce3669c6d2.jpeg)
如图 1 所示,全备开始时,事务 2 尚未提交,Redo log 中仅有事务 2 的一部分数据(B->F),XtraBackup 于是将这一部分数据拷贝到全备文件中。
![82c2c437bcbef024c2bbdb2352902d88.png](https://i-blog.csdnimg.cn/blog_migrate/e44151478e9101380f95db6f5295d2f5.jpeg)
如图 2 所示,增备开始时,事务 2 已经提交,Redo log 中有了事务 2 的完整数据。XtraBackup 于是将事务 2 的后一部分数据拷贝了下来。
![55f034114b9d4dd8fb5ef5f0822e89b9.png](https://i-blog.csdnimg.cn/blog_migrate/c8a048eca483ea4c8d03da9fde7114df.jpeg)
如图 3 所示,恢复时,首先恢复全备中的数据文件,然后回放全备中的 Redo log,回放过程中应用了一部分事务 2(B->F),如果没有设置 apply-log-only,XtraBackup 会在恢复最后一步应用 undo,将这一部分残缺的事务回滚(F->B),就此埋下了祸根。
![08036b5d9ffb4323dc756b3384fb027b.png](https://i-blog.csdnimg.cn/blog_migrate/157f2965c29df2a13286e9ad0e9180c9.jpeg)
如图 4 所示,后续恢复增备文件时,继续回放了事务 2 的后一部分(E->G A->H),导致最终的数据文件中丢失了事务 2 第一部分的数据(B->F),惨剧就发生了。
![dbc894717204ffb43b3c6495e067bc8b.png](https://i-blog.csdnimg.cn/blog_migrate/b76be64eb8fde61ee143989a599e6a1a.jpeg)
如图 5 所示,正确的做法应该是除了最后一个增备,所有的备份恢复都应该设置 apply-log-only 参数(only 指的就是只回放 redo log 阶段,跳过 undo 阶段),避免未完成事务的回滚。如图所示,此时全备恢复后的数据文件才是完整的(包含了B->F)。所有增备恢复完成后的数据也是完整的。
参考:https://www.percona.com/doc/percona-xtrabackup/2.3/xtrabackup_bin/xbk_option_reference.html#cmdoption-xtrabackup-apply-log-only
![ef714211fa9167fbc4fa60d4d660a116.png](https://i-blog.csdnimg.cn/blog_migrate/d3710dfe00ca49219b042066585fef2e.jpeg)