Repository navigation
fix(services): give managed PostgreSQL a larger shared memory ceiling - #220
Merged
Merged
Conversation
Docker's default 64 MiB /dev/shm is too small for PostgreSQL's parallel query segments, which fail with "could not resize shared memory segment". Managed PostgreSQL now gets 1 GiB, or a quarter of a positive memory limit clamped to 256 MiB-1 GiB and never more than half the limit. A zero or unparseable limit keeps the 1 GiB default. The tmpfs allocates nothing up front; used pages count against mem_limit, hence the fraction. Existing services pick it up on the next ob service apply. PostgreSQL services with declared extensions are recreated by the first ob deploy after upgrading, because deploy converges them and shm_size changed. Claude-Session: https://claude.ai/code/session_019ifKpdgURZKS36s78SCmx5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this changes
Managed PostgreSQL ran with Docker's default 64 MiB
/dev/shm. PostgreSQL's parallel queries put their dynamic shared memory segments there (dynamic_shared_memory_type = posix), so a large parallel hash join or sort fails withcould not resize shared memory segment.The generated service document for every managed PostgreSQL service (the Onebox-owned 18 image and the older official images) now sets
shm_size:resources.memorylimit, or with a zero limit (which Docker treats as unlimited).mem_limitis still emitted verbatim for the existing validation path.The tmpfs allocates nothing up front, but pages PostgreSQL writes there count against the container's memory cgroup, which is why the ceiling is a fraction of the limit. The half-limit bound keeps small limits (128 MB, 256 MB) from getting a
/dev/shmthat could fill the whole cgroup and OOM-kill a backend, where the old 64 MiB default would have failed only the query.No other driver changes. No project-file field is added.
The add-a-database guide documents the ceiling and corrects two statements this change made visible as wrong: that
ob deploynever creates or replaces a service container, and that no deploy can stop a service. Deploy converges PostgreSQL services with declared extensions withdocker compose up -d, so it recreates them when their rendered configuration changes.No issue was filed first.
Closes #
Why this is correct
TestPostgresSharedMemoryrenders the service document for: no resources, empty resources, CPU-only,1B,128MB,256MB,512MB,0B,1GB(floor boundary),2GB,1.5GB,4GB(cap boundary),8GB, an overflowing999999999999999999999999TB, and the official version 17 image. It asserts the unmarshalledshm_sizeand thatmem_limitis exactly the authored value.TestOtherServicesHaveNoSharedMemoryOverrideasserts every other managed driver renders noshm_size, with and without a memory limit.types.UnitBytes, the same parser Compose applies tomem_limit. docker/go-units converts the parsed float toint64without an overflow check; on amd64 an out-of-range value becomesMinInt64(arm64 saturates toMaxInt64). A decoded limit of zero or below therefore falls back to 1 GiB, so the result is positive on both architectures.internal/app/testdata/contract-verdicts.json: only the nine PostgreSQL service hashes changed; application hashes, other service hashes, verdicts and error codes are unchanged.just check(fmt, vet, fullgo test ./..., generated docs, site build). Not run: the Docker e2e suite, and the tests on amd64 (the amd64 overflow path was reasoned from source; CI is its first execution).Effect on the safety envelope
Managed PostgreSQL containers get a larger
/dev/shmceiling. Running services keep their current one until recreated: byob service apply, or, for PostgreSQL services with declared extensions, by the firstob deployafter upgrading, because deploy converges those services and their rendered configuration changed. That recreation restarts the database. No/status/capabilitieschange.Checklist
just checkpasses locally.just checkverifies this).https://claude.ai/code/session_019ifKpdgURZKS36s78SCmx5