您的位置:首页 > 数据库

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

2012-08-04 23:27 295 查看
前提:本次描述的是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.具体如下图所示:

 





 

 

 

 

 

 

 

 





 





首先我把命令实例服务和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



.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

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

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

 





 

我们可以通过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



 






 


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

 








 


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










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


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


.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }


 






 


 


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










 


根据 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=8




 

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








 


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


exec distribution..sp_browsereplcmds  @publisher_database_id=7


.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }







 






 


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


DELETE  FROM distribution.dbo.msrepl_commands WHERE publisher_database_id=7


.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }


.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }


 







 


 


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

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


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



 


 


 


 


 


 


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: