calculate-MaxBackends-in-postmaster-3.patch
text/x-diff
Filename: calculate-MaxBackends-in-postmaster-3.patch
Type: text/x-diff
Part: 0
Message:
Re: fix bgworkers in EXEC_BACKEND
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: context
| File | + | − |
|---|---|---|
| src/backend/postmaster/postmaster.c | 20 | 0 |
| src/backend/utils/init/globals.c | 5 | 0 |
| src/backend/utils/misc/guc.c | 2 | 11 |
| src/include/postmaster/postmaster.h | 9 | 0 |
*** a/src/backend/postmaster/postmaster.c
--- b/src/backend/postmaster/postmaster.c
***************
*** 499,504 **** typedef struct
--- 499,505 ----
bool redirection_done;
bool IsBinaryUpgrade;
int max_safe_fds;
+ int MaxBackends;
#ifdef WIN32
HANDLE PostmasterHandle;
HANDLE initial_signal_pipe;
***************
*** 897,911 **** PostmasterMain(int argc, char *argv[])
process_shared_preload_libraries();
/*
! * If loadable modules have added background workers, MaxBackends needs to
! * be updated. Do so now by forcing a no-op update of max_connections.
! * XXX This is a pretty ugly way to do it, but it doesn't seem worth
! * introducing a new entry point in guc.c to do it in a cleaner fashion.
*/
! if (GetNumShmemAttachedBgworkers() > 0)
! SetConfigOption("max_connections",
! GetConfigOption("max_connections", false, false),
! PGC_POSTMASTER, PGC_S_OVERRIDE);
/*
* Establish input sockets.
--- 898,908 ----
process_shared_preload_libraries();
/*
! * Now that loadable modules have had their chance to register background
! * workers, calculate MaxBackends. Add one for the autovacuum launcher.
*/
! MaxBackends = MaxConnections + autovacuum_max_workers + 1 +
! GetNumShmemAttachedBgworkers();
/*
* Establish input sockets.
***************
*** 5214,5219 **** RegisterBackgroundWorker(BackgroundWorker *worker)
--- 5211,5227 ----
return;
}
+ if (MaxConnections + autovacuum_max_workers + 1 + GetNumShmemAttachedBgworkers() >=
+ MAX_BACKENDS)
+ {
+ ereport(LOG,
+ (errcode(ERRCODE_CONFIGURATION_LIMIT_EXCEEDED),
+ errmsg("too many background workers"),
+ errdetail("Up to %d background workers can be registered with the current settings.",
+ MAX_BACKENDS - (MaxConnections + autovacuum_max_workers + 1))));
+ return;
+ }
+
/*
* Copy the registration data into the registered workers list.
*/
***************
*** 5836,5841 **** save_backend_variables(BackendParameters *param, Port *port,
--- 5844,5851 ----
param->IsBinaryUpgrade = IsBinaryUpgrade;
param->max_safe_fds = max_safe_fds;
+ param->MaxBackends = MaxBackends;
+
#ifdef WIN32
param->PostmasterHandle = PostmasterHandle;
if (!write_duplicated_handle(¶m->initial_signal_pipe,
***************
*** 6061,6066 **** restore_backend_variables(BackendParameters *param, Port *port)
--- 6071,6078 ----
IsBinaryUpgrade = param->IsBinaryUpgrade;
max_safe_fds = param->max_safe_fds;
+ MaxBackends = param->MaxBackends;
+
#ifdef WIN32
PostmasterHandle = param->PostmasterHandle;
pgwin32_initial_signal_pipe = param->initial_signal_pipe;
*** a/src/backend/utils/init/globals.c
--- b/src/backend/utils/init/globals.c
***************
*** 103,115 **** int work_mem = 1024;
int maintenance_work_mem = 16384;
/*
! * Primary determinants of sizes of shared-memory structures. MaxBackends is
! * MaxConnections + autovacuum_max_workers + 1 (it is computed by the GUC
! * assign hooks for those variables):
*/
int NBuffers = 1000;
- int MaxBackends = 100;
int MaxConnections = 90;
int VacuumCostPageHit = 1; /* GUC parameters for vacuum */
int VacuumCostPageMiss = 10;
--- 103,116 ----
int maintenance_work_mem = 16384;
/*
! * Primary determinants of sizes of shared-memory structures.
! *
! * MaxBackends is computed by PostmasterMain after modules have had a chance to
! * register background workers.
*/
int NBuffers = 1000;
int MaxConnections = 90;
+ int MaxBackends = 0;
int VacuumCostPageHit = 1; /* GUC parameters for vacuum */
int VacuumCostPageMiss = 10;
*** a/src/backend/utils/misc/guc.c
--- b/src/backend/utils/misc/guc.c
***************
*** 103,119 ****
#define MAX_KILOBYTES (INT_MAX / 1024)
#endif
- /*
- * Note: MAX_BACKENDS is limited to 2^23-1 because inval.c stores the
- * backend ID as a 3-byte signed integer. Even if that limitation were
- * removed, we still could not exceed INT_MAX/4 because some places compute
- * 4*MaxBackends without any overflow check. This is rechecked in
- * check_maxconnections, since MaxBackends is computed as MaxConnections
- * plus the number of bgworkers plus autovacuum_max_workers plus one (for the
- * autovacuum launcher).
- */
- #define MAX_BACKENDS 0x7fffff
-
#define KB_PER_MB (1024)
#define KB_PER_GB (1024*1024)
--- 103,108 ----
***************
*** 199,207 **** static const char *show_tcp_keepalives_idle(void);
static const char *show_tcp_keepalives_interval(void);
static const char *show_tcp_keepalives_count(void);
static bool check_maxconnections(int *newval, void **extra, GucSource source);
- static void assign_maxconnections(int newval, void *extra);
static bool check_autovacuum_max_workers(int *newval, void **extra, GucSource source);
- static void assign_autovacuum_max_workers(int newval, void *extra);
static bool check_effective_io_concurrency(int *newval, void **extra, GucSource source);
static void assign_effective_io_concurrency(int newval, void *extra);
static void assign_pgstat_temp_directory(const char *newval, void *extra);
--- 188,194 ----
***************
*** 1615,1621 **** static struct config_int ConfigureNamesInt[] =
},
&MaxConnections,
100, 1, MAX_BACKENDS,
! check_maxconnections, assign_maxconnections, NULL
},
{
--- 1602,1608 ----
},
&MaxConnections,
100, 1, MAX_BACKENDS,
! check_maxconnections, NULL, NULL
},
{
***************
*** 2290,2296 **** static struct config_int ConfigureNamesInt[] =
},
&autovacuum_max_workers,
3, 1, MAX_BACKENDS,
! check_autovacuum_max_workers, assign_autovacuum_max_workers, NULL
},
{
--- 2277,2283 ----
},
&autovacuum_max_workers,
3, 1, MAX_BACKENDS,
! check_autovacuum_max_workers, NULL, NULL
},
{
***************
*** 8636,8648 **** check_maxconnections(int *newval, void **extra, GucSource source)
return true;
}
- static void
- assign_maxconnections(int newval, void *extra)
- {
- MaxBackends = newval + autovacuum_max_workers + 1 +
- GetNumShmemAttachedBgworkers();
- }
-
static bool
check_autovacuum_max_workers(int *newval, void **extra, GucSource source)
{
--- 8623,8628 ----
***************
*** 8652,8663 **** check_autovacuum_max_workers(int *newval, void **extra, GucSource source)
return true;
}
- static void
- assign_autovacuum_max_workers(int newval, void *extra)
- {
- MaxBackends = MaxConnections + newval + 1 + GetNumShmemAttachedBgworkers();
- }
-
static bool
check_effective_io_concurrency(int *newval, void **extra, GucSource source)
{
--- 8632,8637 ----
*** a/src/include/postmaster/postmaster.h
--- b/src/include/postmaster/postmaster.h
***************
*** 61,64 **** extern Size ShmemBackendArraySize(void);
--- 61,73 ----
extern void ShmemBackendArrayAllocation(void);
#endif
+ /*
+ * Note: MAX_BACKENDS is limited to 2^23-1 because inval.c stores the
+ * backend ID as a 3-byte signed integer. Even if that limitation were
+ * removed, we still could not exceed INT_MAX/4 because some places compute
+ * 4*MaxBackends without any overflow check. This is rechecked in the relevant
+ * GUC check hooks and in RegisterBackgroundWorker().
+ */
+ #define MAX_BACKENDS 0x7fffff
+
#endif /* _POSTMASTER_H */