1
0
mirror of https://github.com/postgres/postgres.git synced 2025-09-02 04:21:28 +03:00

Introduce GUC shared_memory_size_in_huge_pages

This runtime-computed GUC shows the number of huge pages required
for the server's main shared memory area, taking advantage of the
work done in 0c39c29 and 0bd305e.  This is useful for users to estimate
the amount of huge pages required for a server as it becomes possible to
do an estimation without having to start the server and potentially
allocate a large chunk of shared memory.

The number of huge pages is calculated based on the existing GUC
huge_page_size if set, or by using the system's default by looking at
/proc/meminfo on Linux.  There is nothing new here as this commit reuses
the existing calculation methods, and just exposes this information
directly to the user.  The routine calculating the huge page size is
refactored to limit the number of files with platform-specific flags.

This new GUC's name was the most popular choice based on the discussion
done.  This is only supported on Linux.

I have taken the time to test the change on Linux, Windows and MacOS,
though for the last two ones large pages are not supported.  The first
one calculates correctly the number of pages depending on the existing
GUC huge_page_size or the system's default.

Thanks to Andres Freund, Robert Haas, Kyotaro Horiguchi, Tom Lane,
Justin Pryzby (and anybody forgotten here) for the discussion.

Author: Nathan Bossart
Discussion: https://postgr.es/m/F2772387-CE0F-46BF-B5F1-CC55516EB885@amazon.com
This commit is contained in:
Michael Paquier
2021-09-21 10:31:58 +09:00
parent 5e6716cde5
commit 43c1c4f65e
8 changed files with 106 additions and 29 deletions

View File

@@ -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.

View File

@@ -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;
}