xxxx数据库坏块测试报告
一、 测试背景
xxxx数据库存在逻辑坏块,应用程序在执行SQL语句时报ORA-01578错误,导致SQL语句执行失败。搭建测试环境,测试几种坏块处理方法。
二、 测试目的
1、 测试dbms_repair包是否可以跳过坏块;
2、 测试10231事件是否可以跳过坏块;
3、 测试empty_blob()函数是否可以重置BLOG类型的字段置为空置,消除坏的记录。
三、 测试步骤
1、 在测试机器上安装oracle数据库;
2、 安装、配置NBU软件;
3、 RMAN异机恢复备份集;
4、 应用归档,启动数据库;
5、 测试dbms_repair包处理坏块;
6、 测试10231事件处理坏块;
7、 测试empty_blob()函数处理坏的记录。
四、 测试过程
方法一:
dbms_repair包处理坏块,以处理FMIS1600.XTDXDBGRIDFORMAT表为例,不能跳过坏块,测试过程如下:
1、创建REPAIR_TABLE2表,记录坏块信息
begin
dbms_repair.admin_tables (
table_name => ’REPAIR_TABLE2’,
table_type => dbms_repair.repair_table,
action => dbms_repair.create_action,
tablespace => ’SYSTEM’);
end;
/
2、检测坏块,坏块信息存入REPAIR_TABLE2表
declare
rpr_count int;
begin
rpr_count := 0;
dbms_repair.check_object (
schema_name => ’ FMIS1600',
object_name => ’ XTDXDBGRIDFORMAT',
repair_table_name => ’REPAIR_TABLE’,
corrupt_count => rpr_count);
dbms_output.put_line(’repair count: ’ || to_char(rpr_count));
end;
/
3、查询坏块
set serveroutput on
select object_name, block_id, corrupt_type, marked_corrupt,corrupt_description, repair_description from repair_table;
4、标记FMIS1600.XTDXDBGRIDFORMA表的坏块
declare
fix_count int;
begin
fix_count := 0;
dbms_repair.fix_corrupt_blocks (
schema_name => ’ FMIS1600’,
object_name => ‘XTDXDBGRIDFORMAT’,
object_type => dbms_repair.table_object,
repair_table_name => ’REPAIR_TABLE’,
fix_count => fix_count);
dbms_output.put_line(’fix count: ’ || to_char(fix_count));
end;
/
5、跳过所有被标记坏块的数据
begin
dbms_repair.skip_corrupt_blocks (
schema_name => ’ FMIS1600’,
object_name => ‘XTDXDBGRIDFORMAT’,S
object_type => dbms_repair.table_object,
flags => dbms_repair.skip_flag);
end;
/
6、创建表FMIS1600.XTDXDBGRIDFORMAT_TMP失败
create table FMIS1600.XTDXDBGRIDFORMAT_TMP as select * from FMIS1600.XTDXDBGRIDFORMAT;
方法二:
10231事件处理坏块,以处理FMIS1600.XTDXDBGRIDFORMAT表为例,不能跳过坏块,测试过程如下:
1、在会话级开启10231事件
alter system set events '10231 trace name context forever,level 10';
2、创建临时表FMIS1600.XTDXDBGRIDFORMAT_TMP失败
create table FMIS1600.XTDXDBGRIDFORMAT_TMP as select * from FMIS1600.XTDXDBGRIDFORMAT;
方法三:
empty_blob()函数处理损坏的记录,分别测试5张表,FMIS_LOB_ISOLATED、XTDXDBGRIDFORMAT、FMIS_LOB、XTYWDJDELETELOG、XTDXBLOB都可以成功处理损坏的记录。
使用empty_blob()函数处理XTDXDBGRIDFORMAT表中损坏的BLOG字段,将损坏的记字段值重置为空值,测试过程如下:
1、创建表corrupted_data
$ sqlplus /nolog
SQL*Plus: Release 10.2.0.4.0 - Production on Wed Dec 26 10:30:47 2012
Copyright (c) 1982, 2007, Oracle. All Rights Reserved.
SQL> connect /as sysdba;
Connected.
SQL> create table corrupted_data (corrupted_rowid rowid);
Table created.
2、查找损坏的记录rowid,放到corrupted_data表
SQL> set concat off
SQL> declare
2 error_1578 exception;
3 pragma exception_init(error_1578,-1578);
4 n number;
5 begin
6 for cursor_lob in (select rowid r, &&lob_column from &&table_owner.&table_with_lob) loop
7 begin
8 n:=dbms_lob.instr(cursor_lob.&&lob_column,hextoraw('889911')) ;
9 exception
10 when error_1578 then
11 insert into corrupted_data values (cursor_lob.r);
12 commit;
13 end;
14 end loop;
15 end;
16 /
Enter value for lob_column: FORMATINFO
Enter value for table_owner: FMIS1600
Enter value for table_with_lob: XTDXDBGRIDFORMAT
old 6: for cursor_lob in (select rowid r, &&lob_column from &&table_owner.&table_with_lob) loop
new 6: for cursor_lob in (select rowid r, FORMATINFO from FMIS1600.XTDXDBGRIDFORMAT) loop
old 8: n:=dbms_lob.instr(cursor_lob.&&lob_column,hextoraw('889911')) ;
new 8: n:=dbms_lob.instr(cursor_lob. FORMATINFO,hextoraw('889911')) ;
PL/SQL procedure successfully completed.
3、检查坏的记录,并将坏BLOG字段的列设置为空值
SQL> SQL> SQL> SQL> select * from corrupted_data;
CORRUPTED_ROWID
------------------
AAAYQFAAIAAAat7AA9
AAAYQFAAIAAAat7ABG
AAAYQFAANAAAuGUAAH
AAAYQFAANAAAuGUAAK
AAAYQFAANAAAuGpAAL
AAAYQFAANAAAuGpAAM
AAAYQFAANAAAuGpAA2
7 rows selected.
SQL>
SQL> update &table_owner.&table_with_lob
2 set &lob_column = empty_blob()
3 where rowid in (select corrupted_rowid from corrupted_data);
Enter value for table_with_lob: XTDXDBGRIDFORMAT
old 1: update &table_owner.&table_with_lob
new 1: update FMIS1600.XTDXDBGRIDFORMAT
old 2: set &lob_column = empty_blob()
new 2: set FORMATINFO = empty_blob()
7 rows updated.
4、创建临时表FMIS1600.XTDXDBGRIDFORMAT_TMP没有报错
SQL> create table FMIS1600.XTDXDBGRIDFORMAT_TMP as select * from FMIS1600.XTDXDBGRIDFORMAT;
Table created.
使用empty_blob()函数处理FMIS_LOB_ISOLATED表中损坏的BLOG字段,将损坏的记字段值重置为空值,测试过程如下:
1、创建corrupted_data1
SQL> create table corrupted_data1 (corrupted_rowid rowid);
Table created.
2、查找损坏的记录,放到corrupted_data1表
SQL> set concat off
SQL> declare
2 error_1578 exception;
3 pragma exception_init(error_1578,-1578);
4 n number;
5 begin
6 for cursor_lob in (select rowid r, &&lob_column from &&table_owner.&table_with_lob) loop
7 begin
8 n:=dbms_lob.instr(cursor_lob.&&lob_column,hextoraw('889911')) ;
9 exception
10 when error_1578 then
11 insert into corrupted_data1 values (cursor_lob.r);
12 commit;
13 end;
14 end loop;
15 end;
16 /
Enter value for table_with_lob: FMIS_LOB_ISOLATED
old 6: for cursor_lob in (select rowid r, &&lob_column from &&table_owner.&table_with_lob) loop
new 6: for cursor_lob in (select rowid r, LOB_CONTENT from FMIS1600.FMIS_LOB_ISOLATED) loop
old 8: n:=dbms_lob.instr(cursor_lob.&&lob_column,hextoraw('889911')) ;
new 8: n:=dbms_lob.instr(cursor_lob. LOB_CONTENT,hextoraw('889911')) ;
PL/SQL procedure successfully completed.
3、检查坏的记录,并将坏的列设置为空值
SQL> select * from corrupted_data1;
CORRUPTED_ROWID
------------------
AAAD7RAAgAAA2SOAB0
AAAD7RAAgAAA2SOAB3
AAAD7RAAgAAA2SOAB4
AAAD7RAAgAAA2SOAB5
AAAD7RAAgAAA2SOAB6
AAAD7RAAgAAA2SOAB7
AAAD7RAAgAAA2SOAB8
AAAD7RAAgAAA2SOAB9
AAAD7RAAgAAA2SOAB+
AAAD7RAAgAAA2SOAB/
AAAD7RAAgAAA2SOACA
CORRUPTED_ROWID
------------------
AAAD7RAAgAAA2SOACB
AAAD7RAAgAAA2SOACC
AAAD7RAAgAAA2SOACD
AAAD7RAAgAAA2SOACE
AAAD7RAAgAAA2SOACF
AAAD7RAAgAAA2SOACG
AAAD7RAAgAAA2SOACH
AAAD7RAAgAAA2SOACI
AAAD7RAAgAAA2SOACJ
AAAD7RAAgAAA2SOACK
AAAD7RAAgAAA2SOACL
CORRUPTED_ROWID
------------------
AAAD7RAAgAAA2SPAAA
AAAD7RAAgAAA2SPAAB
AAAD7RAAgAAA2SPAAC
AAAD7RAAgAAA2SPAAD
AAAD7RAAgAAA2SPAAE
AAAD7RAAgAAA2SPAAF
AAAD7RAAgAAA2SPAAG
AAAD7RAAgAAA2SPAAH
AAAD7RAAgAAA2SPAAI
AAAD7RAAgAAA2SPAAJ
AAAD7RAAgAAA2SPAAK
CORRUPTED_ROWID
------------------
AAAD7RAAgAAA2SPAAL
34 rows selected.
SQL>
SQL> update &table_owner.&table_with_lob
2 set &lob_column = empty_blob()
3 where rowid in (select corrupted_rowid from corrupted_data1);
Enter value for table_with_lob: FMIS_LOB_ISOLATED
old 1: update &table_owner.&table_with_lob
new 1: update FMIS1600.FMIS_LOB_ISOLATED
old 2: set &lob_column = empty_blob()
new 2: set LOB_CONTENT = empty_blob()
34 rows updated.
SQL> commit;
4、 创建临时表FMIS1600.FMIS_LOB_ISOLATED_TMP
SQL> create table FMIS1600.FMIS_LOB_ISOLATED_TMP as select * from FMIS1600.FMIS_LOB_ISOLATED;
Table created.
使用empty_blob()函数处理FMIS_LOB表中损坏的BLOG字段,将损坏的记字段值重置为空值,测试过程如下:
1、创建corrupted_data2
SQL> create table corrupted_data2 (corrupted_rowid rowid);
Table created.
2、查找损坏的记录,放到corrupted_data2表
SQL> set concat off
SQL> declare
2 error_1578 exception;
3 pragma exception_init(error_1578,-1578);
4 n number;
5 begin
6 for cursor_lob in (select rowid r, &&lob_column from &&table_owner.&table_with_lob) loop
7 begin
8 n:=dbms_lob.instr(cursor_lob.&&lob_column,hextoraw('889911')) ;
9 exception
10 when error_1578 then
11 insert into corrupted_data2 values (cursor_lob.r);
12 commit;
13 end;
14 end loop;
15 end;
16 /
Enter value for table_with_lob: FMIS_LOB
old 6: for cursor_lob in (select rowid r, &&lob_column from &&table_owner.&table_with_lob) loop
new 6: for cursor_lob in (select rowid r, LOB_CONTENT from FMIS1600.FMIS_LOB) loop
old 8: n:=dbms_lob.instr(cursor_lob.&&lob_column,hextoraw('889911')) ;
new 8: n:=dbms_lob.instr(cursor_lob.LOB_CONTENT,hextoraw('889911')) ;
PL/SQL procedure successfully completed.
SQL>
SQL>
3、检查坏的记录,并将坏的列设置为空值
SQL> select * from corrupted_data2;
CORRUPTED_ROWID
------------------
AAAD7OAAhAAAIK2ABd
AAAD7OAAhAAAIK2ABe
AAAD7OAAhAAAIK2ABf
AAAD7OAAhAAAIK2ABg
AAAD7OAAsAAAgnnABB
AAAD7OAAsAAAgnnABC
AAAD7OAAsAAAgnnABD
AAAD7OAAsAAAgnnABE
AAAD7OAAsAAAgnnABF
AAAD7OAAsAAAgnnABG
AAAD7OAAsAAAgnnABH
CORRUPTED_ROWID
------------------
AAAD7OAAsAAAgnnABI
AAAD7OAAsAAAgnnABJ
AAAD7OAAsAAAgnnABK
14 rows selected.
SQL>
SQL> update FMIS1600.FMIS_LOB
2 set LOB_CONTENT = empty_blob()
3 where rowid in (select corrupted_rowid from corrupted_data2);
14 rows updated.
SQL> commit;
Commit complete.
4、创建临时表FMIS1600.FMIS_LOB_TMP成功
SQL> create table FMIS1600.FMIS_LOB_TMP as select * from FMIS1600.FMIS_LOB;
Table created.
使用empty_blob()函数处理XTYWDJDELETELOG表中损坏的BLOG字段,将损坏的记字段值重置为空值,测试过程如下:
1、创建corrupted_data3
SQL> create table corrupted_data3 (corrupted_rowid rowid);
Table created.
2、查找损坏的记录,放到corrupted_data3表
SQL> declare
2 error_1578 exception;
3 pragma exception_init(error_1578,-1578);
4 n number;
5 begin
6 for cursor_lob in (select rowid r, YWDJ from FMIS1600.XTYWDJDELETELOG )
7 loop
8 begin
9 n:=dbms_lob.instr(cursor_lob.YWDJ,hextoraw('889911')) ;
10 exception
11 when error_1578 then
12 insert into corrupted_data3 values (cursor_lob.r);
13 commit;
14 end;
15 end loop;
16 end;
17 /
PL/SQL procedure successfully completed.
3、检查坏的记录,并将坏的列设置为空值
SQL> select * from corrupted_data3;
CORRUPTED_ROWID
------------------
AAAYU1AA2AAALQeABU
SQL>
SQL> update FMIS1600.XTYWDJDELETELOG
2 set YWDJ = empty_blob()
3 where rowid in (select corrupted_rowid from corrupted_data3);
1 row updated.
SQL> commit;
Commit complete.
4、创建临时表FMIS1600.XTYWDJDELETELOG_TMP成功
SQL> create table FMIS1600.XTYWDJDELETELOG_TMP as select * from FMIS1600.XTYWDJDELETELOG;
Table created.
使用empty_blob()函数处理XTDXBLOB表中损坏的BLOG字段,将损坏的记字段值重置为空值,测试过程如下:
1、创建corrupted_data5
SQL> create table corrupted_data5 (corrupted_rowid rowid);
Table created.
2、查找损坏的记录,放到corrupted_data5表
SQL> set concat off
SQL> declare
2 error_1578 exception;
3 pragma exception_init(error_1578,-1578);
4 n number;
5 begin
6 for cursor_lob in (select rowid r, &&lob_column from &&table_owner.&table_with_lob) loop
7 begin
8 n:=dbms_lob.instr(cursor_lob.&&lob_column,hextoraw('889911')) ;
9 exception
10 when error_1578 then
11 insert into corrupted_data5 values (cursor_lob.r);
12 commit;
13 end;
14 end loop;
15 end;
16 /
Enter value for lob_column: CONTENT
Enter value for table_owner: FMIS1600
Enter value for table_with_lob: XTDXBLOB
old 6: for cursor_lob in (select rowid r, &&lob_column from &&table_owner.&table_with_lob) loop
new 6: for cursor_lob in (select rowid r, CONTENT from FMIS1600.XTDXBLOB) loop
old 8: n:=dbms_lob.instr(cursor_lob.&&lob_column,hextoraw('889911')) ;
new 8: n:=dbms_lob.instr(cursor_lob.CONTENT,hextoraw('889911')) ;
PL/SQL procedure successfully completed.
SQL>
3、检查坏的记录,并将坏的列设置为空值
SQL> select * from corrupted_data5;
CORRUPTED_ROWID
------------------
AAZvjAAAOAAAcrXAAl
SQL>
SQL> update FMIS1600.XTDXBLOB
2 set CONTENT = empty_blob()
3 where rowid in (select corrupted_rowid from corrupted_data5);
1 row updated.
SQL> commit;
Commit complete.
4、创建临时表FMIS1600.XTDXBLOB_TMP成功
SQL> create table FMIS1600.XTDXBLOB_TMP as select * from FMIS1600.XTDXBLOB;
Table created.
SQL>
SQL>
五、 测试总结
通过以上测试,dbms_repair包和10231事件并不能跳过坏块,empty_blob()函数可以重置BLOG类型的字段置为空置,消除坏的记录。
附录一、 empty_blob()函数处理5张表损坏记录操作步骤和命令
1、创建表corrupted_data (1分钟)
create table corrupted_data (corrupted_rowid rowid);
2、查找损坏的记录,放到corrupted_data表 (20分钟)
set concat off
declare
error_1578 exception;
pragma exception_init(error_1578,-1578);
n number;
begin
for cursor_lob in (select rowid r, &&lob_column from &&table_owner.&table_with_lob) loop
begin
n:=dbms_lob.instr(cursor_lob.&&lob_column,hextoraw('889911')) ;
exception
when error_1578 then
insert into corrupted_data values (cursor_lob.r);
commit;
end;
end loop;
end;
/
Enter value for lob_column: FORMATINFO
Enter value for table_owner: FMIS1600
Enter value for table_with_lob: XTDXDBGRIDFORMAT
3、检查坏的记录,并将坏的列设置为空值(1分钟)
select * from corrupted_data;
update &table_owner.&table_with_lob
set &lob_column = empty_blob()
where rowid in (select corrupted_rowid from corrupted_data);
Enter value for table_with_lob: XTDXDBGRIDFORMAT
old 1: update &table_owner.&table_with_lob
new 1: update FMIS1600.XTDXDBGRIDFORMAT
old 2: set &lob_column = empty_blob()
new 2: set FORMATINFO = empty_blob()
commit;
4、创建临时表(20分钟)
create table FMIS1600.XTDXDBGRIDFORMAT_TMP as select * from FMIS1600.XTDXDBGRIDFORMAT;
5、检查临时表和原表,确认临时表创建成功后才可以删除原表(10分钟)
select count(*) from FMIS1600.XTDXDBGRIDFORMAT_TMP;
select count(*) from FMIS1600.XTDXDBGRIDFORMAT;
6、删除原表并重命名临时表为原表名(2分钟)
drop table FMIS1600.XTDXDBGRIDFORMAT;
alter table FMIS1600.XTDXDBGRIDFORMAT_TMP rename to XTDXDBGRIDFORMAT;
7、重建主建、索引、外建
-------------FMIS1600.FMIS_LOB_ISOLATED---------
1、创建corrupted_data1 1分钟
create table corrupted_data1 (corrupted_rowid rowid);
2、查找损坏的记录,放放到corrupted_data1表 (10分钟)
set concat off
declare
error_1578 exception;
pragma exception_init(error_1578,-1578);
n number;
begin
for cursor_lob in (select rowid r, &&lob_column from &&table_owner.&table_with_lob) loop
begin
n:=dbms_lob.instr(cursor_lob.&&lob_column,hextoraw('889911')) ;
exception
when error_1578 then
insert into corrupted_data1 values (cursor_lob.r);
commit;
end;
end loop;
end;
/
Enter value for table_with_lob: FMIS_LOB_ISOLATED
old 6: for cursor_lob in (select rowid r, &&lob_column from &&table_owner.&table_with_lob) loop
new 6: for cursor_lob in (select rowid r, LOB_CONTENT from FMIS1600.FMIS_LOB_ISOLATED) loop
old 8: n:=dbms_lob.instr(cursor_lob.&&lob_column,hextoraw('889911')) ;
new 8: n:=dbms_lob.instr(cursor_lob. LOB_CONTENT,hextoraw('889911')) ;
PL/SQL procedure successfully completed.
3、检查坏的记录,并将坏的列设置为空值(1分钟)
select * from corrupted_data1;
update &table_owner.&table_with_lob
set &lob_column = empty_blob()
where rowid in (select corrupted_rowid from corrupted_data1);
Enter value for table_with_lob: FMIS_LOB_ISOLATED
old 1: update &table_owner.&table_with_lob
new 1: update FMIS1600.FMIS_LOB_ISOLATED
old 2: set &lob_column = empty_blob()
new 2: set LOB_CONTENT = empty_blob()
34 rows updated.
commit;
4、创建临时表(20分钟)
create table FMIS1600.FMIS_LOB_ISOLATED_TMP as select * from FMIS1600.FMIS_LOB_ISOLATED;
5、检查临时表和原表,确认临时表创建成功后才可以删除原表(10分钟)
select count(*) from FMIS1600.FMIS_LOB_ISOLATED_TMP;
select count(*) from FMIS1600.FMIS_LOB_ISOLATED;
6、删除原表并重命名临时表为原表名(2分钟)
drop table FMIS1600.FMIS_LOB_ISOLATED;
alter table FMIS1600.FMIS_LOB_ISOLATED_TMP rename to FMIS_LOB_ISOLATED;
7、重建主建、索引、外建
------------------FMIS1600.FMIS_LOB----------
1、创建corrupted_data2 1分钟
create table corrupted_data2 (corrupted_rowid rowid);
2、查找损坏的记录,放到corrupted_data2表 (10分钟)
set concat off
declare
error_1578 exception;
pragma exception_init(error_1578,-1578);
n number;
begin
for cursor_lob in (select rowid r, &&lob_column from &&table_owner.&table_with_lob) loop
begin
n:=dbms_lob.instr(cursor_lob.&&lob_column,hextoraw('889911')) ;
exception
when error_1578 then
insert into corrupted_data2 values (cursor_lob.r);
commit;
end;
end loop;
end;
/
Enter value for table_with_lob: FMIS_LOB
old 6: for cursor_lob in (select rowid r, &&lob_column from &&table_owner.&table_with_lob) loop
new 6: for cursor_lob in (select rowid r, LOB_CONTENT from FMIS1600.FMIS_LOB) loop
old 8: n:=dbms_lob.instr(cursor_lob.&&lob_column,hextoraw('889911')) ;
new 8: n:=dbms_lob.instr(cursor_lob.LOB_CONTENT,hextoraw('889911')) ;
PL/SQL procedure successfully completed.
3、检查坏的记录,并将坏的列设置为空值(1分钟)
select * from corrupted_data2;
update FMIS1600.FMIS_LOB
set LOB_CONTENT = empty_blob()
where rowid in (select corrupted_rowid from corrupted_data2);
commit;
4、创建临时表(20分钟)
create table FMIS1600.FMIS_LOB_TMP as select * from FMIS1600.FMIS_LOB;
5、检查临时表和原表,确认临时表创建成功后才可以删除原表(10分钟)
select count(*) from FMIS1600.FMIS_LOB_TMP;
select count(*) from FMIS1600.FMIS_LOB;
6、删除原表并重命名临时表为原表名(2分钟)
drop table FMIS1600.FMIS_LOB;
alter table FMIS1600.FMIS_LOB_TMP rename to FMIS_LOB;
7、重建主建、索引、外建
------------------FMIS1600.XTYWDJDELETELOG--------------
1、创建corrupted_data3 1分钟
create table corrupted_data3 (corrupted_rowid rowid);
2、查找损坏的记录,放到corrupted_data3表 (10分钟)
set concat off
declare
error_1578 exception;
pragma exception_init(error_1578,-1578);
n number;
begin
for cursor_lob in (select rowid r, YWDJ from FMIS1600.XTYWDJDELETELOG )
loop
begin
n:=dbms_lob.instr(cursor_lob.YWDJ,hextoraw('889911')) ;
exception
when error_1578 then
insert into corrupted_data3 values (cursor_lob.r);
commit;
end;
end loop;
end;
/
PL/SQL procedure successfully completed.
3、检查坏的记录,并将坏的列设置为空值(1分钟)
select * from corrupted_data3;
update FMIS1600.XTYWDJDELETELOG
set YWDJ = empty_blob()
where rowid in (select corrupted_rowid from corrupted_data3);
commit;
4、创建临时表(20分钟)
create table FMIS1600.XTYWDJDELETELOG_TMP as select * from FMIS1600.XTYWDJDELETELOG;
5、检查临时表和原表,确认临时表创建成功后才可以删除原表(10分钟)
select count(*) from FMIS1600.XTYWDJDELETELOG_TMP;
select count(*) from FMIS1600.XTYWDJDELETELOG;
6、删除原表并重命名临时表为原表名(2分钟)
drop table FMIS1600.XTYWDJDELETELOG;
alter table FMIS1600.XTYWDJDELETELOG_TMP rename to XTYWDJDELETELOG;
7、重建主建、索引、外建
---------------FMIS1600.XTDXBLOB---------
1、创建corrupted_data5 1分钟
create table corrupted_data5 (corrupted_rowid rowid);
2、查找损坏的记录,放到corrupted_data5表 (10分钟)
set concat off
declare
error_1578 exception;
pragma exception_init(error_1578,-1578);
n number;
begin
for cursor_lob in (select rowid r, &&lob_column from &&table_owner.&table_with_lob) loop
begin
n:=dbms_lob.instr(cursor_lob.&&lob_column,hextoraw('889911')) ;
exception
when error_1578 then
insert into corrupted_data5 values (cursor_lob.r);
commit;
end;
end loop;
end;
/
Enter value for lob_column: CONTENT
Enter value for table_owner: FMIS1600
Enter value for table_with_lob: XTDXBLOB
old 6: for cursor_lob in (select rowid r, &&lob_column from &&table_owner.&table_with_lob) loop
new 6: for cursor_lob in (select rowid r, CONTENT from FMIS1600.XTDXBLOB) loop
old 8: n:=dbms_lob.instr(cursor_lob.&&lob_column,hextoraw('889911')) ;
new 8: n:=dbms_lob.instr(cursor_lob.CONTENT,hextoraw('889911')) ;
3、检查坏的记录,并将坏的列设置为空值(1分钟)
select * from corrupted_data5;
update FMIS1600.XTDXBLOB
set CONTENT = empty_blob()
where rowid in (select corrupted_rowid from corrupted_data5);
commit;
4、创建临时表(20分钟)
create table FMIS1600.XTDXBLOB_TMP as select * from FMIS1600.XTDXBLOB;
5、检查临时表和原表,确认临时表创建成功后才可以删除原表(10分钟)
select count(*) from FMIS1600.XTDXBLOB_TMP;
select count(*) from FMIS1600.XTDXBLOB;
6、删除原表并重命名临时表为原表名(2分钟)
drop table FMIS1600.XTDXBLOB;
alter table FMIS1600.XTDXBLOB_TMP rename to XTDXBLOB;
7、重建主建、索引、外建
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/27571661/viewspace-751939/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/27571661/viewspace-751939/