web-dev-qa-db-ja.com

破損したデータベースのpostgresqlを修復する

電力サージ後に発生したpostgresql dbで複数のエラーが発生しました。

データベースからほとんどのテーブルにアクセスできません。たとえばselect * from ac_cash_collection、foolowingエラーが発生します。

エラー:pg_toast_2619のトースト値118486855のチャンク番号0がありません

pg_dumpを実行すると、次のエラーが発生します。

サーバーからのエラーメッセージ:エラー:関係 "public.st_stock_item_newlist"は存在しません
 pg_dump:コマンドは次のとおりです:LOCK TABLE public.st_stock_item_newlist IN ACCESS SHARE MODE 

私は先に進み、データベース全体のインデックス再作成を実行しようとしましたが、実際にはそれを実行したままにし、スリープ状態になり、午前中に何も実行していなかったので、キャンセルする必要がありました。

私はこれをできるだけ早く修正するためにいくつかの助けが必要です、助けてください。

16
Jeff Lee Ngotho

実行する前に何かその他、 http://wiki.postgresql.org/wiki/Corruptionそして指示に基づいて行動します。そうしないと、問題が悪化するおそれがあります。


Fine Manual にリストされている2つの構成パラメーターが役立つかもしれません:ignore_system_indexesおよびzero_damaged_pages。私はそれらを使用したことがありませんが、もし私が絶望的だったら私はそうしました...

彼らがトーストテーブルに役立つかどうかはわかりません。いずれにせよ、これらを設定することでデータベースが再び使用可能になった場合は、{バックアップ+ドロップ+復元}を実行して、すべてのテーブルとカタログを新たな形に戻します。成功!

8
wildplasser

バックアップがある場合は、それらから復元します。

そうでない場合-定期的なバックアップが必要な理由を学んだところである。ハードウェアが誤動作した場合、PostgreSQLができることは何もありません。

さらに、このような状況に再び遭遇した場合は、最初にPostgreSQLを停止し、すべてのテーブルスペース、WALなどのすべての完全なファイルレベルのバックアップを作成します。これにより、既知の開始点が得られます。

だから-あなたはまだいくつかのデータを回復したい場合。

  1. 個々のテーブルをダンプしてみてください。この方法でできることを入手してください。
  2. 問題が発生した場合はインデックスを削除します
  3. テーブルのセクションをダンプします(id = 0..9999、1000..19999など)。これにより、一部の行が破損している可能性のある場所を特定し、さらに小さいセクションをダンプして、まだ良好な状態を回復できます。
  4. 特定の列だけをダンプしてみてください-大きなテキスト値は(トーストテーブルに)行外に格納されるため、それらを回避すると、残りのデータが取り出される可能性があります。
  5. システムテーブルが破損している場合は、多くの作業を行っています。

これは大変な作業であり、回復した結果を調べて監査し、不足しているものや正しくないものを特定する必要があります。

できることは他にもあります(場合によっては空のブロックを作成すると、部分的なデータをダンプできる場合があります)が、それらはすべてより複雑で手間がかかり、データが特に価値がない限り、努力する価値はありません。

これを避けるための重要なメッセージ-定期的にバックアップを取り、それらが機能することを確認してください。

7
Richard Huxton

その他の作業を行う前に、破損したデータベースの完全なファイルシステムレベルのコピーを作成してください。

http://wiki.postgresql.org/wiki/Corruption

これを怠ると、破損の原因に関する証拠が破壊されます。つまり、修復作業がうまくいかず、事態が悪化した場合、元に戻すことはできません。

コピーしてください

1
Craig Ringer