fix(postgres): raise max_locks_per_transaction to 256

GitLab's migration on its dedicated postgres sidecar failed in CI run
35674334334 with "ERROR: out of shared memory" and the hint to raise
max_locks_per_transaction. The default of 64 locks per transaction cannot
cover a schema that locks thousands of tables and indexes in one
transaction: a reproduction on postgres:18 failed at table 7453 with the
default and held 20000 tables at 256.

The value sits next to the other postgres tuning constants in the
resource lookup, is exposed as POSTGRES_MAX_LOCKS_PER_TRANSACTION, and
reaches both the central svc-db-postgres command and the per-app sidecar.
The sidecar's new command keeps the image entrypoint and only adds the
flag. The shared lock table grows to about 256 x max_connections entries,
roughly 30 MB at the 400-connection cap.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
kevinveenbirkenbachandClaude Opus 5 committed 2026-09-22 15:52:16 +02:00
1 parent 888e51b42e
commit 7690d2ca6d
4 files changed
+9

No files matched your search

+1
View File
@@ -15,6 +15,7 @@ POSTGRES_SUPERUSER_RESERVED_CONNECTIONS: "{{ lookup('resource', 'postgres_superu
POSTGRES_SHARED_BUFFERS: "{{ lookup('resource', 'postgres_shared_buffers') }}"
POSTGRES_WORK_MEM: "{{ lookup('resource', 'postgres_work_mem') }}"
POSTGRES_MAINTENANCE_WORK_MEM: "{{ lookup('resource', 'postgres_maintenance_work_mem') }}"
POSTGRES_MAX_LOCKS_PER_TRANSACTION: "{{ lookup('resource', 'postgres_max_locks_per_transaction') }}"
POSTGRES_DELAY: "{{ lookup('resource', 'postgres_delay') }}"
TIMEOUT_FACTOR: 1
+2
View File
@@ -21,6 +21,7 @@ _HOST_RESERVE_MEM = 4
_PIDS_LIMIT = 512
_POSTGRES_SUPERUSER_RESERVED_CONNECTIONS = 3
_POSTGRES_DELAY = 2
_POSTGRES_MAX_LOCKS_PER_TRANSACTION = 256
_CONTAINER_PREFIX_REGEX = r"^(web-|svc-).*"
@@ -192,6 +193,7 @@ def _build(
"postgres_maintenance_work_mem_mb": maintenance_work_mem_mb,
"postgres_maintenance_work_mem": f"{maintenance_work_mem_mb}MB",
"postgres_delay": _POSTGRES_DELAY,
"postgres_max_locks_per_transaction": _POSTGRES_MAX_LOCKS_PER_TRANSACTION,
}
if containers is not None:
@@ -16,6 +16,8 @@
- "work_mem={{ POSTGRES_WORK_MEM }}"
- "-c"
- "maintenance_work_mem={{ POSTGRES_MAINTENANCE_WORK_MEM }}"
- "-c"
- "max_locks_per_transaction={{ POSTGRES_MAX_LOCKS_PER_TRANSACTION }}"
{% include 'roles/sys-svc-container/templates/base.yml.j2' %}
{{ lookup('container_healthcheck', service_name) | indent(4) }}
@@ -15,6 +15,10 @@
{% else %}
{{ lookup('container_image', 'svc-db-postgres', 'postgres', image=lookup('database', application_id, 'image'), version=lookup('database', application_id, 'version')) }}
{% endif %}
command:
- "postgres"
- "-c"
- "max_locks_per_transaction={{ POSTGRES_MAX_LOCKS_PER_TRANSACTION }}"
env_file:
- {{ lookup('database', application_id, 'env') }}
{{ lookup('compose_restart') }}