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;

相关文章
IMG社区MySQL技术沙龙南京站圆满结束
IMG社区MySQL技术沙龙南京站圆满结束
改朝换代:MySQL Group Replication
改朝换代:MySQL Group Replication
数据库行业的朋友圈内幕,不知道就没法混了
数据库行业的朋友圈内幕,不知道就没法…
Inside MySQL Group社区启用新LOGO
Inside MySQL Group社区启用新LOGO
MySQL 5.7 semi-sync 1024 bug 修复
MySQL 5.7 semi-sync 1024 bug 修复
MySQL超越Oracle了?
MySQL超越Oracle了?
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年,数据库世界的诸神之战