Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit af53205

Browse files
authored
Merge pull request #49 from rjuju/shmem_request_hook
Various fixes for compatibility with pg 15
2 parents f4a87c5 + 5b50e78 commit af53205

File tree

2 files changed

+70
-27
lines changed

2 files changed

+70
-27
lines changed

collector.c

+12-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ register_wait_collector(void)
4444
memset(&worker, 0, sizeof(worker));
4545
worker.bgw_flags = BGWORKER_SHMEM_ACCESS;
4646
worker.bgw_start_time = BgWorkerStart_ConsistentState;
47-
worker.bgw_restart_time = 0;
47+
worker.bgw_restart_time = 1;
4848
worker.bgw_notify_pid = 0;
4949
snprintf(worker.bgw_library_name, BGW_MAXLEN, "pg_wait_sampling");
5050
snprintf(worker.bgw_function_name, BGW_MAXLEN, CppAsString(collector_main));
@@ -339,8 +339,16 @@ collector_main(Datum main_arg)
339339
* any equivalent of the backend's command-read loop, where interrupts can
340340
* be processed immediately, so make sure ImmediateInterruptOK is turned
341341
* off.
342+
*
343+
* We also want to respond to the ProcSignal notifications. This is done
344+
* in the upstream provided procsignal_sigusr1_handler, which is
345+
* automatically used if a bgworker connects to a database. But since our
346+
* worker doesn't connect to any database even though it calls
347+
* InitPostgres, which will still initializze a new backend and thus
348+
* partitipate to the ProcSignal infrastructure.
342349
*/
343350
pqsignal(SIGTERM, handle_sigterm);
351+
pqsignal(SIGUSR1, procsignal_sigusr1_handler);
344352
BackgroundWorkerUnblockSignals();
345353

346354
#if PG_VERSION_NUM >= 110000
@@ -379,6 +387,9 @@ collector_main(Datum main_arg)
379387
bool write_history,
380388
write_profile;
381389

390+
/* We need an explicit call for at least ProcSignal notifications. */
391+
CHECK_FOR_INTERRUPTS();
392+
382393
/* Wait calculate time to next sample for history or profile */
383394
current_ts = GetCurrentTimestamp();
384395

pg_wait_sampling.c

+58-26
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
PG_MODULE_MAGIC;
4040

4141
void _PG_init(void);
42-
void _PG_fini(void);
4342

4443
/* Global variables */
4544
bool shmem_initialized = false;
@@ -59,6 +58,9 @@ shm_mq *recv_mq = NULL;
5958
shm_mq_handle *recv_mqh = NULL;
6059
LOCKTAG queueTag;
6160

61+
#if PG_VERSION_NUM >= 150000
62+
static shmem_request_hook_type prev_shmem_request_hook = NULL;
63+
#endif
6264
static shmem_startup_hook_type prev_shmem_startup_hook = NULL;
6365
static PGPROC * search_proc(int backendPid);
6466
static PlannedStmt *pgws_planner_hook(Query *parse,
@@ -74,28 +76,40 @@ static void pgws_ExecutorEnd(QueryDesc *queryDesc);
7476
* The value has to be in sync with ProcGlobal->allProcCount, initialized in
7577
* InitProcGlobal() (proc.c).
7678
*
77-
* We calculate the value here as it won't initialized when we need it during
78-
* _PG_init().
79-
*
80-
* Note that the value returned during _PG_init() might be different from the
81-
* value returned later if some third-party modules change one of the
82-
* underlying GUC. This isn't ideal but can't lead to a crash, as the value
83-
* returned during _PG_init() is only used to ask for additional shmem with
84-
* RequestAddinShmemSpace(), and postgres has an extra 100kB of shmem to
85-
* compensate some small unaccounted usage. So if the value later changes, we
86-
* will allocate and initialize the new (and correct) memory size, which
87-
* will either work thanks for the extra 100kB of shmem, of fail (and prevent
88-
* postgres startup) due to an out of shared memory error.
8979
*/
9080
static int
9181
get_max_procs_count(void)
9282
{
9383
int count = 0;
9484

85+
/* First, add the maximum number of backends (MaxBackends). */
86+
#if PG_VERSION_NUM >= 150000
9587
/*
96-
* MaxBackends: bgworkers, autovacuum workers and launcher.
88+
* On pg15+, we can directly access the MaxBackends variable, as it will
89+
* have already been initialized in shmem_request_hook.
90+
*/
91+
Assert(MaxBackends > 0);
92+
count += MaxBackends;
93+
#else
94+
/*
95+
* On older versions, we need to compute MaxBackends: bgworkers, autovacuum
96+
* workers and launcher.
9797
* This has to be in sync with the value computed in
9898
* InitializeMaxBackends() (postinit.c)
99+
*
100+
* Note that we need to calculate the value as it won't initialized when we
101+
* need it during _PG_init().
102+
*
103+
* Note also that the value returned during _PG_init() might be different
104+
* from the value returned later if some third-party modules change one of
105+
* the underlying GUC. This isn't ideal but can't lead to a crash, as the
106+
* value returned during _PG_init() is only used to ask for additional
107+
* shmem with RequestAddinShmemSpace(), and postgres has an extra 100kB of
108+
* shmem to compensate some small unaccounted usage. So if the value later
109+
* changes, we will allocate and initialize the new (and correct) memory
110+
* size, which will either work thanks for the extra 100kB of shmem, of
111+
* fail (and prevent postgres startup) due to an out of shared memory
112+
* error.
99113
*/
100114
count += MaxConnections + autovacuum_max_workers + 1
101115
+ max_worker_processes;
@@ -106,9 +120,11 @@ get_max_procs_count(void)
106120
*/
107121
#if PG_VERSION_NUM >= 120000
108122
count += max_wal_senders;
109-
#endif
123+
#endif /* pg 12+ */
124+
#endif /* pg 15- */
125+
/* End of MaxBackends calculation. */
110126

111-
/* AuxiliaryProcs */
127+
/* Add AuxiliaryProcs */
112128
count += NUM_AUXILIARY_PROCS;
113129

114130
return count;
@@ -266,6 +282,23 @@ setup_gucs()
266282
}
267283
}
268284

285+
#if PG_VERSION_NUM >= 150000
286+
/*
287+
* shmem_request hook: request additional shared memory resources.
288+
*
289+
* If you change code here, don't forget to also report the modifications in
290+
* _PG_init() for pg14 and below.
291+
*/
292+
static void
293+
pgws_shmem_request(void)
294+
{
295+
if (prev_shmem_request_hook)
296+
prev_shmem_request_hook();
297+
298+
RequestAddinShmemSpace(pgws_shmem_size());
299+
}
300+
#endif
301+
269302
/*
270303
* Distribute shared memory.
271304
*/
@@ -345,18 +378,27 @@ _PG_init(void)
345378
if (!process_shared_preload_libraries_in_progress)
346379
return;
347380

381+
#if PG_VERSION_NUM < 150000
348382
/*
349383
* Request additional shared resources. (These are no-ops if we're not in
350384
* the postmaster process.) We'll allocate or attach to the shared
351385
* resources in pgws_shmem_startup().
386+
*
387+
* If you change code here, don't forget to also report the modifications
388+
* in pgsp_shmem_request() for pg15 and later.
352389
*/
353390
RequestAddinShmemSpace(pgws_shmem_size());
391+
#endif
354392

355393
register_wait_collector();
356394

357395
/*
358396
* Install hooks.
359397
*/
398+
#if PG_VERSION_NUM >= 150000
399+
prev_shmem_request_hook = shmem_request_hook;
400+
shmem_request_hook = pgws_shmem_request;
401+
#endif
360402
prev_shmem_startup_hook = shmem_startup_hook;
361403
shmem_startup_hook = pgws_shmem_startup;
362404
planner_hook_next = planner_hook;
@@ -365,16 +407,6 @@ _PG_init(void)
365407
ExecutorEnd_hook = pgws_ExecutorEnd;
366408
}
367409

368-
/*
369-
* Module unload callback
370-
*/
371-
void
372-
_PG_fini(void)
373-
{
374-
/* Uninstall hooks. */
375-
shmem_startup_hook = prev_shmem_startup_hook;
376-
}
377-
378410
/*
379411
* Find PGPROC entry responsible for given pid assuming ProcArrayLock was
380412
* already taken.

0 commit comments

Comments
 (0)