Re: EINTR in ftruncate()
Andres Freund <andres@anarazel.de>
From: Andres Freund <andres@anarazel.de>
To: Thomas Munro <thomas.munro@gmail.com>
Cc: Alvaro Herrera <alvherre@alvh.no-ip.org>, Pg Hackers <pgsql-hackers@lists.postgresql.org>
Date: 2022-07-11T17:45:18Z
Lists: pgsql-hackers
Hi,
On 2022-07-07 17:58:10 +1200, Thomas Munro wrote:
> Even if we go with this approach now, I think it's plausible that we
> might want to reconsider this yet again one day, perhaps allocating
> memory with some future asynchronous infrastructure while still
> processing interrupts. It's not very nice to hold up recovery or
> ProcSignalBarrier for long operations.
I think the next improvement would be to do the fallocate in smaller chunks,
and accept interrupts inbetween.
> I'm a little unclear about ftruncate() here. I don't expect it to
> report EINTR in other places where we use it (ie to make a local file
> on a non-"slow device" smaller), because I expect that to be like
> read(), write() etc which we don't wrap in EINTR loops. Here you've
> observed EINTR when messing around with a debugger*. It seems
> inconsistent to put posix_fallocate() in an EINTR retry loop for the
> benefit of debuggers, but not ftruncate(). But perhaps that's good
> enough, on the theory that posix_fallocate(1GB) is a very large target
> and you have a decent chance of hitting it.
> *It's funny that ftruncate() apparently doesn't automatically restart
> for ptrace SIGCONT on Linux according to your report, while poll()
> does according to my experiments, even though the latter is one of the
> never-restart functions (it doesn't on other OSes I hack on, and you
> feel the difference when debugging missing wakeup type bugs...).
> Random implementation details...
My test was basically while (true); {if (!ftruncate()) bleat(); if
(!fallocate()) bleat();} with a SIGALRM triggering regularly in the
background. The ftruncate failed, rarely, when attaching / detaching strace
-p. Rarely enough that I had already written you an IM saying that I couldn't
make it fail... So it's hard to be confident this can't otherwise be
hit. With that caveat: I didn't hit it with a "real" file on a "real"
filesystem in a few minutes of trying. But unsurprisingly it triggers when
putting the file on a tmpfs.
> @@ -362,6 +355,14 @@ dsm_impl_posix_resize(int fd, off_t size)
> {
> int rc;
>
> + /*
> + * Block all blockable signals, except SIGQUIT. posix_fallocate() can run
> + * for quite a long time, and is an all-or-nothing operation. If we
> + * allowed SIGUSR1 to interrupt us repeatedly (for example, due to recovery
> + * conflicts), the retry loop might never succeed.
> + */
> + PG_SETMASK(&BlockSig);
> +
> /* Truncate (or extend) the file to the requested size. */
> rc = ftruncate(fd, size);
>
Hm - given that we've observed ftruncate failing with strace, and that
stracing to find problems isn't insane, shouldn't we retry the ftruncate too?
It's kind of obsoleted by your next patch, but not really, because it's not
unconceivable that other OSs behave similarly? And IIUC you're planning to not
backpatch 0002?
> + pgstat_report_wait_start(WAIT_EVENT_DSM_FILL_ZERO_WRITE);
(not new in this patch, just moved around) - FILL_ZERO_WRITE is imo an odd
description of what's happening... In my understanding this isn't doing any
writing, just allocating. But whatever...
Greetings,
Andres Freund
Commits
-
Provide sigaction() for Windows.
- b28ac1d24db4 16.0 landed
-
Emulate sigprocmask(), not sigsetmask(), on Windows.
- c94ae9d827a3 16.0 landed
-
Make dsm_impl_posix_resize more future-proof.
- d3b0884c0708 10.22 landed
- 3f2344d4aee1 11.17 landed
- 1661c40b9deb 12.12 landed
- c75b6b454ea1 13.8 landed
- c412c60b91ac 14.5 landed
- 91377a4559d8 15.0 landed
- 3b8d23a3e14f 16.0 landed
-
Don't clobber postmaster sigmask in dsm_impl_resize.
- e26024bea9e9 10.22 landed
- 74a9ee034829 11.17 landed
- a05f40ef874b 12.12 landed
- 17aa39da50c5 13.8 landed
- 8383645592de 14.5 landed
- a715c20043c1 15.0 landed
- 80845b7c0b2c 16.0 landed
-
Create a distinct wait event for POSIX DSM allocation.
- 7bae3bbf62d6 16.0 landed
-
Remove redundant ftruncate() for POSIX DSM memory.
- 712704d3539e 16.0 landed
-
Block signals while allocating DSM memory.
- 4518c798b2b9 16.0 landed
- c4a617ea117e 15.0 landed
- 2019e6ecfa26 14.5 landed
- e73fe6e828d1 13.8 landed
- ff78bf796d80 12.12 landed
- 39683c69a03e 11.17 landed
- 53cfe403c9d2 10.22 landed
-
Remove dsm_resize() and dsm_remap().
- 3c60d0fa231f 12.0 cited
-
XLOG (also known as WAL -:)) Bootstrap/Startup/Shutdown.
- 47937403676d 7.1.1 cited