v13-0001-Introduce-shared_memory_size_in_huge_pages-GUC.patch
application/octet-stream
Filename: v13-0001-Introduce-shared_memory_size_in_huge_pages-GUC.patch
Type: application/octet-stream
Part: 0
Patch
Format: format-patch
Series: patch v13-0001
Subject: Introduce shared_memory_size_in_huge_pages GUC.
| File | + | − |
|---|---|---|
| doc/src/sgml/config.sgml | 21 | 0 |
| doc/src/sgml/ref/postgres-ref.sgml | 2 | 1 |
| doc/src/sgml/runtime.sgml | 11 | 20 |
| src/backend/port/sysv_shmem.c | 28 | 16 |
| src/backend/port/win32_shmem.c | 17 | 0 |
| src/backend/storage/ipc/ipci.c | 14 | 0 |
| src/backend/utils/misc/guc.c | 12 | 0 |
| src/include/storage/pg_shmem.h | 1 | 0 |
From 4a86d93c6c75d3e692bc66d026b68338452c8ead Mon Sep 17 00:00:00 2001
From: Nathan Bossart <bossartn@amazon.com>
Date: Fri, 17 Sep 2021 16:23:59 +0000
Subject: [PATCH v13 1/1] Introduce shared_memory_size_in_huge_pages GUC.
This runtime-computed GUC shows the number of huge pages required
for the server's main shared memory area.
---
doc/src/sgml/config.sgml | 21 ++++++++++++++++++
doc/src/sgml/ref/postgres-ref.sgml | 3 ++-
doc/src/sgml/runtime.sgml | 31 ++++++++++-----------------
src/backend/port/sysv_shmem.c | 44 ++++++++++++++++++++++++--------------
src/backend/port/win32_shmem.c | 17 +++++++++++++++
src/backend/storage/ipc/ipci.c | 14 ++++++++++++
src/backend/utils/misc/guc.c | 12 +++++++++++
src/include/storage/pg_shmem.h | 1 +
8 files changed, 106 insertions(+), 37 deletions(-)
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index ef0e2a7746..0a8e35c59f 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 f72c3b04e4..55a3f6c69d 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 f1cbc1d9e9..aa2291a326 100644
--- a/doc/src/sgml/runtime.sgml
+++ b/doc/src/sgml/runtime.sgml
@@ -1442,31 +1442,22 @@ 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>grep ^Hugepagesize /proc/meminfo</userinput>
-Hugepagesize: 2048 kB
-$ <userinput>ls /sys/kernel/mm/hugepages</userinput>
-hugepages-1048576kB hugepages-2048kB
+$ <userinput>postgres -D $PGDATA -C shared_memory_size_in_huge_pages</userinput>
+3170
</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"/>.
+ Note that you can explicitly request either 2MB or 1GB huge pages with
+ <xref linkend="guc-huge-page-size"/>.
- 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 9de96edf6a..1ad70a3600 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.
*
@@ -476,11 +474,22 @@ PGSharedMemoryAttach(IpcMemoryId shmId,
* 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.
+ * and the hugepage-related mmap flags to use into *mmap_flags. If huge pages
+ * are not supported, *hugepagesize and *mmap_flags will be set to 0. It is
+ * safe to set mmap_flags to NULL if its value is not needed.
*/
-static void
+void
GetHugePageSize(Size *hugepagesize, int *mmap_flags)
{
+#ifndef MAP_HUGETLB
+
+ *hugepagesize = 0;
+
+ if (mmap_flags != NULL)
+ *mmap_flags = 0;
+
+#else
+
Size default_hugepagesize = 0;
/*
@@ -539,23 +548,26 @@ GetHugePageSize(Size *hugepagesize, int *mmap_flags)
*hugepagesize = 2 * 1024 * 1024;
}
- *mmap_flags = MAP_HUGETLB;
+ /* If requested, determine appropriate mmap flags. */
+ if (mmap_flags != NULL)
+ {
+ *mmap_flags = MAP_HUGETLB;
- /*
- * On recent enough Linux, also include the explicit page size, if
- * necessary.
- */
+ /*
+ * 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)
- {
- int shift = pg_ceil_log2_64(*hugepagesize);
+ if (*hugepagesize != default_hugepagesize)
+ {
+ int shift = pg_ceil_log2_64(*hugepagesize);
- *mmap_flags |= (shift & MAP_HUGE_MASK) << MAP_HUGE_SHIFT;
- }
+ *mmap_flags |= (shift & MAP_HUGE_MASK) << MAP_HUGE_SHIFT;
+ }
#endif
-}
-
+ }
#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 d7a71992d8..1d5d902eb8 100644
--- a/src/backend/port/win32_shmem.c
+++ b/src/backend/port/win32_shmem.c
@@ -605,3 +605,20 @@ 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.
+ *
+ * This function sets *hugepagesize to 0. If mmap_flags is not NULL, it also
+ * sets *mmap_flags to 0.
+ */
+void
+GetHugePageSize(Size *hugepagesize, int *mmap_flags)
+{
+ *hugepagesize = 0;
+
+ if (mmap_flags != NULL)
+ *mmap_flags = 0;
+}
diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c
index 13f3926ff6..9fa3e0631e 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 a6e4fcc24e..d2ce4a8450 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;
@@ -2349,6 +2350,17 @@ static struct config_int ConfigureNamesInt[] =
NULL, NULL, NULL
},
+ {
+ {"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."),
diff --git a/src/include/storage/pg_shmem.h b/src/include/storage/pg_shmem.h
index 059df1b72c..518eb86065 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 */
--
2.16.6