ITPub博客

首页 > 数据库 > 数据库开发技术 > UNDO表空间损坏的处理

UNDO表空间损坏的处理

原创 数据库开发技术 作者:charsi 时间:2012-06-15 14:26:20 0 删除 编辑

一个半生产的Oracle数据库.数据库版本Oracle9.2.0.8
数据库为非归档模式运行.

因为要处理的数据量较大,所以在周五临下班前,在后台执行了两个个大数据量的insert插入脚本。
结果周一来的时候,发现那个脚本还没有执行完成.

于是kill操作系统进程,kill Oracle session.然后从v$session中看到session的状态变为KILLED之后,又在操作系统层面上kill数据库的用户进程.
然后看到数据库的UNDO一直没有释放,就想直接重启数据库得了.使用shudown immediate等了很久没停下来,这时候数据库已经处于HANG的状态,于是直接shudown abort。
后来的结果证明这种处理方式简单粗暴,结果是引发了更大麻烦.

再启动数据库之后,UNDO仍然没有释放.
select sid,seq#,event from v$sesion_wait;
看到的部分内容如下:
19 7820 db file sequential read
28 7531 db file sequential read
27 7920 db file sequential read
20 7705 db file sequential read
23 10569 db file sequential read
24 7433 db file sequential read
25 7577 db file sequential read
12 1624 wait for stopper event to be increased SMON session
21 1626 wait for a undo record P001 session

也就是说,这时候是由于一个大的事务回滚,回滚量较大,达到一个阈值,SMON就会使用并发进程来处理。这时候查询v$px_session也可以看到SMON产生了6个并发进程在处理。
在网上找了一个方法,修改fast_start_parallel_rollback参数由默认值LOW改为false,即不使用并发处理回滚.

这时候使用shutdown immediate停止数据库都特别慢,所以我都使用shutdown abort的方式.
alter system set fast_start_parallel_rollback = false;
重启数据库.

但是问题还是解决不了.这时候smon的等待事件变成了db file sequential read
而UNDO表空间的空间一直不能得到释放.
在alert日志中出现了下面的信息:

SMON: mark undo segment 1 as available
SMON: about to recover undo segment 2
SMON: mark undo segment 2 as available
SMON: about to recover undo segment 1
SMON: mark undo segment 1 as available
SMON: about to recover undo segment 2
SMON: mark undo segment 2 as available
SMON: about to recover undo segment 1
SMON: mark undo segment 1 as available
SMON: about to recover undo segment 2
SMON: mark undo segment 2 as available
SMON: about to recover undo segment 1
SMON: mark undo segment 1 as available
SMON: about to recover undo segment 2
SMON: mark undo segment 2 as available
SMON: about to recover undo segment 1
SMON: mark undo segment 1 as available
SMON: about to recover undo segment 2

查看dba_rollback_segs视图,也看到有有几个回滚段的状态为PARTLY AVAILABLE
从这些信息来看,说明回滚段中的内容已经有部分被损坏了。
原因在于数据库是处于非归档模式,而在回滚事务的过程中执行了好几次的shutdown abort操作。

没办法,只能删除现有的UNDO表空间然后重建UNDO表空间.
create undo tablespace UNDO1 datafile '/xxxx/yyyy/zzz/undo01.dbf' size 10240M reuse autoextend off;
alter system set undo_tablespace=UNDO1;
alter tablespace UNDO offline;


这时候问题来了。
当我将UNDO表空间offline之后,原来做的大事务操作insert的表就有问题了。当我全表扫描的时候,它会提示找不到数据文件(offline的那个表空间的数据文件).
这个应该也好理解,因为回滚段中需要回滚的数据正好是那个表中的数据。
解决这个问题,只能将UNDO表空间online之后,重组那几个表。

确认数据库中所有的表都没有问题之后,删除UNDO表空间.
出现的错误是
SQL> drop tablespace UNDO ;
drop tablespace UNDO
*
ERROR at line 1:
ORA-01548: active rollback segment '_SYSSMU1$' found, terminate dropping
tablespace

这种情况下,只能使用下面的方法删除UNDO表空间:
1.创建pfile
create pfile="/xxxx/yyyy/initSID.ora" from spfile;
2.修改pfile,增加_corrupted_rollback_segments参数
_corrupted_rollback_segments=(_SYSSMU1$,_SYSSMU2$)
这里面的_SYSSMU1$,_SYSSMU2$是我从dba_rollback_segs中看到状态为PARTLY AVAILABLE的段名
3.使用这个参数启动数据库
startup pfile="/xxxx/yyyy/initSID.ora"
4.删除UNDO表空间
drop tablespace UNDO including contents and datafiles;
5.重启数据库。
这次使用原来的spfile启动即可。

这样,这次出现的问题终于得到了解决。

通过这次事件,告诉我们:
1.数据库使用非归档模式确实是不安全的;
2.处理问题一定得慎用简单粗暴的方式
3.处理问题的时候一定要非常清楚这一步操作的用处和用途。切忌病急乱投医,否则问题可能越来越麻烦。

最后庆幸一下,幸亏这个数据库不是很重要。

[@more@]

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/23850820/viewspace-1058539/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2010-05-04

  • 博文量
    96
  • 访问量
    406716