如果数据块损坏了那我们如何修复呢(如果是INDEX 损坏 那么我们只需要从建INDEX 就好了,以下方法是针对表中数据块损坏的情况)?有几种方法供大家选择:
1.使用介质恢复,在ORACLE 9I 的RMAN 引入了一个新特性叫做BLOCKRECOVER(这也是最简单最容易的恢复方法),这需要你的数据库是ARCHIVELOG 模式,同时你要有对数据库的备份,以及备份后的日志.如何恢复呢:
首先使用DBV 来检查被损坏的文件
DBVERIFY - 开始验证: FILE = test01.dbf
页 39 标记为损坏
Corrupt block relative dba: 0x01800027 (file 6, block 39)
Bad check value found during dbv:
Data in bad block:
type: 6 format: 2 rdba: 0x01800027
last change scn: 0x0000.000d47fd seq: 0x3 flg: 0x04
spare1: 0x0 spare2: 0x0 spare3: 0x0
consistency value in tail: 0x47fd0603
check value in block header: 0x67a5
computed block checksum: 0x300d
RMAN> blockrecover datafile 6 block 39;
启动 blockrecover 于 30-8月 -08
使用目标数据库控制文件替代恢复目录
分配的通道: ORA_DISK_1
通道 ORA_DISK_1: sid=137 devtype=DISK
通道 ORA_DISK_1: 正在恢复块
通道 ORA_DISK_1: 正在指定要从备份集恢复的块
正在恢复数据文件 00006 的块
通道 ORA_DISK_1: 正在读取备份段 C:\ORACLE\PRODUCT\10.2.0\FLASH_RECOVERY_AREA\ORA
10\BACKUPSET\2008_08_28\O1_MF_NNNDF_TAG20080828T170941_4CDTTRYR_.BKP
通道 ORA_DISK_1: 已从备份段 1 恢复块
段句柄 = C:\ORACLE\PRODUCT\10.2.0\FLASH_RECOVERY_AREA\ORA10\BACKUPSET\2008_08_28
\O1_MF_NNNDF_TAG20080828T170941_4CDTTRYR_.BKP 标记 = TAG20080828T170941
通道 ORA_DISK_1: 块恢复完成, 用时: 00:00:04
正在开始介质的恢复
Bad check value found during dbv:
Data in bad block:
type: 6 format: 2 rdba: 0x0180024c
last change scn: 0x0000.000d4ded seq: 0x9a flg: 0x04
spare1: 0x0 spare2: 0x0 spare3: 0x0
consistency value in tail: 0x4ded069a
check value in block header: 0xaab
computed block checksum: 0x303d
DBVERIFY - 开始验证: FILE = test01.dbf
DBVERIFY - 验证完成
检查的页总数: 1280
处理的页总数 (数据): 1126
失败的页总数 (数据): 0
处理的页总数 (索引): 0
失败的页总数 (索引): 0
处理的页总数 (其它): 34
处理的总页数 (段) : 0
失败的总页数 (段) : 0
空的页总数: 120
标记为损坏的总页数: 0
流入的页总数: 0
最高块 SCN : 877562 (0.877562)
可以看出损坏的数据块已经被恢复.
2.使用EXP和IMP工具(使用此工具的缺点是,CORRUPTION 的BLOCK 内数据将丢失)
scott@ORA10> conn / as sysdba
已连接。
sys@ORA10> select count(*) from scott.test;
select count(*) from scott.test
*
第 1 行出现错误:
ORA-01578: ORACLE 数据块损坏 (文件号 6, 块号 588)
ORA-01110: 数据文件 6: 'C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORA10\TEST01.DBF'
sys@ORA10> show parameter event
NAME TYPE VALUE
------------------------------------ ----------- -----------------------------
event string
sys@ORA10> alter system set event='10231 trace name context forever,level 10' scope=spfile;
系统已更改。
设置10231诊断事件是告诉ORACLE在做FULL TABLE SCAN 的时候跳过CORRUPTION BLOCK.
这样就可以使用EXP把没有损坏的数据EXP出来.
sys@ORA10> shutdown immediate
数据库已经关闭。
已经卸载数据库。
ORACLE 例程已经关闭。
sys@ORA10> startup
ORACLE 例程已经启动。
Total System Global Area 205520896 bytes
Fixed Size 1248092 bytes
Variable Size 79692964 bytes
Database Buffers 117440512 bytes
Redo Buffers 7139328 bytes
数据库装载完毕。
数据库已经打开。
C:\oracle\product\10.2.0\oradata\ora10>exp scott/scott tables=test file=test.dmp
Export: Release 10.2.0.1.0 - Production on 星期六 8月 30 10:53:49 2008
Copyright (c) 1982, 2005, Oracle. All rights reserved.
连接到: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
已导出 ZHS16GBK 字符集和 AL16UTF16 NCHAR 字符集
即将导出指定的表通过常规路径...
. . 正在导出表 TEST导出了 300000 行
成功终止导出, 没有出现警告。
在使用EXP 导出表,可以将原来的表DROP掉,再从新IMP导出的表.
scott@ORA10> conn scott/scott
已连接。
scott@ORA10> drop table test;
表已删除。
C:\oracle\product\10.2.0\oradata\ora10>imp scott/scott file=test.dmp full=y
Import: Release 10.2.0.1.0 - Production on 星期六 8月 30 15:54:12 2008
Copyright (c) 1982, 2005, Oracle. All rights reserved.
连接到: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
经由常规路径由 EXPORT:V10.02.01 创建的导出文件
已经完成 ZHS16GBK 字符集和 AL16UTF16 NCHAR 字符集中的导入
. 正在将 SCOTT 的对象导入到 SCOTT
. 正在将 SCOTT 的对象导入到 SCOTT
. . 正在导入表 "TEST"导入了 300000 行
成功终止导入, 没有出现警告。
3.如果你的表上存在UNIQUE INDEX 那么恢复起来也是很方便的(此方法同样会丢失CORRUPTION BLOCK 的数据)
sys@ORA10> select count(*) from scott.test;
select count(*) from scott.test
*
第 1 行出现错误:
ORA-01578: ORACLE 数据块损坏 (文件号 6, 块号 588)
ORA-01110: 数据文件 6: 'C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORA10\TEST01.DBF'
sys@ORA10>select * from dba_extents where file_id=6 and 588 between block_id and block_id+blocks-1;
OWNER SEGMENT_NAME PARTITION_NAME SEGMENT_TYPE TABLESPACE_NAME EXTENT_ID FILE_ID BLOCK_ID BYTES BLOCKS RELATIVE_FNO
------------------------------ ------------------------------ ------------------------------ ------------------ ------------------------------ ---------- ---------- ---------- ---------- ---------- ------------
SCOTT TEST TABLE TEST 8 6 585 65536 8 6
sys@ORA10> select * from dba_objects where object_name='TEST';
OWNER OBJECT_NAME SUBOBJECT_NAME OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE CREATED LAST_DDL_TIME TIMESTAMP STATUS T G S
------------------------------ -------------------- ------------------------------ ---------- -------------- ------------------- -------------- -------------- ------------------- ------- - - -
SCOTT TEST 52670 52670 TABLE 28-8月 -08 28-8月 -08 2008-08-28:20:30:01 VALID N N N
scott@ORA10> select * from user_indexes;
INDEX_NAME INDEX_TYPE TABLE_OWNER TABLE_NAME TABLE_TYPE UNIQUENES
------------------------------ --------------------------- ------------------------------ ------------------------------ ----------- ---------
TEST_ID NORMAL SCOTT TEST TABLE UNIQUE
PK_EMP NORMAL SCOTT EMP TABLE UNIQUE
PK_DEPT NORMAL SCOTT
scott@ORA10> create table temp as select * from test where 1=2;
scott@ORA10> insert into temp select * from test where rowid < dbms_rowid.rowid_create(1,52670,6,587,0);
已创建29400行。
scott@ORA10> insert into temp select * from test where rowid>dbms_rowid.rowid_create(1,52670,6,589,0);
已创建270600行。
Create the required ROWIDs with the following dbms_rowid.rowid_create function:
function rowid_create (rowid_type IN number, object_number IN number ,relative_fno IN number, block_number IN number ,row_number IN number) return rowid; pragma RESTRICT_REFERENCES(rowid_create,WNDS,RNDS,WNPS,RNPS)[/COLOR]
这样就把TEST中没有损坏的数据都已经移到TEMP中,然后DROP TABLE TEST
RENAME TEMP TO TEST
然后在从建索引约束等等...
4.使用BBED 工具(此工具是ORACLE内部工具没有技术支持使用要慎重),要想使用此工具需要手动进行编译下.
$ cd $ORACLE_HOME/rdbms/lib
$ make -f ins_rdbms.mk $ORACLE_HOME/rdbms/lib/bbed
此工具有个密码保护:blockedit
在你发现某个发生块损坏的时候你刚好有个此文件的物理备份,那么你就可以使用此工具将备份的物理文件中的BLOCK COPY 到当前损坏的文件中(此方法很容易造成数据不一致的情况,例如在你备份完物理文件后,刚好损坏的数据块发生了改变.)
BBED> verify
DBVERIFY - Verification starting
FILE = /oracle/db/oracle/oradata/ora10/users01.dbf
BLOCK = 32
Block 32 is corrupt
Corrupt block relative dba: 0x01000020 (file 0, block 32)
Bad header found during verification
Data in bad block:
type: 3 format: 0 rdba: 0x01000020
last change scn: 0x0000.0006bfdb seq: 0x10 flg: 0x06
spare1: 0x0 spare2: 0x0 spare3: 0x0
consistency value in tail: 0xbfdb0610
check value in block header: 0x26a0
computed block checksum: 0x4a05
sys@ORA10> select * from scott.emp;
select * from scott.emp
*
第 1 行出现错误:
ORA-01578: ORACLE data block corrupted (file # 4, block # 32)
ORA-01110: data file 4: '/oracle/db/oracle/oradata/ora10/users01.dbf'
BBED> copy file 2 block 32 to file 1 block 32
File: /oracle/db/oracle/oradata/ora10/users01.dbf (1)
Block: 32 Offsets: 0 to 8191 Dba:0x00400020
BBED> verify file 1
DBVERIFY - Verification starting
FILE = /oracle/db/oracle/oradata/ora10/users01.dbf
DBVERIFY - Verification complete
Total Blocks Examined : 1120
Total Blocks Processed (Data) : 549
Total Blocks Failing (Data) : 0
Total Blocks Processed (Index): 63
Total Blocks Failing (Index): 0
Total Blocks Empty : 353
Total Blocks Marked Corrupt : 0
Total Blocks Influx : 0
sys@ORA10> shutdown immediate
数据库已经关闭。
已经卸载数据库。
ORACLE 例程已经关闭。
sys@ORA10> startup
ORACLE 例程已经启动。
Total System Global Area 205520896 bytes
Fixed Size 1218532 bytes
Variable Size 79693852 bytes
Database Buffers 121634816 bytes
Redo Buffers 2973696 bytes
数据库装载完毕。
数据库已经打开。
sys@ORA10> select * from scott.emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
7369 SMITH CLERK 7902 17-12月-80 800 20
7499 ALLEN SALESMAN 7698 20-2月 -81 1600 300 30
7521 WARD SALESMAN 7698 22-2月 -81 1250 500 30
7566 JONES MANAGER 7839 02-4月 -81 2975 20
7654 MARTIN SALESMAN 7698 28-9月 -81 1250 1400 30
7698 BLAKE MANAGER 7839 01-5月 -81 2850 30
7782 CLARK MANAGER 7839 09-6月 -81 2450 10
7788 SCOTT ANALYST 7566 19-4月 -87 3000 20
7839 KING PRESIDENT 17-11月-81 5000 10
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
7844 TURNER SALESMAN 7698 08-9月 -81 1500 0 30
7876 ADAMS CLERK 7788 23-5月 -87 1100 20
7900 JAMES CLERK 7698 03-12月-81 950 30
7902 FORD ANALYST 7566 03-12月-81 3000 20
7934 MILLER CLERK 7782 23-1月 -82 1300 10
已选择14行。
5.使用DBMS_REPAIR 包,此包并不能真正修复损坏的块,只不过是标记出损坏的块
admin_tables: Create the repair tables
check_object: Populate the repair tables with information about corruptions and repair directives
fix_corrupt_blocks: Fix the corrupt blocks in specified objects based on information in the repair table (ORA-1578)
dump_orphan_keys: Report on index entries that point to rows in corrupt data blocks (optional)
skip_corrupt_blocks: Skip corrupt blocks during index and table scans