SQL SERVER复制拓扑结构中,订阅端宕机后的处理.....(一)

前提:本次描述的是SQL SERVER 2008R2版本,其它版本没有测试,复制类型主要是Transaction Replication和P2P复制

无论是高可用,高可扩展,还是高性能,SQLSERVER的复制分发都是一个不错的选项,配置相对容易,对前台程序的改动也少,因此使用很广泛,但是后期的日常维护,故障排错就麻烦了,

需要对复制分发的原理,元数据表等相当的了解之后才有可为,否知的话一遇到问题,不知所措,万能的解决方法便是重新初始化。本文测试的是当订阅端突然宕机,或者是人为关机,但是

发布端数据库还在不停地Insert/Update,导致链路挂起,而一旦订阅端重连上后的处理方法。本次测试分订阅端短期中断和长期中断。

publication database : mysales_normal

publication                : pub_mysales_normal

publication type        : transaction replication/peer-to-peer replication

subscription database    : mysales_normal

一个是默认实例,一个是命令实例,参与复制分发的表为vendor.具体如下图所示:

image

image

image

首先我把命令实例服务和Agent关闭,然后往发布端vendor表插入两条记录

USE mysales_normal
GO
INSERT INTO [mysales_normal].[myinventory].[Vendor]
VALUES(1,'peter','beishangguang','shanghai','40034','13458294')
INSERT INTO [mysales_normal].[myinventory].[Vendor]
VALUES(2,'top','yyyyyyyy','guangzhou','40034','13458294')
GO

此时,logreader agent 从mysales_normal里读取两条日志文件,然后把它写入到distribution..msrepl_commands中,distribution agent 从该表中读取命令

后写入订阅端相应的vendor表中,但此时连接已中断,我们可以从replication monitor中看到相应的错误信息。

image

我们可以通过sp_browereplcmds来读取msrepl_commands表中的命令:

SELECT mt.publisher_db,id,article,article_id 
FROM distribution.dbo.MSpublisher_databases md 
INNER JOIN distribution.dbo.msarticles mt
ON mt.publisher_db=md.publisher_db
WHERE mt.publisher_db='mysales_normal'

exec distribution..sp_browsereplcmds
@publisher_database_id=7
, @article_id=8
 
image 
 

可以看到这两条命令已经在msrepl_commands表中了。在replication monitor中也可看到有两条命令没有传送到distributior 中:

image

 

这时候我们重启命名实例服务,看看这两条命令能不能传到订阅端:

image

发现两条命令已经发送到订阅端,在来看看订阅表中的数据:

USE mysales_normal
GO
SELECT *  FROM [mysales_normal].[myinventory].[Vendor]
 
image 
 
 

已经有数据了,说明数据写入了订阅表,但当查看replication monitor中未发送命令时,发现undistributed commands还为2 ,如图所示:

image

 

根据 BOL上的解释:undistributed commands 是:还没有没有发送到订阅服务器的命令数。

The number of commands in the distribution database that have not been delivered to the selected Subscriber.

A command consists of one Transact-SQL data manipulation language (DML) statement or one data definition language (DDL) statement.

 

此时在replication monitor中insert tracer,发现链路是通的,而msrepl_commands中还有两条命令。

exec distribution..sp_browsereplcmds
@publisher_database_id=7
, @article_id=8image 

这些无用的命令什么时候,被谁清理掉了?这就轮到 Distribution clean up:distribution这个job,每隔10分钟运行一次,把那些已写入到订阅端的命令清理掉.

image

 

手动运行一次,在看看结果,发现sp_browereplcmds返回空结果集了。但是通常为replication monitor这个工具监视的需要,msrepl_commands至少要保留一条记录,如图所示:

exec distribution..sp_browsereplcmds  @publisher_database_id=7

image

 
image 
 

可以手工删除msrepl_commands中,这个命令的一行数据,

DELETE  FROM distribution.dbo.msrepl_commands WHERE publisher_database_id=7
 
image 
 
 

总结:1:replication monitor 中 undistributed commands 并不能实时的反应未发送的命令,它只是显示发布项在msrepl_commands中对应的记录有多少条,Distribution clean up:distribution

这个job每隔10分钟跑一次,故 undistributed commands 有10分钟的滞后,我们只能通过Insert tracer来实时监控当前链路是否畅通,如果不畅通,可以大致判断有多少条命令挂起!

2:当订阅端重新连上后,发布服务器会自动的把挂起的命令传送到订阅端,不需要人工干预!

 
 
 
 
 
 
 
原文地址:https://www.cnblogs.com/fly_zj/p/2623494.html