| From: | Manu <manuelreyesbravo(at)gmail(dot)com> |
|---|---|
| To: | shihao zhong <zhong950419(at)gmail(dot)com> |
| Cc: | Alexandre Felipe <o(dot)alexandre(dot)felipe(at)gmail(dot)com>, Andres Freund <andres(at)anarazel(dot)de>, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, Michael Paquier <michael(at)paquier(dot)xyz>, Zsolt Parragi <zsolt(dot)parragi(at)percona(dot)com>, pgsql-hackers(at)lists(dot)postgresql(dot)org |
| Subject: | Re: BUG #19686: Rolling back SET TABLESPACE |
| Date: | 2026-10-18 16:45:31 |
| Message-ID: | 179234193175.237803.1636724777877426621@gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Hi Shihao,
> One correction. v7 copies the indexes in their own tablespace, so the
> room is needed on the old volume, not the destination.
You're right -- thanks for catching it. My earlier "destination tablespace"
was wrong, and I measured it. v7 copies each index into the index's own tablespace, so that is where the
extra room is needed; the destination only has to fit the heap, the same as
master. The extra is the size of the indexes, within about 32 kB: 6.45 MB for
one index, 12.89 MB for two, 25.78 MB for four in my test. A single ALTER
through the extended protocol then fails with ENOSPC on a nearly-full index
volume where master succeeds; inside a transaction block v6 copies too, so
that cost is v7's only for the single extended-protocol statement.
This is the cost the deferred copy (my v4) avoided -- it copied nothing for an
ALTER with no later write, 0 copies across the 15 cases I re-ran. Since the
cost is back, I went back to the two objections that led me to drop it.
Andres, on the old index being pinned: I measured it in 13 scenarios where the
deferred copy runs with a buffer of the old index file still pinned, verified
each time with pg_buffercache before the write. (A plain MVCC btree scan drops
the leaf pin, so the outer scans are index-only or hash, which keep it, plus a
nested loop, a BEFORE trigger, a scrollable cursor, a generic prepared plan, a
partial index and writes under savepoints.) All 13 are correct after COMMIT
and ROLLBACK; master fails every one on ROLLBACK. The oracle is index-vs-seq,
by row md5 over 8 query shapes and index-only scans after VACUUM to surface
stale entries, since amcheck's heapallindexed only checks heap->index. One v4
case does fail -- a REINDEX before a savepoint whose move is then rolled back
-- but that is the savepoint gap v5 already closed, not a pin issue, so a
deferred v8 would keep v5's per-subtransaction rule. This was btree and hash,
one backend.
On the other objection, the performance being harder to reason about, I have
no number that settles it: the copy happens only when a later write makes it
necessary, and the first such write pays for all the indexes, which is a
trade-off to weigh rather than something I can measure away.
For the back branches the deferred copy is a behavior change and, as Michael
noted, not backpatchable, so there the eager copy (v7) is the fix regardless;
the question is only 19 and master.
So, given the space cost: is the deferred copy worth another look for 19, or
should we take the eager copy everywhere? I'm happy to prepare a proper v8 of
it if you'd like to see one, and otherwise v7 stands.
regards,
Manu
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Hannu Krosing | 2026-10-18 16:48:50 | [PATCH v1] Generic Datum Encoding and Compression Contexts (pg_encoding_type, pg_encoding_context) |
| Previous Message | Tom Lane | 2026-10-18 15:49:08 | Re: [DEPARSE] An alias named 'set' on an UPDATE, DELETE or MERGE target does not read back |