科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航



ZDNet>软件频道>数据库-zhiding>Oracle回滚表空间丢失或损坏处理方法

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

  问题描述: 这是一个回滚段表空间数据文件丢失或损坏的情景,这时 oracle 不能识别相应的数据文件。当你试图 startup 数据文件时会报 ORA-1157 , ORA-1110 ,并且可能会伴随着标识操作系统级别的错误。

来源:中国IT实验室 2007年09月30日

关键字:ORACLE 数据库 备份


  问题描述:

这是一个回滚段表空间数据文件丢失或损坏的情景,这时 oracle 不能识别相应的数据文件。当你试图 startup 数据文件时会报 ORA-1157 , ORA-1110 ,并且可能会伴随着标识操作系统级别的错误,比如 ORA-7360 。当你试图以 shutdown normal 或 shutdown immediate 模式关闭数据库时会导至 ORA-1116,ORA-1110, 并可能伴随标识操作系统级别的错误,比如 ORA-7368 ,有时以正常方式 shutdown 数据库根本 shutdown 不下来。

警告:

文章中所提及的步骤是供 oracle的全球技术支持使用的。特别是步骤6中的_corrupted_rollback_segments参数,使用后需要重建数据库,在使用这个参前请观察一下所有其它的选项。

解决方法解释:

如下的解决方法取于检测问题出现时数据库所处于状态 :

I. 数据库是处于关闭状态的。

试图打开数据库时报 ORA-1157 和 ORA-1110 错误,这时的解决方法取于数据库是否是正常 shutdown 的 ( 使用 normal 或 immediate 选项。

I.A. 数据库是正常 shutdown 的

如果数据数据库是正常 shutdown 的,最简单的解决方法是以 offline drop 选项删除丢失或损坏的数据文件,以 restriceted 模式打个数据库,删除并重建这个数据文件所属的那个回滚表空间。如果数据库是以 shutdown abort 或自己崩溃掉的则不要遵循这个过程。

步骤如下:

1 、确认数据库是正常 shutdown 的。可以检查 alter.log 这个文件,定位到最后几行看是否可以看到如下的信息:

"alter database dismount

Completed: alter database dismount"

这当然也包括以正常方式 shutdown, 接然试图启动数据库确失败的状况。如果最近一次你是以 shutdown abort 方式关闭数据库的或数据库是自己 crashed 掉的,你应用使用下面的 I.B 的方法。

2 、在 init.ora 中把属于丢失数据文件的回滚段从 ROLLBACK_SEGMENTS 参数中去掉。如果你不能确信是哪个回滚段,可以简单的把 ROLLBACK_SEGMENTS 这个参数注释掉。

3 、以 restricted 模式 mount 数据库

STARTUP RESTRICT MOUNT;

4 、 Offline drop 丢失或损坏的那个数据文件。

ALTER DATABASE DATAFILE '' OFFLINE DROP;

5 、打开数据库

ALTER DATABASE OPEN ;

如果返回 "Statement processed" 这条信息,转到第 7 步 .

如果得到 ORA-604,ORA-376, 和 ORA-1110 错误,转到第 6 步。

6 、因为打开数据库失败, shutdown 掉数据库并且编辑 int.ora 这个文件。注释掉 ROLLBACK_SEGMENTS 这个参数,并且在 init.ora 文件中加入如下一行:

_corrupted_rollback_segments = (,...,)

这个参数应当包含 ROLLBACK_SEGMENTS 中所有的回滚段。

需要注意的是这个参数只能在指定的情况下或在 oracle 的全球持术支持的指导下才应使用,然后以 restricted 模式打开数据库:

STARTUP RESTRICT

7 、删除掉那个文件所属的回滚段表空间。

DROP TABLESPACE INCLUDING CONTENTS;

8 、重建回滚段表空间及回滚段,创建完后使它们 online.

9 、使数据库所有用户都可用。

ALTER SYSTEM DISABLE RESTRICTED SESSION;

10 、在 init.ora 中把你重新创建的回滚段再一次包括进来,如果你使用了第 6 步则移除掉 CORRUPTED_ROLLBACK_SEGMENTS 这个参数。

I.B. 数据库不是正常 shutdown 的

这种情况,数据库最近一次是用 shutdown abort 或 crashed 掉关闭,回滚段中几乎一定包含着活动的事务。因此,坏的那个数据文件不能脱机 (offline) 或是 drop 掉,你必需从备份恢复这个文件。如果数据为是处于非归档模式的,只有最近的一些事务日志还没有被重写掉的情况你才能成功恢复这个文件。如果这个文件的备份也是无效的,联系一下 oracle 的技术支持吧。

步骤如下:

1 、从备份中恢复丢失的那个数据文件 .

2 、 mount 上数据库

3 、执行如下的查询:

SELECT FILE#,NAME,STATUS FROM V$DATAFILE;

如果数据文件的状态是 offline 的,你必需先把它联机了:

ALTER DATABASE DATAFILE '' ONLINE;

4 、执行如下的查询:

SELECT V1.GROUP#, MEMBER, SEQUENCE#, FIRST_CHANGE#

FROM V$LOG V1, V$LOGFILE V2

WHERE V1.GROUP# = V2.GROUP# ;

这将列出所有的联机的重做日志和他们的序号及首次改变号 (first change numbers).

5 、如果这个数据库是非归档模式的,执行如下的查询:

SELECT FILE#, CHANGE# FROM V$RECOVER_FILE;

如果其中的 CHANG# 比 4 中的最小的那个 FIRST_CHANGE# 大的话,用联机日志就可以完成恢复。

6 、如果 CHANG# 比 4 中的最小的那个 FIRST_CHANGE# 小,则数据库是不能恢复的,可以联系一下 oracle 的技术支持。

译者插入:如果你真是非归档方式且这个文件的备份也是无效的,如果你认为可以丢失回滚段中的那事务,你可以用 I.A中从第6步的方法,这时可以打开数据库,应立即做一个备份,因为库中的数据有些不一致。

RECOVER DATAFILE ''

7 、确认所有的日志都被恢复,只到你收到 "Media recovery complete" 信息。

8 、打开数据库

查看本文来源


  II. 数据库是启动着的
  如果你检测到丢失或损坏了回滚段表空间的数据文件,并且数据库是运行着的,不要把它 down 掉。在很多情况下,数据库是启着的比关闭着解决问题更容易些。
  
  这种情况的两种可能的解决方法 :
  
  A) 使丢失的那个数据文件 offline, 并从备份中恢复它,这种情况适用于数据库是处于归档方式的。
  
  B) 另一个方法是 offline 掉所有的那个文件所属表空间的回滚段, drop 那个表空间 , 然后得建它们。你可能不得不杀掉那些使用着回滚段的进程,以便使它 offline.
  
  方法 II.A: 从备份恢复那个数据文件
  
  这个方法只有你的库是在归档方式下才能使用。
  
  1 、脱机 (offline) 那个丢失的数据文件。
  ALTER DATABASE DATAFILE '<full_path_file_name>' OFFLINE;
  
  提示:其于目前数据库的事务量,你可能需要建一个临时的回滚表空间和一些临时的回滚段以备正常业务运行。
  
  2 、从备份中恢复 (restore) 那个数据文件。
  
  3 、执行如下命令
  
  SELECT V1.GROUP#, MEMBER, SEQUENCE#
  FROM V$LOG V1, V$LOGFILE V2
  WHERE V1.GROUP# = V2.GROUP# ;
  这将列出所有的联机的重做日志和他们的序号及首次改变号 (first change numbers).
  
  4 、得用联机日志及归档日志恢复那个文件
  RECOVER DATAFILE '<full_path_file_name>'
  
  5 、确认所有的日志都被恢复,只到你收到 "Media recovery complete" 信息。
  
  6 、使这个数据文件 online
  ALTER DATABASE DATAFILE '<full_path_file_name>' ONLINE;
  
  方法 II.B: 重建回滚表空间
  
  这种方法不必考虑数据库是否是归档模式的。
  
  步骤如下:
  
  1 、试图脱机所有的丢失或损坏数据文件所在回滚表空间中所包含的回滚段。
  ALTER ROLLBACK SEGMENT <rollback_segment> OFFLINE;
  重复执行这个命令直到所包含的回滚段都脱机 .
  
  2 、检查回滚段的状态。
  在 drop 掉它们之前它们必需是 offline 状态的。
  SELECT SEGMENT_NAME, STATUS FROM DBA_ROLLBACK_SEGS
  WHERE TABLESPACE_NAME = '<TABLESPACE_NAME>';
  
  3 、删除掉所有脱机的 c 。
  DROP ROLLBACK SEGMENT <rollback_segment>;
  
  4 、处理那些保持 online 状态的回滚段
  重复执行 2 一下的命令,如果回滚段在执行 1 中命令仍保扭亏为盈 "ONLINE" 状态,意味着它之中有活动的事务,你可以用如下的查询来确认一下:
  SELECT SEGMENT_NAME, XACTS ACTIVE_TX, V.STATUS
  FROM V$ROLLSTAT V, DBA_ROLLBACK_SEGS
  WHERE TABLESPACE_NAME = '<TABLESPACE_NAME>' AND SEGMENT_ID = USN;
  如果这个查询没有结果返回,意味着没有事务在这些回滚段中了。哪果有结果返回,那些不能 offline 的回滚段的状态应为 "PENDING OFFLINE" 。可以用 5 中的方法把这些事务杀掉。
  
  5 、强制使有活动事务的回滚段脱机
  执行如下查询,看这些 "PENDING OFFLINE" 的回滚段包含哪些事务。
  SELECT S.SID, S.SERIAL#, S.USERNAME, R.NAME "ROLLBACK"
  FROM V$SESSION S, V$TRANSACTION T, V$ROLLNAME R
  WHERE R.NAME IN ('<PENDING_ROLLBACK_1>', ... , '<PENDING_ROLLBACK_N>')
  AND S.TADDR = T.ADDR AND T.XIDUSN = R.USN;
  
  用 ALTER SYSTEM KILL SESSION '<SID>, <SERIAL#>'; 语句杀掉这些事务,重复执行上面的查询,直到没有事务存在,这时运行一下 2 中的查询,确认这些回滚段己经处于 offline 状态 , 并用 3 中的语句把它们 drop 掉。
  
  6 、删除这个回滚表空间。
  DROP TABLESPACE <tablespace_name> INCLUDING CONTENTS;
  如果语句执行失败,请与 oracle 技术支持联系,否则转向 7
  
  7 、重建回滚段表空间。
  
  8 、重建回滚段,并使它们联机 (online) 。
  
  回滚段表空间的数据文件丢失或损坏在实际中是比较棘手和常见的,产生这种问题 的原回很多的,比如介质的损坏、人为的误操作、机器的突然的断电等等。
  
  建议没实践过这种操作的 oracle 的爱好者可以模拟一下这种故障,实际实测一下,注意一定要在测试库,我模拟的方法如下:
  
  1 、单独建了一个 rbs 表空间,并在这个表空间建了一个回滚段 rbs_test 。
  
  2 、指定一个 transaction 用这个回滚段
  
  sql>set transaction use rollback segment rbs_test;
  
  sql>insert into test values ('2');
  
  sql>insert into test values('3');
  
  3 、另开一个 telnet 窗口 telnet 至主机,执行如下命令 :
  
  sqlplus /nolog
  
  sql>conn / as sysdba
  
  sql>shutdown abort
  
  4 、把新加的那个回滚段表空间的数据文件更个名。

查看本文来源

推广二维码
邮件订阅

如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

重磅专题