Skip to content

Commit

Permalink
Extend the ProcSignal mechanism to support barriers.
Browse files Browse the repository at this point in the history
A new function EmitProcSignalBarrier() can be used to emit a global
barrier which all backends that participate in the ProcSignal
mechanism must absorb, and a new function WaitForProcSignalBarrier()
can be used to wait until all relevant backends have in fact
absorbed the barrier.

This can be used to coordinate global state changes, such as turning
checksums on while the system is running.

There's no real client of this mechanism yet, although two are
proposed, but an enum has to have at least one element, so this
includes a placeholder type (PROCSIGNAL_BARRIER_PLACEHOLDER) which
should be replaced by the first real client of this mechanism to
get committed.

Andres Freund and Robert Haas, reviewed by Daniel Gustafsson and,
in earlier versions, by Magnus Hagander.

Discussion: http://postgr.es/m/CA+TgmoZwDk=BguVDVa+qdA6SBKef=PKbaKDQALTC_9qoz1mJqg@mail.gmail.com
  • Loading branch information
robertmhaas committed Dec 19, 2019
1 parent 9f83468 commit 16a4e4a
Show file tree
Hide file tree
Showing 14 changed files with 350 additions and 14 deletions.
6 changes: 5 additions & 1 deletion doc/src/sgml/monitoring.sgml
Original file line number Diff line number Diff line change
Expand Up @@ -1473,7 +1473,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser
<entry>Waiting to apply WAL at recovery because it is delayed.</entry>
</row>
<row>
<entry morerows="66"><literal>IO</literal></entry>
<entry morerows="67"><literal>IO</literal></entry>
<entry><literal>BufFileRead</literal></entry>
<entry>Waiting for a read from a buffered file.</entry>
</row>
Expand Down Expand Up @@ -1593,6 +1593,10 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser
<entry><literal>LogicalRewriteWrite</literal></entry>
<entry>Waiting for a write of logical rewrite mappings.</entry>
</row>
<row>
<entry><literal>ProcSignalBarrier</literal></entry>
<entry>Waiting for a barrier event to be processed by all backends.</entry>
</row>
<row>
<entry><literal>RelationMapRead</literal></entry>
<entry>Waiting for a read of the relation map file.</entry>
Expand Down
4 changes: 4 additions & 0 deletions src/backend/postmaster/autovacuum.c
Original file line number Diff line number Diff line change
Expand Up @@ -820,6 +820,10 @@ HandleAutoVacLauncherInterrupts(void)
rebuild_database_list(InvalidOid);
}

/* Process barrier events */
if (ProcSignalBarrierPending)
ProcessProcSignalBarrier();

/* Process sinval catchup interrupts that happened while sleeping */
ProcessCatchupInterrupt();
}
Expand Down
7 changes: 7 additions & 0 deletions src/backend/postmaster/checkpointer.c
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,9 @@ CheckpointerMain(void)
static void
HandleCheckpointerInterrupts(void)
{
if (ProcSignalBarrierPending)
ProcessProcSignalBarrier();

if (ConfigReloadPending)
{
ConfigReloadPending = false;
Expand Down Expand Up @@ -710,6 +713,10 @@ CheckpointWriteDelay(int flags, double progress)
AbsorbSyncRequests();
absorb_counter = WRITES_PER_ABSORB;
}

/* Check for barrier events. */
if (ProcSignalBarrierPending)
ProcessProcSignalBarrier();
}

/*
Expand Down
4 changes: 4 additions & 0 deletions src/backend/postmaster/interrupt.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "postmaster/interrupt.h"
#include "storage/ipc.h"
#include "storage/latch.h"
#include "storage/procsignal.h"
#include "utils/guc.h"

volatile sig_atomic_t ConfigReloadPending = false;
Expand All @@ -31,6 +32,9 @@ volatile sig_atomic_t ShutdownRequestPending = false;
void
HandleMainLoopInterrupts(void)
{
if (ProcSignalBarrierPending)
ProcessProcSignalBarrier();

if (ConfigReloadPending)
{
ConfigReloadPending = false;
Expand Down
3 changes: 3 additions & 0 deletions src/backend/postmaster/pgstat.c
Original file line number Diff line number Diff line change
Expand Up @@ -3988,6 +3988,9 @@ pgstat_get_wait_io(WaitEventIO w)
case WAIT_EVENT_LOGICAL_REWRITE_WRITE:
event_name = "LogicalRewriteWrite";
break;
case WAIT_EVENT_PROC_SIGNAL_BARRIER:
event_name = "ProcSignalBarrier";
break;
case WAIT_EVENT_RELATION_MAP_READ:
event_name = "RelationMapRead";
break;
Expand Down
6 changes: 5 additions & 1 deletion src/backend/postmaster/startup.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ StartupProcShutdownHandler(SIGNAL_ARGS)
errno = save_errno;
}

/* Handle SIGHUP and SIGTERM signals of startup process */
/* Handle various signals that might be sent to the startup process */
void
HandleStartupProcInterrupts(void)
{
Expand All @@ -121,6 +121,10 @@ HandleStartupProcInterrupts(void)
*/
if (IsUnderPostmaster && !PostmasterIsAlive())
exit(1);

/* Process barrier events */
if (ProcSignalBarrierPending)
ProcessProcSignalBarrier();
}


Expand Down
3 changes: 2 additions & 1 deletion src/backend/replication/walreceiver.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,8 @@ ProcessWalRcvInterrupts(void)
/*
* Although walreceiver interrupt handling doesn't use the same scheme as
* regular backends, call CHECK_FOR_INTERRUPTS() to make sure we receive
* any incoming signals on Win32.
* any incoming signals on Win32, and also to make sure we process any
* barrier events.
*/
CHECK_FOR_INTERRUPTS();

Expand Down
10 changes: 10 additions & 0 deletions src/backend/storage/buffer/bufmgr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1852,6 +1852,10 @@ BufferSync(int flags)
}

UnlockBufHdr(bufHdr, buf_state);

/* Check for barrier events in case NBuffers is large. */
if (ProcSignalBarrierPending)
ProcessProcSignalBarrier();
}

if (num_to_scan == 0)
Expand Down Expand Up @@ -1930,6 +1934,10 @@ BufferSync(int flags)
}

s->num_to_scan++;

/* Check for barrier events. */
if (ProcSignalBarrierPending)
ProcessProcSignalBarrier();
}

Assert(num_spaces > 0);
Expand Down Expand Up @@ -2018,6 +2026,8 @@ BufferSync(int flags)

/*
* Sleep to throttle our I/O rate.
*
* (This will check for barrier events even if it doesn't sleep.)
*/
CheckpointWriteDelay(flags, (double) num_processed / num_to_scan);
}
Expand Down

0 comments on commit 16a4e4a

Please sign in to comment.