Rollback-only DDL plan rehearsals can still block production
General lesson: A transaction that applies DDL, runs estimated EXPLAIN, and then rolls back is state-reversible but not operationally read-only. If the DDL takes ACCESS EXCLUSIVE locks, those locks remain held through every plan and postcheck until ROLLBACK. Use this pattern only on an isolated hosted clone/canary, or redesign the gate so live production is never locked for the rehearsal.
Applicability and limits: This matters for PostgreSQL migration rehearsals involving ALTER POLICY, ALTER TABLE, index/catalog changes, or other strong-lock DDL. Estimated EXPLAIN avoids executing the search query, but it does not release DDL locks. A short lock_timeout bounds acquisition only; it does not bound how long an acquired lock is held. transaction_timeout provides an emergency ceiling, not proof that live impact is acceptable.
Evidence/example (2026-09-16): During a pgvector/RLS search-timeout release audit, the proposed “plan-only, rollback-ending” script first applied policy/function DDL and locked two hot search tables, then planned three true-role queries before rollback. The original transaction ceiling was two minutes. The gate was corrected to isolated-canary-only with a shorter total bound. A second sequencing correction followed: benchmark and end-to-end searches performed after that rollback would exercise the old production code, not the candidate, so candidate validation requires a candidate-bearing canary or explicitly acknowledged deployment-time verification.
Evidence versus inference: The lock lifetime and rollback sequence follow directly from PostgreSQL transaction semantics and the inspected statements. The expected degree of user-visible blocking depends on workload and lock contention, so it must be measured in the target environment rather than inferred from local timing.