2009-10-14 27 views
0

我們使用帶有Sybase bcp的命名管道,以便我們可以即時壓縮輸出。如何可靠地捕獲Sybase bcp錯誤?

Sybase bcp實用程序在其退出代碼中不會返回太多信息。 Sybase文檔指導用戶檢查進程寫入的錯誤消息。

這是我們使用的錯誤處理習慣用語的解釋,在腳本的非bcp部分中的一些錯誤檢查已被刪除以縮短示例。

while : 
do 
    { 
     rm -f $fifo 
     mkfifo $fifo 
     cat $fifo & 
     CatPid=$! 

     bcp $db.$owner.$table out $fifo -c $db_creds >$log 2>&1 
     grep -qi deadlock $log || break 

     # Must have been a deadlock, clean up. 
     kill $CatPid 
    } > $output 
done 

基本上,如果單詞'死鎖'出現在bcp輸出消息中,我們再試一次。

兩個問題

  1. 請問這種做法看起來合理嗎?
  2. 除了死鎖之外,還有哪些其他bcp錯誤需要我們擔心?

我特別感興趣的是檢測瞬態bcp錯誤,我們可以再次嘗試。

我們使用複合語句,以便我們可以在壓縮之前在bcp數據周圍插入頁眉和頁腳,但爲了簡化示例,我忽略了這一點。

回答

1

這真的會去做你想要的嗎?我對bcp命令行工具的理解是沒有事務 - 即。如果您正在加載M行,但插入N行因爲任何原因(約束等)失敗,則會插入前N-1行。所以重新啓動整個文件並不是一個好主意。

可以使用-m X選項來允許bcp在最多X個錯誤的情況下繼續,然後嘗試識別哪些行未能插入並重試它們。

你也可以看看邁克爾Peppler的的Sybase :: BCP Perl模塊,但我們的研究表明,它可能有問題與ASE 15從Sybase ASE的

+0

你好,來自Blighty Mark。這一個具體是一個bcp out。 – 2009-10-20 05:31:42

+0

我們工作的環境可能無法引入Sybase :: BCP。我記得幾年前嘗試過,當時有一些問題,最後直接調用bcp。 – 2009-10-20 13:23:57

+0

從悉尼過來的日子!對不起 - 沒有注意到你在談論bcp。 – 2009-10-23 02:26:03

2

我的想法使用命名管道的bcp out和壓縮數據然後使用LOAD TABLE語句將其加載到Sybase IQ中。不幸的是,失去了一大筆業績。來自命名管道的LOAD TABLE比HP-UX上的LOAD TABLE文件慢10倍:-(我投票選擇將簡單壓縮alghoritm直接實施到OC utils(bcp,isql)。

+1

+1 @maca - 讓讀者從您的經歷中受益。感謝您的迴應。 – 2010-02-06 16:03:01

2

因此,您只需要可靠的失敗快速bcp。某些Sybase版本的Bcp具有控制最大錯誤計數的命令參數。 1)如果將錯誤計數設置爲1,則它將更可​​靠地失敗。 2)然後問題歸結爲捕獲bcp進程的退出代碼,在&的背景下啓動。我不知道應該使用什麼shell語法來完成這個任務,但可能會有一些常見的shell技術。

+0

+1表示'bcp -m'。就在今天,在10021個錯誤記錄之後,在一個字段中出現了一個由bcp轉儲的1.3G內核格式不一致。我們剛剛遷移到Sybase 15,所以我會修改這個主題。 – 2010-02-10 01:47:44

+0

Sybase bcp實用程序不會返回指示問題的退出代碼。具體而言,無法識別像死鎖那樣的暫時性問題 - Sybase文檔會說檢查錯誤消息。 – 2010-12-21 09:14:10

2

這是一個很容易。

這種方法看起來合理嗎?

不是。首先,shell腳本不是很好,它並不需要所有的工作,但我會一個人留下,因爲這不是問題。

其次,bcp不會僵局,即使是在一個活動的數據庫(除非你正在做的數據庫很奇怪的東西,或者運行多個並行bcp流),等待共享鎖明確,所以沒有必要檢查一下。

三,bcp提供完整的和完整的錯誤消息。使用-e bcp_err_file調用參數。然後grep ... bcp_err_file的錯誤或模式("^[Ee]rr""^Msg"是典型的)。我單獨爲錯誤進行陷阱;例外情況;和其他消息。

第四,我永遠不會像shell腳本那樣永遠重試。潛在的無限循環,浪費資源。讓它執行一次,併產生「成功」xor「失敗」和錯誤列表。任何循環都應該僅用於要導出的表的列表。

  • 它被寫爲適當的unix實用程序/命令。 如果您沒有指定錯誤文件,那麼所有錯誤消息都會轉到$stdout,並且它們會與進度消息混合在一起。你可以陷阱在該流中的錯誤,但這是無腳的;指定一個單獨的錯誤文件。

  • 這是正常的捕捉$stdoutbcp_log_file,但這是單獨對Unixis的bcp_err_file

  • 檢查退出狀態不同的事情。如果bcp成功運行(是否產生錯誤消息),它將作爲「成功」退出;只有在unix程序失敗的情況下,您纔會獲得非零退出狀態。

  • 會容忍任何錯誤數目,除非你限制由-m max_errors

也許我們需要的其他BCP錯誤不是僵局而煩惱?

任何及所有錯誤,它們無法預測(它是一個具有固定資源的在線服務器),捕獲所有錯誤,然後檢查bcp_err_file。如上所述,您可以通過grep自動執行檢查。

我特別感興趣的是檢測瞬態bcp錯誤,我們可以再次嘗試。

沒問題。以上詳細介紹瞬間錯誤很少,而且很遠。

您還應該擔心硬錯誤和資源錯誤,並且而不是再試一次(因爲它會再次失敗)。

我們大多數人都擔心導致缺失行的錯誤,這意味着bcp_data_file不完整或不可用。

+0

感謝您的回答。在我們的例子中,bcp _does_會遇到死鎖,也許是由於您提到的多個bcp並行。代碼是一個'釋義' - 不是實際的代碼 - 我們只有在發生死鎖時纔會重試,在這種情況下應該沒有問題重試。迭代次數有限制 - 我們在十次後放棄。我真的很想知道除了死鎖之外,還有什麼瞬間錯誤可以重試?如果是這樣,哪些? – 2011-01-14 07:09:46

+0

@馬丁。 1)僵局。好的,那麼你的平行流正在互相爭鬥。確保你有真正的平行bcps,沒有兩個在同一行上操作。 2)瞬態錯誤。在正常的意義上,沒有短暫的錯誤,但是你必須捕獲所有的錯誤。 *你的*感覺中有短暫的錯誤,就像*你的死鎖一樣。我已經詳細說明如何去捕捉它們。通過這種方式識別出來後,您可以更改程序以重試。 – PerformanceDBA 2011-01-15 22:19:46