ora-07445

目的

本文档主要介绍ora-07445错误相关内容,并给出了对这个错误的进一步诊断建议,文档主要基于unix系统编写,但原理通用。

文档适用范围

主要为DBA处理系统的ora-07445错误时使用。

0ra-07445错误的定义

当oracle服务器进程从操作系统收到一个致命的错误信息时会抛出ora-07445错误,这个错误可以被oracle后台进程或者用户进程激发。当错误被抛出时,系统会首先写一个错误日志到alert.log文件中,然后会写跟踪文件到user_dump_dest或background_dump_dest中;最后会将主存信息转储到core_dump_dest中。

操作系统有很多的非法操作设计,一个经常会碰到的情况就是,当一个进程访问一个非法地址(比如系统预留地址)时致命错误将会产生。

Ora-07445错误是一个非常普通的错误,可能在oracle的任何代码中产生,该错误代码更详细的描述需要进一步跟踪其跟踪文件。

Ora-07445的表现方式

在不同的平台上,ora-07445可能出现的情况有所不同,两种比较经常出现的方式如下所示:

实例1

ORA-07445: exception encountered: core dump [run_some_SQL()+268] [SIGBUS] [Invalid address alignment] [] [] []

实例2 
ORA-07445: exception encountered: core dump [10] [2122262800] [261978112] [] [] []

实例1说明:

l         错误发生在函数run_some_sql()

l         进程收到的信号是SIGBUS

l         一些其他相关信息。

实例2给定的信息相对较少

l         没有给出导致错误的函数名称

l         进程收到的信息是signal 10

l         一些在本次错误中无用的信息

错误发生时需要搜集哪些信息

1,  alert.log文件,这个文件至少可以查出ora-07445错误发生前后的其他相关错误,确认init.ora文件信息也包含在里边。

2,  自实例上次启动以来所有的ora-07445ora-00600错误及其跟踪文件。

 

Trace file文件中信息的相关说明

    *** 2002-05-08 23:35:18.224     <---timestamp 
*** SESSION ID:(194.14075) 2002-05-08 23:35:18.202
 
Exception signal: 10 (SIGBUS), code: 1 (Invalid address alignment), addr: 0x41e7, PC: kjrfnd()+44
 
*** 2002-05-08 23:35:19.404
 
ksedmp: internal or fatal error
 
ORA-07445: exception encountered: core dump [kjrfnd()+44] [SIGBUS] [Invalid
 
address alignment] [16871] [] []     <----the errror
 
Current SQL statement for this session:   <---the current SQL statement
 
DELETE FROM MY_TABLE WHERE COL1 < :b1
 
----- PL/SQL Call Stack -----
 
  object      line  object
 
  handle    number  name
 
e560c680        35  anonymous block
 
e560c680       290  anonymous block
 
----- Call Stack Trace -----           <----Stack trace starts here
 
calling              call      entry                argument values in hex
 
location            type   point                 (? means dubious value)
 
-------------------- -------- -------------------- ----------------------------
 
ksedmp()+168           CALL             ksedst()+0            540 ? 0 ? FFBE4F98 ?
 
                                                                                          FFBE4A3C ? FFBE4A20 ? 0 ?
 
ssexhd()+380            CALL             ksedmp()+0           3 ? 0 ? 1 ? FFBE56B8 ? 1 ?
 
                                                                                          6 ?
 
sigacthandler()+40   PTR_CALL   00000000              A ? FFBE5F10 ? 19FE000 ?
 
                                                                                          19FE000 ? 0 ? 0 ?
 
kjrfnd()+44                  PTR_CALL 00000000               A ? FFBE5F10 ? FFBE5C58 ?
 
kjrref()+176                 CALL             kjrfnd()+0            4177 ? F6A7F020 ? 0 ? 41DF ?
 
kjuocl()+732                CALL             kjrref()+0             FFBE63AC ? 19FA400 ?
 
kjusuc()+1260            CALL             kjuocl()+0            FFBE6218 ? EB5FB9A8 ?

                                                                                          EB5FB9A8 ? 5 ? 5 ? 0 ?
 
ksipget()+832             CALL             kjusuc()+0           19FA400 ? FFBE63AC ? 0 ?
 
                                                                                           E2A2ED40 ? 19FA400 ? 8 ?
 
ksqcmi()+3356            CALL             ksipget()+0          10020 ? FFBE6648 ? EE15430C ?
 
                                                                                           0 ? 0 ? 0 ?
 
ksqgtl()+944               CALL              ksqcmi()+0          FFBE65A8 ? 1 ? EDEB4C90 ?
 
                                                                                           EE1542D4 ? 1 ? 0 ?
 
<... lots of stuff deleted here ...>
 
sou2o()+20                  CALL             opidrv()+0           3C ? FFBEF784 ?19F8000 ?
 
                                                                                            2F6C6F67 ? 0 ? 0 ?
 
main()+160                   CALL             sou2o()+0            FFBEFA80 ? 3C ? 4 ?
 
                                                                                            FFBEFA70 ? 1746CF4 ?
 
                                                                                            1A06318 ?
 
_start()+220                 CALL             main()+0               0 ? FFBEFC2C ?1A1D478 ?
 
                                                                                           19F8000 ? 0 ? 0 ?
 
                                                            <----Stack trace ends here 
----- Argument/Register Address Dump -----

重现错误

如果客户可以随意的重现ora-07445错误,那么诊断并解决问题的时间将会被缩短。重现错误的第一步当然是找出造成错误的current sql。

文档Note 154170.1中主要描述了怎么查找当前错误的执行语句。但我们需要注意的是,当前问题可能是由于前面几个相关的其他语句执行时的上下文环境决定是否能出问题,所以有可能找到当前语句但无法重现问题。

在找到系统出错时执行的语句后我们需要确认下面的问题:

l         是不是只有在当前参数时系统才会报错

l         是否在每天的固定时间点出错

l         出错跟哪些系统操作有主要关联,比如数据库的备份或者其他高消耗操作

l         是在特定的应用程序和用户下出错还是所有的程序和用户都出错

l         第一次报错是什么时间,当时对系统做了什么改变

l         系统出错时有没有伴随其他的错误产生

 

 

 

如何找出错误ora-07445发生时系统执行的语句

在trace file中查找错误出现时的语句主要分两个步骤:首先找到错误发生时的执行语句,然后需要找到语句中绑定变量的值。

Step 1:Find the SQL

在跟踪文件中查找字符串“Current cursor”(一般在cursor dump段的起始部分),使用current cursor后面的数字定位出错时系统的执行语句。

如果找到的这个数字为0说明没有dump出有效的执行语句。

如果找到的这个数字n不为0,接着往下查找,定位到字符串“cursor n”其中n为刚找到的数字。从10.2版本后,你可能需要定位到字符串“cursor #n”,这里cursor name后面跟随的语句就是我们需要的sql。

另外我们也可以通过查找字符串“Current SQL statement for this session”来定位我们需要查找的sql语句,通常情况下,这个语句出现在trace file文件的开始部分。

如果定位到的sql语句中引用了变量(:a1…)那么我们需要通过下面步骤2找出绑定的变量值。

Step 2:find values of the bind variables

如果定位得到的sql语句中出现了绑定变量,那么我们将会在cursor name后面发现”bind *”之类的字符串,其中×为0到n-1的值,n为sql语句中绑定变量的个数。

对每个绑定变量都有一系列的属性说明列表,下面简单描述列表后面的属性。

Dty : databype 1 varchar2 or nvarchar2

            2 number

            8 long

            11 rowid

            12 date

            23 raw

            24 long raw

            96 char

            112 clob or nclob

            113 blob

            114 bfile

Mxl: the maximum lenth

Scl: the scale(for number columns)

Pre: the precision(for number columns)

Value: 绑定变量的值

    通过解析上面的内容,你可以得到绑定变量的类型及其数据值,也有一些情况(非常少),你在bind *后面找不到values字节,那么我们就不能通过这种方式得到绑定变量的值。

Examples

In the following we will work through some examples of how to extract the SQL statement from trace files. 

IMPORTANT: Replacing bind variables with literals can result in the optimizer choosing a different query path and thus the problem may not reproduce!

Example 1:

You should now be able to find the datatype of the bind variable (including length, scale, and precision if applicable) and the value.

The cursor dump starts with:

******************** Cursor Dump ************************ 
Current cursor: 2, pgadep: 1 
Cursor Dump: 
----------------------------------------

so we are looking for cursor 2:

---------------------------------------- 
Cursor 2 (20139ad0): CURFETCH curiob: 2013bca4 
curflg: 7 curpar: 20139ab0
curusr: 0 curses 587a250c 
cursor name: select text from view$ where rowid=:1 
child pin: 50a5b650, child lock: 50a5a628,
parent lock: 50a5a844 
xscflg: 20141466, parent handle: 4f348490, xscfl2: 400 
nxt: 2.0x0000006c nxt: 1.0x000001d8 
Cursor
frame allocation dump: 
frm: -------- Comment -------- Size Seg Off 
bhp size: 52/560 
bind 0: dty=11 mxl=16(16) mal=00
scl=00 pre=00 oacflg=18 oacfl2=1 size=16 
offset=0 
bfp=2013e9f4 bln=16 avl=16 flg=05 
value=0000138C.0046.0004 

The current SQL is:

select text from view$ where rowid=:1 

and the bind variable translates into:

:1 ~ bind 0 - ROWID (dty=11), value = 0000138C.0046.0004 

 
 
ORA-7445(evaopn2)错误

alert文件中发现这个ORA-7445错误,而且错误可以重现。

Oracle 9204 for Solaris下执行下面的SQL报错:

SQL> SELECT COUNT(*)  2 FROM  3 (  4 SELECT A.ID,C.PLAT_NAME PROVINCENAME, A.PROJECT_NAME, 5 DECODE(A.REPORT_TYPE,'1','BUYER','2','ORG','3','OTHER') REPORT_TYPE, 6 A.LINKER_NAME,A.MOBILE,  7 SUM(B.MONEY) MONEY,A.MONEY_REMARK  8 FROM AUD_PROJECT A LEFT JOIN PLT_PLAT D  9 ON D.ID = A.CITY_ID  10 INNER JOIN AUD_PROJECT_ITEM B  11 ON A.ID = B.PROJECT_ID  12 INNER JOIN PLT_PLAT C  13 ON A.PLAT_ID = C.ID  14 GROUP BY A.ID, 15 C.PLAT_NAME, 16 A.PROJECT_NAME, 17 A.REPORT_TYPE, 18 A.LINKER_NAME, 19 A.MOBILE, 20 A.MONEY_REMARK  21 ); SELECT COUNT(*) * ERROR at line 1: ORA-03113: end-of-file on communication channel

对应的alert文件中错误如下:

Errors in file /u1/oracle/admin/repdb01/udump/repdb01_ora_20739.trc: ORA-07445: exception encountered: core dump [00000001009AE204] [SIGSEGV] [Address not mapped to object] [0x000000000] [] []

trace文件中的详细信息如下:

bash-2.03$ more /u1/oracle/admin/repdb01/udump/repdb01_ora_20739.trc /u1/oracle/admin/repdb01/udump/repdb01_ora_20739.trc 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 ORACLE_HOME = /data/oracle/product/920 System name: SunOS Node name: newreport Release: 5.8 Version: Generic_117350-26 Machine: sun4u Instance name: repdb01 Redo thread mounted by this instance: 1 Oracle process number: 18 Unix process pid: 20739, image: oracle@newreport (TNS V1-V3)

*** 2008-06-05 15:22:02.785 *** SESSION ID:(26.294) 2008-06-05 15:22:02.750 Exception signal: 11 (SIGSEGV), code: 1 (Address not mapped to object), addr: 0x0, PC: [0x1009ae204, 00000001009AE204] *** 2008-06-05 15:22:02.788 ksedmp: internal or fatal error ORA-07445: exception encountered: core dump [00000001009AE204] [SIGSEGV] [Address not mapped to object] [0x000000000] [] [] Current SQL statement for this session: SELECT COUNT(*) FROM ( SELECT A.ID,C.PLAT_NAME PROVINCENAME, A.PROJECT_NAME, DECODE(A.REPORT_TYPE,'1','BUYER','2','ORG','3','OTHER') REPORT_TYPE, A.LINKER_NAME,A.MOBILE, SUM(B.MONEY) MONEY,A.MONEY_REMARK FROM AUD_PROJECT A LEFT JOIN PLT_PLAT D ON D.ID = A.CITY_ID INNER JOIN AUD_PROJECT_ITEM B ON A.ID = B.PROJECT_ID INNER JOIN PLT_PLAT C ON A.PLAT_ID = C.ID GROUP BY A.ID, C.PLAT_NAME, A.PROJECT_NAME, A.REPORT_TYPE, A.LINKER_NAME, A.MOBILE, A.MONEY_REMARK ) ----- Call Stack Trace ----- calling call entry argument values in hex  location type point (? means dubious value)  -------------------- -------- -------------------- ---------------------------- ksedmp()+328 CALL ksedst()+0 00000000B ? 000000000 ? 000000000 ? 00000004A ? FFFFFFFF7FFF9778 ? 1031D56C8 ? ssexhd()+604 CALL ksedmp()+0 000000000 ? 000103400 ? 0001035D9 ? 000102C00 ? 1035D9000 ? 1035D9C28 ? sigacthandler()+44 PTR_CALL 0000000000000000 1035E1000 ? FFFFFFFF7FFFA710 ? 000000000 ? 000000001 ? 1035DEDD8 ? 00000000B ? evaopn2()+196 PTR_CALL 0000000000000000 00000000B ? FFFFFFFF7FFFA710 ? FFFFFFFF7FFFA430 ? 00000000B ? 14D61000D0DE76BD ? 5E9E0F7A459B8AAE ? qergsRowP()+1136 CALL evaopn2()+0 6AD0F99F0 ? 00000000C ? 1035E1000 ? 000000001 ? 080000002 ? FFFFFFFF7CF69070 ?

对于这个错误函数evaopn2,查询了METALINK文档,发现文档Doc ID: Note:310099.1汇总了关于这个7445的已知的40多个bug

经过一个个的排除,发现当前的问题和这些bug都不一样。根据METALINKbug描述,这个错误函数相关的绝大部分bug和函数索引、星型连接、树型查询、分区表等问题有关。

看来从METALINK无法获取什么帮助了,只能自己来诊断,好在这个问题是可重现的,只要通过修改SQL,检查错误发生与否,就可以判断问题大概是由于什么引起的,经过简单的测试,发现问题和SQL标准连接写法、GROUP BYDECODE函数有关,去掉三个条件中的任意一个,问题不再重现:

SQL> SELECT COUNT(*)  2 FROM  3 (  4 SELECT A.ID,C.PLAT_NAME PROVINCENAME, A.PROJECT_NAME, 5 DECODE(A.REPORT_TYPE,'1','BUYER','2','ORG','3','OTHER') REPORT_TYPE, 6 A.LINKER_NAME,A.MOBILE,  7 SUM(B.MONEY) MONEY,A.MONEY_REMARK  8 FROM AUD_PROJECT A, PLT_PLAT D, AUD_PROJECT_ITEM B, PLT_PLAT C  9 WHERE D.ID(+) = A.CITY_ID  10 AND A.ID = B.PROJECT_ID  11 AND A.PLAT_ID = C.ID  12 GROUP BY A.ID, 13 C.PLAT_NAME, 14 A.PROJECT_NAME, 15 A.DATA_TYPE, 16 A.REPORT_TYPE, 17 A.LINKER_NAME, 18 A.MOBILE, 19 A.MONEY_REMARK  20 );

COUNT(*) ---------- 4

SQL> SELECT COUNT(*)  2 FROM  3 (  4 SELECT A.ID,C.PLAT_NAME PROVINCENAME, A.PROJECT_NAME, 5 A.LINKER_NAME,A.MOBILE,  6 SUM(B.MONEY) MONEY, A.MONEY_REMARK  7 FROM AUD_PROJECT A LEFT JOIN PLT_PLAT D  8 ON D.ID = A.CITY_ID  9 INNER JOIN AUD_PROJECT_ITEM B  10 ON A.ID = B.PROJECT_ID  11 INNER JOIN PLT_PLAT C  12 ON A.PLAT_ID = C.ID  13 GROUP BY A.ID, 14 C.PLAT_NAME, 15 A.PROJECT_NAME, 16 A.REPORT_TYPE, 17 A.LINKER_NAME, 18 A.MOBILE, 19 A.MONEY_REMARK  20 );

COUNT(*) ---------- 4

SQL> SELECT COUNT(*)  2 FROM  3 (  4 SELECT A.ID,C.PLAT_NAME PROVINCENAME, A.PROJECT_NAME, 5 DECODE(A.REPORT_TYPE,'1','BUYER','2','ORG','3','OTHER') REPORT_TYPE, 6 A.LINKER_NAME,A.MOBILE,  7 A.MONEY_REMARK  8 FROM AUD_PROJECT A LEFT JOIN PLT_PLAT D  9 ON D.ID = A.CITY_ID  10 INNER JOIN AUD_PROJECT_ITEM B  11 ON A.ID = B.PROJECT_ID  12 INNER JOIN PLT_PLAT C  13 ON A.PLAT_ID = C.ID  14 );

COUNT(*) ---------- 19

上面三个SQL分别将SQL标准关联写法改为Oracle的默认写法、去掉了DECODE语句、去掉了SUMGROUP BY语句,无法哪种修改方法,Oracle都可以正常执行。

至于避免这个错误的最简单方法,莫过于使用Oracle的默认连接方式,而不要使用标准连接写法。虽然Oracle支持标准SQL连接写法,但是这种方式较少使用,因此出错的可能性会比较大,而且配合其他Oracle特有的功能,比如DECODE函数,就更容易出现异常了。

下面进一步精简SQL,看看问题到底是什么引起的:

SQL> SELECT COUNT(*)  2 FROM  3 (  4 SELECT A.ID,A.PROJECT_NAME, 5 DECODE(A.REPORT_TYPE,'1','BUYER','2','ORG','3','OTHER') REPORT_TYPE, 6 SUM(B.MONEY) MONEY 7 FROM AUD_PROJECT A LEFT JOIN PLT_PLAT D  8 ON D.ID = A.CITY_ID  9 INNER JOIN AUD_PROJECT_ITEM B  10 ON A.ID = B.PROJECT_ID  11 GROUP BY A.ID, 12 A.PROJECT_NAME, 13 A.REPORT_TYPE, 14 A.MOBILE 15 ); SELECT COUNT(*) * ERROR at line 1: ORA-03113: end-of-file on communication channel

4张关联表减少到3个,问题依旧:

SQL> SELECT COUNT(*)  2 FROM  3 (  4 SELECT A.ID,A.PROJECT_NAME, 5 DECODE(A.REPORT_TYPE,'1','BUYER','2','ORG','3','OTHER') REPORT_TYPE, 6 SUM(B.MONEY) MONEY 7 FROM AUD_PROJECT A INNER JOIN AUD_PROJECT_ITEM B  8 ON A.ID = B.PROJECT_ID  9 GROUP BY A.ID, 10 A.PROJECT_NAME, 11 A.REPORT_TYPE, 12 A.MOBILE 13 );

COUNT(*) ---------- 4

SQL> SELECT COUNT(*)  2 FROM  3 (  4 SELECT A.ID,A.PROJECT_NAME, 5 DECODE(A.REPORT_TYPE,'1','BUYER','2','ORG','3','OTHER') REPORT_TYPE 6 FROM AUD_PROJECT A LEFT JOIN PLT_PLAT D  7 ON D.ID = A.CITY_ID  8 GROUP BY A.ID, 9 A.PROJECT_NAME, 10 A.REPORT_TYPE, 11 A.MOBILE 12 );

COUNT(*) ---------- 5

去掉外连接或者将3张表改为两张表,问题消失。不过现在很难说是由于缺少了一张关联表导致问题消失,还是缺少了SUM聚集操作而使得问题消失:

SQL> SELECT COUNT(*)  2 FROM  3 (  4 SELECT A.ID,A.PROJECT_NAME, 5 DECODE(A.REPORT_TYPE,'1','BUYER','2','ORG','3','OTHER') REPORT_TYPE, 6 SUM(a.id) MONEY 7 FROM AUD_PROJECT A LEFT JOIN PLT_PLAT D  8 ON D.ID = A.CITY_ID  9 GROUP BY A.ID, 10 A.PROJECT_NAME, 11 A.REPORT_TYPE, 12 A.MOBILE 13 ); SELECT COUNT(*) * ERROR at line 1: ORA-03113: end-of-file on communication channel

SQL> CONN SHENJI2 Enter password:  Connected. SQL> SELECT COUNT(*)  2 FROM  3 (  4 SELECT A.ID,A.PROJECT_NAME, 5 DECODE(A.REPORT_TYPE,'1','BUYER','2','ORG','3','OTHER') REPORT_TYPE, 6 COUNT(A.ID) MONEY 7 FROM AUD_PROJECT A LEFT JOIN PLT_PLAT D  8 ON D.ID = A.CITY_ID  9 GROUP BY A.ID, 10 A.PROJECT_NAME, 11 A.REPORT_TYPE, 12 A.MOBILE 13 ); SELECT COUNT(*) * ERROR at line 1: ORA-03113: end-of-file on communication channel

现在问题基本明确了,两张表外关联的标准写法加上DECODE语句和GROUP BY聚集操作公共构造了这个bug的产生。

根据上面的分析,应该在本地环境也可以成功的构造出这个问题:

SQL> CREATE TABLE T_7445_F (ID NUMBER, TYPE NUMBER);

表已创建。

SQL> CREATE TABLE T_7445_C (ID NUMBER);

表已创建。

SQL> INSERT INTO T_7445_F VALUES (1, 1);

已创建 1 行。

SQL> INSERT INTO T_7445_F VALUES (2, 2);

已创建 1 行。

SQL> INSERT INTO T_7445_C VALUES (1);

已创建 1 行。

SQL> INSERT INTO T_7445_C VALUES (2);

已创建 1 行。

SQL> COMMIT;

提交完成。

SQL> SELECT A.ID, DECODE(TYPE, 1, 'A', 2, 'B', 'C') TYPE, COUNT(*) 2 FROM T_7445_F A LEFT JOIN T_7445_C B 3 ON A.ID = B.ID 4 GROUP BY A.ID, TYPE 5 ;

ID T COUNT(*) ---------- - ---------- 1 A 1 2 B 1

奇怪,基本的条件已经都具备了,为什么错误还是没有出现呢,莫非与平台有关,再次观察出错的SQL语句,发现外部包含了一层COUNT(*),莫非这也是构造错误的关键因素之一:

SQL> SELECT COUNT(*) 2 FROM  3 ( 4 SELECT A.ID, DECODE(TYPE, 1, 'A', 2, 'B', 'C') TYPE, COUNT(*) 5 FROM T_7445_F A LEFT JOIN T_7445_C B 6 ON A.ID = B.ID 7 GROUP BY A.ID, TYPE 8 ) 9 ; SELECT COUNT(*) * 1 行出现错误: ORA-03113: 通信通道的文件结束

果然,外面的COUNT(*)也是构成错误的基本条件之一。

so we can eg. reconstruct the original SQL statement as:

SQL> variable a1 varchar2(20)
SQL> exec :a1 := '0000138C.0046.0004';
SQL> select text from view$ where rowid=:a1; 

Note that we construct the statement using a SQL*Plus bind variable in order to prevent the optimizer from choosing a different plan (not that it would make any difference for this particular example).

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值