こんにちは Slack Overflowvians。
それで、8.3.11を実行しているこのPostgreSQLサーバーに出くわしました(ええ、知っています)、それはロックされた状態でした:
ERROR: database is not accepting commands to avoid wraparound data loss in database "postgres"
HINT: Stop the postmaster and use a standalone backend to vacuum that database.
通常、自動バキューム デーモン ( autovacuum=on
) がこれを処理しますが、次の 4 つの TOAST (パンのような大きなフィールド値 8 kB スライスの格納を許可する) のため、データベース オブジェクト. しかし、これらの破損したデータベース オブジェクトが原因で、このデータベースの XID がリセットされることはありませんでした。
以下は、admin ユーザーを使用してシングルユーザー モードでサーバーを実行したときの出力のスニペットです。
SELECT oid, relname, age(relfrozenxid) FROM pg_class WHERE relkind = 't' ORDER BY age(relfrozenxid) DESC LIMIT 4;
----
1: oid = "2421459" (typeid = 26, len = 4, typmod = -1, byval = t)
2: relname = "pg_toast_2421456" (typeid = 19, len = 64, typmod = -1, byval = f)
3: age = "2146484084" (typeid = 23, len = 4, typmod = -1, byval = t)
----
1: oid = "2421450" (typeid = 26, len = 4, typmod = -1, byval = t)
2: relname = "pg_toast_2421447" (typeid = 19, len = 64, typmod = -1, byval = f)
3: age = "2146484084" (typeid = 23, len = 4, typmod = -1, byval = t)
----
1: oid = "2421435" (typeid = 26, len = 4, typmod = -1, byval = t)
2: relname = "pg_toast_2421432" (typeid = 19, len = 64, typmod = -1, byval = f)
3: age = "2146484084" (typeid = 23, len = 4, typmod = -1, byval = t)
----
1: oid = "2421426" (typeid = 26, len = 4, typmod = -1, byval = t)
2: relname = "pg_toast_2421423" (typeid = 19, len = 64, typmod = -1, byval = f)
3: age = "2146484084" (typeid = 23, len = 4, typmod = -1, byval = t)
vacuum_freeze_min_age
このサーバーでは age が (VACUUM が成功した後に設定された値) をはるかに上回っていることに注意してください。上記はVACUUM FULL
;を実行した後です。他のすべてのテーブルは問題ありません。
SELECT relfilenode FROM pg_class WHERE oid=2421459;
そのため、ディスクを調べたところ (上記の各テーブルに pg_class.relfilenode 値を使用)、トースト テーブルのファイルが見つかりませんでした。
$ find /var/lib/pgsql/data/ -type f -name '2421426' | wc -l # Bad toast
0
トーストのインデックスでディスクを見たとき
SELECT relfilenode FROM pg_class WHERE (select reltoastidxid FROM pg_class WHERE oid=2421459)
$ find /var/lib/pgsql/data/ -type f -name '2421459' | wc -l # Bad toast's index
0
次に、不良トースト レコードが関連付けられているテーブルを見つけようとしました。
SELECT * FROM pg_class WHERE reltoastrelid=2421459;
上記の各テーブルで 0 件の結果が得られました! VACUUM
これらの関係の XID をリセットするコマンド のテーブルはありません。
pg_depend テーブルを確認したところ、これらの TOAST テーブルには参照がないことがわかりました。
SELECT * FROM pg_depend WHERE refobjid IN(2421459,2421450,2421435,2421426)
質問
- pg_class テーブルから不適切な TOAST テーブルと TOAST テーブル インデックスを削除できますか (例
DELETE FROM pg_class where oid=2421459
) - リレーションを削除する必要がある他のテーブルはありますか?
- 一時テーブルを作成して、それを TOAST のインデックスの oid にリンクすることはできますか?
上記の #3 の例:
CREATE TABLE adoptedparent (colnameblah char(1));
UPDATE pg_class SET reltoastrelid=2421459 WHERE relname='adoptedparent';
VACUUM FULL VERBOSE adoptedparent
編集:
select txid_current()
は 3094769499 であるため、これらのテーブルはかなり前に破損しています。データを回復する必要はありません。Linux 2.6.18-238.el5 で ext4 ファイル システムを実行しています。関連するlost+found/
ディレクトリを確認しましたが、ファイルはありませんでした。