MySQL 5.6对于Xtrabackup的影响

组提交优化

最近QA在对InnoSQL-5.5.30-v5版本做回归测试时发现数据不一致的问题,简单来说这个测试用例为在主机上进行全备后恢复,会发现数据不一致的情形。因为我们使用全INSERT操作来进行测试,所以可以非常简单的发现不一致的情形。但是这些测试在我们之前的v2版本中都是没有问题的。由于InnoSQL非常强调数据的一致性,因此这个问题在组内得到了极大的关注。小伙伴们测试了多个版本,发现官方MySQL 5.5、InnoSQL 5.5.20-v2版本都没有问题,但是官方MySQL 5.6和InnoSQL 5.5.30-v5版本都有这个问题。经过多方面的定位,最终确定了这个问题的源头——MySQL组提交的优化。

大家或许已经知道MySQL 5.6中修复了组提交的bug,这个修复最早是由MariaDB开发团队的大牛Kristian完成的,MySQL 5.6也借鉴了这样的实现,即一次fsync可以刷新多个事务的提交。在MySQL数据库中,组提交存在于上层binlog也存在于下层的InnoDB引擎层。来看一下组提交在MySQL 5.6中的实现:
MySQL 5.6对于Xtrabackup的影响-MySQL社区 Inside MySQL Group

从上图可以看到,在InnoDB存储引擎层每次每个事务进行prepare操作,都需要触发一次fsync操作,以此确保事务的prepare日志一定写入到redo日志(当然,InnoDB引擎本身支持组提交,可能一次fsync刷新多个事务的prepare日志,但是这个完全是无法控制的行为)。然后,一个组提交中的事务依次向MySQL的二进制日志写日志,这个写操作是缓存写,最后写完进行一次fsync操作。即一个fsync将多个事务的日志写入到了二进制日志,也就是通常所说的组提交。最后完成InnoDB引擎层面的提交操作,这个操作主要是将undo日志放入到History链表,释放锁等相关资源。但是与MySQL 5.5不同是,最后InnoDB引擎层提交操作不再需要fsync

最后这样优化的优化也是Kristian提出并实现的,原因很简单,因为即使InnoDB引擎层的redo日志丢失,但是由于binlog日志已经写入(fsync确保),恢复时只要确定写入binlog的日志在InnoDB引擎层全部提交即可。可以看出,这个优化进一步减少了数据库的fsync次数,从而整体上提升了数据库的性能。InnoSQL 5.5修复了组提交的bug,同时也引入了这个优化。

对Xtrabackup的影响

但是,任何优化可能都会存在一些潜在的影响。这就是为什么MySQL 5.6和InnoSQL 5.5备份会导致数据不一致的问题。我们来看Xtrabackup的内部过程,这里进考虑InnoDB表的备份:

  1. 记录redo日志的LSN,记为lsn1
  2. 拷贝ibdata,*.ibd表空间文件
  3. flush tables with read lock
  4. 记录binlog位置,记录当前redo日志为lsn2
  5. unlock tables
  6. 拷贝lsn1至lsn2的redo日志

但是在MySQL 5.6中xtrackup会遇到问题,因为事务最后提交不再需要fsync操作,这意味这第6步骤拷贝的日志可能会不包括那些已经在步骤4中写入binlog的那些事务,而Xtrabackup对InnoDB的恢复仅通过redo日志回放。虽然,Xtrabackup备份出来的InnoDB数据文件还是一致的,但是这些数据与binlog的位置是不一致的。那么当通过备份重新建立一个slave服务器时,就可能会导致出错。Xtrackup 2.2.3版本解决了这个问题,即在执行步骤6时,先执行一步FLUSH ENGINE LOGS操作,确保重做日志通过fsync刷新到磁盘,从而避免binlog与备份文件的不一致。

总结

各位在使用MySQL 5.6、MariaDB 10.0、InnoSQL版本时,务必确保Xtrabackup已经升级到了2.2.3版本。最后,感谢QA组的同事们,每次在InnoSQL新版本发布前后,总能帮助我们发现很多“奇奇怪怪”的问题

发表评论

8 条评论
  • #6 hQruK 

    万 v部 A 片 高c清 国产.日韩 http://www.288D.pW

  • #5 fmohz 

    打开 288d.pw 都是 浪美眉

  • #4 爱奇趣分享网 

    来瞅瞅啦~

  • 板凳 李大玉 

  • 椅子 李大玉 

    还想请教一下,prepare log有什么用途呢,记录了什么?

    • 姜 承尧
      姜承尧 

      为了保证binlog与InnoDB的事务一致,采用了二阶段事务机制,所以需要先prepare

  • 沙发 李大玉 

    写得非常好,以前一直以为group commit只有binlog,其实redo 也有组提交。这里有个小疑问:安装你的说法:5.5的版本在commit的时候(如果只有一个事务),是否存在3次fsync?第一次为redo prepare的 log,第二次为binlog,第三次为InnoDB引擎层提交的fsync;

相关文章
MySQL 8.0.3性能大杀器 —— CATS
MySQL 8.0.3性能大杀器 —— CATS
2017年MySQL数据库技术嘉年华 —— 有态度的技术大会
2017年MySQL数据库技术嘉年华 —— 有态度…
IMG社区MySQL技术沙龙南京站圆满结束
IMG社区MySQL技术沙龙南京站圆满结束
改朝换代:MySQL Group Replication
改朝换代:MySQL Group Replication
数据库行业的朋友圈内幕,不知道就没法混了
数据库行业的朋友圈内幕,不知道就没法…
Inside MySQL Group社区启用新LOGO
Inside MySQL Group社区启用新LOGO
Oracle MySQL ACE. Author of Inside MySQL and MySQL Core Series. Great at MySQL performance tuning、troubleshooting、systems availability and scalability、capacity planning, etc.

一触即发,2017年,数据库世界的诸神之战