寻找SQL Server 20598 错误的根本原因
2014-01-13 08:46
288 查看
一个香港客户的现网系统,按照客户的需求,我们为他配置和安装了SQL Server的分发订阅功能。实际环境则为:主数据中心位于香港跑马地的总部,运行着MAMDB,DYACDB两个数据库,需要将这两个数据库的数据实时进行同步到位于沙田的分支数据中心,假设跑马地的数据库名称为DB,沙田的分支数据中心名称为BAK的话。实际上就是DB实时将数据传送到BAK上进行同步,保证业务的连续性。
在正常运行了一段时间之后,某天DB数据库报“The row was not found at the Subscriber when applying the replicated command”这个错误,同时会看到有很多的“
SQL Agent The semaphore timeout periodhas expired。”和“[000] Request to run job refused because the job is already running>from a request by Start Sequence 0”
这两条错误将我的注意力一直集中在是否是分发订阅服务出了错误上面。从后两条报错来看,很像是基础网络环境除了问题,但是香港的互联网建设还是很不错的,长时间从跑马地Ping沙田,延时一直都很低。
真的很奇怪,到底是什么原因。
仔细去查看日志,发现一条名叫20598的错误,这是一个很重要的线索。我们需要看看20598该如何处理,Google了一下相关资料,发现尝试输入语句:
于是,得到了如下的回复:
![](https://img-blog.csdn.net/20140113083913312?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMzM5NDk4Mg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](https://img-blog.csdn.net/20140113083928671?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMzM5NDk4Mg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
发现出现问题的GUID号码和相关的数据库名,进入到这个数据库,终于找到了指定的条目记录:
![](https://img-blog.csdn.net/20140113084059265?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMzM5NDk4Mg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
那么为什么会造成此现象呢?查询了一些资料发现:
根本原因是备库出现了人为手动删除的动作。
如果原始数据库是这样的:
DB-1 INT
id log id log
1 A 1 A
2 B 2 B
3 C 3 C
这是理想状态,当人为操作备库,删除id=1的记录后,变成这样:
DB-1 INT
id log id log
1 A 2 B
2 B 3 C
3 C
如果DB-1中id=1的条目发生变化为X,同时又新建了一个条目变成
DB-1 INT
id log id log
1 X 2 B
2 B 3 C
3 C
4 D
分发订阅功能会发出两条指令给INT备库,即:Insert 4,D 以及 Update 1,X
注意这里是Update,而不是Insert!所以系统会报找不到id=1的行。
通过与研发确认:
COM_OPERATEBIFORSYN是触发器插入的记录,插入后会被同步程序处理并删除,确实可能导致再同步删除消息时,备库中已经没有该记录而失败,现场已经能够复现该问题。
问题终于得到有效定位,并开始着手解决。
总结起来:
1。按图索骥,不能着急。
2。对自己要有信心,这期间冷嘲热讽,不信任的声音一直在周围聒噪,当问题当面锣,对面鼓的摆出来时,这群傻逼都要给老子闭嘴!
3。任何问题的定位和解决,拿出证据,并说服别人才是硬道理!
在正常运行了一段时间之后,某天DB数据库报“The row was not found at the Subscriber when applying the replicated command”这个错误,同时会看到有很多的“
SQL Agent The semaphore timeout periodhas expired。”和“[000] Request to run job refused because the job is already running>from a request by Start Sequence 0”
这两条错误将我的注意力一直集中在是否是分发订阅服务出了错误上面。从后两条报错来看,很像是基础网络环境除了问题,但是香港的互联网建设还是很不错的,长时间从跑马地Ping沙田,延时一直都很低。
真的很奇怪,到底是什么原因。
仔细去查看日志,发现一条名叫20598的错误,这是一个很重要的线索。我们需要看看20598该如何处理,Google了一下相关资料,发现尝试输入语句:
USE distribution
02.
03.
go
04.
05.
SELECT
*
06.
FROM
dbo.msarticles m
07.
WHERE
EXISTS (
SELECT
mc.article_id
08.
FROM
msrepl_commands mc
09.
WHERE
mc.xact_seqno = 0x00000022000000480003XXXXXXX
10.
AND
mc.article_id = m.article_id)
11.
12.
EXEC
Sp_browsereplcmds
13.
@xact_seqno_start =
'0x00000022000000480003XXXXXXX'
,
14.
@xact_seqno_end =
'0x00000022000000480003XXXXXXX'
于是,得到了如下的回复:
发现出现问题的GUID号码和相关的数据库名,进入到这个数据库,终于找到了指定的条目记录:
那么为什么会造成此现象呢?查询了一些资料发现:
根本原因是备库出现了人为手动删除的动作。
如果原始数据库是这样的:
DB-1 INT
id log id log
1 A 1 A
2 B 2 B
3 C 3 C
这是理想状态,当人为操作备库,删除id=1的记录后,变成这样:
DB-1 INT
id log id log
1 A 2 B
2 B 3 C
3 C
如果DB-1中id=1的条目发生变化为X,同时又新建了一个条目变成
DB-1 INT
id log id log
1 X 2 B
2 B 3 C
3 C
4 D
分发订阅功能会发出两条指令给INT备库,即:Insert 4,D 以及 Update 1,X
注意这里是Update,而不是Insert!所以系统会报找不到id=1的行。
通过与研发确认:
COM_OPERATEBIFORSYN是触发器插入的记录,插入后会被同步程序处理并删除,确实可能导致再同步删除消息时,备库中已经没有该记录而失败,现场已经能够复现该问题。
问题终于得到有效定位,并开始着手解决。
总结起来:
1。按图索骥,不能着急。
2。对自己要有信心,这期间冷嘲热讽,不信任的声音一直在周围聒噪,当问题当面锣,对面鼓的摆出来时,这群傻逼都要给老子闭嘴!
3。任何问题的定位和解决,拿出证据,并说服别人才是硬道理!
相关文章推荐
- 推荐Sql server一些常见性能问题的解决方法
- SQL Server存储过程的基础说明
- SQL Server下几个危险的扩展存储过程
- 如何在SQL Server 2008下轻松调试T-SQL语句和存储过程
- SQL Server中选出指定范围行的SQL语句代码
- 一些SQL Server存储过程参数及例子
- SQL Server优化50法汇总
- SQL Server数据库管理员(DBA)的工作内容
- 列出SQL Server中具有默认值的所有字段的语句
- MSSQL数据类型及长度限制详细说明
- SQL SERVER函数之深入表值函数的处理分析
- 浅析Sql server锁,独占锁,共享锁,更新锁,乐观锁,悲观锁
- SQL Server常用存储过程及示例
- SQL Server架构
- java数据类型与Sql server数据类型对应关系
- 在SQL Server中获得不包含时间部分的日期
- SQL Server游标的使用
- SQL Server性能调教系列(4)--Profiler(上)
- SQL Server性能调教系列(4)--Profiler(下)
- SQL Server 2012入门实例管理篇:总揽