Skip to content

Commit 7dac010

Browse files
committed
fix(helm-prereqs): size the postgres default for the fleet, and warn when it is too small
The default was 4Gi, and at 4,500 hosts that is not survivable. Postgres running out of memory does not degrade gracefully: the kernel OOM-kills a backend, the postmaster crash-recovers, and every open connection is dropped with in-flight transactions rolled back. Measured on a 4,500-host (13,500 machine) ingestion: 4Gi -> 99.96% memory, 531 OOM kills, 112 crash-recoveries, never completed 24Gi -> ~8.7GiB peak, zero OOM kills, full fleet ingested with every machine reaching ready (reproduced across three runs at 54-56 machines/min) The node had 240GB free, so this was a configured limit rather than a hardware constraint. What made it expensive is that the failure presents downstream: three separate issues were filed as product defects during the period it was in effect (readiness plateau #4750, cleanup panic #4753, and a Postgres deadlock) and none reproduced once the memory was adequate. Days went into tracing individual state machines before the memory pressure was noticed. Raise the default to 16Gi/8CPU (production is documented as 32 CPU / 16Gi, so this aligns rather than exceeds it) and replace the 'tune down for dev clusters' comment -- which reads as though 4Gi is a safe dev value -- with fleet-size guidance and the one-line cgroup check that identifies this condition. Also warn in setup-machine-a-tron.sh Phase 0 when the live limit is below what the requested host count wants, so an undersized database is visible at minute zero instead of hour three. The warning names the reinstall requirement too: teardown deletes the postgres namespace, so a resize applied to a live cluster before a reinstall is silently reverted. Fixes #4839
1 parent 52b85cc commit 7dac010

2 files changed

Lines changed: 62 additions & 5 deletions

File tree

helm-prereqs/setup-machine-a-tron.sh

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,35 @@ for _pw in "$BMC_PASSWORD" "$UEFI_DPU_PASSWORD" "$UEFI_HOST_PASSWORD"; do
358358
done
359359
info "image: ${MAT_IMAGE_REPO}:${MAT_IMAGE_TAG} hosts: ${HOST_COUNT} dpus/host: ${DPU_PER_HOST}"
360360

361+
# GOTCHA: Postgres out-of-memory does not degrade gracefully. The kernel kills a
362+
# backend, the postmaster crash-recovers, and every connection is dropped with
363+
# in-flight transactions rolled back. Downstream that presents as stalled machine
364+
# readiness, controller panics and deadlocks, so the real cause is easy to miss.
365+
# A 4,500-host run against the old 4Gi default logged 531 OOM kills and never
366+
# completed; the same run at 24Gi peaked at ~8.7GiB with zero kills. Warn here so
367+
# an undersized database is visible at minute zero rather than hour three.
368+
_pg_mem="$(kubectl get postgresql -n "${POSTGRES_NS:-postgres}" nico-pg-cluster \
369+
-o jsonpath='{.spec.resources.limits.memory}' 2>/dev/null || true)"
370+
if [[ -n "$_pg_mem" ]]; then
371+
_pg_gib="${_pg_mem%Gi}"
372+
if [[ "$_pg_mem" == *Mi ]]; then _pg_gib=$(( ${_pg_mem%Mi} / 1024 )); fi
373+
if [[ "$_pg_gib" =~ ^[0-9]+$ ]]; then
374+
# Same rough scale as the guidance in helm-prereqs/values.yaml.
375+
_pg_want=4
376+
(( HOST_COUNT > 500 )) && _pg_want=8
377+
(( HOST_COUNT > 1500 )) && _pg_want=16
378+
(( HOST_COUNT > 5000 )) && _pg_want=32
379+
if (( _pg_gib < _pg_want )); then
380+
warn "postgres memory limit is ${_pg_mem} but ${HOST_COUNT} hosts wants >= ${_pg_want}Gi"
381+
warn " undersized postgres OOM-kills under load and breaks ingestion in ways that look unrelated"
382+
warn " raise postgresql.resources.limits.memory in helm-prereqs/values.yaml and reinstall"
383+
warn " (a resize applied before teardown is reverted: teardown deletes the postgres namespace)"
384+
else
385+
ok "postgres memory ${_pg_mem} is adequate for ${HOST_COUNT} hosts (>= ${_pg_want}Gi)"
386+
fi
387+
fi
388+
fi
389+
361390
# =============================================================================
362391
# Phase 1 — namespace
363392
# =============================================================================

helm-prereqs/values.yaml

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -193,11 +193,39 @@ postgresql:
193193
## Points at the operator-managed Service in the postgres namespace.
194194
host: "nico-pg-cluster.postgres.svc.cluster.local"
195195
## Resource limits for each postgres instance.
196-
## Production uses 32 CPU / 16Gi — tune down for dev clusters.
196+
##
197+
## SIZE THIS TO THE FLEET. Postgres running out of memory does not degrade
198+
## gracefully: the kernel OOM-kills a backend, the postmaster performs a full
199+
## crash-recovery, and every open connection is dropped with in-flight
200+
## transactions rolled back. Downstream that looks like unrelated defects --
201+
## stalled machine readiness, controller panics, deadlocks -- so the real
202+
## cause is easy to miss.
203+
##
204+
## Measured on a 4,500-host (13,500 machine) ingestion:
205+
## 4Gi limit -> 99.96% memory, 531 OOM kills, 112 crash-recoveries,
206+
## ingestion unable to complete
207+
## 24Gi limit -> ~8.7GiB peak, zero OOM kills, full fleet ingested and
208+
## every machine reaching ready
209+
##
210+
## Rough guidance (limits.memory), assuming ~3 machines per host:
211+
## up to 500 hosts 4Gi
212+
## up to 1,500 hosts 8Gi
213+
## up to 5,000 hosts 16Gi <- default below
214+
## beyond 32Gi, and measure
215+
##
216+
## To check a running cluster:
217+
## kubectl exec -n postgres <pod> -c postgres -- sh -c \
218+
## 'cat /sys/fs/cgroup/memory.current /sys/fs/cgroup/memory.max; \
219+
## grep oom_kill /sys/fs/cgroup/memory.events'
220+
## A non-zero and rising oom_kill count means everything downstream is a
221+
## symptom of this.
222+
##
223+
## NOTE: teardown deletes the postgres namespace, so a resize applied before
224+
## a reinstall is silently reverted. Change it here, not on the live cluster.
197225
resources:
198226
limits:
199-
cpu: "4"
200-
memory: "4Gi"
227+
cpu: "8"
228+
memory: "16Gi"
201229
requests:
202-
cpu: "500m"
203-
memory: "1Gi"
230+
cpu: "2"
231+
memory: "4Gi"

0 commit comments

Comments
 (0)