我这里有一个奇怪的问题。我在我们的测试复制设置中尝试使用“从 lsn 初始化”,现在已经破坏了我们一个数据库中的所有出版物,从头开始重建(应用新快照)并没有解决问题。
在复制监视器中,分发代理连续运行并报告:
没有可用的复制事务
Tracer 令牌报告:
- 发布者到分销商:00:00:02
- 订阅者的分销商:待定...
- 总延迟:待定...
当我使用以下方法调查分发日志时:
SELECT time,
CAST(comments AS XML) AS comments,
runstatus,
duration,
xact_seqno,
delivered_transactions,
delivered_commands,
average_commands,
delivery_time,
delivery_rate,
delivery_latency / (1000 * 60) AS delivery_latency_Min,
agent_id
FROM dbo.MSlogreader_history WITH (NOLOCK)
WHERE agent_id = 5
ORDER BY time DESC;
SELECT *
FROM dbo.MSdistribution_history
WHERE agent_id = 125
ORDER BY time DESC;
我可以从以下位置看到最新的 xact_seqno:
- LogReader 代理为:0x00000378000384880003
- 分销代理为:0x000CA68B000010A8000A000000070000
作为对其他数据库之一的比较(去同一个订阅者),我得到:
- LogReader 代理是:0x00000D140001F52A0003
- 分发代理为:0x00000D140001F52A0003000000000000
对我来说,分发代理似乎正在记住旧的损坏 xact_seqno(从我在测试“从 lsn 初始化”时出错时起),但现在它似乎已经永久地破坏了该数据库的所有复制。
服务器:
- PubA - 一个发布者托管多个可复制的数据库
- Dist - 一个独立的分销商
- SubA - 第一个订阅者
- SubB - 第二个订阅者
数据库:
- PubA.DB1 = 工作正常的发布者数据库
- PubA.DB2 = 已损坏的发布者数据库
- SubA.PullWorking1 = 第一个订阅者拥有来自 DB1 的有效拉取订阅
- SubA.PullBroken2 = 第一个订阅者也从 DB2 获得了损坏的拉取订阅
- SubA.PushWorking1 = 第二个订阅者有一个来自 DB1 的有效推送订阅
- SubA.PushBroken2 = 第 2 个订阅者也有来自 DB2 的中断推送订阅
出版物:
- PubA.DB1.PushPub_works
- PubA.DB1.PullPub1_works
- PubA.DB1.PullPub2_works
- PubA.DB2.PushPub_broken
- PubA.DB2.PullPub_broken
好的,以防万一有人遇到此问题,我找到了解决方法(尽管不是根本原因)。
使固定
SELECT publication, '0x' + CONVERT(VARCHAR(32),MAX(transaction_timestamp),2) as LastPubLSN FROM dbo.MSreplication_subscriptions GROUP BY publication
DECLARE @Publisher sysname = N'PubA', @PubDB sysname = N'DB2', @Publication sysname = N'PushPub_Broken'; SELECT TOP 1000 trans.entry_time, trans.publisher_database_id, trans.xact_seqno FROM dbo.MSpublications AS p JOIN master..sysservers AS srv ON srv.srvid = p.publisher_id JOIN dbo.MSpublisher_databases AS d ON d.publisher_id = p.publisher_id AND d.publisher_db = p.publisher_db JOIN dbo.MSrepl_transactions AS trans ON trans.publisher_database_id = d.id WHERE p.publication = @Publication AND p.publisher_db = @PubDB AND srv.srvname = @Publisher AND trans.xact_seqno >= p.min_autonosync_lsn ORDER BY trans.entry_time DESC
DECLARE @PubDB INT = 5 /* use the publisher_database_id retrieved above */ select * from MSrepl_commands with (READPAST) where publisher_database_id = @PubDB and command_id = 1 and type <> 30 and /* 30 = normal repl commands */ type <> -2147483611 /* -2147483611 = is ignored by sp_MSget_repl_commands (it's snapshot related?) */
EXEC sp_setsubscriptionxactseqno @publisher = 'PubA', @publisher_db = 'DB2', @publication = 'PushPub_Broken', @xact_seqno = 0x0000... /* New valid LSN to start from (step 3) */
我是怎么找到的
因此,在找到并试用sp_setsubscriptionxactseqno以及知道如何将 LastLSN 应用于订阅者之后,我在分发服务器上运行了跟踪,我能够看到序列是:
自己运行第一个命令,我可以看到返回了 2 个结果集,其中第二个包括错误的 LSN。显然,这个过程中的某些东西导致它覆盖了我希望它应用的 LSN。
找到代码
sp_MSget_repl_commands
,我能够确定它是:从那里,我找到了罪魁祸首记录并能够重新启动复制(在重新同步我的数据之后)