web-dev-qa-db-ja.com

PostgreSQL「タプルはすでに自己更新されています」

私たちのデータベースは壊れているようで、通常はCPUの約1〜2%を使用しますが、1,000万行のテーブルに対してUPDATEおよびINSERTクエリを実行する追加のバックエンドサービスを実行すると(3秒あたり約1クエリ)、すべてが地獄になります( CPU使用率が2%から98%に増加)。

何が起こっているのかをデバッグし、VACUUMとANALYZEを実行して、dbの何が問題になっているのかを知ることにしましたが...

production=# ANALYZE VERBOSE users_user;
INFO:  analyzing "public.users_user"
INFO:  "users_user": scanned 280 of 280 pages, containing 23889 live rows and 57 dead rows; 23889 rows in sample, 23889 estimated total rows
INFO:  analyzing "public.users_user"
INFO:  "users_user": scanned 280 of 280 pages, containing 23889 live rows and 57 dead rows; 23889 rows in sample, 23889 estimated total rows
ERROR:  Tuple already updated by self

どのテーブルでもANALYZEを終了できず、この問題に関する情報を見つけることができませんでした。何が間違っている可能性があるか提案はありますか?

 PostgreSQL 9.6.8 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-16), 64-bit

コメントで要求された追加情報:

Pg_classが破損している可能性があります

SELECT * FROM pg_class WHERE relname = 'users_user';

出力: https://Pastebin.com/WhmkH34

したがって、最初に行うことは、他のすべてのセッションを開始して再試行することです。

追加のセッションはありません。DB全体を新しいテストサーバーにダンプしましたが、問題は引き続き発生します。このDBに接続されているクライアントはありません。

19
Damian Gądziak

重複する行を検索する前に、次のパラメーターを使用してサーバーを起動することをお勧めします。

enable_indexscan = off
enable_bitmapscan = off
ignore_system_indexes = on

サーバーがクラッシュした場合、インデックスはテーブルデータの異なる状態にある可能性があります。これは、たとえば、破損がトランザクションの可視性(pg_clog)に影響を与える場合に発生します。次に、コメントに記載されているように、pg_classまたはpg_statisticで重複する行を検索します。

pg_statisticのクリーンアップを試みることもできます。まず、次のコマンドでサーバーを起動します。

allow_system_table_mods = on

その後、TRUNCATE TABLEANALYZEを発行します。

--Cleaning pg_statistic
TRUNCATE TABLE pg_catalog.pg_statistic;
--Analyze entire database
ANALYZE VERBOSE;

問題がpg_statisticにある場合は、これで十分です。

6
Michel Milezzi