database
resource_error
ai_generated
true
psycopg2.OperationalError: ERROR: out of shared memory HINT: You might need to increase max_locks_per_transaction.
ID: database/postgresql-too-many-snapshots
78%Fix Rate
89%Confidence
1Evidence
2024-04-18First Seen
Version Compatibility
| Version | Status | Introduced | Deprecated | Notes |
|---|---|---|---|---|
| PostgreSQL 14 | active | — | — | — |
| PostgreSQL 15 | active | — | — | — |
| PostgreSQL 16 | active | — | — | — |
Root Cause
PostgreSQL's shared memory for lock management is exhausted, typically because too many concurrent transactions hold locks or snapshots, exceeding the max_locks_per_transaction * max_connections limit.
generic中文
PostgreSQL 用于锁管理的共享内存耗尽,通常是因为太多并发事务持有锁或快照,超过了 max_locks_per_transaction * max_connections 的限制。
Official Documentation
https://www.postgresql.org/docs/16/runtime-config-resource.html#GUC-MAX-LOCKS-PER-TRANSACTIONWorkarounds
-
85% success Increase max_locks_per_transaction in postgresql.conf (e.g., to 128 or 256), then restart PostgreSQL. Verify with SHOW max_locks_per_transaction;. Also consider reducing the number of concurrent long-running transactions.
Increase max_locks_per_transaction in postgresql.conf (e.g., to 128 or 256), then restart PostgreSQL. Verify with SHOW max_locks_per_transaction;. Also consider reducing the number of concurrent long-running transactions.
-
80% success Identify and terminate idle-in-transaction sessions that hold locks: SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE state = 'idle in transaction' AND xact_start < now() - interval '10 minutes';
Identify and terminate idle-in-transaction sessions that hold locks: SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE state = 'idle in transaction' AND xact_start < now() - interval '10 minutes';
中文步骤
Increase max_locks_per_transaction in postgresql.conf (e.g., to 128 or 256), then restart PostgreSQL. Verify with SHOW max_locks_per_transaction;. Also consider reducing the number of concurrent long-running transactions.
Identify and terminate idle-in-transaction sessions that hold locks: SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE state = 'idle in transaction' AND xact_start < now() - interval '10 minutes';
Dead Ends
Common approaches that don't work:
-
Restart PostgreSQL to clear the shared memory, assuming it's a temporary leak
85% fail
If the workload pattern (e.g., many concurrent long-running transactions) remains the same, the error will recur quickly after restart.
-
Increase max_connections instead of max_locks_per_transaction
75% fail
max_connections increases the number of possible connections but does not increase the lock space per connection; the shared memory limit is still bounded by max_locks_per_transaction * max_connections.