どのようにして起こったのかは詳しく説明していませんが、すべて破損したDBから始まりました。ファイルシステムレベルでは問題ありませんでしたが、次のことを試みました。
_select count(*) from mytable
_
結果は次のとおりです。
エラー:ファイル "pg_tblspc/16386/PG_9.6_201608131/16385/16506.1"のブロック257798を読み取れませんでした:8192バイトのうち0のみを読み取りました
テーブルは非常に大きく(〜200GB)、バイナリデータを含むいくつかのbytea
列が含まれています。更新されることはなく、挿入と選択のみが行われます。私はその上でpg_dumpを実行しました。それは長い間動作しており、約200GBのファイルを生成しましたが、最終的に同様のエラーで失敗しました:
_pg_dump -Z9 -Fc -d mydatabase -t mytable -v -f /datadir/mytable.backup
_
pg_dump:テーブル "mytable"の内容のダンプに失敗しました:PQgetResult()が失敗しました。
pg_dump:サーバーからのエラーメッセージ:エラー:ファイル "pg_tblspc/16386/PG_9.6_201608131/16385/16506.1"のブロック257798を読み取れませんでした:8192バイトのうち0のみを読み取りました
pg_dump:コマンドは次のとおりです。COPYpublic.mytable(id、account_id、fetched、col1、col2、col3、col4、col5)TO stdout;
それから私はそれを復元しようとしました、再びそれは長い時間働いていました、結局それはそのテーブルスペースに〜200GBのスペースを取ったが、select count(*) from mytable
は_0
_を返します。
_ pg_restore -Fc -d mydatabase -v /datadir/mytable.backup
_
pg_restore:テーブル "public.mytable"のデータを処理しています
そして久しぶり
pg_restore:入力ファイルから読み取れませんでした:ファイルの終わり
サーバー側では、これは次の結果になりました:
エラー:ユーザーの要求によりステートメントをキャンセルしています
コンテキスト:コピーmytable、行14497030
ステートメント:コピーmytable(id、account_id、fetched、col1、col2、col3、col4、col5)FROM stdin
ログ:クライアントにデータを送信できませんでした:接続がピアによってリセットされました
致命的:クライアントへの接続が失われました
操作全体を中止するように要求されたpg_restoreのようです。
できるだけ多くの行を回復したいのですが、すべてのデータは基本的に不変であるため、まだそこにあるはずであり、最後のレコードだけが破損していると思います。
障害が発生するまで復元されたレコードをPostgresに保持させる方法はありますか?
私はあなたが次の線に沿って何かをしようとすることをお勧めします:
SELECT count(*) FROM mytable WHERE my_primary_key < value ;
...そして、それが失敗した時点で見つけます。 [これは面倒かもしれませんが、最初に失敗する値が見つかるまで、繰り返し半分にカットすることができます。]
テーブルの99%を実際にスキャンする必要がある場合でも、実際にはデータベースにseインデックスを強制するため、インデックスの使用に影響するさまざまな設定を変更する必要があります。 notboomsのページをスキャンしたい。
SELECT
を取得してほとんどのデータを取得できる場合は、次のようなことを行うことができます。
CREATE TABLE my_table_2 AS
SELECT * FROM my_table WHERE my_primary_key < value;
以降:
ALTER TABLE my_table RENAME TO my_table_old ;
ALTER TABLE my_table_2 RENAME TO my_table ;
...そして、取得できるすべてのデータが手に入ります。誰かが後で不足している情報を取得するより良い方法を見つけた場合に備えて、古いテーブルを削除しません。
幸運を祈ります。