【Oracle】ORA-01578の原因と解決方法|data block corrupted・ブロック破損の確認と復旧

【Oracle】ORA-01578の原因と解決方法|data block corrupted・ブロック破損の確認と復旧 Oracle

ORA-01578: ORACLE data block corrupted は、Oracleがデータファイル内の破損ブロックを読み込んだ時に発生するエラーです。多くの場合、続けて ORA-01110 が表示され、対象のデータファイル番号やファイル名を確認できます。通常のSQLミスではなく、データファイル、ストレージ、バックアップ、NOLOGGING操作、リカバリ手順が関係する障害として扱います。

Oracle公式のエラー説明では、ORA-01578はデータブロック破損を示し、併せて ORA-26040 が出る場合はNOLOGGINGまたはUNRECOVERABLE操作由来の可能性があるとされています。まず対象ブロックを特定し、破損範囲を広げないように調査し、RMANやバックアップからの復旧方法を選びます。RMANの基本は Oracle RMAN完全ガイド、NOLOGGINGの考え方は Oracle NOLOGGING完全ガイド も確認してください。

この記事で整理すること

  • ORA-01578が出た時の初動
  • ORA-01110からファイル番号・ブロック番号を読む方法
  • V$DATABASE_BLOCK_CORRUPTION、RMAN VALIDATE、DBVERIFYでの確認
  • 破損ブロックがどのオブジェクトに属するか調べるSQL
  • RMANブロックメディアリカバリ、表領域復旧、Data Pump退避の判断
  • ORA-26040とNOLOGGING由来破損の注意点
  • 再発防止のバックアップ・検証・監視
スポンサーリンク

この記事で扱う範囲

この記事では、ORA-01578 が出た直後に確認する情報、破損ブロックの調べ方、復旧方法の選び方をまとめます。RMAN、DBVERIFY、V$DATABASE_BLOCK_CORRUPTIONDBA_EXTENTS を使い、索引再作成で済むケース、RMANで戻すケース、Data Pumpや表領域復旧を検討するケースを切り分けます。

最初に結論:対象ブロックを特定してから復旧方法を選ぶ

ORA-01578が出た時に、いきなり表をDROPしたり、ファイルをOS上で置き換えたりしてはいけません。まずエラーメッセージに出ているファイル番号とブロック番号を控え、破損範囲と対象オブジェクトを確認します。そのうえで、RMANのブロックメディアリカバリ、データファイル・表領域の復旧、Data Pumpによる退避、オブジェクト再作成を判断します。

まず止める該当処理の再実行を止め、同じブロックを読むバッチやレポートが連続失敗しないようにします。
場所を特定するORA-01110V$DATABASE_BLOCK_CORRUPTION、RMAN VALIDATEでファイル番号・ブロック番号・破損種類を確認します。
影響を見積もる破損ブロックが表、索引、LOB、UNDO、一時的なNOLOGGINGブロックのどれに属するかを調べます。
復旧方法を選ぶRMANで戻せるか、索引再作成で済むか、Data Pump退避が必要か、表領域単位で復旧するかを決めます。

データファイルのリカバリが必要なケースは ORA-01113の原因と解決方法、表領域単位の復旧は RMANで特定の表領域だけを復元する方法 が関連します。

エラーメッセージの読み方

ORA-01578では、ファイル番号とブロック番号が重要です。続くORA-01110には、対象データファイル名が表示されることがあります。

ora-01578-message.txt
ORA-01578: ORACLE data block corrupted (file # 7, block # 123456)
ORA-01110: data file 7: '/u01/oradata/ORCL/users01.dbf'

この例では、ファイル番号7、ブロック番号123456が破損しています。以降のSQLやRMANコマンドでは、この番号を使って調査します。

破損範囲を確認する方法

V$DATABASE_BLOCK_CORRUPTIONを確認する

V$DATABASE_BLOCK_CORRUPTION は、RMANや検査で検出された破損ブロックの情報を確認するビューです。すでに破損が記録されている場合、ファイル番号、ブロック番号、ブロック数、破損タイプを確認できます。

block-corruption-view.sql
SELECT file#,
       block#,
       blocks,
       corruption_change#,
       corruption_type
FROM v$database_block_corruption
ORDER BY file#, block#;

このビューに出ていないから安全、とは限りません。RMAN VALIDATEやDBVERIFYを実行して初めて検出されることがあります。

RMAN VALIDATEで破損を確認する

RMANの VALIDATE は、データファイルやバックアップを読み取り、物理破損や論理破損を確認するために使います。本番では負荷や実行時間を考慮し、対象を絞るかメンテナンス時間帯に実行します。

rman-validate-database.rman
RMAN> VALIDATE DATABASE;

RMAN> VALIDATE CHECK LOGICAL DATABASE;

RMAN> VALIDATE DATAFILE 7;

RMAN> VALIDATE CHECK LOGICAL DATAFILE 7;

CHECK LOGICAL は物理破損だけでなく、行ピースや索引エントリなどの論理破損も確認します。検出後は V$DATABASE_BLOCK_CORRUPTION も再確認します。バックアップ検証全般は バックアップを高速化する方法 も参考になります。

DBVERIFYでデータファイルを検査する

DBVERIFY(dbv)は、データファイルをOSファイルとして検査するユーティリティです。データベース外からファイル単位で確認したい場合に使います。ファイルサイズやI/O負荷が大きい場合があるため、実行タイミングに注意します。

dbverify-example.txt
dbv file=/u01/oradata/ORCL/users01.dbf blocksize=8192 logfile=/tmp/users01_dbv.log

blocksize はデータベースのブロックサイズに合わせます。DBVERIFYの結果とRMAN VALIDATEの結果を突き合わせると、破損範囲を把握しやすくなります。

破損ブロックがどのオブジェクトか調べる

ファイル番号とブロック番号が分かったら、そのブロックがどのセグメントに属するかを確認します。表なのか索引なのかLOBなのかで対応が変わります。

find-segment-by-block.sql
SELECT owner,
       segment_name,
       segment_type,
       partition_name,
       tablespace_name,
       file_id,
       block_id,
       blocks
FROM dba_extents
WHERE file_id = 7
  AND 123456 BETWEEN block_id AND block_id + blocks - 1;

索引セグメントだけが破損している場合、索引再作成で復旧できることがあります。表データブロックやLOBデータの場合は、RMANやバックアップからの復旧を検討します。

原因別の判断フロー

ORA-01578は、原因によって対応が大きく変わります。破損タイプ、対象セグメント、NOLOGGING有無、バックアップの有無を見て判断します。

索引ブロックの破損該当索引を再作成できる可能性があります。制約や業務影響を確認してから実行します。
表データブロックの破損RMANブロックメディアリカバリやデータファイル・表領域復旧を検討します。
LOBブロックの破損該当LOB列、影響行、再投入可否を確認します。アプリ側でファイル再登録が必要な場合もあります。
ORA-26040併発NOLOGGING操作由来の可能性があります。バックアップで戻せない場合、元データから再ロードが必要なことがあります。

復旧方法を選ぶ

索引破損なら再作成で済むことがある

破損セグメントが索引で、元表データが正常なら、索引を再作成することで復旧できる場合があります。ただし、UNIQUE制約や本番負荷、オンライン再構築可否を確認します。

rebuild-index.sql
ALTER INDEX app.ix_orders_01 REBUILD ONLINE;

-- パーティション索引の場合
ALTER INDEX app.ix_orders_01
  REBUILD PARTITION p202605 ONLINE;

索引やパーティション索引の運用は ORA-01502の原因と解決方法 と関連します。

RMANブロックメディアリカバリを検討する

バックアップとアーカイブログが揃っている場合、破損ブロックだけをRMANで復旧できることがあります。実行前に、バックアップの有効性、アーカイブログの範囲、対象がデータファイルかどうかを確認します。

rman-recover-block.rman
RMAN> RECOVER DATAFILE 7 BLOCK 123456;

-- 複数ブロックを指定する例
RMAN> RECOVER DATAFILE 7 BLOCK 123456, 123457, 123458;

-- V$DATABASE_BLOCK_CORRUPTIONに記録された破損ブロックを対象にする例
RMAN> RECOVER CORRUPTION LIST;

ブロックメディアリカバリで戻せない場合は、データファイル単位、表領域単位、または表単位の復旧を検討します。RMANで表領域を復元する流れは RMANで特定の表領域だけを復元する方法 を確認してください。

表単位で退避・再作成する判断

破損範囲が限定的で、表の大部分を読める場合、Data PumpやCTASで読める行を退避し、元データから再投入する選択肢もあります。ただし、破損ブロックを読むSQLは失敗するため、WHERE条件やパーティション単位で切り分けます。

salvage-readable-partition.sql
-- 破損していないパーティションを退避する例
CREATE TABLE orders_salvage AS
SELECT *
FROM orders PARTITION (p202604);

-- 破損が疑われるパーティションは別途RMANや再ロードを検討する

Data Pumpで表単位に退避・復旧する方法は Data Pump完全ガイド指定したテーブルのみリストアする方法 が関連します。

ORA-26040が併発する場合

ORA-26040: Data block was loaded using the NOLOGGING option が併発する場合、NOLOGGINGまたはUNRECOVERABLE操作で生成されたブロックが、リカバリ先で復元できない状態になっている可能性があります。この場合、通常のREDO適用ではデータを復元できないため、元データから再ロードする必要が出ることがあります。

nologging-risk.sql
-- 高速ロード例。障害復旧要件とセットで判断する
INSERT /*+ APPEND */ INTO sales
SELECT *
FROM sales_stage;

-- NOLOGGINGオブジェクトの確認
SELECT owner,
       table_name,
       logging
FROM dba_tables
WHERE logging = 'NO'
ORDER BY owner, table_name;

APPENDやNOLOGGINGを使う場合は、ロード後にバックアップを取得する、FORCE LOGGINGを検討する、Data Guard構成では影響を確認する、といった運用が必要です。APPENDは ダイレクト・パス・インサート完全ガイド も関連します。

Data Guard環境での注意点

NOLOGGING操作は、プライマリでは読めてもスタンバイ側でORA-01578/ORA-26040として見えることがあります。Data Guardを使っている場合は、プライマリとスタンバイの両方で破損状況を確認します。

dataguard-corruption-check.sql
SELECT file#,
       block#,
       blocks,
       corruption_type
FROM v$database_block_corruption
ORDER BY file#, block#;

SELECT force_logging
FROM v$database;

NOLOGGINGを許可するかどうかは、復旧要件、スタンバイ運用、ロード後バックアップのタイミングとセットで決めます。

やってはいけない対応

OSコピーでデータファイルを置き換える制御ファイルやSCNと不整合になり、障害を広げる可能性があります。RMAN手順で対応します。
破損表をすぐDROPする復旧可能性や影響範囲を失います。まず対象ブロックとバックアップを確認します。
NOLOGGINGを常用する復旧不能ブロックのリスクがあります。ロード後バックアップやFORCE LOGGINGを検討します。
VALIDATEを一度も回さないバックアップがあっても、戻せるか検証していなければ安心できません。

本番対応チェックリスト

  • ORA-01578とORA-01110のファイル番号・ブロック番号を控えた
  • V$DATABASE_BLOCK_CORRUPTION を確認した
  • RMAN VALIDATEまたはDBVERIFYで破損範囲を確認した
  • DBA_EXTENTS で破損ブロックの所属セグメントを確認した
  • 表、索引、LOB、UNDO、NOLOGGING由来のどれかを切り分けた
  • 索引破損なら再作成で済むか検討した
  • 表データ破損ならRMANブロックメディアリカバリを検討した
  • ORA-26040併発時はNOLOGGING操作と再ロード元データを確認した
  • Data Guard環境ではスタンバイ側の破損も確認した
  • 復旧後にRMAN VALIDATEと業務確認を実施した

再発防止

ORA-01578の再発防止では、バックアップを取るだけでは足りません。定期的にRMAN VALIDATEを実行し、バックアップが戻せること、破損ブロックが早期に検知できることを確認します。

scheduled-validate.rman
RMAN> BACKUP VALIDATE CHECK LOGICAL DATABASE;

RMAN> VALIDATE CHECK LOGICAL DATABASE;

アーカイブログ領域が詰まると復旧にも影響するため、FRAとアーカイブログ管理も重要です。FRA不足は ORA-00257完全ガイド、表領域設計は Oracle表領域完全ガイド が関連します。

まとめ

ORA-01578は、Oracleがデータブロック破損を検出した時のエラーです。まずORA-01110のファイル番号とブロック番号を控え、V$DATABASE_BLOCK_CORRUPTION、RMAN VALIDATE、DBVERIFYで破損範囲を確認します。

復旧方法は、破損対象が索引なのか、表データなのか、LOBなのか、NOLOGGING由来なのかで変わります。本番では、RMANバックアップ、アーカイブログ、Data Pump退避、元データ再ロード、Data Guardへの影響まで含めて判断しましょう。