v2-0001-Add-shared_memory_size-GUC.patch
text/plain
Filename: v2-0001-Add-shared_memory_size-GUC.patch
Type: text/plain
Part: 0
Patch
Format: format-patch
Series: patch v2-0001
Subject: Add shared_memory_size GUC
| File | + | − |
|---|---|---|
| src/backend/postmaster/postmaster.c | 38 | 22 |
| src/backend/storage/ipc/ipci.c | 83 | 59 |
| src/backend/utils/misc/guc.c | 13 | 0 |
| src/include/storage/ipc.h | 1 | 0 |
From e2345206dacec8b4454c3b429d0cfac01d5a0a58 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Mon, 30 Aug 2021 16:24:59 +0900
Subject: [PATCH] Add shared_memory_size GUC
---
src/include/storage/ipc.h | 1 +
src/backend/postmaster/postmaster.c | 60 +++++++-----
src/backend/storage/ipc/ipci.c | 142 ++++++++++++++++------------
src/backend/utils/misc/guc.c | 13 +++
4 files changed, 135 insertions(+), 81 deletions(-)
diff --git a/src/include/storage/ipc.h b/src/include/storage/ipc.h
index 753a6dd4d7..80e191d407 100644
--- a/src/include/storage/ipc.h
+++ b/src/include/storage/ipc.h
@@ -77,6 +77,7 @@ extern void check_on_shmem_exit_lists_are_empty(void);
/* ipci.c */
extern PGDLLIMPORT shmem_startup_hook_type shmem_startup_hook;
+extern Size CalculateShmemSize(int *num_semaphores);
extern void CreateSharedMemoryAndSemaphores(void);
#endif /* IPC_H */
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 9c2c98614a..0d3b4b1be0 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -893,6 +893,44 @@ PostmasterMain(int argc, char *argv[])
if (!SelectConfigFiles(userDoption, progname))
ExitPostmaster(2);
+ /* Verify that DataDir looks reasonable */
+ checkDataDir();
+
+ /* Check that pg_control exists */
+ checkControlFile();
+
+ /* And switch working directory into it */
+ ChangeToDataDir();
+
+ /*
+ * Register the apply launcher. Since it registers a background worker,
+ * it needs to be called before InitializeMaxBackends(), and it's probably
+ * a good idea to call it before any modules had chance to take the
+ * background worker slots.
+ */
+ ApplyLauncherRegister();
+
+ /*
+ * Process any libraries that should be preloaded at postmaster start.
+ * Thie happens before running -C, so as it is possible to get an
+ * estimation of the total shared memory size allocated to this system,
+ * accounting for the portion from loaded libraries.
+ */
+ process_shared_preload_libraries();
+
+ /* XXX: this should be moved around */
+ {
+ char buf[64];
+ Size size;
+
+ size = CalculateShmemSize(NULL);
+ size += (1024 * 1024) - 1;
+ size /= (1024 * 1024);
+
+ sprintf(buf, "%lu MB", size);
+ SetConfigOption("shared_memory_size", buf, PGC_INTERNAL, PGC_S_OVERRIDE);
+ }
+
if (output_config_variable != NULL)
{
/*
@@ -907,15 +945,6 @@ PostmasterMain(int argc, char *argv[])
ExitPostmaster(0);
}
- /* Verify that DataDir looks reasonable */
- checkDataDir();
-
- /* Check that pg_control exists */
- checkControlFile();
-
- /* And switch working directory into it */
- ChangeToDataDir();
-
/*
* Check for invalid combinations of GUC settings.
*/
@@ -996,19 +1025,6 @@ PostmasterMain(int argc, char *argv[])
*/
LocalProcessControlFile(false);
- /*
- * Register the apply launcher. Since it registers a background worker,
- * it needs to be called before InitializeMaxBackends(), and it's probably
- * a good idea to call it before any modules had chance to take the
- * background worker slots.
- */
- ApplyLauncherRegister();
-
- /*
- * process any libraries that should be preloaded at postmaster start
- */
- process_shared_preload_libraries();
-
/*
* Initialize SSL library, if specified.
*/
diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c
index 3e4ec53a97..b225b1ee70 100644
--- a/src/backend/storage/ipc/ipci.c
+++ b/src/backend/storage/ipc/ipci.c
@@ -75,6 +75,87 @@ RequestAddinShmemSpace(Size size)
total_addin_request = add_size(total_addin_request, size);
}
+/*
+ * CalculateShmemSize
+ * Calculates the amount of shared memory and number of semaphores needed.
+ *
+ * If num_semaphores is not NULL, it will be set to the number of semaphores
+ * required.
+ *
+ * Note that this function freezes the additional shared memory request size
+ * from loadable modules.
+ */
+Size
+CalculateShmemSize(int *num_semaphores)
+{
+ Size size;
+ int numSemas;
+
+ /* Compute number of semaphores we'll need */
+ numSemas = ProcGlobalSemas();
+ numSemas += SpinlockSemas();
+
+ /* Return the number of semaphores if requested by the caller */
+ if (num_semaphores)
+ *num_semaphores = numSemas;
+
+ /*
+ * Size of the Postgres shared-memory block is estimated via moderately-
+ * accurate estimates for the big hogs, plus 100K for the stuff that's too
+ * small to bother with estimating.
+ *
+ * We take some care to ensure that the total size request doesn't overflow
+ * size_t. If this gets through, we don't need to be so careful during the
+ * actual allocation phase.
+ */
+ size = 100000;
+ size = add_size(size, PGSemaphoreShmemSize(numSemas));
+ size = add_size(size, SpinlockSemaSize());
+ size = add_size(size, hash_estimate_size(SHMEM_INDEX_SIZE,
+ sizeof(ShmemIndexEnt)));
+ size = add_size(size, dsm_estimate_size());
+ size = add_size(size, BufferShmemSize());
+ size = add_size(size, LockShmemSize());
+ size = add_size(size, PredicateLockShmemSize());
+ size = add_size(size, ProcGlobalShmemSize());
+ size = add_size(size, XLOGShmemSize());
+ size = add_size(size, CLOGShmemSize());
+ size = add_size(size, CommitTsShmemSize());
+ size = add_size(size, SUBTRANSShmemSize());
+ size = add_size(size, TwoPhaseShmemSize());
+ size = add_size(size, BackgroundWorkerShmemSize());
+ size = add_size(size, MultiXactShmemSize());
+ size = add_size(size, LWLockShmemSize());
+ size = add_size(size, ProcArrayShmemSize());
+ size = add_size(size, BackendStatusShmemSize());
+ size = add_size(size, SInvalShmemSize());
+ size = add_size(size, PMSignalShmemSize());
+ size = add_size(size, ProcSignalShmemSize());
+ size = add_size(size, CheckpointerShmemSize());
+ size = add_size(size, AutoVacuumShmemSize());
+ size = add_size(size, ReplicationSlotsShmemSize());
+ size = add_size(size, ReplicationOriginShmemSize());
+ size = add_size(size, WalSndShmemSize());
+ size = add_size(size, WalRcvShmemSize());
+ size = add_size(size, PgArchShmemSize());
+ size = add_size(size, ApplyLauncherShmemSize());
+ size = add_size(size, SnapMgrShmemSize());
+ size = add_size(size, BTreeShmemSize());
+ size = add_size(size, SyncScanShmemSize());
+ size = add_size(size, AsyncShmemSize());
+#ifdef EXEC_BACKEND
+ size = add_size(size, ShmemBackendArraySize());
+#endif
+
+ /* freeze the addin request size and include it */
+ addin_request_allowed = false;
+ size = add_size(size, total_addin_request);
+
+ /* might as well round it off to a multiple of a typical page size */
+ size = add_size(size, 8192 - (size % 8192));
+
+ return size;
+}
/*
* CreateSharedMemoryAndSemaphores
@@ -102,65 +183,8 @@ CreateSharedMemoryAndSemaphores(void)
Size size;
int numSemas;
- /* Compute number of semaphores we'll need */
- numSemas = ProcGlobalSemas();
- numSemas += SpinlockSemas();
-
- /*
- * Size of the Postgres shared-memory block is estimated via
- * moderately-accurate estimates for the big hogs, plus 100K for the
- * stuff that's too small to bother with estimating.
- *
- * We take some care during this phase to ensure that the total size
- * request doesn't overflow size_t. If this gets through, we don't
- * need to be so careful during the actual allocation phase.
- */
- size = 100000;
- size = add_size(size, PGSemaphoreShmemSize(numSemas));
- size = add_size(size, SpinlockSemaSize());
- size = add_size(size, hash_estimate_size(SHMEM_INDEX_SIZE,
- sizeof(ShmemIndexEnt)));
- size = add_size(size, dsm_estimate_size());
- size = add_size(size, BufferShmemSize());
- size = add_size(size, LockShmemSize());
- size = add_size(size, PredicateLockShmemSize());
- size = add_size(size, ProcGlobalShmemSize());
- size = add_size(size, XLOGShmemSize());
- size = add_size(size, CLOGShmemSize());
- size = add_size(size, CommitTsShmemSize());
- size = add_size(size, SUBTRANSShmemSize());
- size = add_size(size, TwoPhaseShmemSize());
- size = add_size(size, BackgroundWorkerShmemSize());
- size = add_size(size, MultiXactShmemSize());
- size = add_size(size, LWLockShmemSize());
- size = add_size(size, ProcArrayShmemSize());
- size = add_size(size, BackendStatusShmemSize());
- size = add_size(size, SInvalShmemSize());
- size = add_size(size, PMSignalShmemSize());
- size = add_size(size, ProcSignalShmemSize());
- size = add_size(size, CheckpointerShmemSize());
- size = add_size(size, AutoVacuumShmemSize());
- size = add_size(size, ReplicationSlotsShmemSize());
- size = add_size(size, ReplicationOriginShmemSize());
- size = add_size(size, WalSndShmemSize());
- size = add_size(size, WalRcvShmemSize());
- size = add_size(size, PgArchShmemSize());
- size = add_size(size, ApplyLauncherShmemSize());
- size = add_size(size, SnapMgrShmemSize());
- size = add_size(size, BTreeShmemSize());
- size = add_size(size, SyncScanShmemSize());
- size = add_size(size, AsyncShmemSize());
-#ifdef EXEC_BACKEND
- size = add_size(size, ShmemBackendArraySize());
-#endif
-
- /* freeze the addin request size and include it */
- addin_request_allowed = false;
- size = add_size(size, total_addin_request);
-
- /* might as well round it off to a multiple of a typical page size */
- size = add_size(size, 8192 - (size % 8192));
-
+ /* Compute the size of the shared-memory block */
+ size = CalculateShmemSize(&numSemas);
elog(DEBUG3, "invoking IpcMemoryCreate(size=%zu)", size);
/*
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 467b0fd6fe..872bdc1c8e 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -620,6 +620,8 @@ char *pgstat_temp_directory;
char *application_name;
+int shmem_size_mb;
+
int tcp_keepalives_idle;
int tcp_keepalives_interval;
int tcp_keepalives_count;
@@ -2337,6 +2339,17 @@ static struct config_int ConfigureNamesInt[] =
NULL, NULL, NULL
},
+ {
+ {"shared_memory_size", PGC_INTERNAL, RESOURCES_MEM,
+ gettext_noop("Shows the amount of shared memory allocated by the server (rounded up to the nearest MB)."),
+ NULL,
+ GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_UNIT_MB
+ },
+ &shmem_size_mb,
+ 0, 0, INT_MAX,
+ NULL, NULL, NULL
+ },
+
{
{"temp_buffers", PGC_USERSET, RESOURCES_MEM,
gettext_noop("Sets the maximum number of temporary buffers used by each session."),
--
2.33.0