exp导出数据提示数据块损坏的处理办法

前端之家收集整理的这篇文章主要介绍了exp导出数据提示数据块损坏的处理办法前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

操作系统:Windows Server 2003Enterprise SP2

数据库:Oracle 9.2.0.1.0,未开启归档,无RMAN备份

最近准备将数据库迁移至新服务器,同时升级版本为11G,在用exp对原库进行备份时,出现以下提示

...

正在导出表 COMMON_PIC

EXP-00056:遇到ORACLE错误1578

ORA-01578ORACLE数据块损坏(文件11,块号265103

ORA-01110:数据文件11‘D:\ORACLE\ORADATA\PHOTO_INFO.DBF’

...

提示信息很明确,在导出COMMON_PIC表时,检测到11号数据文件中编号为265103的块损坏。

COMMON_PIC用来存放图片包括BLOB类型的二进制数据。

先用DBV工具检查一下:

C:\> dbv file=d:\oracle\oradata\photo_info.dbf blocksize=8192start=265000 end=265200

输出

DBVERIFY: Release 9.2.0.1.0 -Production on 星期三 6月 29 13:21:14 2016

Copyright (c) 1982,2002,Oracle Corporation. All rights reserved.

DBVERIFY - 验证正在开始 : FILE =d:\oracle\oradata\photo_info.dbf

DBVERIFY - 验证完成

检查的页总数 :201

处理的页总数(数据):0

失败的页总数(数据):0

处理的页总数(索引):0

失败的页总数(索引):0

处理的页总数(其它):200

处理的总页数 (段) : 0

失败的总页数 (段) : 0

空的页总数 :0

标记为损坏的总页数:0

汇入的页总数 :0

检查结果显示未发现问题,之后使用dbms_repair.check_object检查COMMON_PIC表也没有任何结果,尝试设置10231事件,让exp跳过坏块:

  1. sql> ALTER SYSTEM SETEVENTS=’10231 TRACE NAME CONTEXT FOREVER,LEVEL 10’;

仍然无效。

为便于操作,打开PLsql,用以下语句找出损坏数据块所在的段:

  1. SELECT e.owner,e.segment_type,e.segment_name,e.tablespace_name,e.block_id,e.blocks
  2. FROM dba_extents e
  3. WHERE 265103 BETWEEN e.block_id AND (block_id + blocks - 1);


输出

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

OWNER

SEGMENT_TYPE

SEGMENT_NAME

TABLESPACE_NAME

BLOCK_ID

BLOCKS

XC

LOBSEGMENT

SYS_LOB0000030307C00003$$

PHOTO_INFO

259081

8192

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

可以看到,坏块所在的段类型是LOBSEGMENT,继续执行以下语句确定坏块对应的列:

  1. SELECT l.table_name,l.column_name
  2. FROM dba_lobs l
  3. WHERE l.segment_name = 'SYS_LOB0000030307C00003$$'
  4. AND owner = 'XC';

输出

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

TABLE_NAME COLUMN_NAME

COMMON_PIC CONTENT

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

执行以下语句,找出坏块对应的ROWID

--建表,存放块坏对应的行

  1. CREATE TABLE corr_rows (row_id ROWID,error_code NUMBER);

--使用dbms_lob包遍历COMMON_PIC表的CONTENT列,触发错误并将对应的ROWID和错误代码插入corr_rows表

  1. DECLARE
  2. n NUMBER;
  3. ERROR_CODE NUMBER;
  4. corr_rows NUMBER := 0;
  5. ora_1578 EXCEPTION;
  6. PRAGMA EXCEPTION_INIT(ora_1578,-1578);
  7. BEGIN
  8. FOR cursor_lob IN (SELECT ROWID rid,CONTENT
  9. FROM XC.COMMON_PIC) LOOP
  10. BEGIN
  11. n := dbms_lob.instr(cursor_lob.CONTENT,hextoraw('01234567'));
  12. EXCEPTION
  13. WHEN ora_1578 THEN
  14. corr_rows := corr_rows + 1;
  15. INSERT INTO corr_rows
  16. VALUES
  17. (cursor_lob.rid,1578);
  18. COMMIT;
  19. WHEN OTHERS THEN
  20. ERROR_CODE := sqlCODE;
  21. corr_rows := corr_rows + 1;
  22. INSERT INTO corr_rows
  23. VALUES
  24. (cursor_lob.rid,ERROR_CODE);
  25. COMMIT;
  26. END;
  27. END LOOP;
  28. dbms_output.put_line('Corrupted rows: ' || corr_rows);
  29. END;
  30. /

输出

Corrupted rows: 1

查询具体结果:

  1. SELECT * FROM corr_rows;

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

ROW_ID ERR_CODE

AAAHZjAALAAAmDrAAX -1578

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

结果显示只有1行的CONTENT列受到坏块影响,根据ROWID查询

  1. SELECT p.rowid,p.CONTENT
  2. FROM XC.COMMON_PIC p
  3. WHERE p.rowid = 'AAAHZjAALAAAmDrAAX';

输出

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

ROWID CONTENT

AAAHZjAALAAAmDrAAX <Value Error>

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

登录相关应用,可以验证本条记录对应的图片确实打开失败,由于确认图片有备份,因此这里把错误的字段清空,先保证exp能正常导出数据,待迁移完成后再恢复图片

  1. UPDATE TABLE XC.COMMON_PIC
  2. SET XC.CONTENT = empty_blob()
  3. WHERE ROWID = 'AAAHZjAALAAAmDrAAX';
  4. COMMIT;

再次使用exp导出成功。

猜你在找的Oracle相关文章