merge語句導致的ORA錯誤分析
最近處理了好幾起關於merge導致的問題,其實看到merge語句內心也還是蠻糾結的,這一次還是碰到了問題,簡直無語了。
先交代下問題的背景。有一套OLTP環境和OLAP環境需要同步一部分資料,都是在每天的半夜開始,OLAP的庫的一個表資料會根據增量的邏輯從OLTP庫中同步,有兩種方式,一種是OLAP從OLTP中去抓取,另外一種是OLTP推送給OLAP。看起來表達的意思是差不多的,實現起來就是完全不同的風格,即一種主動一種被動,而對於大部分的應用需求來看,還是更傾向於OLAP從OLTP中去抓取這種方式,要不OLTP端還是存在一定的耦合度。
但是目前的情況是OLTP主動推送給OLAP,當然這種設計方式看來達到的效果都是一致的,而且因為歷史原因,也是一直這麼用的。
在一次升級以後,藉著升級的機會,而且很巧又碰到了老版本相容merge語句的問題(又是merge),所以就自然而然想一併做個改進,把這個問題規範起來。
改進以後,OLAP會從OLTP中抓取資料,原來的邏輯完全不用修改,只是在兩個表關聯的地方,使用到了DB link來處理,所以程式碼層面可以認為是沒有其它的變化,而且在部署到OLAP端後,我建立了一個小表還測試了一把,沒有發現問題,所以簡單修改配置之後,就部署完成了,還給開發的同事講解了這個改進的意義,自己也還是蠻高興的。
第二天同事就主動找我,說增量資料沒有同步過來,帶著程式設計師最常用的口吻“不可能啊”,“我這裡執行都好好的”之類的想法,我檢視了後臺的JOB執行日誌,結果發現日誌中竟然丟擲了一個ORA錯誤。
ORA-30926: unable to get a stable set of rows in the source tables
ORA-06512: at line 32
這個錯誤看起來似懂非懂,比較模糊,初步感覺是表結構哪裡出現了不一致的情況。
實現的大體思路如下:
insert into test.tmp_usercenter select *from xxx@OLAP where xxxx; --透過這種方式獲得增量資料
然後把增量資料插入test.test_user_center中。不匹配則插入
merge into test.test_user_center a
using (select * from tlbb.tmp_usercenter) b
on (a.uin=b.uin)
when matched then
update set LAST_LOGOUT=b.LAST_LOGOUT,
LAST_IP=b.LAST_IP,
FIRST_GAMESTYLE=b.FIRST_GAMESTYLE
when not matched then
insert (CN,
UIN,
BILL_TYPE,
PRESENT_POINT,。。。
OUTLINE_SCORE,FIRST_GAMESTYLE)
values
(
b.CN,
b.UIN,
b.BILL_TYPE,
b.PRESENT_POINT,。。。
b.FIRST_GAMESTYLE);
commit;
瞭解了大體的思路之後,我對裡面涉及的歷史表欄位都進行了認真的比對,沒有發現任何問題,增量的資料都進行了比對,都是和原來的生成方式一樣的。
但是為什麼這種方式就會出問題呢。這一點上我不好解釋,也不好給其他人解釋,所以我需要認真分析,看看到底是哪裡的問題。
同時我認真比對了ORA-30926錯誤的解釋,發現merge在處理一些DML的時候,如果同一記錄被影響變更多次,則會出現這類問題,那也就意味著表中的資料有冗餘的成分。
但是同樣的資料,同樣的邏輯,幾乎同樣的語句,怎麼原來可以,現在不可以呢。
最後反覆測試,發現原來還是DB link在這一點上有很大的差別,如果在正常情況下存在冗餘資料或者重複資料的情況下,使用merge來更新是會丟擲ORA-30926錯誤的。而使用DB Link竟然會把這個錯誤化解,而一直以來使用的在OLTP端推送資料至OLAP,在這個場景下使用了這樣的方式,看似也是碰到了一些問題,最後採用的那種方式,我不知道之前的人是否意識到那個問題,或者可能認為那種方式不支援這種需求,而我在嘗試改進的時候,就踩到了這個坑。當然我還是希望能夠在OLAP端完成這個需求,而原來可以,我們就可以借鑑成功的思想,所以改進起來就是耍個小聰明。DB link可以繞過這個ORA錯誤,那我們就使用DB link,但是訪問的是當前庫的表資料。即我們建立一個DB link指向自己,然後透過DB Link的方式訪問。這樣反覆測試,發現確實是可以的。
所以語句的邏輯就改為下面的形式:
insert into test.tmp_usercenter select *from xxx@OLAP where xxxx; --透過這種方式獲得增量資料
然後把增量資料插入test.test_user_center中。不匹配則插入
merge into test.test_user_center@OLAP_TEST a --建立一個DB link OLTP_TEST指向當前的資料庫
using (select * from tlbb.tmp_usercenter) b
on (a.uin=b.uin)
when matched then
update set LAST_LOGOUT=b.LAST_LOGOUT,
LAST_IP=b.LAST_IP,
FIRST_GAMESTYLE=b.FIRST_GAMESTYLE
when not matched then
insert (CN,
UIN,
BILL_TYPE,
PRESENT_POINT,。。。
OUTLINE_SCORE,FIRST_GAMESTYLE)
values
(
b.CN,
b.UIN,
b.BILL_TYPE,
b.PRESENT_POINT,。。。
b.FIRST_GAMESTYLE);
commit;
這種方式能夠改進原來的ORA錯誤,權當做一種變相的改進吧。
先交代下問題的背景。有一套OLTP環境和OLAP環境需要同步一部分資料,都是在每天的半夜開始,OLAP的庫的一個表資料會根據增量的邏輯從OLTP庫中同步,有兩種方式,一種是OLAP從OLTP中去抓取,另外一種是OLTP推送給OLAP。看起來表達的意思是差不多的,實現起來就是完全不同的風格,即一種主動一種被動,而對於大部分的應用需求來看,還是更傾向於OLAP從OLTP中去抓取這種方式,要不OLTP端還是存在一定的耦合度。
但是目前的情況是OLTP主動推送給OLAP,當然這種設計方式看來達到的效果都是一致的,而且因為歷史原因,也是一直這麼用的。
在一次升級以後,藉著升級的機會,而且很巧又碰到了老版本相容merge語句的問題(又是merge),所以就自然而然想一併做個改進,把這個問題規範起來。
改進以後,OLAP會從OLTP中抓取資料,原來的邏輯完全不用修改,只是在兩個表關聯的地方,使用到了DB link來處理,所以程式碼層面可以認為是沒有其它的變化,而且在部署到OLAP端後,我建立了一個小表還測試了一把,沒有發現問題,所以簡單修改配置之後,就部署完成了,還給開發的同事講解了這個改進的意義,自己也還是蠻高興的。
第二天同事就主動找我,說增量資料沒有同步過來,帶著程式設計師最常用的口吻“不可能啊”,“我這裡執行都好好的”之類的想法,我檢視了後臺的JOB執行日誌,結果發現日誌中竟然丟擲了一個ORA錯誤。
ORA-30926: unable to get a stable set of rows in the source tables
ORA-06512: at line 32
這個錯誤看起來似懂非懂,比較模糊,初步感覺是表結構哪裡出現了不一致的情況。
實現的大體思路如下:
insert into test.tmp_usercenter select *from xxx@OLAP where xxxx; --透過這種方式獲得增量資料
然後把增量資料插入test.test_user_center中。不匹配則插入
merge into test.test_user_center a
using (select * from tlbb.tmp_usercenter) b
on (a.uin=b.uin)
when matched then
update set LAST_LOGOUT=b.LAST_LOGOUT,
LAST_IP=b.LAST_IP,
FIRST_GAMESTYLE=b.FIRST_GAMESTYLE
when not matched then
insert (CN,
UIN,
BILL_TYPE,
PRESENT_POINT,。。。
OUTLINE_SCORE,FIRST_GAMESTYLE)
values
(
b.CN,
b.UIN,
b.BILL_TYPE,
b.PRESENT_POINT,。。。
b.FIRST_GAMESTYLE);
commit;
瞭解了大體的思路之後,我對裡面涉及的歷史表欄位都進行了認真的比對,沒有發現任何問題,增量的資料都進行了比對,都是和原來的生成方式一樣的。
但是為什麼這種方式就會出問題呢。這一點上我不好解釋,也不好給其他人解釋,所以我需要認真分析,看看到底是哪裡的問題。
同時我認真比對了ORA-30926錯誤的解釋,發現merge在處理一些DML的時候,如果同一記錄被影響變更多次,則會出現這類問題,那也就意味著表中的資料有冗餘的成分。
但是同樣的資料,同樣的邏輯,幾乎同樣的語句,怎麼原來可以,現在不可以呢。
最後反覆測試,發現原來還是DB link在這一點上有很大的差別,如果在正常情況下存在冗餘資料或者重複資料的情況下,使用merge來更新是會丟擲ORA-30926錯誤的。而使用DB Link竟然會把這個錯誤化解,而一直以來使用的在OLTP端推送資料至OLAP,在這個場景下使用了這樣的方式,看似也是碰到了一些問題,最後採用的那種方式,我不知道之前的人是否意識到那個問題,或者可能認為那種方式不支援這種需求,而我在嘗試改進的時候,就踩到了這個坑。當然我還是希望能夠在OLAP端完成這個需求,而原來可以,我們就可以借鑑成功的思想,所以改進起來就是耍個小聰明。DB link可以繞過這個ORA錯誤,那我們就使用DB link,但是訪問的是當前庫的表資料。即我們建立一個DB link指向自己,然後透過DB Link的方式訪問。這樣反覆測試,發現確實是可以的。
所以語句的邏輯就改為下面的形式:
insert into test.tmp_usercenter select *from xxx@OLAP where xxxx; --透過這種方式獲得增量資料
然後把增量資料插入test.test_user_center中。不匹配則插入
merge into test.test_user_center@OLAP_TEST a --建立一個DB link OLTP_TEST指向當前的資料庫
using (select * from tlbb.tmp_usercenter) b
on (a.uin=b.uin)
when matched then
update set LAST_LOGOUT=b.LAST_LOGOUT,
LAST_IP=b.LAST_IP,
FIRST_GAMESTYLE=b.FIRST_GAMESTYLE
when not matched then
insert (CN,
UIN,
BILL_TYPE,
PRESENT_POINT,。。。
OUTLINE_SCORE,FIRST_GAMESTYLE)
values
(
b.CN,
b.UIN,
b.BILL_TYPE,
b.PRESENT_POINT,。。。
b.FIRST_GAMESTYLE);
commit;
這種方式能夠改進原來的ORA錯誤,權當做一種變相的改進吧。
#############################
每日發文,或技術、或總結,偶有日間小事也以為記,謂之學習筆記,成年累月800多天,中間幾乎沒有間斷,要旨只有一個:學習交流,共同進步 。
#############################
學習筆記精華整理,個人新書《Oracle DBA工作筆記》已開售,在京東,噹噹,亞馬遜,淘寶,天貓均有售,歡迎選購。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23718752/viewspace-2122373/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- ORA-04031錯誤導致當機案例分析
- merge語句導致的效能問題緊急優化優化
- ORA-07445錯誤導致叢集CI鎖的問題分析
- MySQL半一致性讀導致語句級Binlog複製錯誤MySql
- 透過ORA錯誤反思sql語句規範SQL
- 通過ORA錯誤反思sql語句規範SQL
- 編譯過程導致ORA-4068錯誤編譯
- 【FGA】FGA handler中使用commit或DDL語句導致ORA-600 [4412]錯誤的再現及處理MIT
- 解決掉電導致的ORA-600(4194)錯誤
- 修改記憶體導致Ora-27100錯誤記憶體
- 資料庫升級導致ORA-918錯誤資料庫
- sql語句錯誤SQL
- 一條insert語句導致的效能問題分析(二)
- 一條insert語句導致的效能問題分析(一)
- 編譯檢視導致ORA-00600_17069錯誤編譯
- 執行merge語句報ora-00926
- 動態建立 @ViewChild 導致執行時錯誤的原因分析View
- ORA-4031導致CJQ程式出現ORA-1003錯誤
- 執行SQL語句導致mysqld的crashMySql
- impdp時parallel=4導致的錯誤Parallel
- INTERVAL分割槽插入大量資料導致ORA-4031錯誤
- ORA-25138錯誤分析
- [20141203]分析語句導致阻塞分析表.txt
- 系統日期設定不正確導致的ORA-01839錯誤
- 使用錯誤的作業系統使用者exp資料導致ORA-15186錯誤作業系統
- 一個SQL語句引發的ORA-00600錯誤排查(二)SQL
- 一個SQL語句引發的ORA-00600錯誤排查(一)SQL
- 多餘索引導致explain錯誤索引AI
- jdbc版本過低或oracle_home配置錯誤,導致ORA-28040JDBCOracle
- impdp 匯入資料導致ora-600,arguments: [klaprs_11]錯誤
- 資料庫增加SGA,導致ORA-27102: out of memory錯誤資料庫
- ORA-00600錯誤分析
- ORA-04021錯誤分析
- ORA-07445錯誤分析
- ORA-00942錯誤分析
- ORA-04031錯誤分析
- 一條sql語句導致的資料庫當機問題及分析SQL資料庫
- 一條sql語句“導致”的資料庫當機問題及分析SQL資料庫