在进行LogMiner操作时碰到了这个错误。下面描述一下错误的起因及解决的过程。

由于要查看被程序删除的一些记录,因此对重做日志进行了LogMiner的操作:

1. SQL> alter session set
2. hh24:mi:ss';  
3. 会话已更改。  
4.  
5. SQL> select * from
6. GROUP# THREAD# SEQUENCE#    BYTES   MEMBERS ARC   
7. STATUS     FIRST_CHANGE#    FIRST_TIME  
8. ------  ------- ---------   ----------  ------- ---  
9. ---------   -------------   ------------------- 
10.         1           1       3285    1073741824            
11. 2   YES     INACTIVE        1.1124E+12  2009-07-28  
12. 00:00:08  
13.         2           1       3286    1073741824            
14. 2   YES     INACTIVE    1.1124E+12  2009-07-28  
15. 00:02:20  
16.         3           1       3287    1073741824            
17. 2   NO      CURRENT
18. 01:00:13  
19.         4           1       3284    1073741824            
20. 2   YES     INACTIVE    1.1124E+12  2009-07-27  
21. 01:00:30  
22.         5           2       1457    1073741824            
23. 2   NO      CURRENT
24. 23:53:27  
25.         6           2       1454 1073741824         2  
26. YES INACTIVE    1.1124E+12  2009-07-26 00:25:45  
27.         7           2       1455 1073741824         2  
28. YES INACTIVE        1.1124E+12  2009-07-26 00:26:39  
29.         8           2       1456 1073741824         2  
30. YES INACTIVE        1.1124E+12  2009-07-26 23:53:34  
31. 已选择8行。

检查日志信息后发现要处理的是当前的日志文件:

1. SQL> select member from v$logfile where group# in
2. MEMBER  
3. -------------------------------------------------- 
4. /dev/vx/rdsk/datadg/tradedb_redo1_3_1_1g  
5. /dev/vx/rdsk/datadg/tradedb_redo1_3_2_1g  
6. /dev/vx/rdsk/datadg/tradedb_redo2_1_1_1g  
7. /dev/vx/rdsk/datadg/tradedb_redo2_1_2_1g  
8. SQL> exec
9. dbms_logmnr.add_logfile('/dev/vx/rdsk/datadg/tradedb_redo1_3  
10. _1_1g', dbms_logmnr.new)  
11. PL/SQL 过程已成功完成。  
12. SQL> exec
13. dbms_logmnr.add_logfile('/dev/vx/rdsk/datadg/tradedb_redo2_1  
14. _1_1g', dbms_logmnr.addfile)  
15. PL/SQL 过程已成功完成。  
16. SQL> exec
17. dbms_logmnr.dict_from_online_catalog)  
18. PL/SQL 过程已成功完成。  
19. SQL> create table
20. as select * from v$logmnr_contents where
21. 'ZHEJIANG' and seg_name = 'LP_PRICE_PROCESS';  
22. create table
23.              *  
24. 第 1 行出现错误:  
25. ORA-03113: 通信通道的文件结束  
26.  
27. SQL> exec
28. ERROR:  
29. ORA-03114: 未连接到 ORALCE

本来一个很简单的操作,没想到遇到了错误。一般前台出现ORA-3113错误,后台多半出现ORA-7445或ORA-600错误,下面检查alert文件:

1. Tue Jul 28 16:04:24 2009  
2. Errors in
3. /opt/oracle/admin/tradedb/udump/tradedb1_ora_10798.trc:  
4. ORA-07445: 出现异常错误: 核心转储 [kdodpm()+2068] [SIGSEGV]  
5. [Invalid permissions for
6. [] []  
7. 在alert文件中果然出现了ORA-7445错误,错误参数为kdodpm。检查  
8. 这个错误对应的trace文件:  
9. *** 2009-07-28 15:59:15.046  
10. *** SERVICE NAME:(SYS$USERS) 2009-07-28 15:59:15.027  
11. *** SESSION ID:(282.47827) 2009-07-28 15:59:15.027  
12. * kjdrpkey2hv: called with
13. *** 2009-07-28 16:04:24.179  
14. Exception signal: 11 (SIGSEGV), code: 2 (Invalid permissions  
15. for
16. [0x10285aa34, kdodpm(  
17. )+2068]  
18. *** 2009-07-28 16:04:24.186  
19. ksedmp: internal or
20. ORA-07445: 出现异常错误: 核心转储 [kdodpm()+2068] [SIGSEGV]  
21. [Invalid permissions for
22. [] []  
23. Current SQL statement for
24. create table
25. as select * from v$logmnr_contents where
26. 'ZHEJIANG' and seg_name = 'LP_PRICE_PROCESS'
27. ----- Call Stack Trace ----- 
28. calling                 call        entry                     
29. argument values in
30. location                type        point                     
31. (? means dubious value)      
32. --------------------    --------    --------------------     
33. ---------------------------- 
34. ksedmp()+744            CALL        ksedst()                  
35. 000000300 ? 1066DE17C ?  
36.                                                       
37. 000000000 ? 1066DAC70 ?  
38.                                                       
39. 1066D99D8 ? 1066DA3D8?

显然问题是LogMiner操作造成的。Oracle从9i开始就提供了LogMiner功能,到10g已经比较稳定了,再加上平时使用LogMiner很少出现错误,那么此次出错应是由于一些特殊的操作或配置导致的。如果说当前这个LogMiner操作与其他普通的操作有什么不同的话,那么主要是两点:一个是当前为RAC环境,LogMiner要同时对两个实例的日志进行分析;另一个就是当前分析的日志是ONLINE日志。

由于RAC环境的日志对于任何一个实例都是可以访问的,理论上不大可能出现上面的问题,可见多半是当前日志造成的问题。切换当前日志,然后再次执行同样的操作:

1. SQL> conn / as
2. 已连接。  
3. SQL> alter session set
4. hh24:mi:ss';  
5. 会话已更改。  
6. SQL> select group#, status from v$log where
7. 'CURRENT';  
8. GROUP# STATUS  
9. ----------  ---------------- 
10. CURRENT
11. CURRENT
12. 已选择2行。  
13. SQL> select member from v$logfile where group# in
14. MEMBER  
15. -------------------------------------------------- 
16. /dev/vx/rdsk/datadg/tradedb_redo1_3_1_1g  
17. /dev/vx/rdsk/datadg/tradedb_redo1_3_2_1g  
18. /dev/vx/rdsk/datadg/tradedb_redo2_1_1_1g  
19. /dev/vx/rdsk/datadg/tradedb_redo2_1_2_1g  
20. 已选择4行。  
21. SQL> alter system archive log current;  
22. 系统已更改。  
23. SQL> select group#, status from v$log where
24. 'CURRENT';  
25. GROUP# STATUS  
26. ----------  ---------------- 
27. CURRENT
28. CURRENT
29. 已选择2行。  
30. SQL> exec
31. dbms_logmnr.add_logfile('/dev/vx/rdsk/datadg/tradedb_redo1_3  
32. _1_1g', dbms_logmnr.new)  
33. PL/SQL 过程已成功完成。  
34. SQL> exec
35. dbms_logmnr.add_logfile('/dev/vx/rdsk/datadg/tradedb_redo2_1  
36. _1_1g', dbms_logmnr.addfile)  
37. PL/SQL 过程已成功完成。  
38. SQL> exec
39. dbms_logmnr.dict_from_online_catalog)  
40. PL/SQL 过程已成功完成。  
41. SQL> create table
42. as select * from
43. where seg_owner = 'ZHEJIANG'
44. and seg_name = 'LP_PRICE_PROCESS';  
45. 表已创建。

切换日志后LogMiner分析的日志不再是ONLINE日志文件,问题不再出现。

在出现错误时不要着急,如能冷静地思考当前的操作有何特殊之处,往往可以迅速地定位并解决问题。