SQL SERVER复制拓扑结构中,订阅端宕机后的处理.....(一)
2012-08-04 23:27
295 查看
前提:本次描述的是SQL SERVER 2008R2版本,其它版本没有测试,复制类型主要是Transaction Replication和P2P复制
无论是高可用,高可扩展,还是高性能,SQLSERVER的复制分发都是一个不错的选项,配置相对容易,对前台程序的改动也少,因此使用很广泛,但是后期的日常维护,故障排错就麻烦了,
需要对复制分发的原理,元数据表等相当的了解之后才有可为,否知的话一遇到问题,不知所措,万能的解决方法便是重新初始化。本文测试的是当订阅端突然宕机,或者是人为关机,但是
发布端数据库还在不停地Insert/Update,导致链路挂起,而一旦订阅端重连上后的处理方法。本次测试分订阅端短期中断和长期中断。
首先我把命令实例服务和Agent关闭,然后往发布端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; }
此时,logreader agent 从mysales_normal里读取两条日志文件,然后把它写入到distribution..msrepl_commands中,distribution agent 从该表中读取命令
后写入订阅端相应的vendor表中,但此时连接已中断,我们可以从replication monitor中看到相应的错误信息。
我们可以通过sp_browereplcmds来读取msrepl_commands表中的命令:
可以看到这两条命令已经在msrepl_commands表中了。在replication monitor中也可看到有两条命令没有传送到distributior 中:
这时候我们重启命名实例服务,看看这两条命令能不能传到订阅端:
发现两条命令已经发送到订阅端,在来看看订阅表中的数据:
.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中还有两条命令。
这些无用的命令什么时候,被谁清理掉了?这就轮到 Distribution clean up:distribution这个job,每隔10分钟运行一次,把那些已写入到订阅端的命令清理掉.
手动运行一次,在看看结果,发现sp_browereplcmds返回空结果集了。但是通常为replication monitor这个工具监视的需要,msrepl_commands至少要保留一条记录,如图所示:
.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中,这个命令的一行数据,
.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:当订阅端重新连上后,发布服务器会自动的把挂起的命令传送到订阅端,不需要人工干预!
无论是高可用,高可扩展,还是高性能,SQLSERVER的复制分发都是一个不错的选项,配置相对容易,对前台程序的改动也少,因此使用很广泛,但是后期的日常维护,故障排错就麻烦了,
需要对复制分发的原理,元数据表等相当的了解之后才有可为,否知的话一遇到问题,不知所措,万能的解决方法便是重新初始化。本文测试的是当订阅端突然宕机,或者是人为关机,但是
发布端数据库还在不停地Insert/Update,导致链路挂起,而一旦订阅端重连上后的处理方法。本次测试分订阅端短期中断和长期中断。
publication database : mysales_normal
publication : pub_mysales_normal
publication type : transaction replication/peer-to-peer replication
subscription database : mysales_normal
一个是默认实例,一个是命令实例,参与复制分发的表为vendor.具体如下图所示:
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中还有两条命令。
这些无用的命令什么时候,被谁清理掉了?这就轮到 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:当订阅端重新连上后,发布服务器会自动的把挂起的命令传送到订阅端,不需要人工干预!
相关文章推荐
- SQL SERVER复制拓扑结构中,订阅端宕机后的处理.....(二)
- SQL SERVER复制订阅无法修改表的处理办法
- SQL Server 可更新订阅事务复制的trigger处理
- 【SQL Server高可用性】数据库复制:修改表结构、新增表、新增存储过程 会被复制到订阅服务器?
- sql server 提示无法彻底删除_复制-而无法删除数据库或重新配置发布订阅
- Sql server]复制表结构到一个指定表
- 参考---创建sql数据库复制的发布、订阅的问题处理
- SQL Server 复制(发布与订阅)
- SQL SERVER 复制之使用代码创建发布订阅
- SQL Server 复制订阅
- sql server 本地复制订阅 实现数据库服务器 读写分离
- SQL Server 2005查询处理结构-用户模式计划(UMS)
- SQL Server 2005 复制:用 SQL 语句快速查看发布(publication)都有哪些订阅(subscription),以及发布包含了哪些表
- 主从复制的常用拓扑结构
- 主从复制的常用拓扑结构
- [Sql server]复制表结构到一个指定表
- sql server复制表结构语法
- MySQL 主从复制的常用拓扑结构
- SQL Server复制中错误处理__收藏
- 参考---创建sql数据库复制的发布、订阅的问题处理