本篇文章是SQL Server Replication系列的第五篇,详细内容请参考原文。
这一系列包含SQL Server事务复制和合并复制的详细内容,从理解基本术语和设置复制的方法,到描述它是如何工作的,以及如何监控基本的复制进程。为了充分利用这一篇文章,你需要理解SQL Server数据修改操作,并熟练使用SSMS。第五篇假定你已经熟悉前四篇的内容。
这一系列的前面几篇讨论了如何在多台服务器的环境配置发布。引入了分发服务器、发布服务器和订阅服务器,同时讲解了分发数据库、发布数据库和订阅数据库。也简单的介绍了复制代理。这一篇重点就在复制代理:它是什么,在事务复制进程它扮演什么角色?
代理和作业
事务复制并不是由SQL Server数据库引擎自己执行的。相反,它是由几个外部服务驱动。这些服务被称为SQL Server复制代理。
这些代理有快照代理、日志读取器代理、分发代理。双向复制中还有队列读取器代理。队列读取器代理将订阅服务器上的变更应用到发布服务器上。更多详细内容请参考Books Online.
The agents are Windows programs that connect to the servers involved in your replication scenario and facilitate the data movement.在标准安装复制,代理过程是由SQL Server代理执行的。SQL Server代理对每个复制代理类型有单独的作业步骤类型。
除了复制代理作业,在事务复制配置期间还会创建一些其他的作业。这些作业主要用于清除和问题检查。更多详细内容会在后面讲到。
The Jobs get created at various steps during the setup of replication. The following sections describe which job is created as part of which step.
本地分发(Local Distribution)
当你将服务器配置为分发服务器,部分作业会创建。图5.1显示了完整的列表。除了syspolicy_purge_history不是复制部分。图5.1中其他作业都是由复制创建的维护作业。
图5.1 本地分发维护作业
远程分发(Remote Distribution)
当你在发布服务器上配置远程分发,只会创建一个维护作业(图5.2)。它的任务是从发布服务器上移除过期的订阅。
图5.2 远程分发维护作业
发布
复制中的下一步是创建一个发布。这会在分发服务器上创建两个作业,发布服务器不会创建作业(图5.3)。这两个作业是,"WORK\SQL08R2-ReplA-1"和"WORK\SQL08R2-ReplA-MySecondPublication-1",分别代表日志读取器和快照代理。
图5.3 发布代理
你可以通过查看作业活动监视器下的类别列区分哪个作业代表哪个复制代理,如图5.4所示
图5.4 作业类别
推送订阅
对于每一个订阅服务器会创建一个额外的作业。这个作业代表分发代理。在推送订阅中,这个作业创建在分发服务器上(图5.5)。这里分发代理作业的名称是"WORK\SQL08R2-ReplA-MySecondPublication-WORK\SQL08R2-3".在图5.5中你同样可以看到推送订阅不会在订阅服务器上创建复制作业。所有的代理存在于分发服务器。
图5.5 推送订阅
请求订阅
请求订阅中分发代理存在于订阅服务器上。因此最后一个作业是创建在那上面。图5.6显示了请求订阅。这里分发代理作业的名称是"WORK\SQL08R2-ReplA-MySecondPublication-WORK\SQL08R2-ReplB-031EABCB-0B54-4BAF-A75A-22B9D292FDBC"
图5.6 请求订阅
同样你可以在作业活动监视器下的类别列区分作业是在分发代理下运行。
图5.7 分发代理
代理
At first glance,好像有大量的作业和代理,每一个在不同的时间做不同的事情。然而,当你深入查看时,事务复制实际只有三个主要代理参与:快照代理、日志读取器代理和分发代理。图5.8显示了三个代理的整体情况
图5.8 Agents Overvies
绿色箭头表示读取,红色箭头表示写入。分发代理存在于分发服务器或订阅服务器,取决于订阅模式。
快照代理
快照代理是快照复制的主要扮演者。在事务复制或其他类型的复制,快照代理用于初始化同步所有的复制对象。当然这不是初始化的唯一方法,但它是最方便的方法。
生成快照引入两个步骤。首先,快照代理生成所有复制对象的删除(drop)和创建(create)脚本并将它们保存到快照文件夹。然后它将所有发布表的数据生成BCP文件。所有生成文件的记录保存在分发数据库中。
use distribution
go
select publisher_database_id
,xact_seqno
,type
,article_id
,originator_id
,command_id
,partial_command
,cast(command as nvarchar(max)) as command_text
,command
,hashkey
,originator_lsn
from dbo.MSrepl_commands
代码5.1 MSrepl_commands
你可以运行代码5.1的语句查看BCP文件条目
For snapshot replication a shared lock is kept on all published tables while the BCP files are generated.这允许快照代理来保证数据的事务一致性,但是它阻塞了此时其他试图往这些表写入数据的请求。依赖发布表的大小,这个时间可能会非常长。在快照复制这是保证事务一致性的唯一方法。
然而,在事务发布不再需要表的共享锁。在SQL Server2005,如果事务复制是通过SSMS图形界面配置的,SQL Server使用一个不同的方法生成快照,它允许更大的并发。这就允许快照生成时表发生更改。事务一致性由下面描述的方法来保证:
1、当快照进程启动时,所有发布的表添加表锁。然后在发布数据库的日志文件中写入一个快照进程开始的标记。待到标记被写入后,锁被释放。在没有表锁的情况下生成BCP文件,然而更多细粒度在页级和行级的短暂锁仍然使用。
2、在BCP文件生成完成,另一个标记会写入到发布数据库的日志文件。它标记快照进程的结束。在开始和结束标记之间对发布表所有提交的变更记录到日志文件被日志读取器代理拷贝到分发数据库(类似于其他事务日志条目)。
3、当应用快照到订阅数据库,使用快照文件夹的脚本删除并重新创建表。然后快照文件夹中的BCP文件应用到表(会有表锁)。一直保持表锁到最后一步,分发代理使用日志数据(快照生成期间捕获的)让所有表保持事务一致性状态。
默认SQL Server为每一个发布创建一个新的SQL代理作业执行快照代理。这类作业的名称按照这种格式:<发布服务器>-<发布数据库>-<发布>-<序号>.如果你需要产生一个新的快照,你可以手动启动快照代理作业,或者你可以计划让它在某个时间点运行。
日志读取器代理
日志读取器代理负责为订阅拷贝事务日志记录(已发布的数据库对象的变更)到分发数据库。数据库中对任何对象的变更,SQL Server首先为数据库写一条记录到事务日志。然后应用变更到真实的数据页。当事务提交后,SQL Server forces the log records to disk before signaling success.This process is an integral part of any ACID compliant relational database management system.
这个过程记录了将更改应用到数据页所需的信息。比如在将所有已提交事务对应数据页写入硬盘前突然断电,日志记录允许SQL Server重启后重做变更完成写入操作。
复制系统使用相同的信息,把发布数据库中对发布对象的变更应用到订阅数据库的目标对象。
如果发布数据库中发布对象发生一个DML(比如insert、update、delete)变更或DDL(比如alter table)变更,对这些对象的更改的日志记录被标记为一个复制标志。对其他对象的更改的记录不会被标记,即使它们在同一个事务。
日志读取器代理连接到发布服务器,查找被标记为复制标记的日志记录,然后拷贝这些信息到分发数据库,应用变更到订阅数据库。因为这个进程,复制可能对数据库日志文件的大小有明显的影响。日志文件是一个环形的缓冲区,只要文件中的页不再需要,它就可以被重用。SQL Server自动处理这些,通常不需要干预。
As long as a page is still required,this page and all logically following ones cannot be reused.页一直需要的原因包括长时间运行的事务或者未完成的日志备份。
With replication an additional reason gets added into the mix.只要日志读取器代理没有处理日志文件中的记录,它们就不能被重用。有几种原因会阻止日志读取器代理及时处理记录。最常见的是,分发服务器停机或者日志读取器代理(由于某种原因)没有运行。分发服务器负载过重也有可能引起日志记录的延迟。
在日志文件页不能重用且文件填满的情况下,SQL Server不得不增大日志文件以继续工作。依赖日志文件自增长设置,这个操作可能消耗大量资源。如果日志文件不能继续增长,因为它达到最大文件大小,或因为磁盘已经满了。SQL Server会阻止任何对数据库的写入,直到问题被解决。
如果你配置了复制,留心发布数据库的日志文件的大小。你可以使用代码5.2查看是否是复制阻止了日志的重用。如果log_reuse_wait_desc列包含"REPLICATION",复制就是日志增长的原因。
select name,log_reuse_wait_desc from sys.databases
代码5.2 日志记录重用状态
在发布数据库创建发布时,SQL Server创建了一个SQL代理作业执行日志读取器代理。这类作业的名称按照这种格式:<发布服务器>-<发布数据库>-<序号>.同一个发布数据库下的其他发布会重用这个作业。
这个作业计划默认是随着代理启动时自动启动。这意味着,它始终是运行的,在上面讨论的日志重用,这是首选的方式,你不应该改变这种行为。
分发代理
分发代理负责将数据从分发数据库传递到订阅数据库。分发代理连接到分发服务器读取变更过的记录,然后连接到订阅服务器,按照它们发生的顺序应用这些变更。只有在单一的订阅中确保顺序。如果你在同一数据库中的不同对象上有两个发布,而且发布对应的订阅在相同的订阅数据库中,则只在保证每一个发布中的顺序,不能保证不同发布之间的顺序。
默认SQL Server为每一个订阅创建一个作业执行分发代理。这个作业在分发服务器(推送订阅)或订阅服务器(请求订阅)上执行。推送订阅分发作业的名称按照这种格式:<发布服务器>-<发布数据库>-<发布>-<订阅服务器>-<序号>
请求订阅分发作业的名称稍有不同:<发布服务器>-<发布数据库>-<发布>-<订阅服务器>-<订阅数据库>-<GUID>
作业
在文章开始就提到,复制系统需要一些额外的作业:
->代理历史记录清除:<分发数据库名称>
代理历史记录清理作业删除所有历史记录——从分发数据库跟踪的代理性能。它使用"历史记录保持期"设置分发数据库决定哪些记录可以删除。
分发服务器上的每一个分发数据库有一个这种类型的作业。
->分发清除: <分发数据库名称>
这个作业从分发数据库删除旧的事务信息。它检查是否所有订阅获取到每一行记录,然后依据检查和复制保持期设置决定哪些记录可以删除。如果没有及时获取事务信息,订阅会被这个作业标记为停用。这个作业也定期刷新分发数据库中的表的统计信息。
分发服务器上的每一个分发数据库有一个这种类型的作业。
->过期的订阅清除
发布保持期内没能连接到订阅服务器,这个作业会删除订阅。这个作业在分发服务器和发布服务器上运行。
分发服务器和发布服务器各有且仅有一个作业。
->重新初始化未通过数据验证的订阅
这个作业识别订阅数据验证错误,并设置为重新初始化。数据验证是一个可以用来验证发布服务器和订阅服务器之间的数据一致性的过程。详细信息参考Validating Replicated Data in Books Online.
->复制代理检查
这个作业监视复制代理。它会在Windows事件日志创建一个条目来报告失败代理在分发数据库中的状态。
-><分发数据库名称>的复制监视刷新器
复制监视器使用此作业刷新缓存查询。
上述作业的具体操作参考:https://www.cnblogs.com/zerocc/p/3208621.html
总结
在这一篇,我描述了复制代理的内核。我们详细地查看了每个复制代理的目的。我们还讨论了复制助手作业以及它们执行的任务。