导航

7. 其它恢复问题

Posted on 2008-09-27 14:03  毅无涯  阅读(286)  评论(0编辑  收藏  举报

7.1 恢复控制文件

控制文件使用原则:

  1. 多元化控制文件
  2. 当数据库物理结构改变时备份控制文件
  3. 诊断控制文件介质失败

当数据库处于OPEN 状态时,如果控制文件出现介质失败,那么ORACLE 会自动终止例程;当数据库处于关闭状态时,如果控制文件出现介质失败,那么当装载数据库时,会显示错误信息。

 

7.1.1 单个控制文件的介质失败

方法一:复制没有损坏的控制文件


SQL> conn / as sysdba
已连接到空闲例程。
SQL> startup
ORACLE 例程已经启动。

Total System Global Area  167772160 bytes
Fixed Size                  1247900 bytes
Variable Size              62915940 bytes
Database Buffers          100663296 bytes
Redo Buffers                2945024 bytes
数据库装载完毕。
数据库已经打开。
SQL> select * from v$controlfile;

STATUS  NAME                                     IS_RECOVERY_DEST_FIL BLOCK_SIZE FILE_SIZE_BLKS
------- ---------------------------------------- -------------------- ---------- --------------
        D:\DEMO\CONTROL01.CTL                    NO                        16384            444
        C:\DEMO\CONTROL02.CTL                    NO                        16384            444


SQL> shutdown immediate
数据库已经关闭。
已经卸载数据库。
ORACLE 例程已经关闭。
SQL>  host del C:\DEMO\CONTROL02.CTL

SQL> startup
ORACLE 例程已经启动。

Total System Global Area  167772160 bytes
Fixed Size                  1247900 bytes
Variable Size              62915940 bytes
Database Buffers          100663296 bytes
Redo Buffers                2945024 bytes
ORA-00205: ?????????, ??????, ???????

alert_demo.log 信息:

Mon Sep 15 09:41:13 2008
ORA-00202: ????: ''C:\DEMO\CONTROL02.CTL''
ORA-27041: ??????
OSD-04002: 无法打开文件
O/S-Error: (OS 2) 系统找不到指定的文件。

SQL> host copy D:\DEMO\CONTROL01.CTL C:\DEMO\CONTROL02.CTL

SQL> startup force
ORACLE 例程已经启动。

Total System Global Area  167772160 bytes
Fixed Size                  1247900 bytes
Variable Size              62915940 bytes
Database Buffers          100663296 bytes
Redo Buffers                2945024 bytes
数据库装载完毕。
数据库已经打开。

--------------------------------------------------------------------------------------------

方法二:去除损坏的控制文件


SQL> select status from v$instance;

STATUS
------------
OPEN

SQL> select * from v$controlfile;

STATUS  NAME                                     IS_RECOVERY_DEST_FIL BLOCK_SIZE FILE_SIZE_BLKS
------- ---------------------------------------- -------------------- ---------- --------------
        D:\DEMO\CONTROL01.CTL                    NO                        16384            444
        C:\DEMO\CONTROL02.CTL                    NO                        16384            444

SQL> shutdown immediate
数据库已经关闭。
已经卸载数据库。
ORACLE 例程已经关闭。
SQL> host del C:\DEMO\CONTROL02.CTL

SQL> startup
ORACLE 例程已经启动。

Total System Global Area  167772160 bytes
Fixed Size                  1247900 bytes
Variable Size              62915940 bytes
Database Buffers          100663296 bytes
Redo Buffers                2945024 bytes
ORA-00205: ?????????, ??????, ???????

alert_demo.log 信息:

Mon Sep 15 09:51:03 2008
ORA-00202: ????: ''C:\DEMO\CONTROL02.CTL''
ORA-27041: ??????
OSD-04002: 无法打开文件
O/S-Error: (OS 2) 系统找不到指定的文件。

SQL> alter system set control_files='D:\DEMO\CONTROL01.CTL' scope=spfile;

系统已更改。

SQL> startup force
ORACLE 例程已经启动。

Total System Global Area  167772160 bytes
Fixed Size                  1247900 bytes
Variable Size              62915940 bytes
Database Buffers          100663296 bytes
Redo Buffers                2945024 bytes
数据库装载完毕。
数据库已经打开。

7.1.2 所有控制文件的介质失败

因为使用手工方法建立控制文件,但这种方法比较复杂,而且容易出错,建立使用跟踪文件建立控制文件。如果已将控制文件备份到跟踪文件中,那么可以直接使用跟踪文件的相应命令。如果跟踪文件不存在,但存在控制文件备份,那么可以使用控制文件备份生成跟踪文件,然后用跟踪文件重新建立控制文件。具体步骤如下:

(1) 复制控制文件备份。

(2) 生成文本跟踪文件。

(3) 编辑文本跟踪文件。

(4) 关闭数据库,然后执行跟踪文件的SQL 和SQL*Plus 命令。

 

SQL> conn / as sysdba
已连接到空闲例程。
SQL> startup
ORACLE 例程已经启动。

Total System Global Area  167772160 bytes
Fixed Size                  1247900 bytes
Variable Size              62915940 bytes
Database Buffers          100663296 bytes
Redo Buffers                2945024 bytes
数据库装载完毕。
数据库已经打开。
SQL> select name from v$controlfile;

NAME
--------------------------------------------------------------------------------
D:\DEMO\CONTROL01.CTL
C:\DEMO\CONTROL02.CTL

SQL> alter database backup controlfile to 'd:\0915\demo.ctl' reuse;

数据库已更改。

SQL> shutdown immediate
数据库已经关闭。
已经卸载数据库。
ORACLE 例程已经关闭。
SQL> host del D:\DEMO\CONTROL01.CTL

SQL> host del C:\DEMO\CONTROL02.CTL

SQL> startup
ORACLE 例程已经启动。

Total System Global Area  167772160 bytes
Fixed Size                  1247900 bytes
Variable Size              62915940 bytes
Database Buffers          100663296 bytes
Redo Buffers                2945024 bytes
ORA-00205: ?????????, ??????, ???????

SQL> shutdown
ORA-01507: ??????

ORACLE 例程已经关闭。
SQL> host copy D:\0915\demo.ctl D:\DEMO\CONTROL01.CTL

SQL> host copy D:\0915\demo.ctl C:\DEMO\CONTROL02.CTL

SQL> startup force mount
ORACLE 例程已经启动。

Total System Global Area  167772160 bytes
Fixed Size                  1247900 bytes
Variable Size              62915940 bytes
Database Buffers          100663296 bytes
Redo Buffers                2945024 bytes
数据库装载完毕。
SQL> alter database backup controlfile to trace noresetlogs;

数据库已更改。

STARTUP NOMOUNT
CREATE CONTROLFILE REUSE DATABASE "DEMO" NORESETLOGS  ARCHIVELOG
    MAXLOGFILES 16
    MAXLOGMEMBERS 3
    MAXDATAFILES 100
    MAXINSTANCES 8
    MAXLOGHISTORY 292
LOGFILE
  GROUP 1 (
    'D:\DEMO\REDO01.LOG',
    'C:\DEMO\REDO01_2.LOG'
  ) SIZE 50M,
  GROUP 2 (
    'D:\DEMO\REDO02.LOG',
    'C:\DEMO\REDO02_2.LOG'
  ) SIZE 50M,
  GROUP 3 (
    'D:\DEMO\REDO03.LOG',
    'C:\DEMO\REDO03_2.LOG'
  ) SIZE 50M
DATAFILE
  'D:\DEMO\SYSTEM01.DBF',
  'D:\DEMO\UNDOTBS01.DBF',
  'D:\DEMO\SYSAUX01.DBF',
  'D:\DEMO\USERS01.DBF'
CHARACTER SET ZHS16GBK
;
RECOVER DATABASE
ALTER SYSTEM ARCHIVE LOG ALL;
ALTER DATABASE OPEN;
ALTER TABLESPACE TEMP ADD TEMPFILE 'D:\DEMO\TEMP01.DBF' REUSE;

SQL> shutdown immediate
ORA-01109: 数据库未打开

已经卸载数据库。
ORACLE 例程已经关闭。
SQL> @d:\0915\demo.sql
ORACLE 例程已经启动。

Total System Global Area  167772160 bytes
Fixed Size                  1247900 bytes
Variable Size              62915940 bytes
Database Buffers          100663296 bytes
Redo Buffers                2945024 bytes

控制文件已创建。

ORA-00283: ??????????
ORA-00264: ?????

系统已更改。

数据库已更改。

表空间已更改。

 

7.2 恢复重做日志

7.2.1 日志组的某个日志成员损坏


SQL> conn / as sysdba
已连接。

SQL>  alter database add logfile member 'e:\demo\REDO02_3.LOG' TO group 2;

数据库已更改。

SQL> host format e: /q 

SQL> select * from v$logfile where status='INVALID';

    GROUP# STATUS  TYPE    MEMBER                         IS_RECOVERY_DEST_FILE
---------- ------- ------- ------------------------------ ------------------------
         2 INVALID ONLINE  E:\DEMO\REDO02_3.LOG           NO

SQL> select group# from v$log where status='CURRENT';

    GROUP#
----------
         2

SQL> alter database drop logfile member 'E:\DEMO\REDO02_3.LOG';
alter database drop logfile member 'E:\DEMO\REDO02_3.LOG'
*
第 1 行出现错误:
ORA-01609: 日志 2 是线程 1 的当前日志 - 无法删除成员
ORA-00312: 联机日志 2 线程 1: 'D:\DEMO\REDO02.LOG'
ORA-00312: 联机日志 2 线程 1: 'C:\DEMO\REDO02_2.LOG'
ORA-00312: 联机日志 2 线程 1: 'E:\DEMO\REDO02_3.LOG'

SQL> alter system switch logfile;

系统已更改。

SQL> alter database drop logfile member 'E:\DEMO\REDO02_3.LOG';

数据库已更改。

SQL>  select * from v$logfile where status='INVALID';

未选定行

SQL> alter database add logfile member 'E:\DEMO\REDO02_3.LOG' to group 2;
alter database add logfile member 'E:\DEMO\REDO02_3.LOG' to group 2
*
第 1 行出现错误:
ORA-00301: 添加日志文件 'E:\DEMO\REDO02_3.LOG' 时出错 - 无法创建文件
ORA-27040: 文件创建错误, 无法创建文件
OSD-04002: 无法打开文件
O/S-Error: (OS 3) 系统找不到指定的路径。

SQL> host md E:\DEMO

SQL> alter database add logfile member 'E:\DEMO\REDO02_3.LOG' to group 2;

数据库已更改。

SQL>  select * from v$logfile where status='INVALID';

    GROUP# STATUS  TYPE    MEMBER                         IS_RECOVERY_DEST_FILE
---------- ------- ------- ------------------------------ ------------------------
         2 INVALID ONLINE  E:\DEMO\REDO02_3.LOG           NO

SQL> alter system switch logfile;

系统已更改。

SQL> /

系统已更改。

SQL> select * from v$logfile where status='INVALID';

未选定行

 

7.2.2 非活动日志组的所有日志成员全部损坏

1. 在OPEN 状态下非活动日志组的所有日志成员全部损坏

重新建立日志组的所有成员。

SQL> alter database clear unarchived logfile group 5;

数据库已更改。

2. 在关闭状态下非活动日志组的所有日志成员全部损坏

增加新日志组,删除原有日志组,然后打开数据库。

SQL> startup
ORACLE 例程已经启动。

Total System Global Area  167772160 bytes
Fixed Size                  1247900 bytes
Variable Size              67110244 bytes
Database Buffers           96468992 bytes
Redo Buffers                2945024 bytes
数据库装载完毕。
ORA-00313: 无法打开日志组 4 (用于线程 1) 的成员
ORA-00312: 联机日志 4 线程 1: 'E:\DEMO\REDO04.LOG'
ORA-00312: 联机日志 4 线程 1: 'E:\DEMO\REDO04_2.LOG'

SQL> select status from v$instance;

STATUS
------------
MOUNTED

SQL> alter database open;
alter database open
*
第 1 行出现错误:
ORA-00313: 无法打开日志组 4 (用于线程 1) 的成员
ORA-00312: 联机日志 4 线程 1: 'E:\DEMO\REDO04.LOG'
ORA-00312: 联机日志 4 线程 1: 'E:\DEMO\REDO04_2.LOG'

SQL> alter database add logfile('e:\DEMO\REDO05.LOG','E:\DEMO\REDO05_2.LOG') size 10M;

数据库已更改。

SQL> alter database drop logfile group 4;

数据库已更改。

SQL> alter database open;

数据库已更改。

SQL> select * from v$log;

    GROUP#    THREAD#  SEQUENCE#      BYTES    MEMBERS ARC STATUS           FIRST_CHANGE# FIRST_TIME
---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- ----------
         1          1         43   52428800          2 YES INACTIVE               1012789 25-9月 -08
         2          1         42   52428800          2 YES INACTIVE               1012685 25-9月 -08
         3          1         41   52428800          2 YES INACTIVE               1012682 25-9月 -08
         5          1         44   10485760          2 NO  CURRENT                1032791 25-9月 -08

 

7.2.3 当前日志组的所有日志成员全部损坏

1. 在关闭状态下当前日志组所有日志成员全部损坏

SQL> conn / as sysdba
已连接到空闲例程。
SQL> startup
ORACLE 例程已经启动。

Total System Global Area  167772160 bytes
Fixed Size                  1247900 bytes
Variable Size              67110244 bytes
Database Buffers           96468992 bytes
Redo Buffers                2945024 bytes
数据库装载完毕。
ORA-00313: 无法打开日志组 5 (用于线程 1) 的成员
ORA-00312: 联机日志 5 线程 1: 'E:\DEMO\REDO05.LOG'
ORA-00312: 联机日志 5 线程 1: 'E:\DEMO\REDO05_2.LOG'

SQL> select status from v$instance;

STATUS
------------
MOUNTED

SQL> recover database until cancel;
完成介质恢复。
SQL> alter database open resetlogs;

数据库已更改。

 

2. 在OPEN 状态下当前日志组所有日志成员全部损坏

SQL>  select group# from v$log where status='CURRENT';

    GROUP#
----------
         5

SQL> insert into scott.test values(1,'yyyy');

已创建 1 行。

SQL> COMMIT;
COMMIT
*
第 1 行出现错误:
ORA-01092: ORACLE 实例终止。强制断开连接

SQL> conn / as sysdba
已连接到空闲例程。
SQL> startup mount
ORACLE 例程已经启动。

Total System Global Area  167772160 bytes
Fixed Size                  1247900 bytes
Variable Size              67110244 bytes
Database Buffers           96468992 bytes
Redo Buffers                2945024 bytes
数据库装载完毕。
SQL> host copy D:\0925\SYSAUX01.DBF d:\demo

SQL>  host copy D:\0925\system01.dbf d:\demo

SQL> host copy D:\0925\UNDOTBS01.DBF d:\demo

SQL>  host copy D:\0925\users01.dbf d:\demo
SQL> recover database until cancel;
ORA-00279: 更改 1083776 (在 09/25/2008 23:04:26 生成) 对于线程 1 是必需的
ORA-00289: 建议: D:\DEMO\ARCHIVE\2_1_666399760.LOG
ORA-00280: 更改 1083776 (用于线程 1) 在序列 #2 中

指定日志: {<RET>=suggested | filename | AUTO | CANCEL}

ORA-00279: 更改 1083982 (在 09/25/2008 23:10:45 生成) 对于线程 1 是必需的
ORA-00289: 建议: D:\DEMO\ARCHIVE\3_1_666399760.LOG
ORA-00280: 更改 1083982 (用于线程 1) 在序列 #3 中
ORA-00278: 此恢复不再需要日志文件 'D:\DEMO\ARCHIVE\2_1_666399760.LOG'

指定日志: {<RET>=suggested | filename | AUTO | CANCEL}

ORA-00279: 更改 1084065 (在 09/25/2008 23:12:14 生成) 对于线程 1 是必需的
ORA-00289: 建议: D:\DEMO\ARCHIVE\4_1_666399760.LOG
ORA-00280: 更改 1084065 (用于线程 1) 在序列 #4 中
ORA-00278: 此恢复不再需要日志文件 'D:\DEMO\ARCHIVE\3_1_666399760.LOG'

指定日志: {<RET>=suggested | filename | AUTO | CANCEL}

ORA-00279: 更改 1084142 (在 09/25/2008 23:13:44 生成) 对于线程 1 是必需的
ORA-00289: 建议: D:\DEMO\ARCHIVE\5_1_666399760.LOG
ORA-00280: 更改 1084142 (用于线程 1) 在序列 #5 中
ORA-00278: 此恢复不再需要日志文件 'D:\DEMO\ARCHIVE\4_1_666399760.LOG'

指定日志: {<RET>=suggested | filename | AUTO | CANCEL}

ORA-00279: 更改 1084215 (在 09/25/2008 23:14:48 生成) 对于线程 1 是必需的
ORA-00289: 建议: D:\DEMO\ARCHIVE\6_1_666399760.LOG
ORA-00280: 更改 1084215 (用于线程 1) 在序列 #6 中
ORA-00278: 此恢复不再需要日志文件 'D:\DEMO\ARCHIVE\5_1_666399760.LOG'

指定日志: {<RET>=suggested | filename | AUTO | CANCEL}

ORA-00279: 更改 1084323 (在 09/25/2008 23:16:31 生成) 对于线程 1 是必需的
ORA-00289: 建议: D:\DEMO\ARCHIVE\7_1_666399760.LOG
ORA-00280: 更改 1084323 (用于线程 1) 在序列 #7 中
ORA-00278: 此恢复不再需要日志文件 'D:\DEMO\ARCHIVE\6_1_666399760.LOG'

指定日志: {<RET>=suggested | filename | AUTO | CANCEL}

ORA-00279: 更改 1084425 (在 09/25/2008 23:18:07 生成) 对于线程 1 是必需的
ORA-00289: 建议: D:\DEMO\ARCHIVE\8_1_666399760.LOG
ORA-00280: 更改 1084425 (用于线程 1) 在序列 #8 中
ORA-00278: 此恢复不再需要日志文件 'D:\DEMO\ARCHIVE\7_1_666399760.LOG'

指定日志: {<RET>=suggested | filename | AUTO | CANCEL}

ORA-00279: 更改 1084436 (在 09/25/2008 23:18:13 生成) 对于线程 1 是必需的
ORA-00289: 建议: D:\DEMO\ARCHIVE\9_1_666399760.LOG
ORA-00280: 更改 1084436 (用于线程 1) 在序列 #9 中
ORA-00278: 此恢复不再需要日志文件 'D:\DEMO\ARCHIVE\8_1_666399760.LOG'

指定日志: {<RET>=suggested | filename | AUTO | CANCEL}

ORA-00279: 更改 1084860 (在 09/25/2008 23:21:21 生成) 对于线程 1 是必需的
ORA-00289: 建议: D:\DEMO\ARCHIVE\10_1_666399760.LOG
ORA-00280: 更改 1084860 (用于线程 1) 在序列 #10 中
ORA-00278: 此恢复不再需要日志文件 'D:\DEMO\ARCHIVE\9_1_666399760.LOG'

指定日志: {<RET>=suggested | filename | AUTO | CANCEL}

ORA-00279: 更改 1084959 (在 09/25/2008 23:23:10 生成) 对于线程 1 是必需的
ORA-00289: 建议: D:\DEMO\ARCHIVE\11_1_666399760.LOG
ORA-00280: 更改 1084959 (用于线程 1) 在序列 #11 中
ORA-00278: 此恢复不再需要日志文件 'D:\DEMO\ARCHIVE\10_1_666399760.LOG'

指定日志: {<RET>=suggested | filename | AUTO | CANCEL}

ORA-00279: 更改 1085097 (在 09/25/2008 23:26:52 生成) 对于线程 1 是必需的
ORA-00289: 建议: D:\DEMO\ARCHIVE\12_1_666399760.LOG
ORA-00280: 更改 1085097 (用于线程 1) 在序列 #12 中
ORA-00278: 此恢复不再需要日志文件 'D:\DEMO\ARCHIVE\11_1_666399760.LOG'

指定日志: {<RET>=suggested | filename | AUTO | CANCEL}
cancel
介质恢复已取消。
SQL> alter database open resetlogs;

数据库已更改。

SQL> alter database begin backup;

数据库已更改。

SQL> host copy d:\demo\SYSAUX01.DBF d:\0925

SQL> host copy d:\demo\system01.dbf d:\0925

SQL> host copy d:\demo\UNDOTBS01.DBF d:\0925

SQL> host copy d:\demo\users01.dbf d:\0925

SQL> alter database end backup;

数据库已更改。

SQL> alter database backup controlfile to 'd:\0925\demo.ctl' reuse;

数据库已更改。

 

7.3 恢复临时文件

当执行以下SQL 操作时,会产生临时数据:

  • CREATE INDEX
  • SELECT ... ORDER BY
  • SELECT DISTINCT ...
  • SELECT ... GROUP BY
  • SELECT ... UNION
  • SELECT ... INTERSECT
  • SELECT ... MINUS
  • ANALYZE 命令

 

SQL> select * from v$tempfile;

未选定行

SQL> select * from scott.test order by name;
select * from scott.test order by name
                    *
第 1 行出现错误:
ORA-25153: 临时表空间为空

SQL> alter tablespace temp add tempfile 'd:\demo\temp01.dbf' size 50M;

表空间已更改。

SQL> select file#,name from v$tempfile;

     FILE# NAME
---------- ------------------------------
         1 D:\DEMO\TEMP01.DBF

 

7.4 处理损坏数据块

使用DBMS_REPAIR包处理损坏数据块时,会弃用损坏数据块的所有数据。

(1) 建立修复表。修复表用于存放表、表分区、索引的损坏块信息。在检查包含损坏块对象之前,必须先建立修复表。修复表名必须要带有REPAIR_ 前缀(大写)。

(2) 确定损坏块个数。

(3) 标记损坏块。

(4) 跳过损坏块。

(5) 确定指向损坏块的索引入口。

 
SQL> conn / as sysdba
已连接。

SQL> create tablespace block datafile 'e:\block01.dbf' size 1M extent management local;

表空间已创建。

SQL> desc scott.test;
名称                                      是否为空? 类型
----------------------------------------- -------- ----------------------------
CODE                                               NVARCHAR2(20)
NAME                                               NVARCHAR2(20)

SQL> create table T1 tablespace block as select * from scott.test where rownum<1000;

表已创建。

SQL> select count(*) from t1;

  COUNT(*)
----------
       999

SQL> create index IX_CODE on T1(code);

索引已创建。

SQL> alter system checkpoint;

系统已更改。

SQL> select count(*) from t1;

  COUNT(*)
----------
       999
SQL> shutdown immediate
数据库已经关闭。
已经卸载数据库。
ORACLE 例程已经关闭。

 

用 UltraEdit工具修改了d:\demo\temp01.dbf 数据。


SQL> startup
ORACLE 例程已经启动。

Total System Global Area  167772160 bytes
Fixed Size                  1247900 bytes
Variable Size              67110244 bytes
Database Buffers           96468992 bytes
Redo Buffers                2945024 bytes
数据库装载完毕。
数据库已经打开。
SQL> select count(*) from t1;
select count(*) from t1
                     *
第 1 行出现错误:
ORA-01578: ORACLE 数据块损坏 (文件号 5, 块号 14)
ORA-01110: 数据文件 5: 'E:\BLOCK01.DBF'

SQL> exec dbms_repair.admin_tables('REPAIR_TABLE',DBMS_REPAIR.REPAIR_TABLE,DBMS_REPAIR.CREATE_ACTION
)

PL/SQL 过程已成功完成。

SQL> var c number

SQL> exec dbms_repair.check_object('SYS','T1',corrupt_count=>:c)

PL/SQL 过程已成功完成。

SQL> print c

         C
----------
         2

SQL> desc repair_table;
名称                                      是否为空? 类型
----------------------------------------- -------- ----------------------------
OBJECT_ID                                 NOT NULL NUMBER
TABLESPACE_ID                             NOT NULL NUMBER
RELATIVE_FILE_ID                          NOT NULL NUMBER
BLOCK_ID                                  NOT NULL NUMBER
CORRUPT_TYPE                              NOT NULL NUMBER
SCHEMA_NAME                               NOT NULL VARCHAR2(30)
OBJECT_NAME                               NOT NULL VARCHAR2(30)
BASEOBJECT_NAME                                    VARCHAR2(30)
PARTITION_NAME                                     VARCHAR2(30)
CORRUPT_DESCRIPTION                                VARCHAR2(2000)
REPAIR_DESCRIPTION                                 VARCHAR2(200)
MARKED_CORRUPT                            NOT NULL VARCHAR2(10)
CHECK_TIMESTAMP                           NOT NULL DATE
FIX_TIMESTAMP                                      DATE
REFORMAT_TIMESTAMP                                 DATE

SQL> col CORRUPT_DESCRIPTION format a30
SQL> col  REPAIR_DESCRIPTION format a30
SQL> set linesize 800
SQL> select object_name,block_id,corrupt_type,marked_corrupt,corrupt_description,repair_description
from repair_table;

OBJECT_NAME                      BLOCK_ID CORRUPT_TYPE MARKED_COR CORRUPT_DESCRIPTION            REPAIR_DESC
------------------------------ ---------- ------------ ---------- ------------------------------ ---
T1                                     14         6148 TRUE                                      mark block
T1                                     16         6148 TRUE                                      mark block

ORACLE 文档上指出完成此步MARKED_CORRUPT值是FALSE, 只有执行了fix_corrupt_blocks过程MARKED_CORRUPT 值才会是TRUE。有可能是ORACLE在执行dbms_repair.check_object的时候,自动执行了dbms_repair.fix_corrupt_blocks。

SQL> var fc number
SQL> exec dbms_repair.fix_corrupt_blocks('SYS','T1',fix_count=>:fc)

PL/SQL 过程已成功完成。

SQL> print fc

        FC
----------
         0

此时结果是0个坏块,说明ORACLE在执行dbms_repair.check_object的时候,自动执行了dbms_repair.fix_corrupt_blocks。

SQL> exec dbms_repair.skip_corrupt_blocks('SYS','T1')

PL/SQL 过程已成功完成。

SQL> select count(*) from t1;

  COUNT(*)
----------
       618

SQL> select * from t1 where code between '14524' and '16392';

CODE                                     NAME
---------------------------------------- ----------------------------------------
145240                                   name14524
145250                                   name14525

SQL> delete from t1 where code='14526';
delete from t1 where code='14526'
            *
第 1 行出现错误:
ORA-01578: ORACLE 数据块损坏 (文件号 5, 块号 16)
ORA-01110: 数据文件 5: 'E:\BLOCK01.DBF'

SQL> exec dbms_repair.admin_tables('ORPHAN_TAB',DBMS_REPAIR.ORPHAN_TABLE,DBMS_REPAIR.CREATE_ACTION)

PL/SQL 过程已成功完成。

SQL> var kc number
SQL> select * from  t1 where code='14526';

未选定行

SQL> select code  from  t1 where code='14526';

CODE
----------------------------------------
14526

SQL> var kc number
SQL> exec dbms_repair.dump_orphan_keys('SYS','IX_CODE',orphan_table_name=>'ORPHAN_TAB',key_count=>:KC)

PL/SQL 过程已成功完成。

SQL> print kc

        KC
----------
       381

SQL> select code  from  t1 where code='14526';

CODE
----------------------------------------
14526

SQL> select *  from  t1 where code='14526';

未选定行

SQL> drop index IX_CODE;

索引已删除。

SQL> create index IX_CODE on T1(CODE);

索引已创建。

SQL>  select code  from  t1 where code='14526';

未选定行

这一步要先DROP INDEX,再CREATE INDEX,如果用REBUILD,重建后还会有不一致的数据。