v13-0003-Refactor-datachecksums-launcher-worker-comms-to-.patch
text/x-patch
Filename: v13-0003-Refactor-datachecksums-launcher-worker-comms-to-.patch
Type: text/x-patch
Part: 2
Message:
Re: Interrupts vs signals
Patch
Format: format-patch
Series: patch v13-0003
Subject: Refactor datachecksums launcher/worker comms to use procnumber
| File | + | − |
|---|---|---|
| src/backend/postmaster/datachecksum_state.c | 33 | 15 |
From 42c0d060f5713111d4f71bd370b54d440608d5fd Mon Sep 17 00:00:00 2001
From: Heikki Linnakangas <heikki.linnakangas@iki.fi>
Date: Tue, 23 Jun 2026 20:58:22 +0300
Subject: [PATCH v13 3/9] Refactor datachecksums launcher/worker comms to use
procnumber
I'm trying to eliminate using PIDs in preparation of the next patches
---
src/backend/postmaster/datachecksum_state.c | 48 ++++++++++++++-------
1 file changed, 33 insertions(+), 15 deletions(-)
diff --git a/src/backend/postmaster/datachecksum_state.c b/src/backend/postmaster/datachecksum_state.c
index 68557c16cb9..47b87f51ad9 100644
--- a/src/backend/postmaster/datachecksum_state.c
+++ b/src/backend/postmaster/datachecksum_state.c
@@ -209,6 +209,7 @@
#include "storage/latch.h"
#include "storage/lmgr.h"
#include "storage/lwlock.h"
+#include "storage/proc.h"
#include "storage/procarray.h"
#include "storage/smgr.h"
#include "storage/subsystems.h"
@@ -326,7 +327,9 @@ typedef struct DataChecksumsStateStruct
*/
uint64 worker_invocation; /* unique invocation number */
Oid database_oid; /* database it's processing */
- pid_t worker_pid; /* worker process's PID */
+
+ /* Worker process's proc number, set by the worker when it starts up */
+ ProcNumber worker_procno;
/*
* These fields indicate the target state that the worker is currently
@@ -840,7 +843,7 @@ ProcessDatabase(DataChecksumsWorkerDatabase *db)
* if it completes successfully.
*/
DataChecksumState->worker_result = DATACHECKSUMSWORKER_FAILED;
- DataChecksumState->worker_pid = InvalidPid;
+ DataChecksumState->worker_procno = INVALID_PROC_NUMBER;
invocation = ++DataChecksumState->worker_invocation_counter;
DataChecksumState->worker_invocation = invocation;
@@ -883,6 +886,7 @@ ProcessDatabase(DataChecksumsWorkerDatabase *db)
*/
LWLockAcquire(DataChecksumsWorkerLock, LW_SHARED);
Assert(DataChecksumState->worker_invocation == invocation);
+ Assert(DataChecksumState->worker_procno == INVALID_PROC_NUMBER);
if (DataChecksumState->worker_result == DATACHECKSUMSWORKER_SUCCESSFUL)
{
LWLockRelease(DataChecksumsWorkerLock);
@@ -924,12 +928,6 @@ ProcessDatabase(DataChecksumsWorkerDatabase *db)
errmsg("initiating data checksum processing in database \"%s\"",
db->dbname));
- /* Save the pid of the worker so we can signal it later */
- LWLockAcquire(DataChecksumsWorkerLock, LW_EXCLUSIVE);
- Assert(DataChecksumState->worker_invocation == invocation);
- DataChecksumState->worker_pid = pid;
- LWLockRelease(DataChecksumsWorkerLock);
-
snprintf(activity, sizeof(activity) - 1,
"Waiting for worker in database %s (pid %ld)", db->dbname, (long) pid);
pgstat_report_activity(STATE_RUNNING, activity);
@@ -942,10 +940,10 @@ ProcessDatabase(DataChecksumsWorkerDatabase *db)
db->dbname),
errhint("Restart the database and restart data checksum processing by calling pg_enable_data_checksums()."));
- LWLockAcquire(DataChecksumsWorkerLock, LW_EXCLUSIVE);
+ LWLockAcquire(DataChecksumsWorkerLock, LW_SHARED);
Assert(DataChecksumState->worker_invocation == invocation);
+ Assert(DataChecksumState->worker_procno == INVALID_PROC_NUMBER);
result = DataChecksumState->worker_result;
- DataChecksumState->worker_pid = InvalidPid;
LWLockRelease(DataChecksumsWorkerLock);
if (result == DATACHECKSUMSWORKER_ABORTED)
@@ -974,12 +972,11 @@ launcher_exit(int code, Datum arg)
if (launcher_running)
{
LWLockAcquire(DataChecksumsWorkerLock, LW_EXCLUSIVE);
- if (DataChecksumState->worker_pid != InvalidPid)
+ if (DataChecksumState->worker_procno != INVALID_PROC_NUMBER)
{
ereport(LOG,
errmsg("data checksums launcher exiting while worker is still running, signalling worker"));
- kill(DataChecksumState->worker_pid, SIGTERM);
- DataChecksumState->worker_pid = InvalidPid;
+ kill(GetPGProcByNumber(DataChecksumState->worker_procno)->pid, SIGTERM);
}
LWLockRelease(DataChecksumsWorkerLock);
}
@@ -1092,7 +1089,6 @@ WaitForAllTransactionsToFinish(void)
void
DataChecksumsWorkerLauncherMain(Datum arg)
{
-
ereport(DEBUG1,
errmsg("background worker \"datachecksums launcher\" started"));
@@ -1529,6 +1525,21 @@ BuildRelationList(bool temp_relations, bool include_shared)
return RelationList;
}
+/*
+ * worker_exit
+ *
+ * Internal routine for cleaning up state when a worker process exits due to
+ * an error.
+ */
+static void
+worker_exit(int code, Datum arg)
+{
+ LWLockAcquire(DataChecksumsWorkerLock, LW_EXCLUSIVE);
+ if (DataChecksumState->worker_invocation == worker_invocation)
+ DataChecksumState->worker_procno = INVALID_PROC_NUMBER;
+ LWLockRelease(DataChecksumsWorkerLock);
+}
+
/*
* DataChecksumsWorkerMain
*
@@ -1566,15 +1577,22 @@ DataChecksumsWorkerMain(Datum arg)
MyBackendType = B_DATACHECKSUMSWORKER_WORKER;
init_ps_display(NULL);
- LWLockAcquire(DataChecksumsWorkerLock, LW_SHARED);
+ LWLockAcquire(DataChecksumsWorkerLock, LW_EXCLUSIVE);
if (DataChecksumState->worker_invocation != worker_invocation)
{
LWLockRelease(DataChecksumsWorkerLock);
return;
}
+ if (DataChecksumState->worker_procno != INVALID_PROC_NUMBER)
+ elog(ERROR, "data checksums background worker is already running");
+ DataChecksumState->worker_procno = MyProcNumber;
+
dboid = DataChecksumState->database_oid;
LWLockRelease(DataChecksumsWorkerLock);
+ /* Arrange to clear worker_procno on exit */
+ on_shmem_exit(worker_exit, 0);
+
BackgroundWorkerInitializeConnectionByOid(dboid, InvalidOid,
BGWORKER_BYPASS_ALLOWCONN);
--
2.47.3