ban-cluster
CLUSTER rewrites the entire table under ACCESS EXCLUSIVE lock.
- operation
- Tables
- lock taken
- ACCESS EXCLUSIVE
- remediation
- Manual rewrite
- category
- Lock safety
- Blocks reads
- Blocks writes
- Rewrites the table
- Can stall the lock queue
What triggers it
Fires on any ClusterStmt — every CLUSTER statement, with or without an explicit USING index target.
What does not
Only non-ClusterStmt statements are skipped. There are no further conditions: every CLUSTER statement is flagged.
Where it applies
Applies to every PostgreSQL version MigrationPilot targets. It works on the SQL text alone — no database connection needed.
The lock, and what it blocks
CLUSTER rewrites the physical storage of the table in index order, holding ACCESS EXCLUSIVE for the entire rewrite — every reader and writer is blocked until the last row is copied and the old storage is swapped in.
Why it matters
CLUSTER physically reorders all table rows to match an index, requiring a full table rewrite under ACCESS EXCLUSIVE. Use pg_repack for online table clustering.
Unsafe, and safe
Flagged
CLUSTER users USING idx_users_created;Safe alternative
-- Use pg_repack for online clusteringWhat it assumes
Assumes the table is large enough that the rewrite duration matters; on a small table CLUSTER finishes almost instantly, and the rule has no size signal to distinguish that case.
What the CLI prints
✗ [MP032] CRITICAL (line 1) CLUSTER on "users" USING "idx_users_created" rewrites the entire table under ACCESS EXCLUSIVE lock. This blocks ALL reads and writes for the entire duration. Safe alternative: -- Use pg_repack for online table reorganization (no ACCESS EXCLUSIVE lock): -- Install: CREATE EXTENSION pg_repack; -- Run: pg_repack --table users --order-by idx_users_created --no-superuser-check Why: CLUSTER physically reorders all rows in the table to match an index, requiring a full table rewrite under ACCESS EXCLUSIVE lock. On large tables this can take hours, blocking all reads and writes. Use pg_repack for online table reorganization without blocking. Docs: https://migrationpilot.dev/rules/mp032
Generated by running the CLI's own formatter over the flagged example above, so it is the text the tool actually produces. A real run also reports the other rules that fire on the same statement; those blocks are left out here.
Turning it off
For one statement, put a comment on the line before it:
-- migrationpilot-disable MP032 CLUSTER users USING idx_users_created;
For the whole project, in .migrationpilotrc.yml — by name or by id:
rules:
MP032: false
# or keep it, and downgrade it
rules:
MP032:
severity: warningTry it
Open this rule's flagged example in the playground. It runs in your browser — edit it and watch the finding appear and disappear.
Run MP032 in the playground