标签云
asm恢复 bbed bootstrap$ dul kcbzib_kcrsds_1 kccpb_sanity_check_2 kcratr_nab_less_than_odr MySQL恢复 obet ORA-00312 ORA-00704 ORA-00742 ORA-01110 ORA-01200 ORA-01555 ORA-01578 ORA-01595 ORA-600 2662 ORA-600 2663 ORA-600 3020 ORA-600 4000 ORA-600 4137 ORA-600 4193 ORA-600 4194 ORA-600 16703 ORA-600 kcbzib_kcrsds_1 ORA-600 KCLCHKBLK_4 ORA-600 kcratr_nab_less_than_odr ORA-15042 ORA-15196 ORACLE 12C oracle dul ORACLE PATCH Oracle Recovery Tools oracle加密恢复 oracle勒索 oracle勒索恢复 oracle异常恢复 ORACLE恢复 Oracle 恢复 ORACLE数据库恢复 oracle碎片 OSD-04016 YOUR FILES ARE ENCRYPTED 比特币加密文章分类
- MongoDB (1)
- MongoDB恢复 (1)
- Others (2)
- 中间件 (2)
- WebLogic (2)
- 操作系统 (112)
- 数据库 (1,881)
- DB2 (22)
- MySQL (82)
- Oracle (1,706)
- Data Guard (53)
- EXADATA (8)
- GoldenGate (24)
- ORA-xxxxx (168)
- ORACLE 12C (72)
- ORACLE 18C (6)
- ORACLE 19C (15)
- ORACLE 21C (3)
- Oracle 23ai (8)
- Oracle ASM (72)
- Oracle Bug (8)
- Oracle RAC (56)
- Oracle 安全 (6)
- Oracle 开发 (28)
- Oracle 监听 (29)
- Oracle备份恢复 (660)
- Oracle安装升级 (108)
- Oracle性能优化 (62)
- 专题索引 (5)
- 勒索恢复 (91)
- PostgreSQL (37)
- pdu工具 (7)
- PostgreSQL恢复 (13)
- SQL Server (34)
- SQL Server恢复 (14)
- TimesTen (7)
- 达梦数据库 (5)
- 达梦恢复 (3)
- 生活娱乐 (2)
- 至理名言 (11)
- 虚拟化 (2)
- VMware (2)
- 软件开发 (51)
- Asp.Net (9)
- JavaScript (12)
- PHP (2)
- 小工具 (34)
- MongoDB (1)
-
最近发表
- 记录一次云存储资源到期之后引起的数据库恢复
- Firebird 损坏数据库数据抢救工具—firebirdext
- Oracle 19c 202610补丁(RUs+OJVM)-19.33
- 由于con$.con#值达到极限,触发数据库增加约束报ORA-600 12807错误
- MongoDB 离线提取工具—mongoext
- .bres勒索病毒加密数据库dmp文件可恢复
- ORA-600 krsm_mrp_rebuild_lf_list.lno_mismatch
- 记录一次0丢失的ORA-00354: 损坏重做日志块标头故障恢复
- 不当数据库恢复操作导致一个月数据丢失
- obet快速修复oracle 位图损坏块
- 不太常见的10.2.0.1的oracle redo损坏恢复
- obet forcecopy功能抢救硬件故障中的数据文件
- kcratr_nab_less_than_odr和system坏块故障处理
- 通过obet 恢复system坏块,打开数据库
- obet dbv功能完整说明
- 分享一例运行在aix上的sap系统数据库恢复过程
- OBET-Oracle Block Editor Tool使用说明
- 几乎动用了所有手段的Oracle故障恢复
- Oracle Block Edit Tool (obet) 功能增强–2026.07
- Oracle 19c 202607补丁(RUs+OJVM)-19.32
分类目录归档:Oracle备份恢复
recover遇到坏块处理本质探讨
如果在还原出来的数据文件中有坏块,而归档日志和联机日志是正常的,那么在应用日志恢复过程中,会出现什么情况,这里通过一个简单的测试给予其中一种情况的说明
创建测试表
SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Prod
PL/SQL Release 10.2.0.4.0 - Production
CORE 10.2.0.4.0 Production
TNS for Linux: Version 10.2.0.4.0 - Production
NLSRTL Version 10.2.0.4.0 - Production
SQL> create table t_xifenfei(object_id,object_name) tablespace xifenfei
2 as
3 select object_id,object_name from dba_objects
4 where rownum<11;
Table created.
SQL> col object_name for a30
SQL> select object_id,object_name,
2 dbms_rowid.rowid_relative_fno(rowid)rel_fno,
3 dbms_rowid.rowid_block_number(rowid)blockno
4 from chf.t_xifenfei;
OBJECT_ID OBJECT_NAME REL_FNO BLOCKNO
---------- ------------------------------ ---------- ----------
20 ICOL$ 5 12
44 I_USER1 5 12
28 CON$ 5 12
15 UNDO$ 5 12
29 C_COBJ# 5 12
3 I_OBJ# 5 12
25 PROXY_ROLE_DATA$ 5 12
39 I_IND1 5 12
51 I_CDEF2 5 12
26 I_PROXY_ROLE_DATA$_1 5 12
10 rows selected.
SQL> select name from v$datafile where file#=5;
NAME
--------------------------------------------------------------
/u01/oracle/oradata/XFF/xifenfei01.dbf
SQL> update t_xifenfei set object_name='WWW.XIFENFEI.COM';
10 rows updated.
SQL> commit;
Commit complete.
SQL> create table t_xifenfei_new(object_id,object_name) tablespace xifenfei
2 as
3 select object_id,object_name from dba_objects
4 where rownum<11;
Table created.
SQL> conn / as sysdba
Connected.
SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
备份数据文件
[oracle@xifenfei XFF]$ cp xifenfei01.dbf ../tmp/ [oracle@xifenfei XFF]$ ll ../tmp/xifenfei01.dbf -rw-r----- 1 oracle oinstall 10493952 Sep 28 19:05 ../tmp/xifenfei01.dbf [oracle@xifenfei XFF]$ date Fri Sep 28 19:05:42 CST 2012
bbed破坏备份文件
[oracle@xifenfei XFF]$ bbed password=blockedit
BBED: Release 2.0.0.0.0 - Limited Production on Fri Sep 28 19:05:59 2012
Copyright (c) 1982, 2007, Oracle. All rights reserved.
************* !!! For Oracle Internal Use only !!! ***************
BBED> set filename '/u01/oracle/oradata/tmp/xifenfei01.dbf'
FILENAME /u01/oracle/oradata/tmp/xifenfei01.dbf
BBED> set block 12
BLOCK# 12
BBED> set mode edit
MODE Edit
BBED> map
File: /u01/oracle/oradata/tmp/xifenfei01.dbf (0)
Block: 12 Dba:0x00000000
------------------------------------------------------------
KTB Data Block (Table/Cluster)
struct kcbh, 20 bytes @0
struct ktbbh, 96 bytes @20
struct kdbh, 14 bytes @124
struct kdbt[1], 4 bytes @138
sb2 kdbr[10] @142
ub1 freespace[7666] @162
ub1 rowdata[360] @7828
ub4 tailchk @8188
BBED> p kcbh
struct kcbh, 20 bytes @0
ub1 type_kcbh @0 0x06
ub1 frmt_kcbh @1 0xa2
ub1 spare1_kcbh @2 0x00
ub1 spare2_kcbh @3 0x00
ub4 rdba_kcbh @4 0x0140000c
ub4 bas_kcbh @8 0x0004d7b0
ub2 wrp_kcbh @12 0x000a
ub1 seq_kcbh @14 0x01
ub1 flg_kcbh @15 0x06 (KCBHFDLC, KCBHFCKV)
ub2 chkval_kcbh @16 0xe573
ub2 spare3_kcbh @18 0x0000
BBED> d offset 8188
File: /u01/oracle/oradata/tmp/xifenfei01.dbf (0)
Block: 12 Offsets: 8188 to 8191 Dba:0x00000000
------------------------------------------------------------------------
0106b0d7
<32 bytes per line>
BBED> m /x 11
Warning: contents of previous BIFILE will be lost. Proceed? (Y/N) y
File: /u01/oracle/oradata/tmp/xifenfei01.dbf (0)
Block: 12 Offsets: 8188 to 8191 Dba:0x00000000
------------------------------------------------------------------------
1106b0d7
<32 bytes per line>
BBED> sum apply
Check value for File 0, Block 12:
current = 0xe563, required = 0xe563
BBED> verify
DBVERIFY - Verification starting
FILE = /u01/oracle/oradata/tmp/xifenfei01.dbf
BLOCK = 12
Block 12 is corrupt
Corrupt block relative dba: 0x0140000c (file 0, block 12)
Fractured block found during verification
Data in bad block:
type: 6 format: 2 rdba: 0x0140000c
last change scn: 0x000a.0004d7b0 seq: 0x1 flg: 0x06
spare1: 0x0 spare2: 0x0 spare3: 0x0
consistency value in tail: 0xd7b00611
check value in block header: 0xe563
computed block checksum: 0x0
DBVERIFY - Verification complete
Total Blocks Examined : 1
Total Blocks Processed (Data) : 0
Total Blocks Failing (Data) : 0
Total Blocks Processed (Index): 0
Total Blocks Failing (Index): 0
Total Blocks Empty : 0
Total Blocks Marked Corrupt : 1
Total Blocks Influx : 2
修改数据库记录
SQL> startup ORACLE instance started. Total System Global Area 318767104 bytes Fixed Size 1267236 bytes Variable Size 109054428 bytes Database Buffers 201326592 bytes Redo Buffers 7118848 bytes Database mounted. Database opened. SQL> conn chf/xifenfei Connected. SQL> update t_xifenfei set object_name='惜分飞'; 10 rows updated. SQL> update t_xifenfei_new set object_name='惜分飞'; 10 rows updated. SQL> commit; Commit complete. SQL> alter system switch logfile; System altered. SQL> alter system switch logfile; System altered. SQL> alter system switch logfile; System altered. SQL> conn / as sysdba Connected. SQL> shutdown immediate Database closed. Database dismounted. ORACLE instance shut down.
利用备份数据文件恢复数据库
[oracle@xifenfei XFF]$ cp xifenfei01.dbf xifenfei01.dbf_bak
[oracle@xifenfei XFF]$ cp ../tmp/xifenfei01.dbf xifenfei01.dbf
[oracle@xifenfei XFF]$ sqlplus / as sysdba
SQL*Plus: Release 10.2.0.4.0 - Production on Fri Sep 28 19:13:59 2012
Copyright (c) 1982, 2007, Oracle. All Rights Reserved.
Connected to an idle instance.
SQL> startup
ORACLE instance started.
Total System Global Area 318767104 bytes
Fixed Size 1267236 bytes
Variable Size 109054428 bytes
Database Buffers 201326592 bytes
Redo Buffers 7118848 bytes
Database mounted.
ORA-01113: file 5 needs media recovery
ORA-01110: data file 5: '/u01/oracle/oradata/XFF/xifenfei01.dbf'
--提示数据需要恢复
SQL> recover datafile 5;
ORA-00279: change 42949990720 generated at 09/28/2012 19:04:10 needed for
thread 1
ORA-00289: suggestion : /u01/oracle/oradata/XFF/archivelog/1_24_792679299.dbf
ORA-00280: change 42949990720 for thread 1 is in sequence #24
Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
auto
Log applied.
Media recovery complete.
SQL> alter database open;
Database altered.
--利用被破坏的数据文件+归档日志恢复数据库正常
SQL> col object_name for a30
SQL> select object_id,object_name from t_xifenfei;
select object_id,object_name from t_xifenfei
*
ERROR at line 1:
ORA-01578: ORACLE data block corrupted (file # 5, block # 12)
ORA-01110: data file 5: '/u01/oracle/oradata/XFF/xifenfei01.dbf'
--提示被破坏的数据块,查询不能完成
--证明坏块之外的数据块还是被正常应用日志
SQL> select object_id,object_name from t_xifenfei_new;
OBJECT_ID OBJECT_NAME
---------- ------------------------------
20 惜分飞
44 惜分飞
28 惜分飞
15 惜分飞
29 惜分飞
3 惜分飞
25 惜分飞
39 惜分飞
51 惜分飞
26 惜分飞
10 rows selected.
SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
dbv检查坏块
[oracle@xifenfei XFF]$ dbv file=xifenfei01.dbf DBVERIFY: Release 10.2.0.4.0 - Production on Fri Sep 28 19:14:52 2012 Copyright (c) 1982, 2007, Oracle. All rights reserved. DBVERIFY - Verification starting : FILE = xifenfei01.dbf DBV-00200: Block, DBA 20971532, already marked corrupt --这里可以看出来,该数据块已经被标志为坏块 DBVERIFY - Verification complete Total Pages Examined : 1280 Total Pages Processed (Data) : 2 Total Pages Failing (Data) : 0 Total Pages Processed (Index): 0 Total Pages Failing (Index): 0 Total Pages Processed (Other): 14 Total Pages Processed (Seg) : 0 Total Pages Failing (Seg) : 0 Total Pages Empty : 1264 Total Pages Marked Corrupt : 1 Total Pages Influx : 0 Highest block SCN : 318700 (10.318700)
查看恢复过程alert日志
Fri Sep 28 19:14:06 2012 Database mounted in Exclusive Mode Completed: ALTER DATABASE MOUNT Fri Sep 28 19:14:06 2012 ALTER DATABASE OPEN ORA-1113 signalled during: ALTER DATABASE OPEN... Fri Sep 28 19:14:11 2012 ALTER DATABASE RECOVER datafile 5 Media Recovery Start parallel recovery started with 2 processes ORA-279 signalled during: ALTER DATABASE RECOVER datafile 5 ... Fri Sep 28 19:14:16 2012 ALTER DATABASE RECOVER CONTINUE DEFAULT Fri Sep 28 19:14:16 2012 --恢复数据库的时候,发现坏块 Media Recovery Log /u01/oracle/oradata/XFF/archivelog/1_24_792679299.dbf Fri Sep 28 19:14:16 2012 Hex dump of (file 5, block 12) in trace file /u01/oracle/admin/XFF/bdump/xff_p001_23011.trc Corrupt block relative dba: 0x0140000c (file 5, block 12) Fractured block found during media recovery Data in bad block: type: 6 format: 2 rdba: 0x0140000c last change scn: 0x000a.0004d7b0 seq: 0x1 flg: 0x06 spare1: 0x0 spare2: 0x0 spare3: 0x0 consistency value in tail: 0xd7b00611 check value in block header: 0xe563 computed block checksum: 0x0 Reread of rdba: 0x0140000c (file 5, block 12) found same corrupted data --继续恢复 Fri Sep 28 19:14:16 2012 Recovery of Online Redo Log: Thread 1 Group 1 Seq 25 Reading mem 0 Mem# 0: /u01/oracle/oradata/XFF/redo01.log Fri Sep 28 19:14:16 2012 Recovery of Online Redo Log: Thread 1 Group 2 Seq 26 Reading mem 0 Mem# 0: /u01/oracle/oradata/XFF/redo02.log Fri Sep 28 19:14:16 2012 Recovery of Online Redo Log: Thread 1 Group 3 Seq 27 Reading mem 0 Mem# 0: /u01/oracle/oradata/XFF/redo03.log Fri Sep 28 19:14:16 2012 Media Recovery Complete (XFF) Completed: ALTER DATABASE RECOVER CONTINUE DEFAULT Fri Sep 28 19:14:31 2012 alter database open
bbed查看修改相关信息
BBED> set filename '/u01/oracle/oradata/XFF/xifenfei01.dbf'
FILENAME /u01/oracle/oradata/XFF/xifenfei01.dbf
BBED> set block 12
BLOCK# 12
BBED> map
File: /u01/oracle/oradata/XFF/xifenfei01.dbf (0)
Block: 12 Dba:0x00000000
------------------------------------------------------------
KTB Data Block (Table/Cluster)
struct kcbh, 20 bytes @0
struct ktbbh, 96 bytes @20
struct kdbh, 14 bytes @124
struct kdbt[1], 4 bytes @138
sb2 kdbr[10] @142
ub1 freespace[7666] @162
ub1 rowdata[360] @7828
ub4 tailchk @8188
BBED> p kcbh
struct kcbh, 20 bytes @0
ub1 type_kcbh @0 0x06
ub1 frmt_kcbh @1 0xa2
ub1 spare1_kcbh @2 0x00
ub1 spare2_kcbh @3 0x00
ub4 rdba_kcbh @4 0x0140000c
ub4 bas_kcbh @8 0x00000000
ub2 wrp_kcbh @12 0x0000
ub1 seq_kcbh @14 0xff <--因为被标记为坏块,所以为ff
ub1 flg_kcbh @15 0x04 (KCBHFCKV)
ub2 chkval_kcbh @16 0xe77d
ub2 spare3_kcbh @18 0x0000
--查看数据块中记录
BBED> p *kdbr[5]
rowdata[69]
-----------
ub1 rowdata[69] @7897 0x2c
BBED> x /rnc
rowdata[69] @7897
-----------
flag@7897: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@7898: 0x02
cols@7899: 2
col 0[2] @7900: 3
col 1[16] @7903: WWW.XIFENFEI.COM <--确实没有被恢复,而是直接被跳过
BBED> set mode edit
MODE Edit
BBED> m /x 01 offset 14
Warning: contents of previous BIFILE will be lost. Proceed? (Y/N) y
File: /u01/oracle/oradata/XFF/xifenfei01.dbf (0)
Block: 12 Offsets: 14 to 525 Dba:0x00000000
------------------------------------------------------------------------
01047de7 00000100 00000dcc 000098d7 …………
<32 bytes per line>
BBED> d offset 8188
File: /u01/oracle/oradata/XFF/xifenfei01.dbf (0)
Block: 12 Offsets: 8188 to 8191 Dba:0x00000000
------------------------------------------------------------------------
ff060000 <--这么说明:数据块被标志为坏块的时候,同时会修改tailchk值
<32 bytes per line>
BBED> m /x 01 offset 8188
File: /u01/oracle/oradata/XFF/xifenfei01.dbf (0)
Block: 12 Offsets: 8188 to 8191 Dba:0x00000000
------------------------------------------------------------------------
01060000
<32 bytes per line>
BBED> sum apply
Check value for File 0, Block 12:
current = 0xe77d, required = 0xe77d
--验证块已经标记为正常块
BBED> verify
DBVERIFY - Verification starting
FILE = /u01/oracle/oradata/XFF/xifenfei01.dbf
BLOCK = 12
DBVERIFY - Verification complete
Total Blocks Examined : 1
Total Blocks Processed (Data) : 1
Total Blocks Failing (Data) : 0
Total Blocks Processed (Index): 0
Total Blocks Failing (Index): 0
Total Blocks Empty : 0
Total Blocks Marked Corrupt : 0
Total Blocks Influx : 0
启动数据库测试
SQL> startup
ORACLE instance started.
Total System Global Area 318767104 bytes
Fixed Size 1267236 bytes
Variable Size 109054428 bytes
Database Buffers 201326592 bytes
Redo Buffers 7118848 bytes
Database mounted.
Database opened.
SQL> conn chf/xifenfei
Connected.
SQL> col object_name for a30
SQL> select object_id,object_name from t_xifenfei;
OBJECT_ID OBJECT_NAME
---------- ------------------------------
20 WWW.XIFENFEI.COM
44 WWW.XIFENFEI.COM
28 WWW.XIFENFEI.COM
15 WWW.XIFENFEI.COM
29 WWW.XIFENFEI.COM
3 WWW.XIFENFEI.COM
25 WWW.XIFENFEI.COM
39 WWW.XIFENFEI.COM
51 WWW.XIFENFEI.COM
26 WWW.XIFENFEI.COM
10 rows selected.
--通过修改数据块的seq_kcbh和tailchk,让这个块恢复正常,但是记录依然丢失,
--因为应用日志恢复之时标记为坏块跳过该块的日志应用
通过实验证明:
1.如果只有数据块异常,应用日志恢复,不一定会出现ORA-600[3020],而是直接把该块标记为坏块,继续应用日志
2.标记坏块其实就是修改seq_kcbh为ff,同时也修改tailchk值
3.经验值:如果在数据库应用日志恢复的时候,如果出现ORA-600[3020]错误,可以使用allow 2 corruption来跳过坏块处理,其实也是修改seq_kcbh为ff,然后让数据库跳过该块的恢复.
发表在 Oracle备份恢复
评论关闭
使用plsql抢救数据
“在oracle出现ORA-8103/ORA-1578/ORA-376″等情况下抢救数据的争论没有停止过,很多人想到的是使用bbed,dul等工具来抢救,其实在很多时候我们使用pl/sql也可以完美的抢救数据.在这里我们通过模拟ORA-8103错误,然后使用plsql来找回数据.这中处理方法相对于bbed风险小,但是缺点是如果数据量大处理时间可能比较长,可能比dul有的一比,但是dul的工具不是任何人都有的.所以整体来说,在大部分情况下,这种方法处理某个数据块错误,抢救某个对象数据,还是很好的方法.
1.有非空列index情况
--创建测试表
SQL> create table xifenfei
2 as
3 select * from dba_objects;
Table created.
--修改某个项为非空值
SQL> alter table xifenfei modify object_id not null;
Table altered.
--创建一个唯一index
SQL> create unique index ind_xifenfei on xifenfei(object_id);
Index created.
--表总记录
SQL> select count(*) from xifenfei;
COUNT(*)
----------
50088
--extent的分布情况
SQL> set pages 100
SQL> select file_id,block_id,block_id+blocks-1
2 from dba_extents
3 where segment_name ='XIFENFEI' AND owner='CHF';
FILE_ID BLOCK_ID BLOCK_ID+BLOCKS-1
---------- ---------- -----------------
9 1545 1552
9 1553 1560
9 1561 1568
9 1569 1576
9 1577 1584
9 1585 1592
9 1593 1600
9 1601 1608
9 1609 1616
9 1617 1624
9 1625 1632
9 1633 1640
9 1641 1648
9 1649 1656
9 1657 1664
9 1665 1672
9 1673 1800
9 1801 1928
9 1929 2056
9 2057 2184
9 2185 2312
21 rows selected.
--2200数据块包含记录
SQL> select count(*)
2 from chf.xifenfei where dbms_rowid.rowid_block_number(rowid)=2200;
COUNT(*)
----------
69
--关闭数据库
SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
--破坏数据块
[oracle@xifenfei ~]$ dd if=/dev/zero of=/u01/oracle/oradata/XFF/users03.dbf bs=8192 count=1 seek=2200 conv=notrunc
1+0 records in
1+0 records out
8192 bytes (8.2 kB) copied, 0.000151554 seconds, 54.1 MB/s
--启动数据库
SQL> startup
ORACLE instance started.
Total System Global Area 318767104 bytes
Fixed Size 1267236 bytes
Variable Size 104860124 bytes
Database Buffers 205520896 bytes
Redo Buffers 7118848 bytes
Database mounted.
Database opened.
--查询结果
SQL> select /*+ full(xifenfei) */ count(*) from chf.xifenfei;
select /*+ full(xifenfei) */ count(*) from chf.xifenfei
*
ERROR at line 1:
ORA-08103: object no longer exists
SQL> create table chf.xifenfei_new
2 as
3 select * from chf.xifenfei;
select * from chf.xifenfei
*
ERROR at line 3:
ORA-08103: object no longer exists
--创建备份表
SQL> create table chf.xifenfei_new
2 as
3 select * from chf.xifenfei where 1=0;
Table created.
--创建坏块相关rowid记录表
SQL> create table chf.bad_rows (row_id rowid, oracle_error_code number);
Table created.
--执行plsql脚本
DECLARE
TYPE RowIDTab IS TABLE OF ROWID INDEX BY BINARY_INTEGER;
CURSOR c1 IS select /*+ index(xifenfei ind_xifenfei) */ rowid
from chf.xifenfei
where object_id is NOT NULL;
r RowIDTab;
rows NATURAL := 20000;
bad_rows number := 0 ;
errors number;
error_code number;
myrowid rowid;
BEGIN
OPEN c1;
LOOP
FETCH c1 BULK COLLECT INTO r LIMIT rows;
EXIT WHEN r.count=0;
BEGIN
FORALL i IN r.FIRST..r.LAST SAVE EXCEPTIONS
insert into chf.xifenfei_new
select /*+ ROWID(A) */ *
from chf.xifenfei A where rowid = r(i);
EXCEPTION
when OTHERS then
BEGIN
errors := SQL%BULK_EXCEPTIONS.COUNT;
FOR err1 IN 1..errors LOOP
error_code := SQL%BULK_EXCEPTIONS(err1).ERROR_CODE;
if error_code in (1410, 8103) then
myrowid := r(SQL%BULK_EXCEPTIONS(err1).ERROR_INDEX);
bad_rows := bad_rows + 1;
insert into chf.bad_rows values(myrowid, error_code);
else
raise;
end if;
END LOOP;
END;
END;
commit;
END LOOP;
commit;
CLOSE c1;
dbms_output.put_line('Total Bad Rows: '||bad_rows);
END;
/
--查询错误记录
SQL> select count(*) from chf.bad_rows ;
COUNT(*)
----------
69
SQL> select * from chf.bad_rows where rownum<10;
ROW_ID ORACLE_ERROR_CODE
------------------ -----------------
AAAMugAAJAAAAiYAAA 8103
AAAMugAAJAAAAiYAAB 8103
AAAMugAAJAAAAiYAAC 8103
AAAMugAAJAAAAiYAAD 8103
AAAMugAAJAAAAiYAAE 8103
AAAMugAAJAAAAiYAAF 8103
AAAMugAAJAAAAiYAAG 8103
AAAMugAAJAAAAiYAAH 8103
AAAMugAAJAAAAiYAAI 8103
9 rows selected.
--查询备份表记录
SQL> select count(*) from chf.xifenfei_new;
COUNT(*)
----------
50019
50088-50019=69和被破坏块中记录一致,证明所有好块中记录全部被找回来
2.无非空列index情况
--创建表
SQL> CONN CHF/XIFENFEI
Connected.
SQL> create table t_xifenfei
2 as
3 select * from dba_objects;
Table created.
--表中记录总数
SQL> select count(*) from t_xifenfei;
COUNT(*)
----------
50086
--extent分布
SQL> SET PAGES 100
SQL> select file_id,block_id,block_id+blocks-1
2 from dba_extents
3 where segment_name ='T_XIFENFEI' AND owner='CHF';
FILE_ID BLOCK_ID BLOCK_ID+BLOCKS-1
---------- ---------- -----------------
9 9 16
9 17 24
9 25 32
9 33 40
9 41 48
9 49 56
9 57 64
9 65 72
9 73 80
9 81 88
9 89 96
9 97 104
9 105 112
9 113 120
9 121 128
9 129 136
9 137 264
9 265 392
9 393 520
9 521 648
9 649 776
21 rows selected.
--700数据块中记录数
SQL> select count(*)
2 from chf.t_xifenfei where dbms_rowid.rowid_block_number(rowid)=700;
COUNT(*)
----------
73
--关闭数据库
SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
--破坏block 700的数据块
[oracle@xifenfei ~]$ dd if=/dev/zero of=/u01/oracle/oradata/XFF/users03.dbf bs=8192 count=1 seek=700 conv=notrunc
1+0 records in
1+0 records out
8192 bytes (8.2 kB) copied, 0.000156576 seconds, 52.3 MB/s
--启动数据库
SQL> startup
ORACLE instance started.
Total System Global Area 318767104 bytes
Fixed Size 1267236 bytes
Variable Size 104860124 bytes
Database Buffers 205520896 bytes
Redo Buffers 7118848 bytes
Database mounted.
Database opened.
--查询报错
SQL> select count(*) from chf.t_xifenfei;
select count(*) from chf.t_xifenfei
*
ERROR at line 1:
ORA-08103: object no longer exists
--创建备份表
SQL> CREATE TABLE T_XIFENFEI_NEW
2 AS
3 SELECT * FROM T_XIFENFEI WHERE 1=0;
--找回记录
set serveroutput on
set concat off
DECLARE
nrows number;
rid rowid;
dobj number;
ROWSPERBLOCK number;
BEGIN
ROWSPERBLOCK:=1000; --估算最大的一个块中记录条数
nrows:=0;
select data_object_id into dobj
from dba_objects
where owner = 'CHF'
and object_name = 'T_XIFENFEI'
-- and subobject_name = '<table partition>' Add this condition if table is partitioned
;
for i in (select relative_fno, block_id, block_id+blocks-1 totblocks
from dba_extents
where owner = 'CHF'
and segment_name = 'T_XIFENFEI'
-- and partition_name = '<table partition>' Add this condition if table is partitioned
-- and file_id != <OFFLINED DATAFILE> This condition is only used if a datafile needs to be skipped due to ORA-376 (A)
order by extent_id)
loop
for br in i.block_id..i.totblocks loop
for j in 1..ROWSPERBLOCK loop
begin
rid := dbms_rowid.ROWID_CREATE(1,dobj,i.relative_fno, br , j-1);
insert into CHF.T_XIFENFEI_NEW
select /*+ ROWID(A) */ *
from CHF.T_XIFENFEI A
where rowid = rid;
if sql%rowcount = 1 then nrows:=nrows+1; end if;
if (mod(nrows,10000)=0) then commit; end if;
exception when others then null;
end;
end loop;
end loop;
end loop;
COMMIT;
dbms_output.put_line('Total rows: '||to_char(nrows));
END;
/
--找回记录数
SQL> SELECT COUNT(*) FROM CHF.T_XIFENFEI_NEW;
COUNT(*)
----------
50013
50086-50013=73 证明非坏块中的数据都被完全寻找回来
参考:
ORA-8103 Troubleshooting, Diagnostic and Solution [ID 268302.1]
Extract rows from a CORRUPT table creating ROWID from DBA_EXTENTS [ID 422547.1]
发表在 Oracle备份恢复
2 条评论

加我微信(17813235971)
加我QQ(107644445)

