| Oracle Database 管理者ガイド 11gリリース1(11.1) E05760-03 |
|
この章の内容は次のとおりです。
Oracle Databaseには、データ・ブロックの破損を検出して修正するために、複数の方法が用意されています。その1つは、破損の検出後にオブジェクトを削除して再作成することです。しかし、この方法が必ずしも可能とはかぎらず、またそれが望ましくない場合もあります。データ・ブロックの破損が行のサブセットにかぎられている場合は、破損した行を除くすべてのデータを選択して表を再作成する方法があります。
また、DBMS_REPAIRパッケージを使用してデータ・ブロック破損を管理する方法もあります。DBMS_REPAIRを使用すると、表と索引の破損ブロックを検出して修復できます。オブジェクトは、再作成または修復の試行中でも続けて使用できます。
ここでは、DBMS_REPAIRパッケージに含まれているプロシージャと、その使用に伴う制約および制限事項について説明します。
次の表は、DBMS_REPAIRパッケージに含まれているプロシージャの一覧を示します。
これらのプロシージャの詳細と使用例は、「DBMS_REPAIRの例」を参照してください。
DBMS_REPAIRプロシージャには、次の制約があります。
SKIP_CORRUPT_BLOCKSおよびREBUILD_FREELISTSプロシージャではサポートされますが、CHECK_OBJECTプロシージャではサポートされません。
DUMP_ORPHAN_KEYSプロシージャは、ビットマップ索引またはファンクション索引には機能しません。
DUMP_ORPHAN_KEYSプロシージャで処理される最大キー長は、3,950バイトです。
データ・ブロック破損に対処する手段としてDBMS_REPAIRを検討する場合は、次のアプローチに従うことをお薦めします。
最初のタスクでは、破損を検出しレポートします。レポートでは、ブロックに関する問題が明らかになるだけでなく、それに対応する修復ディレクティブも識別されます。破損を検出する方法はいくつかあります。表23-1に様々な検出方法を示します。
CHECK_OBJECTプロシージャは、指定されたオブジェクトのブロック破損をチェックしてレポートします。索引と表に対するANALYZE...VALIDATE STRUCTURE文と同様に、索引とデータ・ブロックに対してブロック・チェックが実行されます。
CHECK_OBJECTでは、破損がレポートされるだけでなく、そのオブジェクトに対して後でFIX_CORRUPT_BLOCKSを実行した場合に行われる修正も識別されます。この情報は修復表への移入によって使用可能になるため、最初にADMIN_TABLESプロシージャで修復表を作成しておく必要があります。
CHECK_OBJECTプロシージャを実行した後は、修復表の簡単な問合せによってそのオブジェクトの破損および修復ディレクティブが表示されます。この情報に基づいて、レポートされた問題に最も適切な対処方法を評価できます。
データ破損が発生した場合は、オフライン診断ユーティリティとしてDB_VERIFYを使用します。
ANALYZE TABLE...VALIDATE STRUCTURE文は、分析するオブジェクトの構造の妥当性をチェックします。オブジェクトの構造内で破損が検出されると、エラー・メッセージが表示されます。この場合は、オブジェクトを削除して再作成する必要があります。
ANALYZE TABLE文のCASCADE句を使用すると、1回の操作で、表とすべての索引の構造をチェックできます。この操作ではリソースを大量に消費する可能性があるため、軽量なチェックを実行するFASTオプションを使用できます。詳細は、「表、索引、クラスタおよびマテリアライズド・ビューの妥当性チェック」を参照してください。
DB_BLOCK_CHECKING初期化パラメータをTRUEに設定すると、データベースのブロック・チェックを使用可能にすることができます。これにより、データ・ブロックおよび索引ブロックが変更された際には、必ずそのブロックの内部一貫性がチェックされます。DB_BLOCK_CHECKINGは、ALTER SYSTEM SET文で変更可能な動的パラメータです。システム表領域では、ブロック・チェックは常に使用可能になっています。
DBMS_REPAIRを使用する前に、その利害得失を検討する必要があります。また、破損オブジェクトの対応手段として使用可能な他のオプションも検討してください。次の質問に答えることから開始してください。
破損の有無と修復アクションの要不要を判断するには、CHECK_OBJECTプロシージャを実行して修復表を問い合せます。
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トランザクション内で破損をスキップしないようにします。
これと同様の問題は、連鎖している行の選択時にも発生します。同じ行を問い合せても、破損にアクセスできる場合とできない場合があるため、異なった結果が生じます。
オブジェクトを使用可能にした後で、次の修復アクティビティを実行します。
DUMP_ORPHAN_KEYSプロシージャは、破損データ・ブロック内の行を指す索引エントリをレポートします。この種の索引エントリがすべて、破損のキーとROWIDを格納する孤立キー表に挿入されます。
索引エントリ情報を取り出した後、ALTER INDEX...REBUILD ONLINE文を使用して索引を再作成できます。
セグメントの空き領域がビットマップで管理されている場合(SEGMENT SPACE MANAGEMENT AUTO)は、このプロシージャを使用します。
このプロシージャは、対応するブロックの現在の内容に基づいてビットマップ・エントリの状態を再計算します。また、ビットマップ・エントリを特定の値に設定するように指定することもできます。通常は、状態が適切に再計算されるので、値を強制的に設定する必要はありません。
この項の内容は、次のとおりです。
ADMIN_TABLEプロシージャは、修復表または孤立キー表の作成、パージまたは削除に使用します。
修復表は、CHECK_OBJECTプロシージャによって検出された破損の内容と、FIX_CORRUPT_BLOCKSプロシージャを実行した場合にこれらの破損がどのように処理されるかを示す情報を提供します。また、FIX_CORRUPT_BLOCKSプロシージャの実行が必要かを判断する際にも使用されます。
孤立キー表は、DUMP_ORPHAN_KEYSプロシージャの実行時に使用され、破損行を指す索引エントリが格納されます。DUMP_ORPHAN_KEYSプロシージャは、そのアクティビティをロギングし、索引情報を使用可能な形にして、孤立キー表に移入します。
次の例では、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
次の例は、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の実行中に、破損バッファ・キャッシュ・ヘッダーを持つブロックが検出されると、そのブロックはスキップされます。
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
まだ破損ブロックに破損マークが付いていないため、ここで重要なデータを抽出します。ブロックに破損マークが付けられた後は、そのブロック全体がスキップされます。
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プロシージャは、破損データ・ブロック内の行を指す索引エントリをレポートします。索引エントリごとに、指定した孤立キー表に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プロシージャは、指定されたオブジェクトの索引および表のスキャン時に破損ブロックをスキップするかしないかを指定します。オブジェクトが表であれば、スキップは表とその索引に適用されます。オブジェクトがクラスタであれば、スキップはクラスタ内のすべての表とそれぞれの索引に適用されます。
次の例では、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.