From bda20ec9080b739ee6698b2b5f34d04fbe1b86f6 Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Wed, 1 Sep 2021 18:22:11 +0000 Subject: [PATCH v4 2/3] Introduce shared_memory_size GUC. This runtime-computed GUC shows the size of the server's main shared memory area. It can also be viewed with 'postgres -C', which is useful for calculating the number of huge pages required prior to startup. --- doc/src/sgml/config.sgml | 14 ++++++++++ doc/src/sgml/runtime.sgml | 22 +++++++-------- src/backend/postmaster/postmaster.c | 55 ++++++++++++++++++++++--------------- src/backend/storage/ipc/ipci.c | 24 ++++++++++++++++ src/backend/utils/misc/guc.c | 13 +++++++++ src/include/storage/ipc.h | 1 + 6 files changed, 95 insertions(+), 34 deletions(-) diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index 2c31c35a6b..ef0e2a7746 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -10275,6 +10275,20 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' + + shared_memory_size (integer) + + shared_memory_size configuration parameter + + + + + Reports the size of the main shared memory area, rounded up to the + nearest megabyte. + + + + ssl_library (string) diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index f1cbc1d9e9..2144c0abad 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1442,17 +1442,15 @@ export PG_OOM_ADJUST_VALUE=0 with CONFIG_HUGETLBFS=y and CONFIG_HUGETLB_PAGE=y. You will also have to configure the operating system to provide enough huge pages of the desired size. - To estimate the number of huge pages needed, start - PostgreSQL without huge pages enabled and check - the postmaster's anonymous shared memory segment size, as well as the - system's default and supported huge page sizes, using the - /proc and /sys file systems. - This might look like: + To estimate the number of huge pages needed, use the + postgres command to see the value of + , and use the + /proc and /sys file systems + to find the system's default and supported huge page sizes. This might + look like: -$ head -1 $PGDATA/postmaster.pid -4170 -$ pmap 4170 | awk '/rw-s/ && /zero/ {print $2}' -6490428K +$ postgres -D $PGDATA -C shared_memory_size +6339 $ grep ^Hugepagesize /proc/meminfo Hugepagesize: 2048 kB $ ls /sys/kernel/mm/hugepages @@ -1463,8 +1461,8 @@ hugepages-1048576kB hugepages-2048kB either 2MB or 1GB with . Assuming 2MB huge pages, - 6490428 / 2048 gives approximately - 3169.154, so in this example we need at + 6339 / 2 gives + 3169.5, so in this example we need at least 3170 huge pages. A larger setting would be appropriate if other programs on the machine also need huge pages. We can set this with: diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index 9c2c98614a..c32c21d632 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -893,6 +893,39 @@ 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(); + + /* + * Determine the value of any runtime-computed GUCs that depend on the + * amount of shared memory required. It is important to do this after + * preloaded libraries have had a chance to request additional shared + * memory. + */ + InitializeShmemGUCs(); + if (output_config_variable != NULL) { /* @@ -907,15 +940,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 +1020,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 b225b1ee70..f5736703a8 100644 --- a/src/backend/storage/ipc/ipci.c +++ b/src/backend/storage/ipc/ipci.c @@ -313,3 +313,27 @@ CreateSharedMemoryAndSemaphores(void) if (shmem_startup_hook) shmem_startup_hook(); } + +/* + * InitializeShmemGUCs + * + * This function initializes runtime-computed GUCs related to the amount of + * shared memory required for the current configuration. + */ +void +InitializeShmemGUCs(void) +{ + char buf[64]; + Size size_b; + Size size_mb; + + /* + * Calculate the shared memory size and round up to the nearest + * megabyte. + */ + size_b = CalculateShmemSize(NULL); + size_mb = add_size(size_b, (1024 * 1024) - 1) / (1024 * 1024); + + sprintf(buf, "%lu MB", size_mb); + SetConfigOption("shared_memory_size", buf, PGC_INTERNAL, PGC_S_OVERRIDE); +} diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 467b0fd6fe..a11387c5ce 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 size of the server's main shared memory area (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."), diff --git a/src/include/storage/ipc.h b/src/include/storage/ipc.h index 80e191d407..7a1ebc8559 100644 --- a/src/include/storage/ipc.h +++ b/src/include/storage/ipc.h @@ -79,5 +79,6 @@ extern PGDLLIMPORT shmem_startup_hook_type shmem_startup_hook; extern Size CalculateShmemSize(int *num_semaphores); extern void CreateSharedMemoryAndSemaphores(void); +extern void InitializeShmemGUCs(void); #endif /* IPC_H */ -- 2.16.6