aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/init/postinit.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/init/postinit.c')
-rw-r--r--src/backend/utils/init/postinit.c50
1 files changed, 44 insertions, 6 deletions
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index 5b9ed2f6f52..ca53912f151 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -25,6 +25,7 @@
#include "access/session.h"
#include "access/sysattr.h"
#include "access/tableam.h"
+#include "access/twophase.h"
#include "access/xact.h"
#include "access/xlog.h"
#include "access/xloginsert.h"
@@ -65,6 +66,9 @@
#include "utils/syscache.h"
#include "utils/timeout.h"
+static int MaxBackends = 0;
+static int MaxBackendsInitialized = false;
+
static HeapTuple GetDatabaseTuple(const char *dbname);
static HeapTuple GetDatabaseTupleByOid(Oid dboid);
static void PerformAuthentication(Port *port);
@@ -495,15 +499,49 @@ pg_split_opts(char **argv, int *argcp, const char *optstr)
void
InitializeMaxBackends(void)
{
- Assert(MaxBackends == 0);
-
/* the extra unit accounts for the autovacuum launcher */
- MaxBackends = MaxConnections + autovacuum_max_workers + 1 +
- max_worker_processes + max_wal_senders;
+ SetMaxBackends(MaxConnections + autovacuum_max_workers + 1 +
+ max_worker_processes + max_wal_senders);
+}
+
+/*
+ * Safely retrieve the value of MaxBackends.
+ *
+ * Previously, MaxBackends was externally visible, but it was often used before
+ * it was initialized (e.g., in preloaded libraries' _PG_init() functions).
+ * Unfortunately, we cannot initialize MaxBackends before processing
+ * shared_preload_libraries because the libraries sometimes alter GUCs that are
+ * used to calculate its value. Instead, we provide this function for accessing
+ * MaxBackends, and we ERROR if someone calls it before it is initialized.
+ */
+int
+GetMaxBackends(void)
+{
+ if (unlikely(!MaxBackendsInitialized))
+ elog(ERROR, "MaxBackends not yet initialized");
+
+ return MaxBackends;
+}
+
+/*
+ * Set the value of MaxBackends.
+ *
+ * This should only be used by InitializeMaxBackends() and
+ * restore_backend_variables(). If MaxBackends is already initialized or the
+ * specified value is greater than the maximum, this will ERROR.
+ */
+void
+SetMaxBackends(int max_backends)
+{
+ if (MaxBackendsInitialized)
+ elog(ERROR, "MaxBackends already initialized");
/* internal error because the values were all checked previously */
- if (MaxBackends > MAX_BACKENDS)
+ if (max_backends > MAX_BACKENDS)
elog(ERROR, "too many backends configured");
+
+ MaxBackends = max_backends;
+ MaxBackendsInitialized = true;
}
/*
@@ -609,7 +647,7 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
SharedInvalBackendInit(false);
- if (MyBackendId > MaxBackends || MyBackendId <= 0)
+ if (MyBackendId > GetMaxBackends() || MyBackendId <= 0)
elog(FATAL, "bad backend ID: %d", MyBackendId);
/* Now that we have a BackendId, we can participate in ProcSignal */