Skip to content

Commit 277a4e5

Browse files
committed
Fix shmem allocation size.
MaxBackends is still 0 when _PG_init() is called, which means that we don't request enough memory in RequestAddinShmemSpace(), while the rest of the code sees (and allocate) a correct value. It's technically usually not a problem as postgres adds an extra 100kB of memory for small unaccounted memory usage, but it's better to avoid relying on it too much. Note that the value is still not guaranteed to be exact as other modules _PG_init() could later change the underlying GUCs, but there is not available API to handle that case accurately.
1 parent 59cfadb commit 277a4e5

File tree

1 file changed

+36
-6
lines changed

1 file changed

+36
-6
lines changed

pg_wait_sampling.c

+36-6
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717
#include "miscadmin.h"
1818
#include "optimizer/planner.h"
1919
#include "pgstat.h"
20+
#include "postmaster/autovacuum.h"
21+
#if PG_VERSION_NUM >= 120000
22+
#include "replication/walsender.h"
23+
#endif
2024
#include "storage/ipc.h"
2125
#include "storage/pg_shmem.h"
2226
#include "storage/procarray.h"
@@ -66,20 +70,46 @@ static void pgws_ExecutorEnd(QueryDesc *queryDesc);
6670

6771
/*
6872
* Calculate max processes count.
69-
* Look at InitProcGlobal (proc.c) and TotalProcs variable in it
70-
* if something wrong here.
73+
*
74+
* The value has to be in sync with ProcGlobal->allProcCount, initialized in
75+
* InitProcGlobal() (proc.c).
76+
*
77+
* We calculate the value here as it won't initialized when we need need
78+
* it during _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.
7189
*/
7290
static int
7391
get_max_procs_count(void)
7492
{
7593
int count = 0;
7694

77-
/* MyProcs, including autovacuum workers and launcher */
78-
count += MaxBackends;
95+
/*
96+
* MaxBackends: bgworkers, autovacuum workers and launcher.
97+
* This has to be in sync with the value computed in
98+
* InitializeMaxBackends() (postinit.c)
99+
*/
100+
count += MaxConnections + autovacuum_max_workers + 1
101+
+ max_worker_processes;
102+
103+
/*
104+
* Starting with pg12, wal senders aren't part of MaxConnections anymore
105+
* and have to be accounted for.
106+
*/
107+
#if PG_VERSION_NUM >= 120000
108+
count += max_wal_senders;
109+
#endif
110+
79111
/* AuxiliaryProcs */
80112
count += NUM_AUXILIARY_PROCS;
81-
/* Prepared xacts */
82-
count += max_prepared_xacts;
83113

84114
return count;
85115
}

0 commit comments

Comments
 (0)