Re: BUG #18146: Rows reappearing in Tables after Auto-Vacuum Failure in PostgreSQL on Windows

From: Thomas Munro <thomas(dot)munro(at)gmail(dot)com>
To: Michael Paquier <michael(at)paquier(dot)xyz>
Cc: Heikki Linnakangas <hlinnaka(at)iki(dot)fi>, Alexander Lakhin <exclusion(at)gmail(dot)com>, Robert Haas <robertmhaas(at)gmail(dot)com>, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, Laurenz Albe <laurenz(dot)albe(at)cybertec(dot)at>, rootcause000(at)gmail(dot)com, pgsql-bugs(at)lists(dot)postgresql(dot)org
Subject: Re: BUG #18146: Rows reappearing in Tables after Auto-Vacuum Failure in PostgreSQL on Windows
Date: 2024-09-10 00:43:16
Message-ID: CA+hUKGK+tzjU-vqLr_zA8REzPUyiKNmpxk32Jw5AFR0DZNaXfg@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

On Mon, Sep 9, 2024 at 8:57 PM Thomas Munro <thomas(dot)munro(at)gmail(dot)com> wrote:
> On Mon, Sep 9, 2024 at 7:21 PM Michael Paquier <michael(at)paquier(dot)xyz> wrote:
> > The trick to use _mdfd_segpath() through smgrpreparetruncate() smells
> > too much of magic to me. I don't have an idea that does not involve
> > tweaking the interface of smgr.c or some of its structures on top of
> > my mind, though, which is to save the path before the critical section
> > and pass it through (like a memory area that can be used by
> > md.c).. Or do a MemoryContextAllowInCriticalSection, even if it is
> > not its original purpose.
...
> Another option would be to introduce mdtruncate2(old_nblocks,
> new_nblocks), so that it doesn't have to call smgrnblocks() itself,
> and you can obtain old_nblocks outside the CS...

Here is an experiment to try that out. The requirement to call
smgrnblock() beforehand is still slightly magical, but written in
black and white. I guess it could use an assertion cross-check on the
number of opened segments...

It is possible that an extension that messes with smgrsw[] would not
like this in a minor release:

- smgrsw[reln->smgr_which].smgr_truncate(reln,
forknum[i], nblocks[i]);
+ smgrsw[reln->smgr_which].smgr_truncate(reln, forknum[i],
+
old_nblocks[i], nblocks[i]);

I don't actually know of such an extension myself. I suppose we could
add a new member at the end called smgr_truncatefrom, and have
smgrtruncatefrom() call that if it is non-NULL (md's case), and the
existing smgr_truncate function pointer if it doesn't (ie, some
hypothetical external monkey-patching smgr replacement). Hypothetical
forks of PostgreSQL might be more likely to have used this
interception point, but wouldn't have quite the same ABI problem
(they'd adjust their function when rebasing on a minor release, but
they might also prefer if the old function prototype still worked, or
maybe they'd have some version of this bug themselves and want to be
able to fix it...).

Hmm.

Attachment Content-Type Size
v4-0001-RelationTruncate-must-use-a-critical-section.patch text/x-patch 11.2 KB

In response to

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message hubert depesz lubaczewski 2024-09-10 07:10:00 Re: BUG #18607: UNION ALL discards all foreign key relations + indexes
Previous Message Tom Lane 2024-09-09 16:39:37 Re: [EXT]: Re: BUG #18604: Regression in PostgreSQL 16.4: pg_dump Prevents Essential System Table Modifications