Nicola Contu reported two years ago to pgsql-general[1] that they were having sporadic query failures, because EINTR is reported on some system call. I have been told that the problem persists, though it is very infrequent. I propose the attached patch. Kyotaro proposed a slightly different patch which also protects write(), but I think that's not necessary.
Thomas M. produced some more obscure theories for other things that could fail, but I think we should patch this problem first, which seems the most obvious one, and deal with others if and when they are reported. [1] https://www.postgresql.org/message-id/CAMTZZh2V%2B0wJVgSqTVvXUAVMduF57Uxubvvw58%3DkbOae%2B53%2BQQ%40mail.gmail.com -- Álvaro Herrera Breisgau, Deutschland — https://www.EnterpriseDB.com/ "Use it up, wear it out, make it do, or do without"
>From 466ed63b9b399c2914aa44f56f56e044341a77f5 Mon Sep 17 00:00:00 2001 From: Alvaro Herrera <alvhe...@alvh.no-ip.org> Date: Fri, 1 Jul 2022 17:16:33 +0200 Subject: [PATCH v2] retry ftruncate --- src/backend/storage/ipc/dsm_impl.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/backend/storage/ipc/dsm_impl.c b/src/backend/storage/ipc/dsm_impl.c index 873867e856..4f35e7e3d1 100644 --- a/src/backend/storage/ipc/dsm_impl.c +++ b/src/backend/storage/ipc/dsm_impl.c @@ -362,8 +362,21 @@ dsm_impl_posix_resize(int fd, off_t size) { int rc; - /* Truncate (or extend) the file to the requested size. */ - rc = ftruncate(fd, size); + /* + * Truncate (or extend) the file to the requested size. We may get + * interrupted. If so, just retry unless there is an interrupt pending. + * This avoids the possibility of looping forever if another backend is + * repeatedly trying to interrupt us. + */ + for (;;) + { + errno = 0; + rc = ftruncate(fd, size); + if (rc == 0) + break; + if (errno != EINTR || ProcDiePending || QueryCancelPending) + return rc; + } /* * On Linux, a shm_open fd is backed by a tmpfs file. After resizing with -- 2.30.2