昨天陈娟吉处理平果人民医院物资领用单打印报错的问题,没处理了,晚上医院网管找到我,现将整个分析处理过程共享给大家,希望能引导大家在遇到一些未知的问题时,有较为清晰的处理思路,而不是无从下手。
医院环境:
ZLHIS版本: ZLHIS9
ORACLE版本: 10gR2 无补丁
服务器OS: SERVER 2003
故障现象:
陈娟吉修改医院的报表,将数据库的优化模式由all_rows修改为choose后,物资领用管理模块在打印预览单据的时候,提示:
“未知错误,发生在oraOLEDB...”,具体帮助信息为“ORA-03113,通信信道的文件结束”,然后再确定,提示“ORACLE不可用”。整个导航台程序断开,在PLSQL中执行报表也是如此。陈娟吉当时给我的分析是如果屏蔽掉报表语句中的“and 入出系数=-1”就不会有这个错误了。
分析处理:
1、初步分析-网上搜索
网上百度了一下"0RA-03113"错误,发现大家都说这是一个Oracle类似ORA-600的“经典错误”,大部分说是和网络通讯有关,尝试按itpub等主流论坛的一些帖子去分析。由于是修改优化模式后出现,怀疑是修改优化模式为choose导致执行计划变更,因为choose模式下,如果表有统计信息,将使用cbo模式,如果没有统计信息,将使用rbo模式,而我们原来使用all_rows优化器,应该有统计信息,而统计信息,也应该有很长一段时间没计算了。
2、初步处理-还原模式
初步设想还原all_rows优化模式,并重新计算统计信息,看是否能回归修改前的状态,解决问题。
ALTER SYSTEM SET optimizer_mode='ALL_ROWS' SCOPE=SPFILE; ---将优化器修改为ALL_ROWS
select 'analyze table '||tname||' compute statistics;' from tab where tabtype='TABLE' ---选择出计算语句,在PLSQL命令窗口进行计算。
经过漫长的1个多小时计算,问题依旧。
3、日志分析-alter.log,udump目录下的trace文件
alter_{sid}.log就像windows的日志查看器一样,记录了数据库的所有变更和报警信息,在分析处理错误的时候,非常关键。我远程连过去看到alter_orcl.log文件竟然有近200m,而udump目录下的trace文件在前几天调整优化模式后,日志也异常频繁,平均几分钟一个几m的日志,由于较晚了,让管理员打包发了给我,自己继续分析。
大的日志文件最好用editplus等专业文本编辑软件打开,记事本这些就别想了。发现里面基本都是 “db_recovery_file_dest_size”空间占满的报警信息,并没有ORA-03113的错误记录,先处理这个问题:
alter system set db_recovery_file_dest_size=10g scope=spfile; ---加大大小
alter system set log_archive_dest_state_10=defer scope=spfile; ---停用这组日志输出
接下来分析udump里的trace文件,终于找到出错的语句的具体报错了:
*** ACTION NAME:(Main session) 2008-03-26 23:03:20.921
*** MODULE NAME:(PL/SQL Developer) 2008-03-26 23:03:20.921
*** SERVICE NAME:(orcl) 2008-03-26 23:03:20.921
*** SESSION ID:(350.62) 2008-03-26 23:03:20.921
*** 2008-03-26 23:03:20.921
ksedmp: internal or fatal error
ORA-07445: 出现异常错误: 核心转储 [ACCESS_VIOLATION] [lnxneg+135] [PC:0x4B50C07] [ADDR:0x3] [UNABLE_TO_WRITE] []
Current SQL statement for this session:
SELECT a.no, a.批次,序号,
('【' || b.编码 || '】' || b.名称) AS 物资信息,b.规格,a.产地,
decode(/*B2*/0/*E2*/,0,b.散装单位,b.包装单位) as 单位,
a.批号,to_char(A.效期,'yyyy-mm-dd') as 效期,
A.填写数量/decode(/*B2*/0/*E2*/,0,1,b.换算系数) AS 填写数量,
A.实际数量/decode(/*B2*/0/*E2*/,0,1,b.换算系数) AS 实际数量,
0 AS 单价, a.金额,a.摘要,a.填制人,a.填制日期,
a.审核人,a.审核日期,c.名称 as 发料库房, d.名称 as 领料部门
FROM 物资收发记录 a, 物资目录 b, 部门表 c, 部门表 d
Where a.物资id = b.id and a.库房id=c.id and a.发送部门id=d.id
AND 记录状态 = 1 AND a.单据 = 4 AND a.入出系数=0
and a.核算方式=4 AND a.no = /*B0*/'B0000001'/*E0*/
----- Call Stack Trace -----
*** MODULE NAME:(PL/SQL Developer) 2008-03-26 23:03:20.921
*** SERVICE NAME:(orcl) 2008-03-26 23:03:20.921
*** SESSION ID:(350.62) 2008-03-26 23:03:20.921
*** 2008-03-26 23:03:20.921
ksedmp: internal or fatal error
ORA-07445: 出现异常错误: 核心转储 [ACCESS_VIOLATION] [lnxneg+135] [PC:0x4B50C07] [ADDR:0x3] [UNABLE_TO_WRITE] []
Current SQL statement for this session:
SELECT a.no, a.批次,序号,
('【' || b.编码 || '】' || b.名称) AS 物资信息,b.规格,a.产地,
decode(/*B2*/0/*E2*/,0,b.散装单位,b.包装单位) as 单位,
a.批号,to_char(A.效期,'yyyy-mm-dd') as 效期,
A.填写数量/decode(/*B2*/0/*E2*/,0,1,b.换算系数) AS 填写数量,
A.实际数量/decode(/*B2*/0/*E2*/,0,1,b.换算系数) AS 实际数量,
0 AS 单价, a.金额,a.摘要,a.填制人,a.填制日期,
a.审核人,a.审核日期,c.名称 as 发料库房, d.名称 as 领料部门
FROM 物资收发记录 a, 物资目录 b, 部门表 c, 部门表 d
Where a.物资id = b.id and a.库房id=c.id and a.发送部门id=d.id
AND 记录状态 = 1 AND a.单据 = 4 AND a.入出系数=0
and a.核算方式=4 AND a.no = /*B0*/'B0000001'/*E0*/
----- Call Stack Trace -----
类似高难度的错误,一般搜索引擎和论坛都很难找到,又该怎么办呢?