今天开发的同事发给我一个问题,在运行某一个Job的时候抛出了ORA-01555错误,希望我们看看从数据库层面能不能发现什么。
错误日志如下:
Function: EntitySQLCursor::query
Line number: 113
Time: Thu Jul 2 22:52:46 2015
Message text: (PE1-000143) Internal IO Framework Database Error, message ORA-01555: snapshot too old: rollback segment number 22 with name "_SYSSMU22_234950861$" too small, code 1555.
看这个错误,似乎是Oracle分配的回滚段太小导致的。对于这个问题,因为已经过去了一段时间,所以能够合理分析的一种途径就是使用ash.
根据错误信息中的时间戳,基本定位在了22:52~22:53这一分钟之内,抓取了一个ash报告。
因为信息针对性更强,可以很清晰的看到在那一分钟之内数据库层面有一些查询和dml的语句在运行,有些走了全表扫描,有些走了索引扫描。
Top SQL with Top Events
SQL IDPlanhashSampled # of Executions% ActivityEvent% EventTop Row Source% RwSrcSQL Textfzn01wc5pg2dg 1199754052 2 15.67 CPU + Wait for CPU 11.75 TABLE ACCESS - FULL 11.75 SELECT /*+ ALL_ROWS USE_NL ("A...
db file sequential read 2.61 TABLE ACCESS - FULL 2.61
direct path read 1.31 TABLE ACCESS - FULL 1.31
5q2mguqdcrq4a 421773076 1 12.01 db file sequential read 12.01 INDEX - RANGE SCAN 7.05 SELECT RE.L3_NET_START_TIME, R...
a793wrq0q27c5 201265388 1 10.70 db file sequential read 8.09 DELETE 8.09 delete from RATED_EVENT WHERE ...
CPU + Wait for CPU 1.57 DELETE 1.57
direct path read temp 1.04 DELETE 1.04
496x3fkydc1xj 84305990 1 9.92 db file sequential read 8.62 INDEX - RANGE SCAN 8.62 ** SQL Text Not Available **
CPU + Wait for CPU 1.31 INDEX - RANGE SCAN 1.31
dm1d93bw2jdzc 2843169790 27 8.09 db file sequential read 4.70 INDEX - RANGE SCAN 2.09 select sk.rowid , sk.subscribe...
CPU + Wait for CPU 3.39 SELECT STATEMENT 2.35
需要重点关注的是全表扫描的语句和DML语句。
先来看看全表扫描的语句。
SELECT /*+ ALL_ROWS USE_NL ("AC1_CONTROL_HIST") FULL ("AC1_CONTROL_HIST") */ .... from "AC1_CONTROL_HIST" WHERE "CUR_PGM_NAME"='RGD' AND "IDENTIFIER"=:1
语句输出字段较多,但是相关的表只有一个,这个表从表名可以看出是一个历史表,数据量相比也是相当大的,一查看统计信息,数据量都在亿级以上。
这么大的表,使用了hint,指定全表扫描,相比是某些地方需要吧,带着疑问查看了索引的信息,而其中的主键索引就是IDENTIFIER字段开始的。
所以从这个角度来看,这个问题是一个很明显的问题,因为使用Hint不当导致了,本该走索引扫描的查询结果走了极为消耗资源的全表扫描。