【一記難忘的誤操作】當shareplex的capture queue file被刪除之後

viadeazhu發表於2010-06-03
    2010年6月2日傍晚,月黑風高,不料天有不測風雲,一次痛苦而難忘的誤操作就發生於此。
在生產環境的誤操作尤其是DBA的夢魘。雖然最後竭盡全力,力挽狂瀾,但仍心有餘悸。
    故事發生在為Oracle提供高階複製的軟體Shareplex身上。
    起因,Shareplex有一個一直未曾解決的Bug,在vardir目錄下會產生許多capture queue files,直到將vardir撐爆。目前的workaround是找到當前使用的capture queue file,人為刪掉前面所有的capture queue files。
    經過,傍晚是睡意朦朧之際,警覺之心頓消,copy&paste的速度越發地熟練和不假思索,於是,悲劇地多刪了最後,也就是當前的capture queue file。
    結果,(此處省略幾千字)Fixed。

    收穫:
    每一次成功都會有所收穫,而每一次失敗卻收穫更豐。因為失敗是稀少的(如果很多也太悲劇了。。),失敗是讓人記憶深刻的,失敗也是會成為一個大腦裡的標記的。
此次失敗的原因是多方面的,其中重要的原因是對此類事情做得太多了,有種“輕敵”的感覺,於是思想上略顯懈怠,於是手先於腦。這也就是為什麼常常人們的誤操作都發生在每週會做無數次的小事情上,而複雜的操作往往會引起人們的警覺,因為能得到完美的完成。
    All about Tech:
    不說廢話,針對Shareplex capture queue file丟失的情況,我們該如何解決呢?
首先講講Shareplex capture queue file是幹什麼的?它是在Source端,接受reader程式讀redo log產生的messages。
那麼如果capture queue file被刪除了,那麼意味著我們丟失了一部分從redo log裡讀出來的messages,而reader程式是不知道他們丟失了的,因此繼續往下讀。從而形成了一個messages的gap,後面的messages無法傳輸到Target。
所以,正確的流程是採用shareplex的point in time recovery技術強制讓reader從誤操作前面一個時間點的歸檔日誌開始讀,雖然由於不知道具體的時間偏移量,會有部分重複的資料讀出然後被Target應用,重複的時間裡有一些OOS(Out of Sync)Errors出現,但是,這樣可以保證不丟失資料。

    那我們是如何嘗試解決的呢?又遇到了哪些意想不到的苦難呢?
    1.處於本能,在Source端發現誤操作後,嘗試了採用qview -i裡的fixup all命令,重啟shareplex,幻想這個萬能命令能解決問題。
結果是reader died。
    2.於是call QUEST support,採用了徹底丟棄掉被我刪除的capture queue file裡的差不多1k多條messages,以此來保證Shareplex的正常工作,至少reader復活了。
採用的具體辦法如下:
qview> uscan 0 1 3
***Sque 0, mid 14225964996, sqmid 14225964996, mlen 1157248, nextm 10902612993877, mqseq 10902611836629, mpseq 28467640162888, 06/02/10 05:12:03, FIXUP to patch 1321 missing messages
Sque 0, mid 14225964997, qseq 10902612993877, 06/02/10 04:50:00, 230678/257876132, transid 0, COMMIT, AAAAAAAAAAAAAAAAAA  , SCN  3583017198059, forward = 0
Sque 0, mid 14225964998, qseq 10902612994221, 06/02/10 04:50:00, 230678/257918560, transid 0, Insert, AAADiHAAZAABKPRABm  , SCN  3583017198060, forward = 1
qview> exit


$> qview -i
qview> qinit
qview> open c r
Current queue o.XXX+C        user +PR+o.XXX+sp_ordr+o.XXX
qview> rrls 0 10902612993877



這裡我們發現丟失了1321條messages,於是將它們都release掉,之後Shareplex能正常工作。
但是,問題是,之後在Target發現了無數的OOS Errors。由於表都巨大無比,而且巨多,所以無法每一個都進行compare&repair。
這時,我們打算自己進行point in time recovery。
    3.第一次在Source的point in time recovery。
首先透過在Target執行show post,找到當前所有post queue進行到了哪個log sequence號了,而記錄這個sequence號作為我們point in time recovery的起點。也就是讓reader從這個log sequence開始抓取messages。
a.shutdown source和target的shareplex
b.備份好source和target的vardir目錄,例如tar一下放到旁邊。
c.在source和target上執行ora_cleansp / , 這裡會清空shareplex的一些表。
d.start shareplex on source,然後
stop export
activate config  xxx.cfg seqno=

這裡要注意觀察是否capture程式執行良好,開始堆積messages。
e.start shareplex on target,然後
start post
f.在source:
start export
這時,在target的event log裡,我們會看到大量的OOS Errors,這是正常的,等到recover過了出錯點後,就會趨於平靜。
由於point in time recovery不支援LOB欄位,所以我們還要為包含LOB欄位的表進行特殊處理:
SQL> select TABLE_NAME from dba_tab_columns where WNER='XXX' and DATA_TYPE in ('CLOB','BLOB');
然後自行向辦法同步,這裡略去。
    4.修復Target sp_cop消失的詭異問題
本來到這裡,我們基本修復了所有問題,可見shareplex point in time recovery的強大。
但是意想不到的問題在Target發生了:
也許是由於早期大量的OOS Errors,Target端的sp_cop程式突然不見了,但是post卻還在幹活。
由於現在無法登入Console,於是在OS層面kill掉所有的shareplex程式,重啟shareplex,core dump。。。
透過ipcs -a發現有shared memory segments和Semaphores沒被釋放,於是ipcrm -m幹掉。
重啟,繼續core dump。。。
於是再次call QUEST support,在support的幫助下,rename了一些檔案:
在data目錄:
\mv statusdb statusdb.bak3
\mv dirty dirty.bak3

在rim目錄:
\mv shstinfo.ipc shstinfo.ipc.bak3
\mv shmaddr.loc shmaddr.loc.bak3

然後重啟shareplex,終於成功!頓時覺得幾個lock檔案都能使shareplex重啟core dump,太讓人意外的了。
    5.修復Target端專門複製sequence的post queue不停死掉的問題
這是以前遇到過的一個bug,某複製sequence的post queue不停死掉。
在event log裡會看到如下錯誤:
Error    2010-06-02 20:13:07.988013 3969 5 Poster: Poster exit on 9i ddl error due to ORA-04002:
INCREMENT must be a non-zero integer. on ALTER SEQUENCE "xxx"."xxx" INCREMENT...  
(posting from XXX, queue xxx, to xxx) [module opo]

於是第三次call QUEST support,採用了對這個queue加一個引數,使得ddl error不會讓這個queue死掉。
再加一個debug這個queue的引數。
加完之後,這個queue就再也沒死了。
sp_ctrl > set param sp_opo_stop_on_ddl_err queue 0
sp_ctrl > set param sp_opo_debug_flag queue 0x0f0021ff
sp_ctrl > start post

如果以後沒有繼續出現這個錯誤,可以考慮取消他倆:
reset param sp_opo_stop_on_ddl_err queue
reset param sp_opo_debug_flag queue
stop post queue
start post queue

    至此,此次漫長的修復之路到此為止。

    教訓:
1.不要輕視任何簡單、常規、無聊的任務。
2.不要讓手先於大腦做事情,等到大腦反應過來的時候發現已經晚了。
3.不要急於完成多個任務,要淡定!

總結,怎麼最後寫得像檢討。。。
積累rp,總結經驗,重新再戰!

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/15415488/viewspace-664339/,如需轉載,請註明出處,否則將追究法律責任。

相關文章