SQL Sever AlwaysOn的数据同步原理
1. SQL Server AlwaysOn数据同步基本工作
AlwaysOn 副本同步需要完成三件事:
1.把主副本上发生的数据变化记录下来。
2.把这些记录传输到各个辅助副本。
3.把数据变化在辅助副本上同样完成一遍。
这3件工作主要由以下4个线程完成
Log Writer线程:当任何一个SQL用户提交一个数据修改事务时,它会负责把记录本次修改的日志信息先记入一段内存中的日志缓冲区,然后再写入物理日志文件(日志固化)。
Log Scanner工作线程:位于主副本所在SQL Server上。这个线程专门负责将日志记录从日志缓冲区或者日志文件里中读出,打包成日志块,发送给各个辅助副本。由于它的不间断工作,才使主副本上的数据变化,可以不断地向辅助副本上传播。
固化(Harden)线程和重做(Redo)线程:位于辅助副本所在的SQL server上。固化线程会将主副本Log Scanner所发过来的日志块写入辅助副本的磁盘上的日志文件里(这个过程被称为"固化")。而重做线程,则负责从磁盘上读取日志块,将日志记录翻译成数据修改操作,在辅助副本的数据库上完成。
这些线程在工作上各自独立,以达到更高的效率。Log Scanner负责传送日志块,而无须等待Log Writer完成日志固化;辅助副本完成日志固化以后就会发送消息到主副本,告知数据已经传递完毕,而无须等待重做完成。其设计目标,是尽可能地减少AlwaysOn所带来的额外操作对正常数据库操作的性能影响。
AlwaysOn的数据同步有可分为异步提交和同步提交
2. AlwaysOn同步提交模式
在同步提交模式下由可分为 辅助副本发出同步请求和主副本发出同步请求。
2.1 辅助副本发出同步请求
此情况,主要发生在辅助副本刚刚加入可用性组、或者网络等原因主副本出现差异、或者辅助副本出现脏页(物理)等少数情况下。
步 骤 |
行 为 |
1.连接 | 辅助副本通过主副本的镜像端点建立两者之间的连接。 |
2.请求数据 |
辅助副本发出一个请求到主副本,要求主副本发送日志块。辅助副本和主副本 会协商出一个日志块的LSN初始位置以及一些其他的信息。 |
3.运行Log Scanner |
在主副本上,Log Scanner的工作线程开始工作。Log Scanner负责将日志块 传送到辅助副本。 |
4.固化和重做日志 |
辅助副本会使用固化(Harden)线程和重做(Redo)线程的工作线程来处理 Log Scanner发送过来的日志块,固化线程将日志块固化到辅助副本的磁盘上 ,而重做线程负责将日志中记录的事务在辅助副本上重新演绎。 |
5.反馈进度 |
每当辅助副本收到3条来自主副本的消息的时候,就把固化和重做的进度作为 一个消息返回给主副本。如果超过1秒还没收到3条消息,进度消息也会被返回。 反馈到主副本的消息里包含了哪些LSN已经在辅助副本上被重做和固化。 |
2.1 主副本发出同步请求,即客户端提交SQL请求触发的同步请求
步 骤 | 行 为 |
1.提交事务 | 在主副本上运行COMMIT TRAN命令来提交事务. |
2.写入到本 |
在主副本上,COMMIT TRAN命令会被写成一条日志记录(此时记录还在主数据库的日志缓存中). 然后主副本上的log writer工作线程会把直到COMMIT命令为止的所有日志记录组成一个日志块 从缓存写入到磁盘上的LDF文件中。当日志被写入到磁盘之后,主数据库就开始等待来自辅助副本 的消息来确认日志在辅助数据库上被成功写入磁盘。在这之前,该事务提交操作会保持等待。 |
3.扫描日志 |
当日志块开始被从缓存写入到磁盘上时,它也会发信号给Log Scanner工作线程,告诉 Log Scanner“日志已经准备好了,可以被发送到辅助副本上”。Log Scanner从缓存中取出 日志块,把它发送给AlwaysOn的日志块解码器(Log Block Cracker)。解码器会搜索日志 中那些需要特别处理的操作,比如file stream操作,文件增长等。解码器会把这些操作作为 一个消息发送给辅助副本。一旦日志块被解码完毕,整个日志块也会被作为消息发送给辅助副本. |
4.处理日志块消息 |
日志块消息在辅助副本上得到处理。固化线程负责将日志固化到磁盘上。然后日志被保存到辅助 数据库的日志缓存中,重做线程从缓存中获得日志块并开始执行重做操作. |
5.反馈进度 |
每当辅助副本收到3条来自主副本的消息时,就把固化和重做的进度作为一个消息返回给主副本。 如果超过1秒还没收到3条消息,进度消息也会被返回。进度信息中包含当前哪些LSN被固化了, 哪些LSN已经被重做了。由于重做线程晚于固化操作启动,被固化的LSN可能会多于被重做的LSN. |
6.完成提交 | 主数据库受到了辅助副本来的确认消息,完成事务提交处理并向客户端发送一条确认消息. |
2. 补充说明
- 在同步提交模式下,日志块必须在主副本和辅助副本上都被固化到磁盘上,事务才能真正在主数据上提交。但是它并不要求日志在辅助副本上完成重做,这样可以减轻对主副本的性能影响。
- 进入DISCONNECTED或"NOT SYNCHRONIZING"状态后,即使可用性副本处于同步提交模式,事务也不需要等待该副本的响应就可以在主副本上提交。
- 如果为当前主副本配置了异步提交可用性模式,则它将通过异步方式为所有辅助副本提交事务,而不管这些副本各自的可用性模式设置如何。
- 它可以保证事务日志是同步的,也就是可以保证不丢失数据,但不能保证数据变化没有延时,这是由于辅助副本在接收主副本传来的Trans log时,首先将其缓到本地Log Cache,接着强制硬化到本地Ldf,然后随即向主副本告知你可以commit了,但注意,此时的硬化到本地ldf并非本地数据已经变化,这是因为辅助副本将trans log硬化到本地的同时,它是使用一个异步进程去redo这些trans log产生的Page变化到Data文件的,所以数据的延时就是肯定的了。
3.AlwaysOn异步提交模式
- 当辅助副本处于异步提交模式下时,主副本无须确认该辅助副本已经完成日志固化,就可以提交事务。因此,主数据库事务提交不会受到辅助数据库的影响而产生等待。
- 对于主副本和辅助副本相隔很远而且不希望小错误影响主副本性能的灾难恢复方案,异步提交模式将会很有用。而且,由于主副本不会等待来自辅助副本的确认,因而辅助副本上的问题从不会影响主副本。
- 在异步提交模式下,辅助副本会尽量与自主副本的日志记录保持一致。不过,即使辅助数据库和主数据库上的数据事实上是同步的,可用性组也始终认为辅助数据库处于“SYNCHRONIZING”状态(即“未同步”状态)。
部分内容参照书籍《SQL Server 2012 实施与管理实战指南》,感谢原作者。