我已经通过拉方法在两个Server 2012数据库之间建立了合并复制设置。
有几个合并复制会影响不同的表集(实际上,每个表有3组2-5个表)。DBs中没有外键将它们连接到其他表。
订阅服务器和发布服务器都在更改复制表中的数据。通常,发行者每天每12小时有超过800 k的插入,订阅服务器上的插入量约为300 K;几乎没有更新。
此外,我还启用了简单的过滤--几乎所有合并的表都检查一个bit NULL列为NULL;过滤器中没有joins。主数据库在这些表中有大约80G的数据,订阅服务器由于过滤而有大约30G的数据。所有这些筛选列都有索引。表按-原样复制,没有选择性列。
在大多数表中,主键范围增加到10M (以确保它们不会经常被重新放置)。
已启用架构复制,但不会发生架构更改。
合并复制保留期设置为2天(结果是存储了3天的数据--在MSmerge_contents表中大约有3M行)。
复制作业计划每15分钟启动一次。
问题是--有时,当同步作业启动时,它会阻止此DB中所有合并副本中所有表上的所有插入/更新。它似乎只发生在复制过程结束时,而不管同步行数(对于某些运行,可能只有1-2更改/添加行),并且可以持续5-10分钟,这是不可接受的。
我跟踪了在锁定时执行的过程,并捕获了使用Server事件探查器并手动启动它的阻塞报告(它似乎是安全的):
<blocked-process-report monitorLoop="201058">
<blocked-process>
<process id="process38d8dd0c8" taskpriority="0" logused="1268" waitresource="OBJECT: 5:690456609:0 " waittime="5002" ownerId="4004024182" transactionname="UPDATE" lasttranstarted="2015-03-11T16:08:39.890" XDES="0x1b253649e8" lockMode="IX" schedulerid="1" kpid="5132" status="suspended" spid="84" sbid="0" ecid="0" priority="0" trancount="1" lastbatchstarted="2015-03-11T16:08:39.880" lastbatchcompleted="2015-03-11T16:08:39.880" lastattention="2015-03-11T15:29:13.240" hostname="COMP-177" hostpid="2976" loginname="user" isolationlevel="read committed (2)" xactid="4004024182" currentdb="5" lockTimeout="4294967295" clientoption1="673316896" clientoption2="128056">
<executionStack>
<frame line="46" stmtstart="4398" stmtend="4936" sqlhandle="0x030005008910305b49b9150057a4000000000000000000000000000000000000000000000000000000000000"/>
<frame line="1" stmtstart="30" sqlhandle="0x020000003f32c4168d189e55398799d8e66489e031b7fa8b0000000000000000000000000000000000000000"/>
<frame line="1" stmtstart="30" sqlhandle="0x02000000538a8c182d9ff435ad6897538e470878728dfd940000000000000000000000000000000000000000"/>
</executionStack>
<inputbuf>
set nocount on;update [replicated_table] set CHECK_CI='1456',DATE_CHECK_CI=getdate(),DATE_MODIFY=getdate(),where R_ID='284598973'
</inputbuf>
</process>
</blocked-process>
<blocking-process>
<process status="running" spid="150" sbid="0" ecid="0" priority="-5" trancount="2" lastbatchstarted="2015-03-11T16:08:39.347" lastbatchcompleted="2015-03-11T16:08:21.833" lastattention="1900-01-01T00:00:00.833" clientapp="Microsoft SQL Server Management Studio - Query" hostname="COMP-120" hostpid="9460" loginname="userp" isolationlevel="read committed (2)" xactid="4004019824" currentdb="5" lockTimeout="4294967295" clientoption1="673319008" clientoption2="390168">
<executionStack>
<frame line="366" stmtstart="32078" stmtend="32458" sqlhandle="0x0300ff7fa885d0f933812f012ba3000001000000000000000000000000000000000000000000000000000000"/>
<frame line="1" sqlhandle="0x010005002698da17601c849b1d00000000000000000000000000000000000000000000000000000000000000"/>
</executionStack>
<inputbuf>
exec sp_MSmakegeneration </inputbuf>
</process>
</blocking-process>
</blocked-process-report>sys.sp_MSmakegeneration执行会阻止所有其他活动。据我所知,这个过程正在生成要复制的行列表。我可以理解它可以运行一段时间--但是为什么它阻止在所有启用合并的表上进行其他插入/更新?不管哪个出版物是同步的-所有启用合并的表(即使是来自此DB中的另一个出版物)也停止工作。
等待对象waitresource="OBJECT: 5:690456609:0 "是MSmerge_genhistory表。所以,它在那张桌子上挡住了,但为什么?
我试图捕捉这个过程的实际执行计划--我得到了14k行XML,但没有发现任何可疑之处(没有明显的表扫描或其他繁重的活动)。
除了generation_leveling_threshold选项在问题调查期间增加到10000之外,复制设置大多是默认的。没什么用。
Server 2012诉11.0.5058.0
默认隔离级别设置为读取提交的快照;这些插入/更新只是普通的插入/更新,不更改隔离级别或启动显式事务。
我可以在工作日后成功地同步服务器(当没有人接触DB时),它在20-30分钟内运行正常(同时传输一整天的数据),但是我需要连续同步(延迟15-20分钟是可以的)。
我在谷歌上搜索了这个问题--很多人的合并复制由于大量的数据变化(从100万行开始)而停滞不前,但与我的问题没有任何相似之处。
发布于 2015-04-03 21:13:13
我个人不建议在这种情况下设置合并复制。但是,由于我没有办法(除了做这个工作或开发我自己的复制解决方案),我花了两周的时间做实验,找到了一个解决方案。
使用此功能,我能够成功地同步3台服务器,在工作日期间每分钟有3-10k插入/更新,没有重大延迟。
https://dba.stackexchange.com/questions/95025
复制相似问题