初始化发布或订阅后,合并复制将跟踪并枚举对已发布表中数据的所有更改。 通过触发器(复制为每个已发布的表创建)和发布和订阅数据库中的系统表跟踪更改。 这些复制系统表填充了元数据,这些元数据指示应传播哪些更改。 在同步过程中,“合并代理”运行时,代理会枚举变更,然后根据需要将其应用于发布服务器和订阅服务器。
更改跟踪
合并复制使用以下触发器和系统表来跟踪所有已发布表的更改:
MSmerge_ins_<GUID>:插入触发器(此触发器的 GUID 值和其他触发器派生自sysmergearticles)MSmerge_upd_<GUID>:更新触发器MSmerge_del_<GUID>:删除触发器MSmerge_contentsMSmerge_tombstoneMSmerge_genhistory
合并复制使用以下额外的系统表来跟踪筛选表的更改:
MSmerge_partition_groupsMSmerge_current_partition_mappingsMSmerge_past_partition_mappings
注释
列出的系统表供数据库中的所有合并发布和订阅使用;例如,如果发布数据库中有多个发布,则 MSmerge_contents 包含所有发布中文章的项目。
更改未筛选表的跟踪
系统表
用于未筛选和筛选表的系统表包含以下元数据:
对于数据库中已发布表中插入或更新的每一行,
MSmerge_contents都包含一行。对于从数据库中已发布表中删除的每一行,
MSmerge_tombstone都包含一行。MSmerge_genhistory包含一行对应于每一代。 一代是传递给发布者或订阅者的更改的集合。 每次运行合并代理时,代系都会被关闭;数据库的后续更改将添加到一个或多个开放代系中。
更改跟踪过程
以下更改跟踪过程用于所有未筛选的表:
在已发布的表中发生插入或更新时,
MSmerge_ins_<GUID>或MSmerge_upd_<GUID>触发器会触发,并将一行插入到MSmerge_contents系统表中。MSmerge_contents的rowguid列包含插入或更新的行的 GUID,表示下次发生同步时,用户表中相应的插入或更新行应发送给发布者或订阅者。 如果后续更新发生在用户表中的某一行上,则会更新该MSmerge_contents行以反映此状态。当对已发布的表进行删除时,
MSmerge_del_<GUID>触发器会触发,并将一行插入到MSmerge_tombstone系统表中。MSmerge_tombstone的rowguid列包含删除的行的 GUID,表示下次发生同步时,应向用户表中相应已删除行的发布者或订阅者发送删除。 如果已删除的行在MSmerge_contents中被引用(因为自上次同步以来该行已被插入或更新),那么该行将从MSmerge_contents中删除。
更改已筛选表的跟踪
系统表
除了上一部分所述的系统表外,发布数据库中的三个表还包含用于跟踪筛选表更改的元数据:
MSmerge_partition_groups包含发布中定义的每个分区的一行。 分区可以是:明确使用“发布属性”对话框的
sp_addmergepartition或“数据分区”页面定义。如果订阅者需要的分区在
MSmerge_partition_groups中还没有条目,则在订阅者同步时自动创建。
对于
MSmerge_contents和MSmerge_partition_groups中的每个唯一行组合,MSmerge_current_partition_mappings都包含一行。 例如,如果用户表中的一行属于两个分区,并且该行已更新,则会插入MSmerge_contents一行以反映更新,并且插入两行MSmerge_current_partition_mappings,以指示更新行属于这两个分区。对于不再属于给定分区的每一行,
MSmerge_past_partition_mappings都包含一行。 在下列情况下,将行移出分区:删除该行。 如果从用户表中删除一行,则会插入一行到
MSmerge_tombstone,并插入一行或多行到MSmerge_past_partition_mappings。用于筛选的列中的值已更改。 例如,如果参数化筛选器取决于公司总部所在的州,而公司搬迁了,那么关于该公司的行(以及其他表中的相关行)可能会从一个销售人员的数据分区转移到另一个销售人员的数据分区。 如果更新某一行以致其不再属于分区,则会在
MSmerge_contents中插入或更新一行,并在MSmerge_past_partition_mappings中插入一行或多行。
注释
如果使用每个分区有一个订阅的非重叠分区(sp_addmergearticle 的 @partition_options 参数的值为 3),则不使用系统表 MSmerge_current_partition_mappings 和 MSmerge_past_partition_mappings 来跟踪行的分区映射,因为每一行只属于一个分区,并且只能在一个订阅者上进行更改。
更改跟踪过程
前面介绍的过程(在 未筛选表的更改跟踪部分)还用于筛选表,并添加以下内容:
在已发布的表中发生插入时,除了将数据更新或插入到
MSmerge_contents,还会为每个包含该行的分区在MSmerge_current_partition_mappings中添加分区映射。当在已发布的表上发生更新时,除了更新或插入到
MSmerge_contents中的数据外,如果该行所属的每个分区的MSmerge_current_partition_mappings中不存在分区映射,则添加一个。 如果更新导致一行从一个分区移动到另一个分区,则在MSmerge_current_partition_mappings中会更新一行,并在MSmerge_past_partition_mappings中添加一行。当对已发布的表进行删除时,除了将一行插入到
MSmerge_tombstone中外,还将从MSmerge_current_partition_mappings中删除一行,并将一行添加到MSmerge_past_partition_mappings中。
更改枚举
系统表和过程
合并代理运行时,使用多个系统表和存储过程枚举更改:
MSmerge_genhistory包含一行对应于每一代。 一代是传递给发布者或订阅者的更改的集合。 每次运行合并代理时,代系都会被关闭;数据库的后续更改将添加到一个或多个开放代系中。sysmergesubscriptions包含有关订阅的信息,包括节点发送和接收的上一代更改记录。 在发布数据库中,此表包含用于发布者的一行和用于每个订阅者的一行。 在订阅数据库中,此表通常包含订阅方和发布方的一行。MSmerge_generation_partition_mappings仅用于筛选表,记录给定生成是否包含与给定分区相关的任何更改。 发布数据库中的此表包含一行,对应于MSmerge_genhistory和MSmerge_partition_groups中每一行的唯一组合。sp_MSmakegeneration在枚举过程开始时关闭所有打开的代。sp_MSenumchanges枚举表的更改(在此过程中还使用了几个名称以sp_MSenumchanges开头的相关过程)。sp_MSgetmetadata确定是否应将一个节点的更改作为插入、更新或删除应用于另一个节点。
更改枚举过程
在更改枚举过程中会发生以下过程:
系统过程
sp_MSmakegeneration称为:对于未筛选的表和已筛选的表,此过程将关闭
MSmerge_genhistory中引用的所有打开的代(关闭的代在列genstatus中的值为1或2)。对于筛选表,此过程将填充系统表
MSmerge_generation_partition_mappings。 如果生成包含一个或多个与分区相关的更改,则会将一行插入到系统表中。 如果某个世代不包含与特定分区相关的任何更改,则不会在MSmerge_generation_partition_mappings中插入行,并且不会为接收该分区的任何订阅者枚举更改。
将调用存储过程
sp_MSenumchanges和相关过程。 这些过程枚举自上次同步发生以来发生的更改:过程首先根据表
sysmergesubscriptions中列sentgen(发送的最后一代)和recgen(接收的最后一代)确定枚举开始的代。例如,在确定必须为给定订阅者枚举哪些代的更改时,将比较订阅者的
sentgen(存储在发布数据库中)和订阅者的recgen(存储在订阅数据库中)。 如果值相同(这表明订阅者已成功接收到从发布者发送的最后一代),则从MSmerge_genhistory中的下一代开始枚举更改。 如果值不相同,则使用两个值的下限来确保发送所有必需的更改。然后,程序列举更改:
对于未筛选的表,枚举了
sentgen或recgen中生成后的几代中包含的所有更改:MSmerge_genhistory与MSmerge_contents和MSmerge_tombstone联接,以确定必须发送哪些更改。对于已筛选的表,
MSmerge_generation_partition_mappings联接到:MSmerge_current_partition_mappings和MSmerge_contents,以及MSmerge_past_partition_mappings和MSmerge_tombstone,以确定哪些更改与订阅者接收的分区相关。
调用存储过程
sp_MSgetmetadata以确定更改是否应作为插入、更新或删除应用。 此时,将执行冲突检测和解决;有关详细信息,请参阅 合并复制如何检测和解决冲突。
相关内容
- 合并复制
- MSmerge_contents (Transact-SQL)
- MSmerge_current_partition_mappings
- MSmerge_generation_partition_mappings (Transact-SQL)
- MSmerge_genhistory(Transact-SQL)
- MSmerge_partition_groups (Transact-SQL)
- MSmerge_past_partition_mappings (Transact-SQL)
- MSmerge_tombstone (Transact-SQL)
- sp_addmergearticle (Transact-SQL)
- sp_addmergepartition(Transact-SQL)
- sysmergearticles (Transact-SQL)
- sysmergesubscriptions (Transact-SQL)
- 连接过滤器
- 参数化筛选器 - 参数化行筛选器