From c7e8d7937a940ecc5d22c4cc757d452bb536ac3e Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Tue, 31 Aug 2021 05:05:43 +0000 Subject: [PATCH v3 2/2] Introduce shared_memory_size and huge_pages_required GUCs. These parameters are intended to simplify huge pages setup. Instead of manually calculating the number of huge pages required for the main shared memory segment, a command like the following can be used to determine how many are needed: postgres -D $PGDATA -C huge_pages_required --- doc/src/sgml/config.sgml | 30 ++++++++++++++++++++ doc/src/sgml/runtime.sgml | 33 +++++++--------------- src/backend/port/sysv_shmem.c | 2 +- src/backend/postmaster/postmaster.c | 55 ++++++++++++++++++++++--------------- src/backend/storage/ipc/ipci.c | 48 ++++++++++++++++++++++++++++++++ src/backend/utils/misc/guc.c | 25 +++++++++++++++++ src/include/storage/ipc.h | 1 + src/include/storage/pg_shmem.h | 4 +++ 8 files changed, 152 insertions(+), 46 deletions(-) diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index 2c31c35a6b..e586427640 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -10101,6 +10101,22 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' + + huge_pages_required (integer) + + huge_pages_required configuration parameter + + + + + Reports the number of huge pages that are required for the main + shared memory segment based on the specified + . If the huge page size cannot + be determined, this will be -1. + + + + integer_datetimes (boolean) @@ -10275,6 +10291,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 segment, 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..28bc36283e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1442,32 +1442,19 @@ 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 + . This might look like: -$ head -1 $PGDATA/postmaster.pid -4170 -$ pmap 4170 | awk '/rw-s/ && /zero/ {print $2}' -6490428K -$ grep ^Hugepagesize /proc/meminfo -Hugepagesize: 2048 kB -$ ls /sys/kernel/mm/hugepages -hugepages-1048576kB hugepages-2048kB +$ postgres -D $PGDATA -C huge_pages_required +3170 - In this example the default is 2MB, but you can also explicitly request - either 2MB or 1GB with . - - Assuming 2MB huge pages, - 6490428 / 2048 gives approximately - 3169.154, 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: + Note that you can explicitly request either 2MB or 1GB huge pages with + . While we need at least + 3170 huge pages in this example, a larger setting + would be appropriate if other programs on the machine also need huge + pages. We can allocate the huge pages with: # sysctl -w vm.nr_hugepages=3170 diff --git a/src/backend/port/sysv_shmem.c b/src/backend/port/sysv_shmem.c index 9de96edf6a..f42f1ac171 100644 --- a/src/backend/port/sysv_shmem.c +++ b/src/backend/port/sysv_shmem.c @@ -478,7 +478,7 @@ PGSharedMemoryAttach(IpcMemoryId shmId, * Returns the (real, assumed or config provided) page size into *hugepagesize, * and the hugepage-related mmap flags to use into *mmap_flags. */ -static void +void GetHugePageSize(Size *hugepagesize, int *mmap_flags) { Size default_hugepagesize = 0; 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..86061da1bc 100644 --- a/src/backend/storage/ipc/ipci.c +++ b/src/backend/storage/ipc/ipci.c @@ -14,6 +14,10 @@ */ #include "postgres.h" +#ifndef WIN32 +#include +#endif + #include "access/clog.h" #include "access/commit_ts.h" #include "access/heapam.h" @@ -313,3 +317,47 @@ 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; +#if defined(MAP_HUGETLB) || defined(WIN32) + Size hp_size; + Size hp_required; +#endif +#ifdef MAP_HUGETLB + int unused; +#endif + + /* + * Calculate the shared memory size in bytes and in megabytes (rounded + * 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); + + /* Calculate the number of huge_pages required */ +#if defined(MAP_HUGETLB) + GetHugePageSize(&hp_size, &unused); +#elif defined(WIN32) + hp_size = GetLargePageMinimum(); +#endif + +#if defined(MAP_HUGETLB) || defined(WIN32) + hp_required = (size_b / hp_size) + 1; + sprintf(buf, "%lu", hp_required); + SetConfigOption("huge_pages_required", buf, PGC_INTERNAL, PGC_S_OVERRIDE); +#endif +} diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 467b0fd6fe..0d4dd27394 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -620,6 +620,9 @@ char *pgstat_temp_directory; char *application_name; +int shmem_size_mb; +int huge_pages_required; + int tcp_keepalives_idle; int tcp_keepalives_interval; int tcp_keepalives_count; @@ -2223,6 +2226,17 @@ static struct config_int ConfigureNamesInt[] = NULL, NULL, NULL }, + { + {"huge_pages_required", PGC_INTERNAL, RESOURCES_MEM, + gettext_noop("Shows the number of huge pages needed for the main shared memory area."), + gettext_noop("-1 indicates that the huge page size could not be determined."), + GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE + }, + &huge_pages_required, + -1, -1, INT_MAX, + NULL, NULL, NULL + }, + { /* This is PGC_SUSET to prevent hiding from log_lock_waits. */ {"deadlock_timeout", PGC_SUSET, LOCK_MANAGEMENT, @@ -2337,6 +2351,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."), 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 */ diff --git a/src/include/storage/pg_shmem.h b/src/include/storage/pg_shmem.h index 059df1b72c..c44403ed6a 100644 --- a/src/include/storage/pg_shmem.h +++ b/src/include/storage/pg_shmem.h @@ -88,4 +88,8 @@ extern PGShmemHeader *PGSharedMemoryCreate(Size size, extern bool PGSharedMemoryIsInUse(unsigned long id1, unsigned long id2); extern void PGSharedMemoryDetach(void); +#ifdef MAP_HUGETLB +extern void GetHugePageSize(Size *hugepagesize, int *mmap_flags); +#endif + #endif /* PG_SHMEM_H */ -- 2.16.6