oracle经常锁表、ORA-01555 快照过旧怎么办?深入解决办法!
最近生产环境oracle数据库经常锁表,很影响客户使用,现将解决办法记录如下,希望能帮助被同样问题困扰的码友。
第一步,查找锁表语句,sql如下
select l.session_id sid ,s.serial#,l.locked_mode,l.opacle_username,s.user#,l.os_user_name,s.machine,s.terminal,a.sql_text,a.acttion from v
s
q
l
a
r
e
a
a
,
v
sqlarea a,v
sqlareaa,vsession s,v$locked_object l where l.session_id = s.sid and s.prev_sql_addr = a.address;
第二步,分析问题。通过上面语句,我们已经发现是有两个定时任务的存储过程执行缓慢,又同时操作两个大表,导致资源竞争,还有缓存undo空间占满,并发导致快照过旧的问题。经过对存储过程的分析,发现存在无意义的sql嵌套问题,还有两个千万级数据量的表有多个组合索引。
第三步,解决问题。经过分析,现在问题已经明确,就是sql冗杂和索引滥用引起的问题。解决办法就是对症下药,把大表索引重新建立,只对经常用到的字段建立单个B树索引,对经常用到的查询条件才建立联合索引。sql语句重新编写,去掉冗余的嵌套,还有注意不能导致索引失效,具体可参看下面的链接。
经过这次处理,存储过程执行的效率大大提高,原来半天跑完一次,现在只需要十几分钟就可以了。
另外,锁表的并发症状是ora-01555 快照过旧,这是由于在对大表进行查询的过程中,有insert或者update操作,为保证数据一致性,新数据暂时存储在undo空间,但是undo有上限和存储时效,一般15分钟。查询还没有结束、新的数据又来了、undo空间已达上限、有效时间到期,导致初始存储的数据被篡改,这时查询结束,插入数据时就会报这个错误。
链接: link.