目的本文档主要介绍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可能出现的情况有所不同,两种比较经常出现的方式如下所示:实例1ORA-07445: exception encountered: core dump[run_some_SQL()+268] [SIGBUS] [Invalid address alignment] [] [] []实例2ORA-07445: exception encountered: core dump [10] [2122262800] [261978112] [] [] []实例1说明:错误发生在函数run_some_sql()中进程收到的信号是SIGBUS一些其他相关信息。
实例2给定的信息相对较少没有给出导致错误的函数名称进程收到的信息是signal 10一些在本次错误中无用的信息错误发生时需要搜集哪些信息1,alert.log文件,这个文件至少可以查出ora-07445错误发生前后的其他相关错误,确认init.ora文件信息也包含在里边。
2,自实例上次启动以来所有的ora-07445和ora-00600错误及其跟踪文件。
Trace file文件中信息的相关说明*** 2002-05-08 23:35:18.224 <---timestamp*** SESSION ID:(194.14075) 2002-05-08 23:35:18.202Exception signal: 10 (SIGBUS), code: 1 (Invalid address alignment),addr: 0x41e7, PC: kjrfnd()+44*** 2002-05-08 23:35:19.404ksedmp: internal or fatal errorORA-07445: exception encountered: core dump [kjrfnd()+44] [SIGBUS] [Invalidaddress alignment] [16871] [] [] <----the errrorCurrent SQL statement for this session: <---the current SQL statementDELETE FROM MY_TABLE WHERE COL1 < :b1----- PL/SQL Call Stack -----object line objecthandle number namee560c680 35 anonymous blocke560c680 290 anonymous block----- Call Stack Trace ----- <----Stack trace starts herecalling call entry argument values in hexlocation 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()+019FA400 ? FFBE63AC ? 0 ?E2A2ED40 ? 19FA400 ? 8 ?ksqcmi()+3356 CALL ksipget()+0 10020 ?FFBE6648 ? EE15430C ?0 ? 0 ? 0 ?ksqgtl()+944 CALL ksqcmi()+0FFBE65A8 ? 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()+0FFBEFA80 ? 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中主要描述了怎么查找当前错误的执行语句。
但我们需要注意的是,当前问题可能是由于前面几个相关的其他语句执行时的上下文环境决定是否能出问题,所以有可能找到当前语句但无法重现问题。
在找到系统出错时执行的语句后我们需要确认下面的问题:是不是只有在当前参数时系统才会报错是否在每天的固定时间点出错出错跟哪些系统操作有主要关联,比如数据库的备份或者其他高消耗操作是在特定的应用程序和用户下出错还是所有的程序和用户都出错第一次报错是什么时间,当时对系统做了什么改变系统出错时有没有伴随其他的错误产生如何找出错误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 nvarchar22 number8 long11 rowid12 date23 raw24 long raw96 char112 clob or nclob113 blob114 bfileMxl: the maximum lenthScl: the scale(for number columns)Pre: the precision(for number columns)Value: 绑定变量的值通过解析上面的内容,你可以得到绑定变量的类型及其数据值,也有一些情况(非常少),你在bind *后面找不到values字节,那么我们就不能通过这种方式得到绑定变量的值。
ExamplesIn 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: 1Cursor Dump:----------------------------------------so we are looking for cursor 2:----------------------------------------Cursor 2 (20139ad0): CURFETCH curiob: 2013bca4curflg: 7 curpar: 20139ab0curusr: 0 curses 587a250ccursor name: select text from view$ where rowid=:1child pin: 50a5b650, child lock: 50a5a628,parent lock: 50a5a844xscflg: 20141466, parent handle: 4f348490, xscfl2: 400nxt: 2.0x0000006c nxt: 1.0x000001d8Cursorframe allocation dump:frm: -------- Comment -------- Size Seg Offbhp size: 52/560bind 0: dty=11 mxl=16(16) mal=00scl=00 pre=00 oacflg=18 oacfl2=1 size=16offset=0bfp=2013e9f4 bln=16 avl=16 flg=05value=0000138C.0046.0004The current SQL is:select text from view$ where rowid=:1and the bind variable translates into::1 ~ bind 0 - ROWID (dty=11), value = 0000138C.0046.0004so 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).Example 2:The cursor dump starts with:******************** Cursor Dump ************************ Current cursor: 11, pgadep: 1Cursor Dump:----------------------------------------ie. we should look for cursor 11:----------------------------------------Cursor 11 (202cb9f0): CURBOUND curiob: 202f8b04curflg: dd curpar:0 curusr: 0 curses 30047c7ccursor name: SELECT LOCKID FROM DBMS_LOCK_ALLOCATED WHERE NAME =:b1 FOR UPDATEchild pin:0, child lock: 300dc9b4, parent lock: 301730b8xscflg: 1151421, parent handle: 3025b4dcbind 0: dty=1 mxl=32(00) mal=00 scl=00 pre=00 oacflg=01No bind buffers allocated----------------------------------------The current SQL statement is then:SELECT LOCKID FROM DBMS_LOCK_ALLOCATED WHERE NAME = :b1 FOR UPDATEThe bind variable :b1 is of type VARCHAR2(32) (dty=1, mxl=32), but no value has been assigned to it at the time of the dump ("No bind buffers allocated").Example 3:******************** Cursor Dump ************************ Current cursor: 2, pgadep: 0Cursor Dump:----------------------------------------...----------------------------------------Cursor 2 (20140444): CURNULL curiob: 0curflg: 44 curpar: 0 curusr: 0 curses 701dc94c----------------------------------------In this case there is no SQL being executed at the time of the dump. Example 4:******************** Cursor Dump ************************ Current cursor: 1, pgadep: 0pgactx: ccf361c0ctxcbk: 0 ctxqbc: 0 ctxrws: 0Cursor Dump:----------------------------------------Cursor 1 (400d9478): CURBOUND curiob:400e43d8curflg: 4c curpar: 0 curusr: 0 curses d5348f80cursor name: BEGINmyparser.convert('/tmp','workflow000_2.log',2);END;child pin: d14a4d70, child lock: d1589968, parent lock:d14c64a0xscflg: 100064, parent handle: d083f1c0, xscfl2: 4040408 nxt: 1.0x000000a8Cursor frame allocation dump:frm: -------- Comment -------- Size Seg Off----------------------------------------No binds included, so the SQL statement is the PL/SQL block: BEGIN myparser.convert('/tmp','workflow000_2.log',2); END;。