|Oracle9i Database Administrator's Guide
Release 1 (9.0.1)
Part Number A90117-01
This chapter explains using the
DBMS_REPAIR PL/SQL package to repair data block corruption in database schema objects. It contains the following topics:
Oracle provides different methods for detecting and correcting data block corruption. One method of correction is to drop and re-create an object after the corruption is detected. However, this is not always possible or desirable. If data block corruption is limited to a subset of rows, another option is to rebuild the table by selecting all data except for the corrupt rows.
Yet another way to manage data block corruption is to use the
DBMS_REPAIR package. You can use
DBMS_REPAIR to detect and repair corrupt blocks in tables and indexes. Using this approach, you can address corruptions where possible, and also continue to use objects while you attempt to rebuild or repair them.
Any corruption that involves the loss of data requires analysis and understanding of how that data fits into the overall database system.
This section describes the
DBMS_REPAIR procedures contained in the package and notes some limitations and restrictions on their use.
Oracle9i Supplied PL/SQL Packages and Types Reference for more information on the syntax, restrictions, and exceptions for the
The following table lists the procedures included in the
Detects and reports corruptions in a table or index
Marks blocks (that were previously identified by the
Reports index entries (into an orphan key table) that point to rows in corrupt data blocks
Rebuilds an object's free lists
Provides the capability to fix the corrupted state of a bitmap entry when segment space management is
When used, ignores blocks marked corrupt during table and index scans. If not used, you get error
Note: These tables are always created in the
These procedures are further described, with examples of their use, in "DBMS_REPAIR Examples".
DBMS_REPAIR procedures have the following limitations:
LOBs, nested tables, and varrays are supported, but the out of line columns are ignored.
REBUILD_FREELISTSprocedures, but not in the
LOBindexes are not supported.
DUMP_ORPHAN_KEYSprocedure does not operate on bitmap indexes or function-based indexes.
DUMP_ORPHAN_KEYSprocedure processes keys that are, at most, 3,950 bytes long.
The following approach is recommended when considering
DBMS_REPAIR for addressing data block corruption:
These tasks are discussed in succeeding sections.
Your first task, before using
DBMS_REPAIR, should be the detection and reporting of corruptions. Reporting not only indicates what is wrong with a block, but also identifies the associated repair directive. You have several options, in addition to
DBMS_REPAIR, for detecting corruptions. Table 22-1 describes the different detection methodologies.
Performs block checking for a specified table, partition, or index. Populates a repair table with results.
External command-line utility that performs block checking on an offline database.
Used with the
Performed when the initialization parameter
CHECK_OBJECT procedure checks and reports block corruptions for a specified object. Similar to the
ANALYZE ... VALIDATE STRUCTURE statement for indexes and tables, block checking is performed for index and data blocks.
Not only does
CHECK_OBJECT report corruptions, but it also identifies any fixes that would occur if
FIX_CORRUPT_BLOCKS is subsequently run on the object. This information is made available by populating a repair table, which must first be created by the
After you run the
CHECK_OBJECT procedure, a simple query on the repair table shows the corruptions and repair directives for the object. With this information, you can assess how best to address the problems reported.
Typically, you use
DB_VERIFY as an offline diagnostic utility when you encounter data corruption problems.
Oracle9i Database Utilities for more information about
ANALYZE TABLE ... VALIDATE STRUCTURE statement validates the structure of the analyzed object. If Oracle successfully validates the structure, a message confirming its validation is returned to you. If Oracle encounters corruption in the structure of the object, an error message is returned to you. In this case, drop and re-create the object.
Oracle9i SQL Reference for more information about the
You can set block checking for instances using the
DB_BLOCK_CHECKING initialization parameter (the default value is
FALSE). This checks data and index blocks whenever they are modified.
DB_BLOCK_CHECKING is a dynamic parameter, modifiable by the
ALTER SYSTEM SET statement. Block checking is always enabled for the system tablespace.
Oracle9i Database Reference for more information about the
DBMS_REPAIR you must weigh the benefits of its use in relation to the liabilities. You should also examine other options available for addressing corrupt objects.
A first step is to answer the following questions:
To determine if there are corruptions and repair actions, execute the
CHECK_OBJECT procedure, and query the repair table.
DBMS_REPAIRto make an object usable? Can these be addressed? What is the effort required to do so?
It is possible that you do not have access to rows in blocks marked corrupt. However, a block could be marked corrupt even though there are still rows that you can validly access.
It is also possible that referential integrity constraints are broken when blocks are marked corrupt. If this occurs, disable and re-enable the constraint; any inconsistencies are reported. After fixing all problems, you should be able to successfully re-enable the constraint.
Logical corruption can occur when there are triggers defined on the table. For example, if rows are re-inserted, should insert triggers be fired or not? You can address these issues only if you understand triggers and their use in your installation.
Free list blocks can become inaccessible. If a corrupt block is at the head or tail of a free list, space management reinitializes the free list. There then can be blocks that should be on a free list, but are not. You can address this by running the
Indexes and tables are out of sync. You can address this by first executing the
DUMP_ORPHAN_KEYS procedure (to obtain information from the keys that might be useful in rebuilding corrupted data). Then issue the
ALTER INDEX ... REBUILD ONLINE statement to get the table and its indexes back in sync.
You can retrieve data from the index when a data block is marked corrupt. The
DUMP_ORPHAN_KEYS procedure can help you retrieve this information. Of course, retrieving data in this manner depends on the amount of redundancy between the indexes and the table.
In this task
DBMS_REPAIR makes the object usable by ignoring corruptions during table and index scans.
You make a corrupt object usable by establishing an environment that skips corruptions that remain outside the scope of
DBMS_REPAIR's repair capabilities.
If corruptions involve a loss of data, such as a bad row in a data block, all such blocks are marked corrupt by the
FIX_CORRUPT_BLOCKS procedure. Then, you can run the
SKIP_CORRUPT_BLOCKS procedure, which skips blocks marked corrupt for the object. When skip is set, table and index scans skip all blocks marked corrupt. This applies to both media and software corrupt blocks.
If an index and table are out of sync, then a
SET TRANSACTION READ ONLY transaction can be inconsistent in situations where one query probes only the index, and then a subsequent query probes both the index and the table. If the table block is marked corrupt, then the two queries return different results, thereby breaking the rules of a read-only transaction. One way to approach this is to not skip corruptions when in a
SET TRANSACTION READ ONLY transaction.
A similar issue occurs when selecting rows that are chained. Essentially, a query of the same row may or may not access the corruption, thereby producing different results.
After making an object usable, you can perform the following repair activities.
DUMP_ORPHAN_KEYS procedure reports on index entries that point to rows in corrupt data blocks. All such index entries are inserted into an orphan key table that stores the key and rowid of the corruption.
After the index entry information has been retrieved, you can rebuild the index using the
ALTER INDEX ... REBUILD ONLINE statement.
Use this procedure if free space in segments is being managed using free lists (
SEGMENT SPACE MANAGEMENT MANUAL).
When a block marked "corrupt" is found at the head or tail of a free list, the free list is reinitialized and an error is returned. Although this takes the offending block off the free list, it causes you to lose free list access to all blocks that followed the corrupt block.
You can use the
REBUILD_FREELISTS procedure to reinitialize the free lists. The object is scanned, and if it is appropriate for a block to be on the free list, it is added to the master free list. Free list groups are handled by distributing blocks in an equitable fashion, one block at a time. Any blocks marked "corrupt" in the object are ignored during the rebuild.
Use this procedure if free space in segments is being managed using bitmaps (
SEGMENT SPACE MANAGEMENT AUTO).
This procedure either recalculates the state of a bitmap entry based on the corresponding block's current contents, or you can specify that a bitmap entry be set to a specific value. Usually, the state is recalculated correctly and there is no need to force a setting.
In this section, examples are presented reflecting the use of the
A repair table provides information about what corruptions were found by the
CHECK_OBJECT procedure and how these will be addressed if the
FIX_CORRUPT_BLOCKS procedure is run. Further, it is used to drive the execution of the
An orphan key table is used when the
DUMP_ORPHAN_KEYS procedure is executed and it discovers index entries that point to corrupt rows. The
DUMP_ORPHAN_KEYS procedure populates the orphan key table by logging its activity and providing the index information in a usable manner.
ADMIN_TABLE procedure is used to create, purge, or drop a repair table or an orphan key table.
The following example creates a repair table for the
BEGIN DBMS_REPAIR.ADMIN_TABLES ( TABLE_NAME => 'REPAIR_TABLE', TABLE_TYPE => dbms_repair.repair_table, ACTION => dbms_repair.create_action, TABLESPACE => 'USERS'); END; /
For each repair or orphan key table, a view is also created that eliminates any rows that pertain to objects that no longer exist. The name of the view corresponds to the name of the repair or orphan key table, but is prefixed by
DBA_ (for example
The following query describes the repair table created in the previous example.
SQL> DESC REPAIR_TABLE Name Null? Type ---------------------------- -------- -------------- OBJECT_ID NOT NULL NUMBER TABLESPACE_ID NOT NULL NUMBER RELATIVE_FILE_ID NOT NULL NUMBER BLOCK_ID NOT NULL NUMBER CORRUPT_TYPE NOT NULL NUMBER SCHEMA_NAME NOT NULL VARCHAR2(30) OBJECT_NAME NOT NULL VARCHAR2(30) BASEOBJECT_NAME VARCHAR2(30) PARTITION_NAME VARCHAR2(30) CORRUPT_DESCRIPTION VARCHAR2(2000) REPAIR_DESCRIPTION VARCHAR2(200) MARKED_CORRUPT NOT NULL VARCHAR2(10) CHECK_TIMESTAMP NOT NULL DATE FIX_TIMESTAMP DATE REFORMAT_TIMESTAMP DATE
This example illustrates the creation of an orphan key table for the
BEGIN DBMS_REPAIR.ADMIN_TABLES ( TABLE_NAME => 'ORPHAN_KEY_TABLE', TABLE_TYPE => dbms_repair.orphan_table, ACTION => dbms_repair.create_action, TABLESPACE => 'USERS'); END; /
The orphan key table is described in the following query:
SQL> DESC ORPHAN_KEY_TABLE Name Null? Type ---------------------------- -------- ----------------- SCHEMA_NAME NOT NULL VARCHAR2(30) INDEX_NAME NOT NULL VARCHAR2(30) IPART_NAME VARCHAR2(30) INDEX_ID NOT NULL NUMBER TABLE_NAME NOT NULL VARCHAR2(30) PART_NAME VARCHAR2(30) TABLE_ID NOT NULL NUMBER KEYROWID NOT NULL ROWID KEY NOT NULL ROWID DUMP_TIMESTAMP NOT NULL DATE
CHECK_OBJECT procedure checks the specified objects, and populates the repair table with information about corruptions and repair directives. You can optionally specify a range, partition name, or subpartition name when you would like to check a portion of an object.
Validation consists of checking all blocks in the object that have not previously been marked corrupt. For each block, the transaction and data layer portions are checked for self consistency. During
CHECK_OBJECT, if a block is encountered that has a corrupt buffer cache header, then that block is skipped.
Here is an example of executing the
CHECK_OBJECT procedure for the
SET SERVEROUTPUT ON DECLARE num_corrupt INT; BEGIN num_corrupt := 0; DBMS_REPAIR.CHECK_OBJECT ( SCHEMA_NAME => 'SCOTT', OBJECT_NAME => 'DEPT', REPAIR_TABLE_NAME => 'REPAIR_TABLE', CORRUPT_COUNT => num_corrupt); DBMS_OUTPUT.PUT_LINE('number corrupt: ' || TO_CHAR (num_corrupt)); END; /
SQL*PLUS outputs the following line, indicating one corruption:
Querying the repair table produces information describing the corruption and suggesting a repair action.
SELECT OBJECT_NAME, BLOCK_ID, CORRUPT_TYPE, MARKED_CORRUPT, CORRUPT_DESCRIPTION, REPAIR_DESCRIPTION FROM REPAIR_TABLE; OBJECT_NAME BLOCK_ID CORRUPT_TYPE MARKED_COR ------------------------------ ---------- ------------ ---------- CORRUPT_DESCRIPTION -------------------------------------------------------------------------------- REPAIR_DESCRIPTION -------------------------------------------------------------------------------- DEPT 3 1 FALSE kdbchk: row locked by non-existent transaction table=0 slot=0 lockid=32 ktbbhitc=1 mark block software corrupt
At this point, the corrupted block has not yet been marked corrupt, so this is the time to extract any meaningful data. After the block is marked corrupt, the entire block must be skipped.
FIX_CORRUPT_BLOCKS procedure to fix the corrupt blocks in specified objects based on information in the repair table that was previously generated by the
CHECK_OBJECT procedure. Prior to effecting any change to a block, the block is checked to ensure the block is still corrupt. Corrupt blocks are repaired by marking the block software corrupt. When a repair is performed, the associated row in the repair table is updated with a fix timestamp.
This example fixes the corrupt block in table
scott.dept that was reported by the
SET SERVEROUTPUT ON DECLARE num_fix INT; BEGIN num_fix := 0; DBMS_REPAIR.FIX_CORRUPT_BLOCKS ( SCHEMA_NAME => 'SCOTT', OBJECT_NAME=> 'DEPT', OBJECT_TYPE => dbms_repair.table_object, REPAIR_TABLE_NAME => 'REPAIR_TABLE', FIX_COUNT=> num_fix); DBMS_OUTPUT.PUT_LINE('num fix: ' || TO_CHAR(num_fix)); END; / SQL*Plus outputs the following line: num fix: 1
To following query confirms that the repair was done.
SELECT OBJECT_NAME, BLOCK_ID, MARKED_CORRUPT FROM REPAIR_TABLE; OBJECT_NAME BLOCK_ID MARKED_COR ------------------------------ ---------- ---------- DEPT 3 TRUE
DUMP_ORPHAN_KEYS procedure reports on index entries that point to rows in corrupt data blocks. For each such index entry encountered, a row is inserted into the specified orphan key table. The orphan key table must have been previously created.
This information can be useful for rebuilding lost rows in the table and for diagnostic purposes.
In this example,
pk_dept is an index on the
scott.dept table. It is scanned to determine if there are any index entries pointing to rows in the corrupt data block.
SET SERVEROUTPUT ON DECLARE num_orphans INT; BEGIN num_orphans := 0; DBMS_REPAIR.DUMP_ORPHAN_KEYS ( SCHEMA_NAME => 'SCOTT', OBJECT_NAME => 'PK_DEPT', OBJECT_TYPE => dbms_repair.index_object, REPAIR_TABLE_NAME => 'REPAIR_TABLE', ORPHAN_TABLE_NAME=> 'ORPHAN_KEY_TABLE', KEY_COUNT => num_orphans); DBMS_OUTPUT.PUT_LINE('orphan key count: ' || TO_CHAR(num_orphans)); END; /
The following line is output, indicating there are three orphan keys:
Index entries in the orphan key table implies that the index should be rebuilt. This guarantees that a table probe and an index probe return the same result set.
REBUILD_FREELISTS procedure rebuilds the free lists for the specified object. All free blocks are placed on the master free list. All other free lists are zeroed. If the object has multiple free list groups, then the free blocks are distributed among all free lists, allocating to the different groups in round-robin fashion.
This example rebuilds the free lists for the table
BEGIN DBMS_REPAIR.REBUILD_FREELISTS ( SCHEMA_NAME => 'SCOTT', OBJECT_NAME => 'DEPT', OBJECT_TYPE => dbms_repair.table_object); END; /
SKIP_CORRUPT_BLOCKS procedure enables or disables the skipping of corrupt blocks during index and table scans of the specified object. When the object is a table, skip applies to the table and its indexes. When the object is a cluster, it applies to all of the tables in the cluster, and their respective indexes.
The following example enables the skipping of software corrupt blocks for the
BEGIN DBMS_REPAIR.SKIP_CORRUPT_BLOCKS ( SCHEMA_NAME => 'SCOTT', OBJECT_NAME => 'DEPT', OBJECT_TYPE => dbms_repair.table_object, FLAGS => dbms_repair.skip_flag); END; /
scott's tables using the
DBA_TABLES view shows that
SKIP_CORRUPT is enabled for table
SELECT OWNER, TABLE_NAME, SKIP_CORRUPT FROM DBA_TABLES WHERE OWNER = 'SCOTT'; OWNER TABLE_NAME SKIP_COR ------------------------------ ------------------------------ -------- SCOTT ACCOUNT DISABLED SCOTT BONUS DISABLED SCOTT DEPT ENABLED SCOTT DOCINDEX DISABLED SCOTT EMP DISABLED SCOTT RECEIPT DISABLED SCOTT SALGRADE DISABLED SCOTT SCOTT_EMP DISABLED SCOTT SYS_IOT_OVER_12255 DISABLED SCOTT WORK_AREA DISABLED 10 rows selected.