Re: Interrupts vs signals
Heikki Linnakangas <hlinnaka@iki.fi>
From: Heikki Linnakangas <hlinnaka@iki.fi>
To: Thomas Munro <thomas.munro@gmail.com>
Cc: pgsql-hackers <pgsql-hackers@postgresql.org>,
Andres Freund <andres@anarazel.de>, Robert Haas <robertmhaas@gmail.com>
Date: 2024-08-07T14:59:23Z
Lists: pgsql-hackers
On 10/07/2024 09:48, Thomas Munro wrote:
> The next problems to remove are, I think, the various SIGUSR2, SIGINT,
> SIGTERM signals sent by the postmaster. These should clearly become
> SendInterrupt() or ProcSetLatch(). The problem here is that the
> postmaster doesn't have the proc numbers yet. One idea is to teach
> the postmaster to assign them! Not explored yet.
With my latest patches on the "Refactoring postmaster's code to cleanup
after child exit" thread [1], every postmaster child process is assigned
a slot in the pmsignal.c array, including all the aux processes. If we
moved 'pending_interrupts' and the process Latch to the pmsignal.c
array, then you could send an interrupt also to a process that doesn't
have a PGPROC entry. That includes dead-end backends, backends that are
still in authentication, and the syslogger.
That would also make it so that the postmaster would never need to poke
into the procarray. pmsignal.c is already designated as the limited
piece of shared memory that is accessed by the postmaster
(BackgroundWorkerSlots is the other exception), so it would be kind of
nice if all the information that the postmaster needs to send an
interrupt was there. That would mean that where you currently use a
ProcNumber to identify a process, you'd use an index into the
PMSignalState array instead.
I don't insist on changing that right now, I think this patch is OK as
it is, but that might be a good next step later.
[1]
https://www.postgresql.org/message-id/8f2118b9-79e3-4af7-b2c9-bd5818193ca4%40iki.fi
I'm also wondering about the relationship between interrupts and
latches. Currently, SendInterrupt sets a latch to wake up the target
process. I wonder if it should be the other way 'round? Move all the
wakeup code, with the signalfd, the self-pipe etc to interrupt.c, and in
SetLatch, call SendInterrupt to wake up the target process? Somehow that
feels more natural to me, I think.
> This version is passing on Windows. I'll create a CF entry. Still
> work in progress!
Some comments on the patch details:
> ereport(WARNING,
> (errmsg("NOTIFY queue is %.0f%% full", fillDegree * 100),
> - (minPid != InvalidPid ?
> - errdetail("The server process with PID %d is among those with
the oldest transactions.", minPid)
> + (minPgprocno != INVALID_PROC_NUMBER ?
> + errdetail("The server process with pgprocno %d is among those
with the oldest transactions.", minPgprocno)
> : 0),
> - (minPid != InvalidPid ?
> + (minPgprocno != INVALID_PROC_NUMBER ?
> errhint("The NOTIFY queue cannot be emptied until that process
ends its current transaction.")
> : 0)));
This makes the message less useful to the user, as the ProcNumber isn't
exposed to users. With the PID, you can do "pg_terminate_backend(pid)"
> diff --git a/src/backend/optimizer/util/pathnode.c
b/src/backend/optimizer/util/pathnode.c
> index c42742d2c7b..bfb89049020 100644
> --- a/src/backend/optimizer/util/pathnode.c
> +++ b/src/backend/optimizer/util/pathnode.c
> @@ -18,6 +18,7 @@
>
> #include "foreign/fdwapi.h"
> #include "miscadmin.h"
> +#include "postmaster/interrupt.h"
> #include "nodes/extensible.h"
> #include "optimizer/appendinfo.h"
> #include "optimizer/clauses.h"
misordered
> + * duplicated interrupts later if we switch backx.
typo: backx -> back
> - if (IdleInTransactionSessionTimeoutPending)
> + if (ConsumeInterrupt(INTERRUPT_IDLE_TRANSACTION_TIMEOUT))
> {
> /*
> * If the GUC has been reset to zero, ignore the signal. This is
> @@ -3412,7 +3361,6 @@ ProcessInterrupts(void)
> * interrupt. We need to unset the flag before the injection point,
> * otherwise we could loop in interrupts checking.
> */
> - IdleInTransactionSessionTimeoutPending = false;
> if (IdleInTransactionSessionTimeout > 0)
> {
> INJECTION_POINT("idle-in-transaction-session-timeout");
The "We need to unset the flag.." comment is a bit out of place now,
since the flag was already cleared by ConsumeInterrupt(). Same in the
INTERRUPT_TRANSACTION_TIMEOUT and INTERRUPT_IDLE_SESSION_TIMEOUT
handling after this.
--
Heikki Linnakangas
Neon (https://neon.tech)
Commits
-
Ignore SIGINT in walwriter and walsummarizer
- a92b809f9da1 19 (unreleased) landed
-
Split WaitEventSet functions to separate source file
- 393e0d231405 18.0 landed
-
Use ModifyWaitEvent to update exit_on_postmaster_death
- 84e5b2f07a5e 18.0 landed
-
Remove unused ShutdownLatchSupport() function
- a98e4dee63ce 18.0 landed
-
Rename two functions that wake up other processes
- 368d8270c838 18.0 landed
-
Use ProcNumbers instead of direct Latch pointers to address other procs
- a9c546a5a378 18.0 landed
-
Clean up WaitLatch calls that passed latch without WL_LATCH_SET
- f9ecb57a506a 18.0 landed
-
Remove unneeded #include
- 094ae071605d 18.0 landed
-
Remove unused latch
- 6c0c49f7d37d 18.0 landed
-
Remove support for background workers without BGWORKER_SHMEM_ACCESS.
- 80a8f95b3bca 15.0 cited