獲取導致匯入失敗的資料(三)
前不久從一個資料庫執行匯出操作時報錯,通過直接路徑方式跳過後,匯入時候再次報錯。推測是由於源資料庫出現的異常導致表中資料超過表定義的精度。
由於源資料庫中錯誤記錄已經被刪除,因此只能想辦法從匯出的dmp檔案中獲取錯誤的記錄。
匯出、匯入過程的描述可以參考:
EXP在9R2上匯出時報錯ORA-3113和ORA-24324:http://yangtingkun.itpub.net/post/468/460647
EXP在9R2上匯出時報錯ORA-3113和ORA-24324(二):http://yangtingkun.itpub.net/post/468/460831
繼續尋找解決問題的方法,並最終獲取了導致錯誤的記錄。
獲取導致匯入失敗的資料:http://yangtingkun.itpub.net/post/468/461401
獲取導致匯入失敗的資料(二):http://yangtingkun.itpub.net/post/468/461600
BEFORE觸發器修正資料錯誤:http://yangtingkun.itpub.net/post/468/461506
在上一篇中,發現採用系統觸發器的方法只能獲取匯入操作的語句,也就是說,獲取的SQL是所有問題的起源SQL,而並非導致操作的SQL語句。
也就是說,利用觸發器獲取錯誤資訊的方式是行不通的。既然觸發器中引發錯誤的SQL無法被系統觸發器所捕獲,那麼這個SQL能不能被Oracle的V$SQL所捕獲呢。
先做個測試,看看這種由於精度問題導致的SQL語句是否可以從V$SQL中查詢到:
SQL> CREATE TABLE TEST (ID NUMBER(3));
表已建立。
SQL> INSERT INTO TEST VALUES (100);
已建立 1 行。
SQL> INSERT INTO TEST VALUES (1000);
INSERT INTO TEST VALUES (1000)
*
ERROR 位於第 1 行:
ORA-01438: 值大於此列指定的允許精確度
SQL> SELECT SQL_TEXT FROM V$SQL WHERE SQL_TEXT LIKE 'INSERT INTO TEST VALUES%';
SQL_TEXT
-----------------------------------------------------------------------------
INSERT INTO TEST VALUES (1000)
INSERT INTO TEST VALUES (100)
從上面的結果可以看到,由於精度問題出現的錯誤,是會被Oracle的V$SQL所記錄下來的,但是如果分析階段報錯,就無法從V$SQL中查詢了:
SQL> SELECT * FROM ASDFA;
SELECT * FROM ASDFA
*
ERROR 位於第 1 行:
ORA-00942: 表或檢視不存在
SQL> SELECT SQL_TEXT FROM V$SQL WHERE SQL_TEXT LIKE '%ASDFA%';
SQL_TEXT
---------------------------------------------------------
SELECT SQL_TEXT FROM V$SQL WHERE SQL_TEXT LIKE '%ASDFA%'
而根據上面最後一次的匯入報錯資訊看,似乎獲取的數值格式錯誤,出現了逗號,導致觸發器中SQL語句分析時報錯,而這種方式是無法被V$SQL所捕獲的。
下面修改SHGOV_ORDER_BAK表,將欄位改為VARCHAR2(4000),並修改觸發器,使之按照字元型別插入資料:
SQL> DROP TABLE SHGOV_ORDER_BAK;
表已丟棄。
SQL> CREATE TABLE SHGOV_ORDER_BAK
2 (
3 TRADE_RATE VARCHAR2(4000),
4 ORDER_AMOUONT VARCHAR2(4000),
5 SEND_AMOUNT VARCHAR2(4000),
6 RECEIVE_AMOUNT VARCHAR2(4000),
7 UNIT_PRICE VARCHAR2(4000),
8 MAX_PRICE VARCHAR2(4000),
9 MIN_PRICE VARCHAR2(4000),
10 PRICE_RATE VARCHAR2(4000)
11 );
表已建立。
SQL> CREATE OR REPLACE TRIGGER FIND_ERR_SQL
2 BEFORE INSERT ON SHGOV_ORDER
3 FOR EACH ROW
4 DECLARE
5 PRAGMA AUTONOMOUS_TRANSACTION;
6 BEGIN
7 EXECUTE IMMEDIATE 'INSERT INTO SHGOV_ORDER_BAK
8 (
9 TRADE_RATE, ORDER_AMOUONT, SEND_AMOUNT, RECEIVE_AMOUNT,
10 UNIT_PRICE, MAX_PRICE, MIN_PRICE, PRICE_RATE
11 )
12 VALUES
13 (
14 ''' || :NEW.TRADE_RATE || ''', ''' || :NEW.ORDER_AMOUONT || ''', '''
15 || :NEW.SEND_AMOUNT || ''', ''' || :NEW.RECEIVE_AMOUNT || ''', '''
16 || :NEW.UNIT_PRICE || ''', ''' || :NEW.MAX_PRICE || ''', '''
17 || :NEW.MIN_PRICE || ''', ''' || :NEW.PRICE_RATE || ''')';
18 COMMIT;
19 END;
20 /
觸發器已建立
下面再次執行導致操作,準備從V$SQL中獲取異常的資料:
[oracle@bjtest data]$ imp test/test file=jg080424.dmp tables=shgov_order buffer=2048000 ignore=y
Import: Release 9.2.0.4.0 - Production on 星期五 5月 9 21:29:00 2008
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
連線到: Oracle9i Enterprise Edition Release 9.2.0.4.0 - 64bit Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.4.0 - Production
經由常規路徑匯出由EXPORT:V09.02.00建立的檔案
警告: 此物件由 SHGOV 匯出, 而不是當前使用者
已經完成ZHS16GBK字符集和AL16UTF16 NCHAR 字符集中的匯入
. 正在將SHGOV的物件匯入到 TEST
. . 正在匯入表 "SHGOV_ORDER" 420835行被匯入
IMP-00009: 匯出檔案異常結束
成功終止匯入,但出現警告。
另人吃驚的是,匯入居然成功了。要知道雖然SHGOV_ORDER_BAK表的數值型別欄位全部設定為VARCHAR2(4000),但是SHGOV_ORDER表中仍然為NUMBER型別。
在觸發器中直接轉化為字元型別會報錯,無效的數值,這一點可以參考第一篇文章中的例子,但是Oracle的imp居然成功的將輸入插入進去,真是不可思議。
SQL> SELECT COUNT(*) FROM SHGOV_ORDER_BAK;
COUNT(*)
----------
420835
SQL> SELECT COUNT(*) FROM SHGOV_ORDER;
COUNT(*)
----------
420835
SQL> DESC SHGOV_ORDER
名稱 是否為空? 型別
------------------------------------ -------- --------------
ORDER_ITEM_ID NOT NULL CHAR(24)
PLAT_ID CHAR(24)
PRODUCT_ID CHAR(24)
CODE VARCHAR2(50)
C_NAME_CHN VARCHAR2(300)
MEDICAL_ID CHAR(24)
MEDICAL_CODE VARCHAR2(150)
TRADE_NAME VARCHAR2(300)
USE_UNIT VARCHAR2(150)
USED_NAME VARCHAR2(1000)
MANUFACTURE_ID CHAR(24)
MANUFACTURE_NAME VARCHAR2(150)
MANUFACTURE_ABBR VARCHAR2(150)
M_SPELL_ABBR VARCHAR2(150)
STAND_RATE VARCHAR2(150)
SPEC VARCHAR2(4000)
E_NAME_CHN VARCHAR2(150)
JX_NAME_CHN VARCHAR2(150)
WRAP_NAME VARCHAR2(150)
TAX_PRICE VARCHAR2(150)
NATIONAL_RETAIL_PRICE VARCHAR2(150)
TRADE_RATE NUMBER
MED_INSURE VARCHAR2(100)
ORDER_ID CHAR(24)
ORDER_AMOUONT NUMBER
SEND_AMOUNT NUMBER
RECEIVE_AMOUNT NUMBER
UNIT_PRICE NUMBER
SOURCE_TYPE CHAR(1)
MAX_PRICE NUMBER
HIS_NAME VARCHAR2(150)
HIS_ABBR VARCHAR2(50)
HIS_ID CHAR(24)
DEALER_NAME VARCHAR2(150)
DEALER_ID CHAR(24)
DEALER_ABBR VARCHAR2(50)
MIN_PRICE NUMBER
SENDER_NAME VARCHAR2(150)
SENDER_ID CHAR(24)
SENDER_ABBR VARCHAR2(150)
CREATE_DATE DATE
SENDE_DATE DATE
PRICE_RATE NUMBER
不管怎麼說,現在資料已經匯入了,檢查一下第31323條記錄的情況:
SQL> SELECT * FROM (SELECT ROWNUM RN, A.* FROM SHGOV_ORDER_BAK A WHERE ROWNUM < 31324)
2 WHERE RN > 31322;
RN
----------
TRADE_RATE
-------------------------------------------------------------------------------
ORDER_AMOUONT
-------------------------------------------------------------------------------
SEND_AMOUNT
-------------------------------------------------------------------------------
RECEIVE_AMOUNT
-------------------------------------------------------------------------------
UNIT_PRICE
-------------------------------------------------------------------------------
MAX_PRICE
-------------------------------------------------------------------------------
MIN_PRICE
-------------------------------------------------------------------------------
PRICE_RATE
-------------------------------------------------------------------------------
31323
-53525351485153525352.535299ED98~m~m77311951
-311951531753535353535349535353535353535345000000000000000000000000000000000000
-505353535353535252524948536449.535152534552
-000000000000000000000000000000000000
-.00000000000000195153175353535353535253535353535352505049
.00000000000000000000000000000033293311.,
-~
-515550504648000000000000
果然,數值型別已經變為完全沒有意義的亂碼了,裡面甚至還包括一些字母和標點符號。最後看看Oracle的imp匯入進去的數值型別是什麼樣子:
SQL> SELECT * FROM
2 (
3 SELECT ROWNUM RN, TRADE_RATE, ORDER_AMOUONT, SEND_AMOUNT, RECEIVE_AMOUNT,
4 UNIT_PRICE, MAX_PRICE, MIN_PRICE, PRICE_RATE
5 FROM SHGOV_ORDER
6 WHERE ROWNUM < 31324
7 )
8 WHERE RN > 31322;
RN TRADE_RATE ORDER_AMOUONT SEND_AMOUNT RECEIVE_AMOUNT UNIT_PRICE MAX_PRICE MIN_PRICE PRICE_RATE
---------- ---------- ------------- ----------- -------------- ---------- ---------- ---------- ----------
31323 -5.353E+19 -3.120E+77 -5.054E+29 -5.300E+35 -1.952E-15 3.3295E-31 -~ -5.156E+23
*** glibc detected *** sqlplus: free(): invalid next size (normal): 0x000000000cda7520 ***
======= Backtrace: =========
/lib64/libc.so.6[0x3c0a66e8a0]
/lib64/libc.so.6(cfree+0x8c)[0x3c0a671fbc]
sqlplus(safifre+0xc)[0x42c69c]
sqlplus[0x423675]
sqlplus[0x4155fa]
sqlplus[0x413a7b]
sqlplus[0x419bba]
sqlplus[0x433596]
sqlplus[0x43253b]
sqlplus[0x408433]
sqlplus[0x40780e]
/lib64/libc.so.6(__libc_start_main+0xf4)[0x3c0a61d8a4]
sqlplus[0x40773a]
======= Memory map: ========
00400000-00494000 r-xp 00000000 08:02 10031306 /opt/oracle/product/9.2/bin/sqlplus
00594000-0059b000 rwxp 00094000 08:02 10031306 /opt/oracle/product/9.2/bin/sqlplus
0cd25000-0ce8c000 rwxp 0cd25000 00:00 0
3c0a200000-3c0a21a000 r-xp 00000000 08:02 3365501 /lib64/ld-2.5.so
3c0a419000-3c0a41a000 r-xp 00019000 08:02 3365501 /lib64/ld-2.5.so
3c0a41a000-3c0a41b000 rwxp 0001a000 08:02 3365501 /lib64/ld-2.5.so
3c0a600000-3c0a744000 r-xp 00000000 08:02 3365502 /lib64/libc-2.5.so
3c0a744000-3c0a944000 ---p 00144000 08:02 3365502 /lib64/libc-2.5.so
3c0a944000-3c0a948000 r-xp 00144000 08:02 3365502 /lib64/libc-2.5.so
3c0a948000-3c0a949000 rwxp 00148000 08:02 3365502 /lib64/libc-2.5.so
3c0a949000-3c0a94e000 rwxp 3c0a949000 00:00 0
3c0aa00000-3c0aa82000 r-xp 00000000 08:02 3365504 /lib64/libm-2.5.so
3c0aa82000-3c0ac81000 ---p 00082000 08:02 3365504 /lib64/libm-2.5.so
3c0ac81000-3c0ac82000 r-xp 00081000 08:02 3365504 /lib64/libm-2.5.so
3c0ac82000-3c0ac83000 rwxp 00082000 08:02 3365504 /lib64/libm-2.5.so
3c0ae00000-3c0ae02000 r-xp 00000000 08:02 3365505 /lib64/libdl-2.5.so
3c0ae02000-3c0b002000 ---p 00002000 08:02 3365505 /lib64/libdl-2.5.so
3c0b002000-3c0b003000 r-xp 00002000 08:02 3365505 /lib64/libdl-2.5.so
3c0b003000-3c0b004000 rwxp 00003000 08:02 3365505 /lib64/libdl-2.5.so
3c0b200000-3c0b215000 r-xp 00000000 08:02 3365398 /lib64/libpthread-2.5.so
3c0b215000-3c0b414000 ---p 00015000 08:02 3365398 /lib64/libpthread-2.5.so
3c0b414000-3c0b415000 r-xp 00014000 08:02 3365398 /lib64/libpthread-2.5.so
3c0b415000-3c0b416000 rwxp 00015000 08:02 3365398 /lib64/libpthread-2.5.so
3c0b416000-3c0b41a000 rwxp 3c0b416000 00:00 0
3c0ca00000-3c0ca0d000 r-xp 00000000 08:02 3365507 /lib64/libgcc_s-4.1.1-20070105.so.1
3c0ca0d000-3c0cc0c000 ---p 0000d000 08:02 3365507 /lib64/libgcc_s-4.1.1-20070105.so.1
3c0cc0c000-3c0cc0d000 rwxp 0000c000 08:02 3365507 /lib64/libgcc_s-4.1.1-20070105.so.1
3c11a00000-3c11a14000 r-xp 00000000 08:02 3365523 /lib64/libnsl-2.5.so
3c11a14000-3c11c13000 ---p 00014000 08:02 3365523 /lib64/libnsl-2.5.so
3c11c13000-3c11c14000 r-xp 00013000 08:02 3365523 /lib64/libnsl-2.5.so
3c11c14000-3c11c15000 rwxp 00014000 08:02 3365523 /lib64/libnsl-2.5.so
3c11c15000-3c11c17000 rwxp 3c11c15000 00:00 0
2aaaaaaab000-2aaaaaaad000 rwxp 2aaaaaaab000 00:00 0
2aaaaaaad000-2aaaab5fd000 r-xp 00000000 08:02 10162165 /opt/oracle/product/9.2/lib/libclntsh.so.9.0
2aaaab5fd000-2aaaab6fd000 ---p 00b50000 08:02 10162165 /opt/oracle/product/9.2/lib/libclntsh.so.9.0
2aaaab6fd000-2aaaab75c000 rwxp 00b50000 08:02 10162165 /opt/oracle/product/9.2/lib/libclntsh.so.9.0
2aaaab75c000-2aaaab76f000 rwxp 2aaaab75c000 00:00 0
2aaaab76f000-2aaaab771000 r-xp 00000000 08:02 10162044 /opt/oracle/product/9.2/lib/libwtc9.so
2aaaab771000-2aaaab870000 ---p 00002000 08:02 10162044 /opt/oracle/product/9.2/lib/libwtc9.so
2aaaab870000-2aaaab871000 rwxp 00001000 08:02 10162044 /opt/oracle/product/9.2/lib/libwtc9.so
2aaaab871000-2aaaab894000 rwxp 2aaaab871000 00:00 0
2aaaab895000-2aaaab8bf000 rwxp 2aaaab895000 00:00 0
2aaaab8e2000-2aaaab8ec000 r-xp 00000000 08:02 3365244 /lib64/libnss_files-2.5.so
2aaaab8ec000-2aaaabaeb000 ---p 0000a000 08:02 3365244 /lib64/libnss_files-2.5.so
2aaaabaeb000-2aaaabaec000 r-xp 00009000 08:02 3365244 /lib64/libnss_files-2.5.so
2aaaabaec000-2aaaabaed000 rwxp 0000a000 08:02 3365244 /lib64/libnss_files-2.5.so
2aaaac000000-2aaaac021000 rwxp 2aaaac000000 00:00 0
2aaaac021000-2aaab0000000 ---p 2aaaac021000 00:00 0
7fffe2300000-7fffe2316000 rwxp 7fffe2300000 00:00 0 [stack]
ffffffffff600000-ffffffffffe00000 ---p 00000000 00:00 0 [vdso]
Aborted
沒想到,一個簡單的查詢居然導致sqlplus直接錯誤退出。
檢查alert檔案,沒有發現對應錯誤資訊的生成。看來這種邏輯錯誤造成的資料異常還是有很大危害性的,可能會直接造成應用程式的錯誤。
像上面這個錯誤似乎是由於錯誤資料導致sqlplus在呼叫free函式的時候出現了地址錯誤,從直接被Oracle強制結束。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4227/viewspace-264934/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 獲取導致匯入失敗的資料
- 獲取導致匯入失敗的資料(五)
- 獲取導致匯入失敗的資料(四)
- 獲取導致匯入失敗的資料(二)
- 解決辦法:由於oracle版本不同導致匯入資料時失敗Oracle
- 儲存互斥失敗導致資料丟失的資料恢復成功案例資料恢復
- 獲取登入驗證碼失敗及前後端不同域導致session丟失問題分析記錄後端Session
- selinux導致sqlplus登入失敗LinuxSQL
- rman備份的時候讀取v$session_longops失敗導致備份失敗SessionGo
- sqlldr 匯入重複資料導致PK INDEX失效SQLIndex
- DTS-073102獲取增量資料失敗
- 華納雲:sqlserver匯入資料庫失敗怎麼解決?SQLServer資料庫
- 把TXT文字匯入SQLServer 出錯:資料轉換失敗SQLServer
- wait_type SOS_WORKER導致資料庫連線失敗AI資料庫
- hibernate懶載入導致多表聯合查詢失敗
- 故障分析 | DDL 導致的 Xtrabackup 備份失敗
- Autodesk Vault: 獲取授權失敗
- imp 匯入 FK (Foreign Key) 導致資料不能正確匯入處理
- Filestream/Windows Share導致Alwayson Failover失敗WindowsAI
- linux系統重灌導致免密碼key登入失敗Linux密碼
- springboot衝突導致的發版失敗Spring Boot
- sock鎖檔案導致的MySQL啟動失敗MySql
- 糟糕的範圍管理導致專案失敗(轉)
- 使用mybatis-plus,由於表名關鍵字導致插入資料失敗MyBatis
- 源設定導致Docker映象構建失敗Docker
- stream pool設定過小導致impdp失敗
- window換行符導致Linux下sqlldr載入圖片失敗LinuxSQL
- 迴圈引用導致的json序列化失敗JSON
- appium 獲取混合頁面元素失敗APP
- ENVI匯出的tif檔案,python讀取失敗。Python
- Docker 導致阿里雲 ECS 內網互通失敗Docker阿里內網
- impdp 匯入資料導致ora-600,arguments: [klaprs_11]錯誤
- 資料泵取匯出和匯入(一)
- 企業使用ERP系統導致失敗的因素所在
- 使用impdp不當導致的資料丟失問題
- ORACLE 分割槽索引UNUSABLE導致的DML操作失敗引起的血案Oracle索引
- 11.2.0.3 ASM例項出現ORA-4031導致資料庫歸檔失敗ASM資料庫
- 記一次簡單的資料庫恢復,控制檔案不一致導致的啟動失敗。資料庫