2019-12-17 19:14:28 +01:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
|
|
|
* interrupt.c
|
|
|
|
* Interrupt handling routines.
|
|
|
|
*
|
2024-01-04 02:49:05 +01:00
|
|
|
* Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
|
2019-12-17 19:14:28 +01:00
|
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
|
|
*
|
|
|
|
* IDENTIFICATION
|
|
|
|
* src/backend/postmaster/interrupt.c
|
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "postgres.h"
|
|
|
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
#include "miscadmin.h"
|
|
|
|
#include "postmaster/interrupt.h"
|
|
|
|
#include "storage/ipc.h"
|
|
|
|
#include "storage/latch.h"
|
2019-12-19 20:56:20 +01:00
|
|
|
#include "storage/procsignal.h"
|
2019-12-17 19:14:28 +01:00
|
|
|
#include "utils/guc.h"
|
2022-01-11 15:19:59 +01:00
|
|
|
#include "utils/memutils.h"
|
2019-12-17 19:14:28 +01:00
|
|
|
|
|
|
|
volatile sig_atomic_t ConfigReloadPending = false;
|
|
|
|
volatile sig_atomic_t ShutdownRequestPending = false;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Simple interrupt handler for main loops of background processes.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
HandleMainLoopInterrupts(void)
|
|
|
|
{
|
2019-12-19 20:56:20 +01:00
|
|
|
if (ProcSignalBarrierPending)
|
|
|
|
ProcessProcSignalBarrier();
|
|
|
|
|
2019-12-17 19:14:28 +01:00
|
|
|
if (ConfigReloadPending)
|
|
|
|
{
|
|
|
|
ConfigReloadPending = false;
|
|
|
|
ProcessConfigFile(PGC_SIGHUP);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ShutdownRequestPending)
|
|
|
|
proc_exit(0);
|
2022-01-11 15:19:59 +01:00
|
|
|
|
|
|
|
/* Perform logging of memory contexts of this process */
|
|
|
|
if (LogMemoryContextPending)
|
|
|
|
ProcessLogMemoryContextInterrupt();
|
2019-12-17 19:14:28 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Simple signal handler for triggering a configuration reload.
|
|
|
|
*
|
|
|
|
* Normally, this handler would be used for SIGHUP. The idea is that code
|
|
|
|
* which uses it would arrange to check the ConfigReloadPending flag at
|
|
|
|
* convenient places inside main loops, or else call HandleMainLoopInterrupts.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
SignalHandlerForConfigReload(SIGNAL_ARGS)
|
|
|
|
{
|
|
|
|
int save_errno = errno;
|
|
|
|
|
|
|
|
ConfigReloadPending = true;
|
|
|
|
SetLatch(MyLatch);
|
|
|
|
|
|
|
|
errno = save_errno;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Simple signal handler for exiting quickly as if due to a crash.
|
|
|
|
*
|
|
|
|
* Normally, this would be used for handling SIGQUIT.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
SignalHandlerForCrashExit(SIGNAL_ARGS)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* We DO NOT want to run proc_exit() or atexit() callbacks -- we're here
|
|
|
|
* because shared memory may be corrupted, so we don't want to try to
|
|
|
|
* clean up our transaction. Just nail the windows shut and get out of
|
|
|
|
* town. The callbacks wouldn't be safe to run from a signal handler,
|
|
|
|
* anyway.
|
|
|
|
*
|
|
|
|
* Note we do _exit(2) not _exit(0). This is to force the postmaster into
|
|
|
|
* a system reset cycle if someone sends a manual SIGQUIT to a random
|
|
|
|
* backend. This is necessary precisely because we don't clean up our
|
|
|
|
* shared memory state. (The "dead man switch" mechanism in pmsignal.c
|
|
|
|
* should ensure the postmaster sees this as a crash, too, but no harm in
|
|
|
|
* being doubly sure.)
|
|
|
|
*/
|
|
|
|
_exit(2);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Simple signal handler for triggering a long-running background process to
|
|
|
|
* shut down and exit.
|
|
|
|
*
|
2020-11-02 07:14:41 +01:00
|
|
|
* Typically, this handler would be used for SIGTERM, but some processes use
|
Perform apply of large transactions by parallel workers.
Currently, for large transactions, the publisher sends the data in
multiple streams (changes divided into chunks depending upon
logical_decoding_work_mem), and then on the subscriber-side, the apply
worker writes the changes into temporary files and once it receives the
commit, it reads from those files and applies the entire transaction. To
improve the performance of such transactions, we can instead allow them to
be applied via parallel workers.
In this approach, we assign a new parallel apply worker (if available) as
soon as the xact's first stream is received and the leader apply worker
will send changes to this new worker via shared memory. The parallel apply
worker will directly apply the change instead of writing it to temporary
files. However, if the leader apply worker times out while attempting to
send a message to the parallel apply worker, it will switch to
"partial serialize" mode - in this mode, the leader serializes all
remaining changes to a file and notifies the parallel apply workers to
read and apply them at the end of the transaction. We use a non-blocking
way to send the messages from the leader apply worker to the parallel
apply to avoid deadlocks. We keep this parallel apply assigned till the
transaction commit is received and also wait for the worker to finish at
commit. This preserves commit ordering and avoid writing to and reading
from files in most cases. We still need to spill if there is no worker
available.
This patch also extends the SUBSCRIPTION 'streaming' parameter so that the
user can control whether to apply the streaming transaction in a parallel
apply worker or spill the change to disk. The user can set the streaming
parameter to 'on/off', or 'parallel'. The parameter value 'parallel' means
the streaming will be applied via a parallel apply worker, if available.
The parameter value 'on' means the streaming transaction will be spilled
to disk. The default value is 'off' (same as current behaviour).
In addition, the patch extends the logical replication STREAM_ABORT
message so that abort_lsn and abort_time can also be sent which can be
used to update the replication origin in parallel apply worker when the
streaming transaction is aborted. Because this message extension is needed
to support parallel streaming, parallel streaming is not supported for
publications on servers < PG16.
Author: Hou Zhijie, Wang wei, Amit Kapila with design inputs from Sawada Masahiko
Reviewed-by: Sawada Masahiko, Peter Smith, Dilip Kumar, Shi yu, Kuroda Hayato, Shveta Mallik
Discussion: https://postgr.es/m/CAA4eK1+wyN6zpaHUkCLorEWNx75MG0xhMwcFhvjqm2KURZEAGw@mail.gmail.com
2023-01-09 02:30:39 +01:00
|
|
|
* other signals. In particular, the checkpointer exits on SIGUSR2, and the WAL
|
|
|
|
* writer and the logical replication parallel apply worker exits on either
|
|
|
|
* SIGINT or SIGTERM.
|
2019-12-17 19:14:28 +01:00
|
|
|
*
|
|
|
|
* ShutdownRequestPending should be checked at a convenient place within the
|
|
|
|
* main loop, or else the main loop should call HandleMainLoopInterrupts.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
SignalHandlerForShutdownRequest(SIGNAL_ARGS)
|
|
|
|
{
|
|
|
|
int save_errno = errno;
|
|
|
|
|
|
|
|
ShutdownRequestPending = true;
|
|
|
|
SetLatch(MyLatch);
|
|
|
|
|
|
|
|
errno = save_errno;
|
|
|
|
}
|