Oracle 使用DBMS_REPAIR 或事件 10231从损坏表中抽取数据

如果自己搞不定可以找诗檀软件专业ORACLE数据库修复团队成员帮您恢复!

诗檀软件专业数据库修复团队

服务热线 : 13764045638 QQ号:47079569 邮箱:[email protected]

 

 

05-Jun-2015检查相关性

 

*****************

*** IMPORTANT ***

*****************

本文是文章Note:28814.1的扩展,有关处理块损坏错误,其中数据块的块包装wrapper指示块是坏的。 (通常为ORA-1578错误)。

 

只有当块内部损坏,这里的详细内容才适用(例如:对于ORA-600或其他错误)。在这种情况下,从Oracle8i及以上版本,可以使用DBMS_REPAIR标记问题块为软损坏soft corrupt,使得被访问时会发出ORA-1578。参阅10.2文档了解使用DBMS_REPAIR.CHECK_OBJECT/ FIX_CORRUPT_BLOCKS的细节。

 

在读本说明之前,请参阅Note:28814.1

 

本方法仅适用于堆组织heap-organized表。

对于索引组织表(IOT),参阅Note 794772.1 – EVENT 43810 “check-and-skip corrupt blocks in index scans” including IOT’s

 

简介

~~~~~~~~~~~~

本文说明了如何在对象上跳过损坏块,使用SKIP_CORRUPT 表标识flag (Oracle8i及以上可用)或特殊Oracle事件号10231 ,在Oracle releases 7 到8.1 inclusive可用。

本文信息说明了如何使用这些选项。

 

在继续处理之前,你应该:

  1. a) 确认损坏块在一个USER表上。

(即:不是一个数据自动表)

  1. b) 联系了Oracle Support Services并被建议使用事件10231 或SKIP_CORRUPT flag。
  2. c) 决定了如何重建表。

例:导出,且磁盘空间可用等。。

  1. d) 已安排了尝试salvage操作的停机时间

已在某处还原了一个问题数据库的副本,为了在副本上执行数据抽取。

  1. e) 有数据库的备份。
  2. f) 有重建问题表的SQL,它的索引,约束,触发器,授权grant等。。。

SQL应当包括相关存储子句。

 

 

事件10231是什么?

~~~~~~~~~~~~~~~~~~~~~

该事件允许Oracle在全表扫描上仅跳过损坏块的特定类型,因此允许导出或”create table as select” 类型操作来从不再损坏块中的表检索行。在损坏块中的数据已丢失。

 

该事件的范围对于Oracle 7.2之前的版本有限制,仅允许你跳过’soft corrupt’ 块。

大多数ORA 1578错误是媒体损坏media 的结果且在这样的情况下事件10231 是无用的。

从Oracle 7.2 以上起,该事件允许你跳过软损坏块以及媒体损坏块的许多形式,所以 非常有用。它仍 *未* 保证作用。

Note:28814.1 describes alternatives which can be used if this event

fails.

 

SKIP_CORRUPT flag是什么?

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

从Oracle8i起,10231事件的功能在每个段的基础上被外在化externalised ,使得可能标记表来跳过损坏块。使用DBMS_REPAIR 包来设置或清除flag。DBA_TABLES有一个SKIP_CORRUPT列,表示该flag为对象设置与否。

 

设置事件或标志flag

~~~~~~~~~~~~~~~~~~~~~~~~~

事件可以在会话中或在数据库实例级别被设置。如果你想使用CREATE TABLE AS SELECT 或ALTER TABLE <> MOVE,则在会话中设置事件足够了。如果你想导出表数据,则最好在实例级别设置事件,或在Oracle8i及以上设置SKIP_CORRUPT 表属性。

 

Oracle8i,9i,10g,11g

~~~~~~~~~~~~~~~~~~~

作为SYSDBA 用户连接,并将表标记为需要跳过损坏块,因此:

execute DBMS_REPAIR.SKIP_CORRUPT_BLOCKS(”,”);

 

现在你应该能对损坏发出CREATE TABLE AS SELECT / ALTER TABLE <> MOVE 操作来从所有非损坏块中提取数据,或导出表。

例:

CREATE TABLE salvage_emp

AS SELECT * FROM corrupt_emp;

ALTER TABLE <> MOVE

 

要清除表使用的属性:

execute DBMS_REPAIR.SKIP_CORRUPT_BLOCKS(”,”,

flags=>dbms_repair.noskip_flag);

 

注意,当由于设置了SKIP_CORRUPT使得会话跳过损坏块,则对每个被跳过的块,信息被写入跟踪文件(而不是警报日志),形式为:

table scan: segment: file# 6 block# 11

skipping corrupt block file# 6 block# 12

 

 

在会话中设置事件

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

以一个能访问损坏表的用户连接到Oracle并发现命令:

 

ALTER SESSION SET EVENTS

‘10231 TRACE NAME CONTEXT FOREVER, LEVEL 10’;

 

现在,你应该能对损坏表发出CREATE TABLE AS SELECT操作提取所有未损坏块的数据,但导出仍会失败,因为该事件仅在当前会话中设置。

例:

CREATE TABLE salvage_emp

AS SELECT * FROM corrupt_emp;

 

 

ALTER TABLE <> MOVE

 

在实例级别设置事件

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

这要求事件被添加到init$ORACLE_SID.ora 文件,用于启动实例:

 

关闭数据库

 

编辑你的init.ora 启动配置文件并添加一行读取:

 

event=”10231 trace name context forever, level 10″

 

确保这出现在任何其他init.ora 文件中的EVENT= lines旁边。

 

如果你在使用spfile,请参阅Note:160178.1

‘How to set EVENTS in the SPFILE’.

 

STARTUP启动

如果实例无法启动,检查事件参数的语法与上述完全匹配。

注意逗号,它很重要。

 

SHOW PARAMETER EVENT 显示参数事件

要检查事件被设置在正确的位置。

你应该看到你的init.ora 文件中行的文本的初始部分。如果没有检查启动数据库使用哪个参数文件。

使用全表扫描操作从表中选出数据。

例:使用表级别导出

或create table as select  或ALTER TABLE <> MOVE

 

导出警告:如果表非常大,则一些导出版本可能无法将超过2GB的数据写入到导出文件。参见:Note:62427.1了解各版本Oracle2Gb限制的一般信息。

 

 

从损坏块本身拯救数据

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

SKIP_CORRUPT 和事件10231 从好的块中抽取数据并通过损坏。要从损坏块中抽取数据有三种选择:

 

– 从任何好的索引中select列数据

这在以下2篇文章中讨论:

Oracle7 – using ROWID range scans    Note:34371.1

Oracle8/8i – using ROWID range scans Note:61685.1

 

– 了解Oracle Support是否能从损坏块的HEX dump中抽取数据。

 

– 也许能使用Log Miner拯救一些数据

 

 

一旦数据被抽取

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

一旦你将所需的数据抽取到一个导出文件或另一个表,确保在处理之前有有效的数据库备份。这一点的重要性怎么强调也不过分。

 

再次确认你有重建对象及其索引的SQL等等。。

 

再次确认有Oracle support请求的任何诊断信息。一旦你继续drop对象的操作,特定信息就会被破坏,所以当时捕获是很重要的。

 

现在你可以:

 

如果10231在实例级别被设置:

从init.ora 文件中删除’event’行

 

关闭并重启数据库。

 

显示参数事件

确保10231 事件不再显示

 

重命名或DROP 问题表

如果有空间,建议重命名问题表,而不要在这个阶段drop它。

 

重建表。

例:通过导入。

特别注意在重建表时,有正确的存储子句。

 

创建所需的索引,触发器等。。

再次注意存储子句。

 

重新将访问权限授予表。

 

如果你重命名了原始表,一旦新表被测试后,你就能drop它。


Posted

in

by

Tags:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *