diff options
-rw-r--r-- | doc/src/sgml/config.sgml | 21 | ||||
-rw-r--r-- | doc/src/sgml/ref/postgres-ref.sgml | 3 | ||||
-rw-r--r-- | doc/src/sgml/runtime.sgml | 27 | ||||
-rw-r--r-- | src/backend/port/sysv_shmem.c | 43 | ||||
-rw-r--r-- | src/backend/port/win32_shmem.c | 14 | ||||
-rw-r--r-- | src/backend/storage/ipc/ipci.c | 14 | ||||
-rw-r--r-- | src/backend/utils/misc/guc.c | 12 | ||||
-rw-r--r-- | src/include/storage/pg_shmem.h | 1 |
8 files changed, 106 insertions, 29 deletions
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index ef0e2a77462..0a8e35c59f4 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -10289,6 +10289,27 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' </listitem> </varlistentry> + <varlistentry id="guc-shared-memory-size-in-huge-pages" xreflabel="shared_memory_size_in_huge_pages"> + <term><varname>shared_memory_size_in_huge_pages</varname> (<type>integer</type>) + <indexterm> + <primary><varname>shared_memory_size_in_huge_pages</varname> configuration parameter</primary> + </indexterm> + </term> + <listitem> + <para> + Reports the number of huge pages that are needed for the main shared + memory area based on the specified <xref linkend="guc-huge-page-size"/>. + If huge pages are not supported, this will be <literal>-1</literal>. + </para> + <para> + This setting is supported only on <productname>Linux</productname>. It + is always set to <literal>-1</literal> on other platforms. For more + details about using huge pages on <productname>Linux</productname>, see + <xref linkend="linux-huge-pages"/>. + </para> + </listitem> + </varlistentry> + <varlistentry id="guc-ssl-library" xreflabel="ssl_library"> <term><varname>ssl_library</varname> (<type>string</type>) <indexterm> diff --git a/doc/src/sgml/ref/postgres-ref.sgml b/doc/src/sgml/ref/postgres-ref.sgml index f72c3b04e42..55a3f6c69d1 100644 --- a/doc/src/sgml/ref/postgres-ref.sgml +++ b/doc/src/sgml/ref/postgres-ref.sgml @@ -143,7 +143,8 @@ PostgreSQL documentation <para> This can be used on a running server for most parameters. However, the server must be shut down for some runtime-computed parameters - (e.g., <xref linkend="guc-shared-memory-size"/> and + (e.g., <xref linkend="guc-shared-memory-size"/>, + <xref linkend="guc-shared-memory-size-in-huge-pages"/>, and <xref linkend="guc-wal-segment-size"/>). </para> diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index f1cbc1d9e92..d74d1ed7afa 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1442,17 +1442,14 @@ export PG_OOM_ADJUST_VALUE=0 with <varname>CONFIG_HUGETLBFS=y</varname> and <varname>CONFIG_HUGETLB_PAGE=y</varname>. 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 - <productname>PostgreSQL</productname> 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 - <filename>/proc</filename> and <filename>/sys</filename> file systems. + To determine the number of huge pages needed, use the + <command>postgres</command> command to see the value of + <xref linkend="guc-shared-memory-size-in-huge-pages"/>. Note that the + server must be shut down to view this runtime-computed parameter. This might look like: <programlisting> -$ <userinput>head -1 $PGDATA/postmaster.pid</userinput> -4170 -$ <userinput>pmap 4170 | awk '/rw-s/ && /zero/ {print $2}'</userinput> -6490428K +$ <userinput>postgres -D $PGDATA -C shared_memory_size_in_huge_pages</userinput> +3170 $ <userinput>grep ^Hugepagesize /proc/meminfo</userinput> Hugepagesize: 2048 kB $ <userinput>ls /sys/kernel/mm/hugepages</userinput> @@ -1460,13 +1457,13 @@ hugepages-1048576kB hugepages-2048kB </programlisting> In this example the default is 2MB, but you can also explicitly request - either 2MB or 1GB with <xref linkend="guc-huge-page-size"/>. + either 2MB or 1GB with <xref linkend="guc-huge-page-size"/> to adapt + the number of pages calculated by + <varname>shared_memory_size_in_huge_pages</varname>. - Assuming <literal>2MB</literal> huge pages, - <literal>6490428</literal> / <literal>2048</literal> gives approximately - <literal>3169.154</literal>, so in this example we need at - least <literal>3170</literal> huge pages. A larger setting would be - appropriate if other programs on the machine also need huge pages. + While we need at least <literal>3170</literal> huge pages in this example, + a larger setting would be appropriate if other programs on the machine + also need huge pages. We can set this with: <programlisting> # <userinput>sysctl -w vm.nr_hugepages=3170</userinput> diff --git a/src/backend/port/sysv_shmem.c b/src/backend/port/sysv_shmem.c index 9de96edf6ad..cd385c4df65 100644 --- a/src/backend/port/sysv_shmem.c +++ b/src/backend/port/sysv_shmem.c @@ -456,8 +456,6 @@ PGSharedMemoryAttach(IpcMemoryId shmId, return shmStat.shm_nattch == 0 ? SHMSTATE_UNATTACHED : SHMSTATE_ATTACHED; } -#ifdef MAP_HUGETLB - /* * Identify the huge page size to use, and compute the related mmap flags. * @@ -475,13 +473,19 @@ PGSharedMemoryAttach(IpcMemoryId shmId, * hugepage sizes, we might want to think about more invasive strategies, * such as increasing shared_buffers to absorb the extra space. * - * Returns the (real, assumed or config provided) page size into *hugepagesize, - * and the hugepage-related mmap flags to use into *mmap_flags. + * Returns the (real, assumed or config provided) page size into + * *hugepagesize, and the hugepage-related mmap flags to use into + * *mmap_flags if requested by the caller. If huge pages are not supported, + * *hugepagesize and *mmap_flags are set to 0. */ -static void +void GetHugePageSize(Size *hugepagesize, int *mmap_flags) { +#ifdef MAP_HUGETLB + Size default_hugepagesize = 0; + Size hugepagesize_local = 0; + int mmap_flags_local = 0; /* * System-dependent code to find out the default huge page size. @@ -519,12 +523,12 @@ GetHugePageSize(Size *hugepagesize, int *mmap_flags) if (huge_page_size != 0) { /* If huge page size is requested explicitly, use that. */ - *hugepagesize = (Size) huge_page_size * 1024; + hugepagesize_local = (Size) huge_page_size * 1024; } else if (default_hugepagesize != 0) { /* Otherwise use the system default, if we have it. */ - *hugepagesize = default_hugepagesize; + hugepagesize_local = default_hugepagesize; } else { @@ -536,26 +540,39 @@ GetHugePageSize(Size *hugepagesize, int *mmap_flags) * writing, there are no reports of any non-Linux systems being picky * about that. */ - *hugepagesize = 2 * 1024 * 1024; + hugepagesize_local = 2 * 1024 * 1024; } - *mmap_flags = MAP_HUGETLB; + mmap_flags_local = MAP_HUGETLB; /* * On recent enough Linux, also include the explicit page size, if * necessary. */ #if defined(MAP_HUGE_MASK) && defined(MAP_HUGE_SHIFT) - if (*hugepagesize != default_hugepagesize) + if (hugepagesize_local != default_hugepagesize) { - int shift = pg_ceil_log2_64(*hugepagesize); + int shift = pg_ceil_log2_64(hugepagesize_local); - *mmap_flags |= (shift & MAP_HUGE_MASK) << MAP_HUGE_SHIFT; + mmap_flags_local |= (shift & MAP_HUGE_MASK) << MAP_HUGE_SHIFT; } #endif -} + + /* assign the results found */ + if (mmap_flags) + *mmap_flags = mmap_flags_local; + if (hugepagesize) + *hugepagesize = hugepagesize_local; + +#else + + if (hugepagesize) + *hugepagesize = 0; + if (mmap_flags) + *mmap_flags = 0; #endif /* MAP_HUGETLB */ +} /* * Creates an anonymous mmap()ed shared memory segment. diff --git a/src/backend/port/win32_shmem.c b/src/backend/port/win32_shmem.c index d7a71992d81..64fde8de8f0 100644 --- a/src/backend/port/win32_shmem.c +++ b/src/backend/port/win32_shmem.c @@ -605,3 +605,17 @@ pgwin32_ReserveSharedMemoryRegion(HANDLE hChild) return true; } + +/* + * This function is provided for consistency with sysv_shmem.c and does not + * provide any useful information for Windows. To obtain the large page size, + * use GetLargePageMinimum() instead. + */ +void +GetHugePageSize(Size *hugepagesize, int *mmap_flags) +{ + if (hugepagesize) + *hugepagesize = 0; + if (mmap_flags) + *mmap_flags = 0; +} diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c index 13f3926ff67..9fa3e0631e6 100644 --- a/src/backend/storage/ipc/ipci.c +++ b/src/backend/storage/ipc/ipci.c @@ -326,6 +326,7 @@ InitializeShmemGUCs(void) char buf[64]; Size size_b; Size size_mb; + Size hp_size; /* * Calculate the shared memory size and round up to the nearest megabyte. @@ -334,4 +335,17 @@ InitializeShmemGUCs(void) size_mb = add_size(size_b, (1024 * 1024) - 1) / (1024 * 1024); sprintf(buf, "%zu", size_mb); SetConfigOption("shared_memory_size", buf, PGC_INTERNAL, PGC_S_OVERRIDE); + + /* + * Calculate the number of huge pages required. + */ + GetHugePageSize(&hp_size, NULL); + if (hp_size != 0) + { + Size hp_required; + + hp_required = add_size(size_b / hp_size, 1); + sprintf(buf, "%zu", hp_required); + SetConfigOption("shared_memory_size_in_huge_pages", buf, PGC_INTERNAL, PGC_S_OVERRIDE); + } } diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index a6e4fcc24ed..d2ce4a84506 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -665,6 +665,7 @@ static int max_identifier_length; static int block_size; static int segment_size; static int shared_memory_size_mb; +static int shared_memory_size_in_huge_pages; static int wal_block_size; static bool data_checksums; static bool integer_datetimes; @@ -2350,6 +2351,17 @@ static struct config_int ConfigureNamesInt[] = }, { + {"shared_memory_size_in_huge_pages", PGC_INTERNAL, PRESET_OPTIONS, + gettext_noop("Shows the number of huge pages needed for the main shared memory area."), + gettext_noop("-1 indicates that the value could not be determined."), + GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_RUNTIME_COMPUTED + }, + &shared_memory_size_in_huge_pages, + -1, -1, INT_MAX, + NULL, NULL, NULL + }, + + { {"temp_buffers", PGC_USERSET, RESOURCES_MEM, gettext_noop("Sets the maximum number of temporary buffers used by each session."), NULL, diff --git a/src/include/storage/pg_shmem.h b/src/include/storage/pg_shmem.h index 059df1b72c2..518eb860657 100644 --- a/src/include/storage/pg_shmem.h +++ b/src/include/storage/pg_shmem.h @@ -87,5 +87,6 @@ extern PGShmemHeader *PGSharedMemoryCreate(Size size, PGShmemHeader **shim); extern bool PGSharedMemoryIsInUse(unsigned long id1, unsigned long id2); extern void PGSharedMemoryDetach(void); +extern void GetHugePageSize(Size *hugepagesize, int *mmap_flags); #endif /* PG_SHMEM_H */ |