資料補丁中需要注意的幾個問題

dbasdk發表於2015-05-05
今天來感慨一下在工作中碰到的幾處資料補丁問題,當然這些細節都是流程之外的控制和規範了,但是也或多或少出現了不少的問題,有些讓人糾結,有些讓人抓狂,有些讓人無奈,但是不管怎麼樣,資料補丁是修復資料,完善業務的,DBA在這個關鍵時候就不能麻痺大意,把好這個關口還是很重要的。

讓人吐血的dump檔案
這是個真實的案例,早上很早到了公司,發現有個開發同事提交了一個資料補丁,需要部署在某某客戶環境中,看到補丁的說明還是比較簡單的,是需要匯入一個dump檔案,但是補丁也太簡單了,除了這個說明其它什麼都沒有,也沒有附上對應的dump檔案,我就感覺納悶,他的解釋說dump檔案太大了,有好幾百兆,透過圖形工具提交申請補丁已經超過最大附件的限制了,看來這個問題還得特事特辦了。因為公司環境和客戶環境是完全的兩套網路,網路對映有了,但是網速還是很慢的。結果就這樣scp了一早上,眼睜睜看著dump檔案一點一點的傳輸,最後好不容易傳送完成了,按照補丁的說明匯入,發現匯入的表只有一個,而且匯入的資料就100多行,真是讓人淚奔啊。
對於這個問題的反思,對於資料補丁的稽核還是需要加強,可能開發的同事本身沒有意識到很多細節,就會給你提供錯誤的資訊誤導你,所以需要自己的火眼金睛來識別了。大檔案有大檔案的處理方式,小檔案有小檔案的部署方式,哪些可以自動執行,哪些需要手工校驗,檢查點喲哪些,這些資訊都需要我們來考慮。這樣不同的問題就會有不同的處理方式,也就不用那麼糾結了。

不統一的匯入匯出方式
還是資料匯入的問題,開發提交了兩個資料補丁,按照補丁的提示是需要匯入一些表,然後提供了指令碼做資料稽核,但是第一個dump檔案就讓人很糾結了,第二個也沒讓人省心。第二個在匯入的時候報了錯誤,

IMP-00010: not a valid export file, header failed verification

IMP-00000: Import terminated unsuccessfully

看這個錯誤,感覺是dump檔案出問題了。但是開發的同事堅稱在其它環境中已經成功部署了,看來是不是我哪裡檢查錯了,我又從源地址複製了一份嘗試,還是同樣的錯誤,在本地測試也是這個錯誤,最後使用strings檢視dump的內容的時候,發現dump的內容是xml格式的,這很明顯就是使用expdp匯出的,這種問題讓人很是糾結。
對於這個問題的反思,還是希望能夠在提交資料補丁的時候,能夠統一一下,儘管嚴格來說,這也不是錯誤,但是多多少少會造成一些誤導,這種補丁DBA去部署都會產生誤解,更不用說自動部署了。

分散式部署環境的集中管理
目前在一個專案中使用的環境有上百套,不同的業務,不同的環境,有時候弄幾個資料補丁感覺很費勁,因為很多時間都在找環境上,公司內網的環境,客戶的環境,各種型別的測試環境,在文件中描述得還算清晰,但是自己去查詢的時候,感覺就跟拿字典查生字的感覺一樣,每次都得根據環境編碼去一個一個對應環境,感覺有些手工勞動的成分,儘管文件很豐富,很細緻,但是自己使用起來還是不夠完善。最後下決心改善這種情況,寫了幾個指令碼,我只需要輸入環境代號,就會在後臺就做各種匹配和驗證,然後輸出一個報告。這樣就能節省很多的額外勞動,手工校驗,而且還可能有遺漏。
這個問題帶來的反思是很多時候公司會存在大量的分散式環境,如何能夠更加靈活的管理,對於自己就是莫大的幫助。因為從架構上,流程上都滿足要求,但是如何能夠更高效的管理,自己也盡一份力,給複雜繁瑣的工作添磚加瓦。

補丁中的update導致的資料問題
這個問題源於一個同事的疑問,因為在環境中某個服務出現了問題,開發同事在查詢的時候發現有些地方的資料出現了不一致的情況也不好定位,剛好最近部署了一個資料補丁,就希望我來看看。問題如果細細描述下來涉及業務背景,感覺就很抽象了。自己簡單模擬一下。
我們建立兩個表,
create table test_sub (id number,name varchar2(30));
create table test_temp(id number,name varchar2(30));   
然後往兩個表中插入資料,test_sub表中的資料是完整的資料,有6條,test_temp中少一些,只有4條。
insert into test_sub values(1,'a');
insert into test_sub values(2,'b');
insert into test_sub values(3,'c');
insert into test_sub values(4,'d');
insert into test_sub values(5,'e');
insert into test_sub values(6,'f');

insert into test_temp values(1,'a');
insert into test_temp values(2,'b');
insert into test_temp values(3,'c');
insert into test_temp values(4,'d');
然後在update的時候需要關聯test_temp表來做資料的變更,可以看到標黃的部分,是明確在子查詢中指定id值不為1和2的。 where中的1=1只是想說明這個語句做了一些資料過濾,得到的結果還是一個相對比較完整的結果集。   
 update test_sub sub
   set name=(select name from test_temp tmp where tmp.id=sub.id and id not in (1,2))
    where 1=1;
這條語句的更新條數是2行,4行還是6行呢。
簡單測試就會發現變更了6行,這可能和預期的結果也有一定的差別。
6 rows updated.
檢視變更後的結果,發現對於id為1,2,3,4,5,6的表test_sub和test_temp透過id做了關聯,所以過濾後的資料只有4行,但是在子查詢中又排除了id為1,2的記錄,所以應該只有id為3,4的記錄行應該更新。
n1@TEST11G> select *from test_sub;
        ID NAME
---------- ------------------------------
         1
         2
         3 c
         4 d
         5
         6
6 rows selected.
但是如果細細看來,id為1,2,5,6的資料行都把name欄位給清空了。這種問題需要好好消化消化,在資料補丁中還是比較常見的問題,最可怕的情況就是資料越修越亂。
對於這個問題的反思還是儘量在一些資料補丁中避免使用複雜的子查詢和過濾,可能直接根據限定的列來做資料變更,控制範圍更加合理,不會有牽一髮而動全身的感覺。

以上幾個問題都是在工作中碰到的一些小問題,但是這些細節問題如果不注意,就對自己的工作造成很大的困擾,浪費了時間,工作效率上不去,所以有責改進,無則加勉。

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

相關文章