私たちのデータベースは壊れているようで、通常は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に接続されているクライアントはありません。
重複する行を検索する前に、次のパラメーターを使用してサーバーを起動することをお勧めします。
enable_indexscan = off
enable_bitmapscan = off
ignore_system_indexes = on
サーバーがクラッシュした場合、インデックスはテーブルデータの異なる状態にある可能性があります。これは、たとえば、破損がトランザクションの可視性(pg_clog
)に影響を与える場合に発生します。次に、コメントに記載されているように、pg_class
またはpg_statistic
で重複する行を検索します。
pg_statistic
のクリーンアップを試みることもできます。まず、次のコマンドでサーバーを起動します。
allow_system_table_mods = on
その後、TRUNCATE TABLE
とANALYZE
を発行します。
--Cleaning pg_statistic
TRUNCATE TABLE pg_catalog.pg_statistic;
--Analyze entire database
ANALYZE VERBOSE;
問題がpg_statisticにある場合は、これで十分です。