PostgreSQLの16ロック問題、18で解消
Sixteen Locks Ought to Be Enough for Anybody
PostgreSQLはクエリ実行時、使用の有無にかかわらずテーブル上の全インデックスにAccessShareLockを取得する。インデックスが16個を超えると、高速パスロックの枠から溢れた分が共有ロックテーブルを経由し、高負荷時にLWLock:LockManagerの競合を引き起こす。PostgreSQL 18ではfast-path配列がmax_locks_per_transactionに応じて拡張され、この問題が解消される。根本的な対策は不要なインデックスの削除だ。
16個だ。自分のインデックスを数えてみてほしい。クエリが16個を超えるリレーションロックを必要とすると、溢れた分は共有ロックテーブルを通り、LWLockもろとも処理される。