資料泵匯入分割槽表統計資訊報錯(四)

yangtingkun發表於2009-08-11

今天在進行資料泵匯入操作時,發現一個bug

這篇文章描述問題的解決過程。

資料泵匯入分割槽表統計資訊報錯(一):http://yangtingkun.itpub.net/post/468/456176

資料泵匯入分割槽表統計資訊報錯(二):http://yangtingkun.itpub.net/post/468/456378

資料泵匯入分割槽表統計資訊報錯(三):http://yangtingkun.itpub.net/post/468/489067

 

 

看來透過檢查資料字典資訊是找不到什麼問題的原因了,只有透過手工執行收集統計資訊的過程來嘗試發現問題。

為了避免bug意外被解決所導致的問題無法重現,同時也為了可以在解決bug的過程中使用一些特別的手段而不影響使用者的使用,這裡透過備份建立了一個測試環境,下面的操作是在測試環境中執行。

首先修改統計資訊對應的JOBNEXT_DATE,使其在後臺執行,檢查收集統計資訊後,測試資料庫上是否能重現問題:

SQL> SELECT JOB, WHAT FROM USER_JOBS;

       JOB WHAT
---------- ------------------------------------------------------------
        27 dbms_stats.gather_schema_stats(user, cascade => true);

SQL> EXEC DBMS_JOB.NEXT_DATE(27, SYSDATE)

PL/SQL 過程已成功完成。

SQL> COMMIT;

提交完成。

等待一段時間後檢查USER_TABLES,發現除了3個分割槽表外,其他的物件的統計資訊都收集了:

SQL> SELECT TABLE_NAME, LAST_ANALYZED FROM USER_TABLES;

TABLE_NAME                     LAST_ANALYZED
------------------------------ -------------------
ORD_ORDER_CHECK                2009-08-07 16:11:55
ORD_ORDER_CHECK_TERM           2009-08-07 16:11:55
ORD_ORDER_ITEM_NO_FOSHAN       2009-08-07 16:11:55
ORD_ORDER_ITEM_NO_SHUDE        2009-08-07 16:11:55
ORD_ORDER_OOS_HISTORY          2009-08-07 16:11:57
ORD_ORDER_PAY                  2009-08-07 16:12:02
ORD_ORDER_RETURN               2009-08-07 16:16:24
ORD_ORDER_TOTAL_FOSHAN         2009-08-07 16:16:26
ORD_ORDER_TOTAL_SHUDE          2009-08-07 16:16:26
ORD_PURCHASE                   2009-08-07 16:16:37
ORD_PURCHASE_ITEM              2007-05-03 15:33:17
ORD_ORDER_ITEM                 2007-05-03 15:30:25
ORD_ORDER                      2007-05-03 15:23:42
ORD_ORDER_RECEIVE              2009-08-07 16:15:00

已選擇14行。

SQL> SELECT TABLE_NAME FROM USER_PART_TABLES;

TABLE_NAME
------------------------------
ORD_ORDER
ORD_ORDER_ITEM
ORD_PURCHASE_ITEM

如果JOB自動執行存在問題,那麼嘗試手工呼叫RUN過程:

SQL> EXEC DBMS_JOB.RUN(27)              

PL/SQL 過程已成功完成。

SQL> SELECT TABLE_NAME, LAST_ANALYZED FROM USER_TABLES;

TABLE_NAME                     LAST_ANALYZED
------------------------------ -------------------
ORD_ORDER_CHECK                2009-08-07 16:23:53
ORD_ORDER_CHECK_TERM           2009-08-07 16:23:54
ORD_ORDER_ITEM_NO_FOSHAN       2009-08-07 16:23:54
ORD_ORDER_ITEM_NO_SHUDE        2009-08-07 16:23:54
ORD_ORDER_OOS_HISTORY          2009-08-07 16:23:56
ORD_ORDER_PAY                  2009-08-07 16:24:00
ORD_ORDER_RETURN               2009-08-07 16:29:14
ORD_ORDER_TOTAL_FOSHAN         2009-08-07 16:29:16
ORD_ORDER_TOTAL_SHUDE          2009-08-07 16:29:16
ORD_PURCHASE                   2009-08-07 16:29:23
ORD_PURCHASE_ITEM              2007-05-03 15:33:17
ORD_ORDER_ITEM                 2007-05-03 15:30:25
ORD_ORDER                      2007-05-03 15:23:42
ORD_ORDER_RECEIVE              2009-08-07 16:27:04

已選擇14行。

問題依舊,既然透過JOB呼叫存在問題,嘗試手工執行DBMS_STATS包:

SQL> EXEC dbms_stats.gather_schema_stats(user, cascade => true);

PL/SQL 過程已成功完成。

SQL> SELECT TABLE_NAME, LAST_ANALYZED FROM USER_TABLES;

TABLE_NAME                     LAST_ANALYZED
------------------------------ -------------------
ORD_ORDER_CHECK                2009-08-07 16:39:25
ORD_ORDER_CHECK_TERM           2009-08-07 16:39:26
ORD_ORDER_ITEM_NO_FOSHAN       2009-08-07 16:39:26
ORD_ORDER_ITEM_NO_SHUDE        2009-08-07 16:39:26
ORD_ORDER_OOS_HISTORY          2009-08-07 16:39:28
ORD_ORDER_PAY                  2009-08-07 16:39:33
ORD_ORDER_RETURN               2009-08-07 16:44:03
ORD_ORDER_TOTAL_FOSHAN         2009-08-07 16:44:06
ORD_ORDER_TOTAL_SHUDE          2009-08-07 16:44:06
ORD_PURCHASE                   2009-08-07 16:44:14
ORD_PURCHASE_ITEM              2007-05-03 15:33:17
ORD_ORDER_ITEM                 2007-05-03 15:30:25
ORD_ORDER                      2007-05-03 15:23:42
ORD_ORDER_RECEIVE              2009-08-07 16:42:44

已選擇14行。

手工呼叫DBMS_STATS包收集當前SCHEMA的物件同樣會遺漏3個分割槽表,下面直接以表級的方式收集ORD_ORDER表的統計資訊:

SQL> exec dbms_stats.gather_table_stats(user, 'ORD_ORDER')
BEGIN dbms_stats.gather_table_stats(user, 'ORD_ORDER'); END;

*
1 行出現錯誤:
ORA-20005: object statistics are locked (stattype = ALL)
ORA-06512:
"SYS.DBMS_STATS", line 13182
ORA-06512:
"SYS.DBMS_STATS", line 13202
ORA-06512:
line 1


SQL> exec dbms_stats.gather_table_stats(user, 'ORD_ORDER_ITEM')
BEGIN dbms_stats.gather_table_stats(user, 'ORD_ORDER_ITEM'); END;

*
1 行出現錯誤:
ORA-20005: object statistics are locked (stattype = ALL)
ORA-06512:
"SYS.DBMS_STATS", line 13182
ORA-06512:
"SYS.DBMS_STATS", line 13202
ORA-06512:
line 1

收集統計資訊的過程報錯了。這是一個好訊息,有了錯誤資訊就容易定位問題了,如果沒有報錯且系統還不正常,問題才更難解決。

而且這個錯誤資訊其實已經很明確了,表的統計資訊被鎖住了,而OracleDBMS_STATS包就有UNLOCK的過程:

SQL> exec dbms_stats.unlock_table_stats(user, 'ORD_ORDER')

PL/SQL 過程已成功完成。

SQL> exec dbms_stats.gather_table_stats(user, 'ORD_ORDER')

PL/SQL 過程已成功完成。

SQL> SELECT TABLE_NAME, LAST_ANALYZED FROM USER_TABLES;

TABLE_NAME                     LAST_ANALYZED
------------------------------ -------------------
ORD_ORDER_CHECK                2009-08-07 16:39:25
ORD_ORDER_CHECK_TERM           2009-08-07 16:39:26
ORD_ORDER_ITEM_NO_FOSHAN       2009-08-07 16:39:26
ORD_ORDER_ITEM_NO_SHUDE        2009-08-07 16:39:26
ORD_ORDER_OOS_HISTORY          2009-08-07 16:39:28
ORD_ORDER_PAY                  2009-08-07 16:39:33
ORD_ORDER_RETURN               2009-08-07 16:44:03
ORD_ORDER_TOTAL_FOSHAN         2009-08-07 16:44:06
ORD_ORDER_TOTAL_SHUDE          2009-08-07 16:44:06
ORD_PURCHASE                   2009-08-07 16:44:14
ORD_PURCHASE_ITEM              2007-05-03 15:33:17
ORD_ORDER_ITEM                 2007-05-03 15:30:25
ORD_ORDER                      2009-08-07 17:27:32
ORD_ORDER_RECEIVE              2009-08-07 16:42:44

已選擇14行。

對於DBMS_STATS.GATHER_SCHEMA_STATS過程來說,發現一些表的統計資訊被鎖定,自動跳過了這些表的統計資訊的收集過程,因此一致沒有報錯。本來以為要對DBMS_STATS包的執行過程進行TRACE,然後分析TRACE檔案,沒想到問題這麼輕易就解決了。

 

 

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

相關文章