《Replication的犄角旮旯》系列導(dǎo)讀
Replication的犄角旮旯(一)--變更訂閱端表名的應(yīng)用場(chǎng)景
Replication的犄角旮旯(二)--尋找訂閱端丟失的記錄
Replication的犄角旮旯(三)--聊聊@bitmap
Replication的犄角旮旯(四)--關(guān)于事務(wù)復(fù)制的監(jiān)控
Replication的犄角旮旯(五)--關(guān)于復(fù)制identity列
Replication的犄角旮旯(六)-- 一個(gè)DDL引發(fā)的血案(上)(如何近似估算DDL操作進(jìn)度)
Replication的犄角旮旯(七)-- 一個(gè)DDL引發(fā)的血案(下)(聊聊logreader的延遲)
Replication的犄角旮旯(八)-- 訂閱與發(fā)布異構(gòu)的問(wèn)題
Replication的犄角旮旯(九)-- sp_setsubscriptionxactseqno,賦予訂閱活力的工具
---------------------------------------華麗麗的分割線(xiàn)--------------------------------------------
接觸Replication時(shí)間長(zhǎng)了,遇到“應(yīng)用復(fù)制的命令時(shí)在訂閱服務(wù)器上找不到該行。”這樣錯(cuò)誤的幾率大大增加,而如何定位并手動(dòng)填補(bǔ)數(shù)據(jù)成了DBA的必修課;本文將介紹一種暴力方法來(lái)追蹤已丟失的熱點(diǎn)數(shù)據(jù),尤其是對(duì)于同表多條記錄丟失的問(wèn)題,提高DBA的工作效率;
本文設(shè)計(jì)思路由陳璟童鞋提供,本人只是加以整理,如有侵權(quán),烤鴨伺候……
本方法雖多次經(jīng)受驗(yàn)證無(wú)誤,但多次被MS supporter們建議不要嘗試使用此方法,還望各位DBA三思!
一般來(lái)說(shuō),定位“訂閱端丟失的記錄”分成以下幾步:
1、通過(guò)xact_seqno、command_id定位到具體命令
2、解析commands,確定命令類(lèi)型(insert、update、delete)、對(duì)象名稱(chēng)、主鍵
3、根據(jù)上述獲取的條件補(bǔ)數(shù)(insert或DTS),這是我們的關(guān)鍵,也是我們需要簡(jiǎn)化的步驟
關(guān)于定位失敗的命令,可以參考微軟官方博客
http://blogs.msdn.com/b/apgcdsd/archive/2012/01/10/10254809.aspx
沒(méi)錯(cuò),我也是這樣操作,但如果你發(fā)現(xiàn),剛剛補(bǔ)過(guò)一條記錄后,msrepl_errors又出現(xiàn)新的記錄,咋辦?再1、2、3的執(zhí)行一遍?關(guān)鍵的問(wèn)題是我們也不知道到底丟失了多少命令。如果這是發(fā)生在夜里,幾分鐘報(bào)一次警,持續(xù)1、2個(gè)小時(shí),相信所有的DBA們都會(huì)瘋掉……so,自己動(dòng)手豐衣足食吧;
先來(lái)分析一下可能造成“找不到行”的復(fù)制命令的類(lèi)型;
1、insert
這類(lèi)操作對(duì)DBA絕對(duì)是個(gè)blackhole;試想一下,如果一個(gè)insert操作丟失了,如果這個(gè)丟失的記錄后續(xù)沒(méi)有通過(guò)復(fù)制進(jìn)行過(guò)update、delete,你是絕對(duì)發(fā)現(xiàn)不了的;沒(méi)辦法,這樣的工作只能交給驗(yàn)證訂閱或者定期進(jìn)行tablediff這類(lèi)第三方工具搞定了,不過(guò)我相信大部分DBA都是在業(yè)務(wù)方發(fā)現(xiàn)數(shù)據(jù)不一致以后才后知后覺(jué)的……
2、update
update是三個(gè)DML操作里面比較復(fù)雜的,一個(gè)update命令傳到訂閱端但發(fā)現(xiàn)沒(méi)有這條記錄的時(shí)候就會(huì)報(bào)錯(cuò),由于在發(fā)現(xiàn)命令丟失時(shí)發(fā)布端已經(jīng)完成更新,所以直接手動(dòng)從發(fā)布庫(kù)里導(dǎo)入這條記錄到訂閱端即可;
3、delete
delete是最簡(jiǎn)單的無(wú)需關(guān)心的操作,如果一個(gè)delete的復(fù)制命令傳到訂閱端發(fā)現(xiàn)沒(méi)有記錄,你會(huì)像處理update那樣重新從發(fā)布庫(kù)導(dǎo)入這條記錄到訂閱端?那你一定是大腦掉線(xiàn)了……帥鍋,這時(shí)候發(fā)布庫(kù)已經(jīng)沒(méi)有這條記錄了,然后你會(huì)瘋了一樣的問(wèn)自己腫木辦,腫木辦么?
有人說(shuō),在訂閱端insert一條只有主鍵的偽記錄,然后delete就可以正常下去了。沒(méi)錯(cuò),這確實(shí)是個(gè)辦法,但不是個(gè)好辦法,畢竟一個(gè)insert你也是要敲上十幾個(gè)甚至幾十個(gè)字符的……其實(shí)處理方法很簡(jiǎn)單,已經(jīng)刪了的記錄就沒(méi)必要再找回來(lái)了,關(guān)掉監(jiān)控就行了;當(dāng)然我指的是MS errors的報(bào)警監(jiān)控。
處理方法:
1、定位具體命令
你還在通過(guò)復(fù)制監(jiān)視器查看出錯(cuò)信息?那補(bǔ)上一條數(shù)估計(jì)要幾分鐘(等待出錯(cuò)信息刷新的時(shí)間),要是丟了幾十條記錄,那你這一天就不用干別的事情了;
直接從distribution.dbo.msrepl_errors里查吧;
SELECT * FROM distribution.dbo.MSrepl_errorsORDER BY time DESCView Code
2、解析commands
根據(jù)上面查詢(xún)的結(jié)果,取出xact_seqno(出錯(cuò)的命令的事務(wù)號(hào))、command_id(命令id),在根據(jù)下面的系統(tǒng)存儲(chǔ)過(guò)程定位到具體的語(yǔ)句
USE distributiongosp_browsereplcmds '0x00026BBC000A3DDE000400000000','0x00026BBC000A3DDE000400000000' --兩個(gè)字符串均是上一步獲取的xact_seqnoView Code
在結(jié)果集中使用上一步的command_id定位到具體的行,取出command,就是出錯(cuò)的命令
3、分析命令
[sp_MSupd_dbotest4] 這是調(diào)用訂閱端的存儲(chǔ)過(guò)程名,upd說(shuō)明是update操作,test4是訂閱端的對(duì)象名;
‘abc’ 這個(gè)是update操作的value,具體對(duì)應(yīng)的哪一個(gè)column,那就數(shù)數(shù)逗號(hào)吧(自己測(cè)試一下就會(huì)發(fā)現(xiàn)規(guī)律);實(shí)際上我們并不需要知道要更新哪一列;
10002 這個(gè)是主鍵的value,復(fù)制命令到訂閱端執(zhí)行都是按照主鍵去操作的,這個(gè)看一下訂閱端的存儲(chǔ)過(guò)程就清楚了;
0x02 這個(gè)是8進(jìn)制的bitmap,簡(jiǎn)單說(shuō)就是這一類(lèi)操作的位圖值,在這一章不會(huì)用到這個(gè),后續(xù)的文章里會(huì)涉及到;
新聞熱點(diǎn)
疑難解答
圖片精選