ALTER TABLE .. DETACH PARTITION CONCURRENTLY
Alvaro Herrera <alvherre@2ndquadrant.com>
From: Alvaro Herrera <alvherre@2ndquadrant.com>
To: Pg Hackers <pgsql-hackers@lists.postgresql.org>
Date: 2020-08-03T23:48:54Z
Lists: pgsql-hackers
Attachments
I've been working on the ability to detach a partition from a partitioned table, without causing blockages to concurrent activity. I think this operation is critical for some use cases. There was a lot of great discussion which ended up in Robert completing a much sought implementation of non-blocking ATTACH. DETACH was discussed too because it was a goal initially, but eventually dropped from that patch altogether. Nonetheless, that thread provided a lot of useful input to this implementation. Important ones: [1] https://postgr.es/m/CA+TgmoYg4x7AH=_QSptvuBKf+3hUdiCa4frPkt+RvXZyjX1n=w@mail.gmail.com [2] https://postgr.es/m/CA+TgmoaAjkTibkEr=xJg3ndbRsHHSiYi2SJgX69MVosj=LJmug@mail.gmail.com [3] https://postgr.es/m/CA+TgmoY13KQZF-=HNTrt9UYWYx3_oYOQpu9ioNT49jGgiDpUEA@mail.gmail.com Attached is a patch that implements ALTER TABLE ... DETACH PARTITION .. CONCURRENTLY. In the previous thread we were able to implement the concurrent model without the extra keyword. For this one I think that won't work; my implementation works in two transactions so there's a restriction that you can't run it in a transaction block. Also, there's a wait phase that makes it slower than the non-concurrent one. Those two drawbacks make me think that it's better to keep both modes available, just like we offer both CREATE INDEX and CREATE INDEX CONCURRENTLY. Why two transactions? The reason is that in order for this to work, we make a catalog change (mark it detached), and commit so that all concurrent transactions can see the change. A second transaction waits for anybody who holds any lock on the partitioned table and grabs Access Exclusive on the partition (which now no one cares about, if they're looking at the partitioned table), where the DDL action on the partition can be completed. ALTER TABLE is normally unable to run in two transactions. I hacked it (0001) so that the relation can be closed and reopened in the Exec phase (by having the rel as part of AlteredTableInfo: when ATRewriteCatalogs returns, it uses that pointer to close the rel). It turns out that this is sufficient to make that work. This means that ALTER TABLE DETACH CONCURRENTLY cannot work as part of a multi-command ALTER TABLE, but that's alreay enforced by the grammar anyway. DETACH CONCURRENTLY doesn't work if a default partition exists. It's just too problematic a case; you would still need to have AEL on the default partition. I haven't yet experimented with queries running in a standby in tandem with a detach. -- Álvaro Herrera
Commits
-
Make detach-partition-concurrently-4 less timing sensitive
- eb43bdbf5104 14.0 landed
-
Improve documentation on DETACH PARTITION lock levels
- db6e1aeb952e 14.0 landed
-
Track detached partitions more accurately in partdescs
- 3fe773b14975 14.0 landed
-
Allow a partdesc-omitting-partitions to be cached
- d6b8d29419df 14.0 landed
-
Fix relcache inconsistency hazard in partition detach
- 8aba9322511f 14.0 landed
-
Don't add a redundant constraint when detaching a partition
- 7b357cc6ae55 14.0 landed
-
ALTER TABLE ... DETACH PARTITION ... CONCURRENTLY
- 71f4c8c6f74b 14.0 landed
-
Let ALTER TABLE Phase 2 routines manage the relation pointer
- cd03c6e94b09 14.0 landed
-
Check default partitions constraints while descending
- f481d2823297 14.0 landed
- ef1e1250e716 12.5 landed
- d0230a43fcae 13.0 landed