Oracleデータベースのブロック破損を検出・修復する完全ガイド
本記事では、Oracle®データベースにおけるデータファイル(システムデータファイルを含む)の単一または複数ブロック破損の修復方法について解説します。ブロック破損は、データベース障害の一般的な原因の一つです。
データベースブロックは、その内容がOracleデータベースが期待する値と異なる場合に「破損」とみなされます。ブロック破損を予防または修復しないまま放置すると、データベース全体がダウンし、重要なビジネスデータが失われる可能性があります。
これは、本番データベースの運用において実際に直面し、対応が求められる典型的な問題の一つです。
ブロック破損の発見と修復
以下の画像は、発生しうるブロック破損の例を示しています。
画像出典: https://blog.toadworld.com/2017/12/01/block-corruption-in-an-oracle-database
1. 破損箇所を特定する
まず、以下のコマンドを実行して破損ブロックを特定します。
SQL> select * from V$DATABASE_BLOCK_CORRUPTION;
FILE# BLOCK# BLOCKS CORRUPTION_CHANGE# CORRUPTION
----- ---------- ---------- ------------------ ----------
352 173191 9 0 ALL ZERO
SQL> SELECT FILE_ID,RELATIVE_FNO,FILE_NAME,TABLESPACE_NAME FROM DBA_DATA_FILES WHERE FILE_ID=352;
FILE_ID RELATIVE_FNO FILE_NAME TABLESPACE_NAME
---------- ------------ -------------------------------------------------- ------------------
352 352 /u01/apps_st/samusxxxxxxxx_data2/system09.dbf SYSTEM
SQL> SELECT owner, segment_name, segment_type FROM dba_extents WHERE RELATIVE_FNO = 352 AND Block_id BETWEEN 173191 AND 173191 + blocks - 1;
OWNER SEGMENT_NAME SEGMENT_TYPE
-------- --------------- ------------------
SYS I_COL3 INDEX
SYS C_OBJ# CLUSTER
補足: このケースでは、SYSオブジェクトのセグメント I_COL3 にブロック破損が発生しています。dbv コマンドによって報告された破損ブロックは、dba_free_space ビュー上では空き領域として表示される点に注意してください。
2. ブロックを解放する
ファイル352のブロックを解放するには、以下のコマンドを実行します。
SQL> select * from V$DATABASE_BLOCK_CORRUPTION;
FILE# BLOCK# BLOCKS CORRUPTION_CHANGE# CORRUPTION
----- ---------- ---------- ------------------ ----------
352 173191 9 0 ALL ZERO
SQL> Select * from dba_free_space where file_id =352 and 173191 between block_id and block_id + blocks -1;
TABLESPACE_NAME FILE_ID BLOCK_ID BYTES BLOCKS RELATIVE_FNO
--------------- ------- -------- ----- ---------- ------------
SYSTEM 352 173191 73728 9 352
3. 破損ブロックを強制的にクリアする
ブロックが解放された後、以下の手順で破損ブロックを強制的にクリアできます。これは、どのセグメントにも属さない破損ブロックを再フォーマットする処理としても知られています。
手順1: ユーザーを作成し、データベースへのアクセス権を付与する
create user Scott identified by password default tablespace SYSTEM;
grant resource, connect, create table, create trigger to Scott;
手順2: データファイルに対して破損ブロックを確認する
[Thu Nov 17 11:59:19 orbdev@samusxxxxxxxx:~ ] $ dbv file='/mnt/apps_st/samusxxxxxxxx_data2/system09.dbf' userid=sys/xxxxx
DBVERIFY: Release 11.2.0.4.0 - Production on Thu Nov 17 11:59:21 2016
Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved.
DBVERIFY - Verification starting: FILE = /mnt/apps_st/samusxxxxxxxx_data2/system09.dbf
Page 173191 is marked corrupt
Corrupt block relative dba: 0x5802a487 (file 352, block 173191)
Completely zero block found during dbv:
Page 173192 is marked corrupt
Corrupt block relative dba: 0x5802a488 (file 352, block 173192)
Completely zero block found during dbv:
Page 173193 is marked corrupt
Corrupt block relative dba: 0x5802a489 (file 352, block 173193)
Completely zero block found during dbv:
Page 173194 is marked corrupt
Corrupt block relative dba: 0x5802a48a (file 352, block 173194)
Completely zero block found during dbv:
Page 173195 is marked corrupt
Corrupt block relative dba: 0x5802a48b (file 352, block 173195)
Completely zero block found during dbv:
Page 173196 is marked corrupt
Corrupt block relative dba: 0x5802a48c (file 352, block 173196)
Completely zero block found during dbv:
Page 173197 is marked corrupt
Corrupt block relative dba: 0x5802a48d (file 352, block 173197)
Completely zero block found during dbv:
Page 173198 is marked corrupt
Corrupt block relative dba: 0x5802a48e (file 352, block 173198)
Completely zero block found during dbv:
Page 173199 is marked corrupt
Corrupt block relative dba: 0x5802a48f (file 352, block 173199)
Completely zero block found during dbv:
DBVERIFY - Verification complete
Total Pages Examined : 917504
Total Pages Processed (Data): 253735
Total Pages Failing (Data) : 0
Total Pages Processed (Index): 335744
Total Pages Failing (Index): 0
Total Pages Processed (Other): 375
Total Pages Processed (Seg) : 17
Total Pages Failing (Seg) : 0
Total Pages Empty : 327624
Total Pages Marked Corrupt : 9
Total Pages Influx : 0
Total Pages Encrypted : 0
Highest block SCN : 3412538527 (1421.3412538527)
[Thu Nov 17 12:00:13 orbdev@samusxxxxxxxx:~ ] $
手順3: 空き領域を確認する
Select * from dba_free_space where file_id= <絶対ファイル番号> and <破損ブロック番号> between block_id and block_id + blocks -1;
SQL> Select * from dba_free_space where file_id=352 and 173191 between block_id and block_id + blocks -1;
TABLESPACE_NAME FILE_ID BLOCK_ID BYTES BLOCKS RELATIVE_FNO
--------------- ---------- ---------- ---------- --------- ------------
SYSTEM 352 173196 73728 9 352
手順4: 最初の破損ブロックを再フォーマットする
すべての破損ブロックが再フォーマットされるまで、この手順を繰り返します。
create table scott.s (n number,c varchar2(4000)) nologging tablespace SYSTEM;
select owner,table_name,tablespace_name from dba_tables where table_name='S';
SQL> CREATE OR REPLACE TRIGGER corrupt_trigger
AFTER INSERT ON scott.s
REFERENCING OLD AS p_old NEW AS new_p
FOR EACH ROW
DECLARE
corrupt EXCEPTION;
BEGIN
IF (dbms_rowid.rowid_block_number(:new_p.rowid)=&blocknumber)
and (dbms_rowid.rowid_relative_fno(:new_p.rowid)=&filenumber) THEN
RAISE corrupt;
END IF;
EXCEPTION
WHEN corrupt THEN
RAISE_APPLICATION_ERROR(-20000, 'Corrupt block has been formatted');
END;
/
Enter value for blocknumber: 173191
old 8: IF (dbms_rowid.rowid_block_number(:new_p.rowid)=&blocknumber)
new 8: IF (dbms_rowid.rowid_block_number(:new_p.rowid)=173191)
Enter value for filenumber: 352
old 9: and (dbms_rowid.rowid_relative_fno(:new_p.rowid)=&filenumber) THEN
new 9: and (dbms_rowid.rowid_relative_fno(:new_p.rowid)=352) THEN
Trigger created.
Select BYTES/1024/1024 from dba_free_space where file_id=352 and 173191 between block_id and block_id + blocks -1;
72K
SQL> BEGIN
FOR i IN 1..100000 LOOP
EXECUTE IMMEDIATE 'alter table scott.s allocate extent (DATAFILE '||'''/mnt/apps_st/samusxxxxxxxx_data2/system09.dbf''' ||'SIZE 72K)';
END LOOP;
END;
/
SQL> BEGIN
FOR i IN 1..1000000 LOOP
INSERT /*+ APPEND */ INTO scott.s select i, lpad('REFORMAT',3092, 'R') from dual;
commit ;
END LOOP;
END;
/
SQL> Select * from v$database_block_corruption;
no rows selected
DROP TABLE scott.s;
Alter system switch logfile;
Alter system checkpoint;
DROP trigger corrupt_trigger;
手順5: 破損ブロックが修復されたことを確認する
SQL> select * from V$DATABASE_BLOCK_CORRUPTION;
no rows selected
[Wed Nov 16 08:12:37 orbdev@samusxxxxxx:~ ] $ dbv file='/mnt/apps_st/samusxxxxxx_data2/system09.dbf' userid=sys/****
DBVERIFY: Release 11.2.0.4.0 - Production on Wed Nov 16 08:12:41 2016
Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved.
DBVERIFY - Verification starting : FILE = /mnt/apps_st/samusxxxxxx_data2/system09.dbf
DBVERIFY - Verification complete
Total Pages Examined : 655359
Total Pages Processed (Data) : 260868
Total Pages Failing (Data) : 0
Total Pages Processed (Index): 340482
Total Pages Failing (Index): 0
Total Pages Processed (Other): 278
Total Pages Processed (Seg): 15
Total Pages Failing (Seg): 0
Total Pages Empty : 53716
Total Pages Marked Corrupt : 0
Total Pages Influx : 0
Total Pages Encrypted : 0
Highest block SCN : 136830000 (1422.136830000)
[Wed Nov 16 08:14:50 orbldev2@samusxxxxxx:~ ] $
まとめ
データ破損を検出・防止するために、以下のMaximum Availability Architecture(MAA)のベストプラクティスを実施することを推奨します。
- Oracle Data Guardを活用する。
- Oracle Databaseのブロック破損検出パラメータを設定する。
- Recovery Manager(RMAN)によるバックアップ・リカバリ戦略を導入する。
これらの高可用性ソリューションはOracle Databaseと統合されており、基盤となるデータ構造を活用します。そのため、これらのツールは、新しいクラスのインテリジェントなデータ保護およびディザスタリカバリ機能を提供します。
ご意見やご質問がある場合は、フィードバックタブをご利用ください。
データベースサービスやRackspace Applicationサービスの詳細については、関連ページをご覧ください。
-
Windows Update データベース破損エラーの解決方法【5つの対処法を徹底解説】
Windows 10のアップデート中に更新処理が途中で止まってしまったり、Windows Updateデータベース破損エラーのせいでアップデート自体ができないことがあります。このエラーは「Windows Updateのトラブルシューティングツール」を実行したときに初めて判明することが多いのですが、通常ならツールが自動的に問題を修復してくれるところ、このケースでは「潜在的なWindows Updateデータベースエラーが検出されました」と表示されるものの、「修正を適用」をクリックしても修復が失敗し、しばらく実行した後に「未修正」と表示されてしまいます。 新しいアップデートをダウンロードできない状
-
Windows 10 で破損したプログラムを修復またはアンインストールする方法
Windows 10 の環境には、数え切れないほどのプログラムやアプリケーションが搭載されており、私たちのPC体験を快適で楽しいものにしてくれています。しかし、あるアプリが突然クラッシュして、原因がまったく分からないということも少なくありません。もちろん、アプリやプログラムがクラッシュしたり応答しなくなったりすると、Windowsはすぐに修復ウィンドウを開いてくれます。ただ、この解決策は必ずしも効果的とは言えません。 そのため、何らかの理由でWindows上のアプリがクラッシュした場合は、すぐに対処する必要があります。Windowsの修復機能で問題が解決しない場合は、以下の方法を試してみてく