合并复制的概述
也许读者对下面的实际例子并不陌生,在某一大型企业的分销系统中,销售经理或一些销售骨干人员经常要外出处理业务,将签订的合同通过手边的笔记本电脑传递到总部销售信息数据库。在这一例子中有两个主要的特;征任何销售经理和销售骨干都可以修改销售信息数据库;只有在进行数据传递时才将源数据库与目标数据库相连。在SQL Server 中,合并复制为这一情况提供了较好的解决方案。
合并复制作为一种从出版者向订购者分发数据方法允许出版者和订购者对出版数据进行修改,而不管订购者与出版者是相互连接或断开,然后当所有(或部分)节点相连时便合并发生在各个节点的变化。在合并复制中,每个节点都独立完成属于自己的任务,不像事务复制和快照复制那样订购者与出版者之间要相互连接,完全不必连接到其它节点,也不必使用MS DTC 来实现两阶段提交就可以在多个节点对出版进行修改,只是在某一时刻才将该节点与其它节点相连(此时所指的其它节点并不一定指所有其它节点),然后将所发生的数据变化复制到这些相连节点的数据库中。如果在复制时因更新同一数据而发生冲突,则数据的最终结果并不总是出版者修改后的结果,也不一定包含在某一节点上所做的所有修改。因为各节点都有自主权,都可以对出版物(复制数据)进行修改,这样在按照所设定的冲突解决规则对冲突处理之后,数据库最终的结果往往是包含了多个节点的修改。
可以看出尽管最后所有的数据库都有相同的结果集,但这个结果是在多个节点共同参与下形成的,是多个修改合并到目标数据库的结果。因此合并复制并不维护事务的一致。
与创建快照复制和事务复制出版物相比,当创建一个合并出版物时,SQL Server 会对数据库以及出版表进行以下处理(见图16-54):
(1) SQL Server 把出版表中的每一行都加上一个标识列,这样在表的多个拷贝间能惟一标识出该行。如果基本表上已存在具有ROWGUIDCOL 属性的标识列,则 SQL Server 将自动把其作为复制表的行标识,如果没有,则或在创建出版物过程中这些表被激活时,或在SQL Server Agent 第一次为该出版物提供服务时, SQL Server 将向表中添加一个具有ROWGUIDCOL 属性的rowguid。
(2) SQL Server 添加一个触发器来跟踪每一行或列数据的变化,并把捕捉到的变化存储到几个系统表中,或在创建出版物过程中复制表被激活时,或在SQL Server Agent 第一次为出版物提供服务时,将创建这些跟踪触发器。
(3) SQL Server 把用户跟踪的系统表添加到数据库,来执行冲突的检测,解决和记录。MSmerger_contents MSmerger_tombstone 系统表用来跟踪对出版物中数据的UPDATE、 DELETE、 INSERTS 操作。
16.5.2 合并复制的执行步骤
合并复制的执行需要快照代理和合并代理。其主要步骤是:
(1) 与快照复制、事务复制中快照代理的作用一样,合并复制的快照代理在开始复制之前也要完成二项任务;创建快照文件(同步集合)将存储在分发者的复制目录下;在出版数据库记录同步作业。合并代理将初始快照文件分发给订购者,从而完成订购初始化(出版数据库与订购数据库同步)。
(2) 当在某一节点(订购者)对出版物中表的某一行进行修改时,触发器会触发,并将该行的生成列generation column 设置为零。当合并代理执行时,它把所有生成列为零的合成一组或多组,凡是新的生成列值比原来的大,则用新值替换旧值。
(3) 在进行同步处理时,合并代理把所有生成列值为零的列(被修改的列)复制到所有其它订购者。
(4) 在目标数据库,从节点送来的数据与已存在数据进行合并,合并代理来进行冲突检测,如果未发生冲突则接收复制数据;如果发生冲突,合并代理根据缺省或所设定的冲突解决规则来解决冲突。