使用DBMS_REPAIR包修复坏块(一)
使用DBMS_REPAIR包修复坏块(一)
今天来学习一下数据坏块的检测和修复。Oracle为了检测和纠正数据块随坏,提供了不同的方法,纠正方法有很多,第一是在检测到损坏之后,就删除并重建该对象,但是这个方法有时是不可用的,而且效果也不理想。如果数据块损坏局限于行的子集,则可以选取除了损坏行之外的所有行来重建表。
第二个方法是使用DBMS_REPAIR包来检测和修复表或索引中的损坏数据块。这个方法的好处在于可以确定损坏出现的位置,并重建或修复它们,使对象可以继续使用。
需要注意的是:任何包含数据丢失的损坏都需要分析和理解数据是如何填充进整个数据库系统中的。所以DBMS_REPAIR的修复方法并不一定适用于每个损坏问题,基于损坏的本质,是有可能丢失数据或引入逻辑矛盾的,因此在使用DBMS_REPAIR修复时要权衡其带来的得失利弊。
首先介绍一下DBMS_REPAIR包(注意:这个包只能由sys用户查看、使用):
CREATE OR REPLACE PACKAGE dbms_repair
IS
----------------------------------
-- OVERVIEW
--
-- The DBMS_REPAIR package consists of data corruption repair procedures
--
-- SECURITY
--
-- The package is owned by SYS.
-- Execution privilege is not granted to other users.
----------------------------------
--
-- ENUMERATION TYPES:
--
-- Object Type Specification
--
TABLE_OBJECT constant binary_integer := 1;
INDEX_OBJECT constant binary_integer := 2;
CLUSTER_OBJECT constant binary_integer := 4;
----------------------------------
-- OVERVIEW
--
-- The DBMS_REPAIR package consists of data corruption repair procedures
--
-- SECURITY
--
-- The package is owned by SYS.
-- Execution privilege is not granted to other users.
----------------------------------
--
-- ENUMERATION TYPES:
--
-- Object Type Specification
--
TABLE_OBJECT constant binary_integer := 1;
INDEX_OBJECT constant binary_integer := 2;
CLUSTER_OBJECT constant binary_integer := 4;
--
-- Flags Specification
--
SKIP_FLAG constant binary_integer := 1;
NOSKIP_FLAG constant binary_integer := 2;
-- Flags Specification
--
SKIP_FLAG constant binary_integer := 1;
NOSKIP_FLAG constant binary_integer := 2;
--
-- Admin Action Specification
--
CREATE_ACTION constant binary_integer := 1;
PURGE_ACTION constant binary_integer := 2;
DROP_ACTION constant binary_integer := 3;
-- Admin Action Specification
--
CREATE_ACTION constant binary_integer := 1;
PURGE_ACTION constant binary_integer := 2;
DROP_ACTION constant binary_integer := 3;
--
-- Admin Table Type Specification
--
REPAIR_TABLE constant binary_integer :=1;
ORPHAN_TABLE constant binary_integer :=2;
-- Admin Table Type Specification
--
REPAIR_TABLE constant binary_integer :=1;
ORPHAN_TABLE constant binary_integer :=2;
--
-- Object Id Specification
--
ALL_INDEX_ID constant binary_integer :=0;
-- Object Id Specification
--
ALL_INDEX_ID constant binary_integer :=0;
--
-- Lock Wait Specification
--
LOCK_NOWAIT constant binary_integer := 0;
LOCK_WAIT constant binary_integer := 1;
-----------------------------------
--
-- PROCEDURES AND FUNCTIONS
--
--
-- Lock Wait Specification
--
LOCK_NOWAIT constant binary_integer := 0;
LOCK_WAIT constant binary_integer := 1;
-----------------------------------
--
-- PROCEDURES AND FUNCTIONS
--
--
--
-- NOTE: default table_name will be 'REPAIR_TABLE' when table_type is
-- REPAIR_TABLE, and will be 'ORPHAN_KEY_TABLE' when table_type is
-- ORPHAN_TABLE
procedure admin_tables(
table_name IN varchar2 DEFAULT 'GENERATE_DEFAULT_TABLE_NAME',
table_type IN binary_integer,
action IN binary_integer,
tablespace IN varchar2 DEFAULT NULL);
-- NOTE: default table_name will be 'REPAIR_TABLE' when table_type is
-- REPAIR_TABLE, and will be 'ORPHAN_KEY_TABLE' when table_type is
-- ORPHAN_TABLE
procedure admin_tables(
table_name IN varchar2 DEFAULT 'GENERATE_DEFAULT_TABLE_NAME',
table_type IN binary_integer,
action IN binary_integer,
tablespace IN varchar2 DEFAULT NULL);
--admin_tables用于修复或隔离键表的管理函数(创建、删除、净化)
--
procedure check_object(
schema_name IN varchar2,
object_name IN varchar2,
partition_name IN varchar2 DEFAULT NULL,
object_type IN binary_integer DEFAULT TABLE_OBJECT,
repair_table_name IN varchar2 DEFAULT 'REPAIR_TABLE',
flags IN binary_integer DEFAULT NULL,
relative_fno IN binary_integer DEFAULT NULL,
block_start IN binary_integer DEFAULT NULL,
block_end IN binary_integer DEFAULT NULL,
corrupt_count OUT binary_integer);
procedure check_object(
schema_name IN varchar2,
object_name IN varchar2,
partition_name IN varchar2 DEFAULT NULL,
object_type IN binary_integer DEFAULT TABLE_OBJECT,
repair_table_name IN varchar2 DEFAULT 'REPAIR_TABLE',
flags IN binary_integer DEFAULT NULL,
relative_fno IN binary_integer DEFAULT NULL,
block_start IN binary_integer DEFAULT NULL,
block_end IN binary_integer DEFAULT NULL,
corrupt_count OUT binary_integer);
--check_object用于检测和报告表中或索引中的损坏
--
procedure dump_orphan_keys(
schema_name IN varchar2,
object_name IN varchar2,
partition_name IN varchar2 DEFAULT NULL,
object_type IN binary_integer DEFAULT INDEX_OBJECT,
repair_table_name IN varchar2 DEFAULT 'REPAIR_TABLE',
orphan_table_name IN varchar2 DEFAULT 'ORPHAN_KEY_TABLE',
flags IN binary_integer DEFAULT NULL,
key_count OUT binary_integer);
procedure dump_orphan_keys(
schema_name IN varchar2,
object_name IN varchar2,
partition_name IN varchar2 DEFAULT NULL,
object_type IN binary_integer DEFAULT INDEX_OBJECT,
repair_table_name IN varchar2 DEFAULT 'REPAIR_TABLE',
orphan_table_name IN varchar2 DEFAULT 'ORPHAN_KEY_TABLE',
flags IN binary_integer DEFAULT NULL,
key_count OUT binary_integer);
--dump_orphan_keys报告指出损坏数据块中的行的索引项(在一个孤立键表中)
--
procedure fix_corrupt_blocks(
schema_name IN varchar2,
object_name IN varchar2,
partition_name IN varchar2 DEFAULT NULL,
object_type IN binary_integer DEFAULT TABLE_OBJECT,
repair_table_name IN varchar2 DEFAULT 'REPAIR_TABLE',
flags IN binary_integer DEFAULT NULL,
fix_count OUT binary_integer);
procedure fix_corrupt_blocks(
schema_name IN varchar2,
object_name IN varchar2,
partition_name IN varchar2 DEFAULT NULL,
object_type IN binary_integer DEFAULT TABLE_OBJECT,
repair_table_name IN varchar2 DEFAULT 'REPAIR_TABLE',
flags IN binary_integer DEFAULT NULL,
fix_count OUT binary_integer);
--fix_corrupt_blocks用于将被check_object标记出来的数据块标记为软件错误
--
procedure rebuild_freelists(
schema_name IN varchar2,
object_name IN varchar2,
partition_name IN varchar2 DEFAULT NULL,
object_type IN binary_integer DEFAULT TABLE_OBJECT);
procedure rebuild_freelists(
schema_name IN varchar2,
object_name IN varchar2,
partition_name IN varchar2 DEFAULT NULL,
object_type IN binary_integer DEFAULT TABLE_OBJECT);
--rebuild_freelists用于重建对象的空闲列表
--
procedure skip_corrupt_blocks(
schema_name IN varchar2,
object_name IN varchar2,
object_type IN binary_integer DEFAULT TABLE_OBJECT,
flags IN binary_integer DEFAULT SKIP_FLAG);
procedure skip_corrupt_blocks(
schema_name IN varchar2,
object_name IN varchar2,
object_type IN binary_integer DEFAULT TABLE_OBJECT,
flags IN binary_integer DEFAULT SKIP_FLAG);
--skip_corrupt_blocks扫描或索引期间,忽略被标记为损坏的数据块
--不使用是遇到损坏块会报错:ORA-01578
--
procedure segment_fix_status(
segment_owner IN varchar2,
segment_name IN varchar2,
segment_type IN binary_integer DEFAULT TABLE_OBJECT,
file_number IN binary_integer DEFAULT NULL,
block_number IN binary_integer DEFAULT NULL,
status_value IN binary_integer DEFAULT NULL,
partition_name IN varchar2 DEFAULT NULL);
procedure segment_fix_status(
segment_owner IN varchar2,
segment_name IN varchar2,
segment_type IN binary_integer DEFAULT TABLE_OBJECT,
file_number IN binary_integer DEFAULT NULL,
block_number IN binary_integer DEFAULT NULL,
status_value IN binary_integer DEFAULT NULL,
partition_name IN varchar2 DEFAULT NULL);
--segment_fix_status:当SEGMENT管理为AUTO时,提供确定位图项的损坏状态。
--
procedure rebuild_shc_index(
segment_owner IN varchar2,
cluster_name IN varchar2);
procedure rebuild_shc_index(
segment_owner IN varchar2,
cluster_name IN varchar2);
--
function online_index_clean(
object_id IN binary_integer DEFAULT ALL_INDEX_ID,
wait_for_lock IN binary_integer DEFAULT LOCK_WAIT)
return boolean;
-- Example Usage of online_index_clean:
-- DECLARE
-- isClean BOOLEAN;
-- BEGIN
--
-- isClean := FALSE;
-- WHILE isClean=FALSE
-- LOOP
-- isClean := DBMS_REPAIR.ONLINE_INDEX_CLEAN(DBMS_REPAIR.ALL_INDEX_ID,
-- DBMS_REPAIR.LOCK_WAIT);
-- DBMS_LOCK.SLEEP(10);
-- END LOOP;
--
-- EXCEPTION
-- WHEN OTHERS THEN
-- RAISE;
-- END;
-- /
function online_index_clean(
object_id IN binary_integer DEFAULT ALL_INDEX_ID,
wait_for_lock IN binary_integer DEFAULT LOCK_WAIT)
return boolean;
-- Example Usage of online_index_clean:
-- DECLARE
-- isClean BOOLEAN;
-- BEGIN
--
-- isClean := FALSE;
-- WHILE isClean=FALSE
-- LOOP
-- isClean := DBMS_REPAIR.ONLINE_INDEX_CLEAN(DBMS_REPAIR.ALL_INDEX_ID,
-- DBMS_REPAIR.LOCK_WAIT);
-- DBMS_LOCK.SLEEP(10);
-- END LOOP;
--
-- EXCEPTION
-- WHEN OTHERS THEN
-- RAISE;
-- END;
-- /
END dbms_repair;
DBMS_REPAIR的限制有以下几点:
1、支持具有LOB列、嵌入表、varray列的表,但忽略out of line columns
2、SKIP_CORRUPT_BLOCKS和REBUILD_FREELISTS支持簇,但CHECK_OBJECT不支持簇
3、不支持索引结构表和LOB索引
4、DUMP_ORPHAN_KEYS过程不能用于位图索引或基于函数的索引
5、DUMP_ORPHAN_KEYS过程最多处理3950字节长的键
下面开始从头来说明检测、修复坏块的过程:
一、检测和报告损坏
这个过程不仅仅是指出数据块出什么错了,还要指出相关的修复方针。为了检测损坏,除了DBMS_REPAIR之外,还有几个其他不同的选择:
1、DBMS_REPAIR
对一个指定的表、分区或索引执行数据块检查,用结果填充一个修复表。使用CHECK_OBJECT和ADMIN_TABLES两个过程。
CHECK_OBJECT检查和报告指定对象的数据块损坏,与用于索引和表的ANALYZE...VALIDATE STRUCTURE语句相同,数据块检查是用于索引和数据块的。CHECK_OBJECT不仅报告损坏,如果以后在该对象上运行FIX_CORRUPT_BLOCKS时,它还标识任何方位。通过将这些信息填充进修复表而使这些信息可用,必须先用ADMIN_TABLES过程创建修复表。(执行CHECK_OBJECT过程后,查询修复表即可知道对象的损坏和修复方针)
2、DB_VERIFY
外部命令行工具,它在脱机数据库上执行数据块检查,具体使用方法另详。
3、ANALYZE
与VALIDATE STRUCTURE选项一起使用,确认索引、表或簇的结构完整性;检查或确认表和索引是同步的。
ANALYZE TABLE ... VALIDATE STRUCTURE 语句校验被分析对象的结构。如果Oracle成功地校验了该结构,则返回一条确认消息,如果Oracle遇到了对象结构中的损坏,则返回一条错误消息。此时就应该删除并重建该对象。
4、DB_BLOCK_CHECKING
当DB_BLOCK_CHECKING=TRUE时被执行。在实际被标记成损坏之前识别损坏的数据块。当数据块被修改是执行检查。
------------------
剩下关于如何操作和修复明天再学习。