On Sat, Dec 21, 2024 at 11:41 AM Matthias van de Meent
<boekewurm+postgres@gmail.com> wrote:
> The unlinking of forks in the FileTag infrastructure has been broken
> since b0a55e43 in PG16,
Well spotted.
- p = relpathperm(ftag->rlocator, MAIN_FORKNUM);
+ p = _mdfd_segpath_rflb(rlfb, ftag->forknum, ftag->segno);
As you say, a harmless thinko as far as core is concerned, as we only
ever use it for the "tombstone" file preventing relfilenode recycling.
The tombstone is the bare relfilenode (main segment 0), since every
other segment is unlinked on commit.
> while a segment number other than 0 has never
> been unlinked (at least not since the introduction of the system with
> 3eb77eba in PG12)
Right, and that predates the FileTag refactoring, it's just that the
earlier coding didn't explicitly mention the segment number so it
looks slightly different. In fact it was hard-coded to unlink
relpathperm(entry->rnode, MAIN_FORKNUM) before that work, so both fork
and segment number were always fixed, it's just that the FileTag
mechanism was made slightly more general, really for the SYNC stuff,
not so much for the UNLINK stuff which uses the same tags.
> However, extensions may still make use of this and
> incorrectly assume that only the requested file of the requested fork
> 's segment will be unlinked, when it actually unlinks data from the
> main fork.
It seems unlikely to be useful for any purpose other than tombstones.
And it seems like if someone is already using it, they would have been
in touch to say that it doesn't work. Or perhaps you tried to use it
and noticed this flaw, or know of someone who would like to use it?
Or more likely I guess you're working on smgr extension support. It
is not a reliable mechanism (pull the power after the checkpoint
record is written and before it processes that list and you've leaked
a file), and it's dealing with an edge case we should close in a
better way, and then get rid of it.
> The attached fixes that for PG16+. PG13-15 will take a little bit more
> effort due to code changes in PG16; though it'd probably still require
> a relatively minor change.
The patch does not seem unreasonable and I'd like to help tidy this
up, but ... hmm, could we also consider going the other way?
register_unlink_segment(), mdunlinkfiletag() and the macro that
populates md.c's FileTag are internal to md.c, and we don't expect
external code to be pushing md.c SYNC_UNLINK_REQUEST requests into the
request queue (who would do that and what could the motivation
possibly be?) Doesn't feel like a supported usage to me... So my
question is: what bad thing would happen if we just renamed
register_unlink_segment() to register_unlink_tombstone() without
fork/seg arguments, to make it clear that it's not really a general
purpose unreliable segment unlink mechanism that we want anyone to
build more stuff on top of?