Repository navigation
Create partitions with LIKE + ATTACH PARTITION instead of PARTITION OF - #34
codybswaney wants to merge 3 commits into
Conversation
…ION OF CREATE TABLE ... PARTITION OF takes ACCESS EXCLUSIVE on the partitioned parent, so add_partitions/maintain waits behind any open transaction that touched the parent and every query on the parent queues behind it until lock_timeout fires. Create each partition as a standalone table (LIKE parent INCLUDING DEFAULTS CONSTRAINTS STORAGE GENERATED [COMPRESSION]), add the classic per-partition primary key and grants, then ATTACH it, which takes SHARE UPDATE EXCLUSIVE on the parent and does not conflict with DML. ATTACH clones indexes, the parent-owned primary key, foreign keys and row triggers, so the result is catalog-identical to PARTITION OF. A table that already exists under a new partition's name but is not attached now raises an error instead of being skipped silently. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PARTITION OF places a partition in the parent's tablespace when none is given; the standalone CREATE TABLE would fall back to the database default. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| CREATE TABLE t.posts ( | ||
| id varchar NOT NULL, | ||
| author_id int NOT NULL REFERENCES t.authors (id) ON DELETE CASCADE, | ||
| status text NOT NULL DEFAULT 'new' CHECK (status <> ''), | ||
| score int CHECK (score >= 0), | ||
| double_score int GENERATED ALWAYS AS (score * 2) STORED, | ||
| body text, | ||
| created_at timestamp NOT NULL DEFAULT now(), | ||
| PRIMARY KEY (id, created_at) | ||
| ) PARTITION BY RANGE (created_at) |
There was a problem hiding this comment.
Identity columns lack parity coverage The new creation path deliberately omits
INCLUDING IDENTITY, but neither catalog-parity fixture has an identity column. A regression when attaching a partition to an identity-column parent would therefore go unnoticed. Please add an identity-column parent to the parity tests.
Knowledge Base Used: Partitioned table model
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/attach-partition.test.ts
Line: 672-681
Comment:
**Identity columns lack parity coverage** The new creation path deliberately omits `INCLUDING IDENTITY`, but neither catalog-parity fixture has an identity column. A regression when attaching a partition to an identity-column parent would therefore go unnoticed. Please add an identity-column parent to the parity tests.
**Knowledge Base Used:** [Partitioned table model](https://app.greptile.com/workos/-/custom-context/knowledge-base/workos/pgslice/-/docs/partitioned-table-model.md)
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.
Problem
add_partitions/maintaincreate partitions withCREATE TABLE … PARTITION OF, which takes ACCESS EXCLUSIVE on the parent: any open transaction on the parent blocks it, and every later query queues behind it. Today's scheduledmaintainon our production core database hit exactly this: a long-running application transaction held row locks on several parents, every partition creation timed out on the 5slock_timeout,, with ~100 application queries piling up behind each attempt.Solution
Create each partition as a standalone table and attach it:
CREATE TABLE child (LIKE parent INCLUDING DEFAULTS CONSTRAINTS STORAGE GENERATED [COMPRESSION]) [TABLESPACE …]ALTER TABLE parent ATTACH PARTITION child FOR VALUES …ATTACH takes SHARE UPDATE EXCLUSIVE on the parent, which doesn't conflict with DML. ATTACH clones indexes, the parent-owned PK, FKs and row triggers, so INDEXES and IDENTITY (per-partition sequences) are left out of LIKE. The child is empty, so validation is free. It's still one transaction under
lock_timeoutand the UTC pin. Without--tablespace, the parent's tablespace carries over (as withPARTITION OF). An existing but unattached table with a new partition's name is now an error, not a silent skip that left a coverage hole.What we validated
I ran the full suite on postgres:13.20 and 18.4: 410 pass, plus 2 tablespace tests run against a real tablespace on 13. The new
src/attach-partition.test.tsuses committed tables and multiple connections to cover:pg_locksmode while ATTACH waits, with concurrent INSERTs completingPARTITION OF(attributes, constraints incl. inbound/outbound FKs, indexes, triggers, ACLs incl. PUBLIC, tablespace), which is identicalWhat reviewers need to know
This doesn't remove every lock. Cloning an outbound FK still takes SHARE ROW EXCLUSIVE on the referenced table, and that's true of
PARTITION OFtoo. An open transaction that wrote the referenced table still blocks creation, and writes to that table queue for up tolock_timeout. Reads and writes on the partitioned table itself keep flowing. When the blocker also writes the FK target, runs will still time out, just without stalling the partitioned table. A DEFAULT partition still gets ACCESS EXCLUSIVE and a scan, same as before. The README now documents both.Rollout and validation
Merging doesn't change production. Bumping the image pin in the Terrace
pgsliceapp (pgslice:<sha>) is what promotes this. After that, re-runmaintain-coremanually and confirm every table extends and no AccessExclusiveLock waits show up on the parents.🤖 Generated with Claude Code