データ・ブロックの破損を検出し、修正できます。
注意:
DBMS_REPAIRパッケージについて詳しくない場合は、このパッケージに含まれる修復プロシージャを実行する際に、Oracleサポート・サービスのアナリストと共同で作業することをお薦めします。
Oracle Databaseには、データ・ブロックの破損を検出して修正するために、複数の方法が用意されています。
その1つは、破損の検出後にオブジェクトを削除して再作成することです。しかし、この方法が必ずしも可能とはかぎらず、またそれが望ましくない場合もあります。データ・ブロックの破損が行のサブセットにかぎられている場合は、破損した行を除くすべてのデータを選択して表を再作成する方法があります。
また、DBMS_REPAIRパッケージを使用してデータ・ブロック破損を管理する方法もあります。DBMS_REPAIRを使用すると、表と索引の破損ブロックを検出して修復できます。オブジェクトは、再作成または修復の試行中でも続けて使用できます。
Recovery Manager (RMAN)のコマンドRECOVER BLOCKを使用して、破損したデータ・ブロックまたはデータ・ブロックのセットを修復することもできます。
注意:
データの損失を伴う破損の場合は、そのデータがデータベース・システム全体にどのように格納されているかを分析して理解する必要があります。修復の内容によっては、データを失ったり、論理的一貫性が損なわれる場合があります。このパッケージで提供される修復アプローチが特定の破損に対して適切かどうかを個々に判断する必要があります。
関連項目:
RMANのRECOVER BLOCKコマンドの詳細は、『Oracle Databaseバックアップおよびリカバリ・リファレンス』を参照してください。
DBMS_REPAIRパッケージには、データ破損修復プロシージャが含まれており、表および索引にある破損ブロックを検出して修復できます。
関連項目:
DBMS_REPAIRプロシージャの構文、制限事項および例外の詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。
DBMS_REPAIRパッケージのプロシージャにより、破損したブロックを検出および修復できます。
次の表は、DBMS_REPAIRパッケージに含まれているプロシージャの一覧を示します。
| プロシージャ名 | 説明 |
|---|---|
|
修復表および孤立キー表の管理機能(作成、削除、パージ)を提供します。 注意: これらの表は常に |
|
表または索引の破損を検出し、レポートします。 |
|
破損データ・ブロック内の行を指す索引エントリをレポートします。 |
|
すでに |
|
オブジェクトの空きリストを再作成します。 |
|
セグメント領域管理が |
|
このプロシージャを使用すると、表と索引のスキャン時に、破損マークが付いたブロックが無視されます。使用しない場合は、破損マークが付いたブロックが検出されたときにエラー |
これらのプロシージャの詳細と使用例は、「DBMS_REPAIRの例」を参照してください。
いくつかの制限および制約事項がDBMS_REPAIRプロシージャに適用されます。
DBMS_REPAIRプロシージャには、次の制約があります。
LOBデータ型、ネストした表およびVARRAYを含む表はサポートされますが、表外格納の列は無視されます。
クラスタは、SKIP_CORRUPT_BLOCKSおよびREBUILD_FREELISTSプロシージャではサポートされますが、CHECK_OBJECTプロシージャではサポートされません。
索引構成表およびLOB索引はサポートされません。
グローバル一時表はサポートされていません。
DUMP_ORPHAN_KEYSプロシージャは、ビットマップ索引またはファンクション索引には機能しません。
DUMP_ORPHAN_KEYSプロシージャで処理される最大キー長は、3,950バイトです。
データ・ブロックの破損に対処するために、DBMS_REPAIRパッケージを使用できます。
最初のタスクでは、破損を検出しレポートします。レポートでは、ブロックに関する問題が明らかになるだけでなく、それに対応する修復ディレクティブも識別されます。
破損を検出するには、いくつかの方法があります。
表25-1に、異なる検出方法を示します。
表25-1 破損検出方法の比較
| 検出方法 | 説明 |
|---|---|
|
指定した表、パーティションまたは索引のブロック・チェックを実行します。修復表に結果を移入します。 |
|
オフライン・データベースでブロック・チェックを実行します。 |
|
|
|
|
CHECK_OBJECTプロシージャは、指定されたオブジェクトのブロック破損をチェックしてレポートします。ADMIN_TABLESプロシージャは、破損の修正を円滑に行うために修復表を作成します。
CHECK_OBJECTプロシージャでは、索引と表に対するANALYZE...VALIDATE STRUCTURE文と同様に、索引とデータ・ブロックに対してブロック・チェックが実行されます。
CHECK_OBJECTでは、破損がレポートされるだけでなく、そのオブジェクトに対して後でFIX_CORRUPT_BLOCKSを実行した場合に行われる修正も識別されます。この情報は修復表への移入によって使用可能になるため、最初にADMIN_TABLESプロシージャで修復表を作成しておく必要があります。
CHECK_OBJECTプロシージャを実行した後は、修復表の簡単な問合せによってそのオブジェクトの破損および修復ディレクティブが表示されます。この情報に基づいて、レポートされた問題に最も適切な対処方法を評価できます。
データ破損が発生した場合は、オフライン診断ユーティリティとしてDB_VERIFYを使用します。
関連項目:
DB_VERIFYの詳細は、『Oracle Databaseユーティリティ』を参照してください。
ANALYZE TABLE...VALIDATE STRUCTURE文は、分析するオブジェクトの構造の妥当性をチェックします。オブジェクトの構造内で破損が検出されると、エラー・メッセージが表示されます。この場合、オブジェクトを削除して作成しなおす必要があります。
ANALYZE TABLE文のCASCADE句を使用すると、1回の操作で、表とすべての索引の構造をチェックできます。この操作ではリソースを大量に消費する可能性があるため、軽量なチェックを実行するFASTオプションを使用できます。詳細は、「表、索引、クラスタおよびマテリアライズド・ビューの妥当性チェック」を参照してください。
関連項目:
ANALYZE文の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。
DB_BLOCK_CHECKING初期化パラメータをTRUEに設定すると、データベースのブロック・チェックを使用可能にすることができます。
これにより、データ・ブロックおよび索引ブロックが変更された際には、必ずそのブロックの内部一貫性がチェックされます。DB_BLOCK_CHECKINGは、ALTER SYSTEM SET文で変更可能な動的パラメータです。システム表領域では、ブロック・チェックは常に使用可能になっています。
関連項目:
DB_BLOCK_CHECKING初期化パラメータの詳細は、『Oracle Databaseリファレンス』を参照してください。
DBMS_REPAIRを使用する前に、その利害得失を検討する必要があります。また、破損オブジェクトの対応手段として使用可能な他のオプションも検討してください。
次の質問に答えることから開始してください。
破損の範囲はどの程度ですか。
破損の有無と修復アクションの要不要を判断するには、CHECK_OBJECTプロシージャを実行して修復表を問い合せます。
ブロック破損の対応手段として使用可能な他のオプションがありますか。この質問については、次の対応が可能かどうかを検討します。
他のソースからのデータが使用可能な場合は、そのオブジェクトを削除し、再作成して再移入する。
CREATE TABLE...AS SELECT文を発行して、破損表から新しい表を作成する。
SELECT文から破損行を除外して、破損を無視する。
メディア・リカバリを実行する。
DBMS_REPAIRを使用してオブジェクトを使用可能にした場合に、どのような論理的な破損や副作用が生じますか。それらの問題に対処できますか。そのためにはどんな作業が必要ですか。
破損マークが付いたブロックの行にはアクセスできない場合があります。また、正常にアクセスできる行が含まれているブロックでも、破損マークが付いている場合があります。
ブロックに破損マークが付いている場合は、参照整合性制約が壊れていることがあります。この場合は、制約を使用禁止にし、再び使用可能にすると、不整合がレポートされます。すべての問題を解決すれば、再び制約を使用できるようになります。
表にトリガーが定義されている場合は、論理的な破損が生じることがあります。たとえば、行を再度挿入したときに、挿入トリガーが起動されるかどうかを確認します。これらの問題に対処するには、インストレーションでどのトリガーがどのように使用されているかを理解する必要があります。
索引と表が同期化されていない場合は、DUMP_ORPHAN_KEYSプロシージャを実行して、破損データの再作成に役立つ情報をキーから取得します。次に、ALTER INDEX...REBUILD ONLINE文を発行し、表と索引を同期化します。
修復によってデータが失われる場合に、このデータを取り出すことができますか。
データ・ブロックに破損マークが付いている場合は、索引からデータを取り出すことができます。この情報を取り出すには、DUMP_ORPHAN_KEYSプロシージャを利用します。
DBMS_REPAIRを使用して表と索引のスキャン時に破損を無視することにより、オブジェクトを使用可能にします。
DBMS_REPAIRの機能の適用範囲外にある破損をスキップする環境を設定し、それによって破損オブジェクトを使用可能にできます。
破損が、データ・ブロック内の不良行などのデータの損失を伴う場合は、FIX_CORRUPT_BLOCKSプロシージャによって、そのようなブロックすべてに破損マークが付けられます。次に、破損マークが付いたブロックをスキップするSKIP_CORRUPT_BLOCKSプロシージャを実行できます。SKIP_FLAGパラメータがプロシージャに設定されている場合は、破損マークが付いているすべてのブロックが、表と索引のスキャンでスキップされます。これはメディアとソフトウェアの両方の破損ブロックに適用されます。
破損したブロックをスキップすると、いくつかの状況では、問合せから異なる結果が返されることがあります。
索引と表が同期化されていない場合、ある問合せで索引のみをプローブし、後続の問合せで索引と表の両方をプローブするような状況下では、SET TRANSACTION READ ONLYトランザクションの一貫性が保たれないことがあります。表ブロックに破損マークが付いている場合、この2つの問合せは異なる結果を返すので、読取り専用トランザクションのルールに違反します。この場合の対処方法の1つとして、SET TRANSACTION READ ONLYトランザクション内で破損をスキップしないようにします。
これと同様の問題は、連鎖している行の選択時にも発生します。同じ行を問い合せても、破損にアクセスできる場合とできない場合があるため、異なった結果が生じます。
DBMS_REPAIRパッケージの使用方法の例を示します。
修復表は、破損に関する情報を提供します。孤立キー表は、破損した行を指す索引エントリに関する情報を提供します。
ADMIN_TABLEプロシージャは、修復表または孤立キー表の作成、パージまたは削除に使用します。
修復表は、CHECK_OBJECTプロシージャによって検出された破損の内容と、FIX_CORRUPT_BLOCKSプロシージャを実行した場合にこれらの破損がどのように処理されるかを示す情報を提供します。また、FIX_CORRUPT_BLOCKSプロシージャの実行が必要かを判断する際にも使用されます。
孤立キー表は、DUMP_ORPHAN_KEYSプロシージャの実行時に使用され、破損行を指す索引エントリが格納されます。DUMP_ORPHAN_KEYSプロシージャは、そのアクティビティをロギングし、索引情報を使用可能な形にして、孤立キー表に移入します。
ADMIN_TABLESプロシージャを使用して修復表を作成する例を示します。
次の例では、users表領域の修復表を作成しています。
BEGIN
DBMS_REPAIR.ADMIN_TABLES (
TABLE_NAME => 'REPAIR_TABLE',
TABLE_TYPE => dbms_repair.repair_table,
ACTION => dbms_repair.create_action,
TABLESPACE => 'USERS');
END;
/
修復表または孤立キー表それぞれについて、存在しなくなったオブジェクトに関連する行を除外するビューも作成されます。ビュー名は、修復表または孤立キー表の名前に対応しており、接頭辞DBA_が付いています(例: DBA_REPAIR_TABLE、DBA_ORPHAN_KEY_TABLE)。
次の問合せでは、users表領域に作成された修復表が表示されます。
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
ADMIN_TABLESプロシージャを使用して孤立キー表を作成する例を示します。
次の例は、users表領域の孤立キー表の作成方法を示しています。
BEGIN
DBMS_REPAIR.ADMIN_TABLES (
TABLE_NAME => 'ORPHAN_KEY_TABLE',
TABLE_TYPE => dbms_repair.orphan_table,
ACTION => dbms_repair.create_action,
TABLESPACE => 'USERS');
END;
/
次の問合せでは、孤立キー表の定義を表示しています。
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プロシージャによって破損を検出する例を示します。
CHECK_OBJECTプロシージャは、指定されたオブジェクトをチェックし、破損および修復ディレクティブに関する情報を修復表に移入します。オブジェクトの一部をチェックする場合は、必要に応じて、範囲、パーティション名またはサブパーティション名を指定できます。
妥当性チェックでは、オブジェクト内部でそれまでに破損マークが付けられていないブロックがすべてチェックされます。ブロックごとに、トランザクションおよびデータ・レイヤー部分の自己整合性がチェックされます。CHECK_OBJECTの実行中に、破損バッファ・キャッシュ・ヘッダーを持つブロックが検出されると、そのブロックはスキップされます。
scott.dept表に対するCHECK_OBJECTプロシージャの実行例を次に示します。
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には、1つの破損を示す次の行が出力されます。
number corrupt: 1
修復表を問い合せると、破損の説明および修復アクションに関する提案を含む情報が表示されます。
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
まだ破損ブロックに破損マークが付いていないため、ここで重要なデータを抽出します。ブロックに破損マークが付けられた後は、そのブロック全体がスキップされます。
FIX_CORRUPT_BLOCKSプロシージャによって破損ブロックを修正する例を示します。
CHECK_OBJECTプロシージャによって生成した修復表内の情報に基づいて、FIX_CORRUPT_BLOCKSプロシージャを使用し、指定したオブジェクトの破損ブロックを修正します。ブロックの変更前には、そのブロックがまだ破損状態にあるかどうかが確認されます。破損ブロックは、そのブロックにソフトウェア破損のマークを付けることによって修復されます。修復が実行されると、修復表内の対応する行がタイムスタンプ付きで更新されます。
次の例では、CHECK_OBJECTプロシージャによってレポートされた表scott.deptの破損ブロックを修正しています。
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では次の行が出力されます。
num fix: 1
次の問合せによって、修復が完了していることが確認されます。
SELECT OBJECT_NAME, BLOCK_ID, MARKED_CORRUPT
FROM REPAIR_TABLE;
OBJECT_NAME BLOCK_ID MARKED_COR
------------------------------ ---------- ----------
DEPT 3 TRUE
DUMP_ORPHAN_KEYSプロシージャを使用して破損データ・ブロックを指す索引エントリを検索する例を示します。
DUMP_ORPHAN_KEYSプロシージャは、破損データ・ブロック内の行を指す索引エントリをレポートします。索引エントリごとに、指定した孤立キー表に1行ずつ挿入されます。この孤立キー表は、事前に作成しておく必要があります。
この情報は、表内の失われた行を再作成する場合や診断に使用します。
注意:
このプロシージャは、修復表で識別された表に対応付けられている索引ごとに実行する必要があります。
この例では、pk_deptはscott.dept表の索引です。これがスキャンされて、破損したデータ・ブロックの行を指す索引エントリがあるかどうかが見極められます。
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;
/
次の出力は、孤立キーが3つあることを示しています。
orphan key count: 3
孤立キー表の索引エントリは、索引の再作成が必要であることを示しています。索引の再作成により、表プローブと索引プローブが同じ結果セットを返すことが保証されます。
SKIP_CORRUPT_BLOCKSプロシージャを使用して破損ブロックをスキップする例を示します。
SKIP_CORRUPT_BLOCKSプロシージャは、指定されたオブジェクトの索引および表のスキャン時に破損ブロックをスキップするかしないかを指定します。オブジェクトが表であれば、スキップは表とその索引に適用されます。オブジェクトがクラスタのときは、クラスタ内のすべての表およびその各索引に適用されます。
次の例では、scott.dept表のソフトウェア破損ブロックのスキップを可能に設定しています。
BEGIN
DBMS_REPAIR.SKIP_CORRUPT_BLOCKS (
SCHEMA_NAME => 'SCOTT',
OBJECT_NAME => 'DEPT',
OBJECT_TYPE => dbms_repair.table_object,
FLAGS => dbms_repair.skip_flag);
END;
/
DBA_TABLESビューを使用してscottの表を問い合せると、表scott.deptのSKIP_CORRUPTが使用可能になっていることが示されます。
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.