暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

踩坑SQL Server AlwaysOn“数据实时同步”

磊哥谈技术 2019-02-21
1794

    有项目需要系统性能优化,数据库是SQL Server 2014。采用AlwaysOn的同步提交模式将主副本的数据同步到辅助副本,主副本作为生产库使用,辅助副本作为查询库使用。

     有一个业务模块因为业务需求,需要每15s刷新一次数据,刷新出数据后对数据进行打印,并更新打印标志,等待进一步的数据处理,每15s刷新的原始数据会源源不断的进来。由于同步刷新的客户端比较多,刷新频率也算比较高,查询数据的语句也有点复杂,遇到了性能瓶颈。

       遂考虑将每15s刷新数据的操作从原来的主副本迁移到辅助副本来提高系统性能。大家普遍认为采用了AlwaysOn的同步提交模式,主副本和辅助副本的数据肯定是完全一样的。经过测试发现,主副本的数据更改后能够“实时同步到辅助副本”。然后就是大胆的修改程序,每15s从辅助副本检索数据进行打印,然后将对应记录的打印标志更新到主副本数据库,理论上,对主副本数据更新的同时,数据会同步到辅助副本数据库。程序修改完成后,发现系统性能提升明显,然后找了一个客户端测试,没有发现任何问题。然后下午晚些时候对所有客户端进行了程序更新。

       结果,意想不到的事情出现了,第二天业务高并发时间段,竟然出现了对主副本数据库更新的打印标志无法实时同步到辅助副本数据库,造成数据的偶发性重复打印。个别数据的同步延迟竟然超过了1分钟,造成重复打印四次。

       只好亲自去弄清楚AlwaysOn的同步提交模式原理,此模式主要有五个步骤:

  1. 主副本的logwriter把事务修改的日志信息先记入一段内存中的日志缓冲区,然后再写入物理日志文件(日志固化)。

  2. 主副本的logscanner从缓存中或者日志文件中读取日志块,然后把它发送给AlwaysON的日志块解码器。

  3. 主副本将日志块通过网络传送给辅助副本。

  4. 辅助副本接收到日志块后,logwriter把事务修改的日志信息先记入一段内存中的日志缓冲区,然后再写入物理日志文件(日志固化),在日志固化后,辅助副本反馈信息给主副本,主副本在接收到辅助副本完成固化的消息后提交该事务。

  5. 重做(Redo)线程将日志中记录的事务在辅助副本上重新演绎。重做线程每隔固定的时间点,会跟主副本通信,告知它自己的工作进度。



         弄清楚这五个步骤后,就明白这次踩坑,问题出在哪里了,从第4步和第5步,我们可以看到,同步提交模式,事务日志的传输是实时的,在辅助副本上重做事务却是异步的。它保证了数据的完整同步,也保证了系统的性能,但是没有保证数据在辅助副本的实时体现。


        既然同步提交模式无法保证数据在辅助副本的实时体现,那它跟异步提交模式的区别又体现在什么地方呢?经过查询发现,在异步提交模式下主副本无须等待辅助副本完成日志固化,就可以提交事务。因此,主副本数据库事务提交不会受到辅助数据库的影响而产生等待。但是,辅助副本的更新会滞后于主副本的更新,如果发生故障转移,可能会导致某些数据丢失。

          至此,此次踩坑也整明白了。

文章转载自磊哥谈技术,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论