首页 > 开发 > 综合 > 正文

Replication的犄角旮旯(二)--寻找订阅端丢失的记录

2024-07-21 02:51:06
字体:
来源:转载
供稿:网友
Replication的犄角旮旯(二)--寻找订阅端丢失的记录

《Replication的犄角旮旯》系列导读

Replication的犄角旮旯(一)--变更订阅端表名的应用场景

Replication的犄角旮旯(二)--寻找订阅端丢失的记录

Replication的犄角旮旯(三)--聊聊@bitmap

Replication的犄角旮旯(四)--关于事务复制的监控

Replication的犄角旮旯(五)--关于复制identity列

Replication的犄角旮旯(六)-- 一个DDL引发的血案(上)(如何近似估算DDL操作进度)

Replication的犄角旮旯(七)-- 一个DDL引发的血案(下)(聊聊logreader的延迟)

Replication的犄角旮旯(八)-- 订阅与发布异构的问题

Replication的犄角旮旯(九)-- sp_setsubscriptionxactseqno,赋予订阅活力的工具

---------------------------------------华丽丽的分割线--------------------------------------------

接触Replication时间长了,遇到“应用复制的命令时在订阅服务器上找不到该行。”这样错误的几率大大增加,而如何定位并手动填补数据成了DBA的必修课;本文将介绍一种暴力方法来追踪已丢失的热点数据,尤其是对于同表多条记录丢失的问题,提高DBA的工作效率;

本文设计思路由陈璟童鞋提供,本人只是加以整理,如有侵权,烤鸭伺候……

本方法虽多次经受验证无误,但多次被MS supporter们建议不要尝试使用此方法,还望各位DBA三思!

一般来说,定位“订阅端丢失的记录”分成以下几步:

1、通过xact_seqno、command_id定位到具体命令

2、解析commands,确定命令类型(insert、update、delete)、对象名称、主键

3、根据上述获取的条件补数(insert或DTS),这是我们的关键,也是我们需要简化的步骤

关于定位失败的命令,可以参考微软官方博客

http://blogs.msdn.com/b/apgcdsd/archive/2012/01/10/10254809.aspx

没错,我也是这样操作,但如果你发现,刚刚补过一条记录后,msrepl_errors又出现新的记录,咋办?再1、2、3的执行一遍?关键的问题是我们也不知道到底丢失了多少命令。如果这是发生在夜里,几分钟报一次警,持续1、2个小时,相信所有的DBA们都会疯掉……so,自己动手丰衣足食吧;

先来分析一下可能造成“找不到行”的复制命令的类型;

1、insert

  这类操作对DBA绝对是个blackhole;试想一下,如果一个insert操作丢失了,如果这个丢失的记录后续没有通过复制进行过update、delete,你是绝对发现不了的;没办法,这样的工作只能交给验证订阅或者定期进行tablediff这类第三方工具搞定了,不过我相信大部分DBA都是在业务方发现数据不一致以后才后知后觉的……

2、update

  update是三个DML操作里面比较复杂的,一个update命令传到订阅端但发现没有这条记录的时候就会报错,由于在发现命令丢失时发布端已经完成更新,所以直接手动从发布库里导入这条记录到订阅端即可;

3、delete

  delete是最简单的无需关心的操作,如果一个delete的复制命令传到订阅端发现没有记录,你会像处理update那样重新从发布库导入这条记录到订阅端?那你一定是大脑掉线了……帅锅,这时候发布库已经没有这条记录了,然后你会疯了一样的问自己肿木办,肿木办么?

  有人说,在订阅端insert一条只有主键的伪记录,然后delete就可以正常下去了。没错,这确实是个办法,但不是个好办法,毕竟一个insert你也是要敲上十几个甚至几十个字符的……其实处理方法很简单,已经删了的记录就没必要再找回来了,关掉监控就行了;当然我指的是MS errors的报警监控。

处理方法:

1、定位具体命令

  你还在通过复制监视器查看出错信息?那补上一条数估计要几分钟(等待出错信息刷新的时间),要是丢了几十条记录,那你这一天就不用干别的事情了;

  直接从distribution.dbo.msrepl_errors里查吧;  

SELECT * FROM distribution.dbo.MSrepl_errorsORDER BY time DESC
View Code

2、解析commands

  根据上面查询的结果,取出xact_seqno(出错的命令的事务号)、command_id(命令id),在根据下面的系统存储过程定位到具体的语句

USE distributiongosp_browsereplcmds '0x00026BBC000A3DDE000400000000','0x00026BBC000A3DDE000400000000' --两个字符串均是上一步获取的xact_seqno
View Code

  在结果集中使用上一步的command_id定位到具体的行,取出command,就是出错的命令

3、分析命令

  [sp_MSupd_dbotest4]  这是调用订阅端的存储过程名,upd说明是update操作,test4是订阅端的对象名;

  ‘abc’  这个是update操作的value,具体对应的哪一个column,那就数数逗号吧(自己测试一下就会发现规律);实际上我们并不需要知道要更新哪一列;

  10002 这个是主键的value,复制命令到订阅端执行都是按照主键去操作的,这个看一下订阅端的存储过程就清楚了;

  0x02  这个是8进制的bitmap,简单说就是这一类操作的位图值,在这一章不会用到这个,后续的文章里会涉及到;

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表