mirror of
https://github.com/postgres/postgres.git
synced 2025-06-16 06:01:02 +03:00
Add shared_memory_type GUC.
Since 9.3 we have used anonymous shared mmap for our main shared memory region, except in EXEC_BACKEND builds. Provide a GUC so that users can opt for System V shared memory once again, like in 9.2 and earlier. A later patch proposes to add huge/large page support for AIX, which requires System V shared memory and provided the motivation to revive this possibility. It may also be useful on some BSDs. Author: Andres Freund (revived and documented by Thomas Munro) Discussion: https://postgr.es/m/HE1PR0202MB28126DB4E0B6621CC6A1A91286D90%40HE1PR0202MB2812.eurprd02.prod.outlook.com Discussion: https://postgr.es/m/2AE143D2-87D3-4AD1-AC78-CE2258230C05%40FreeBSD.org
This commit is contained in:
@ -1694,6 +1694,31 @@ include_dir 'conf.d'
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry id="guc-shared-memory-type" xreflabel="shared_memory_type">
|
||||||
|
<term><varname>shared_memory_type</varname> (<type>enum</type>)
|
||||||
|
<indexterm>
|
||||||
|
<primary><varname>shared_memory_type</varname> configuration parameter</primary>
|
||||||
|
</indexterm>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Specifies the shared memory implementation that the server
|
||||||
|
should use for the main shared memory region that holds
|
||||||
|
<productname>PostgreSQL</productname>'s shared buffers and other
|
||||||
|
shared data. Possible values are <literal>mmap</literal> (for
|
||||||
|
anonymous shared memory allocated using <function>mmap</function>),
|
||||||
|
<literal>sysv</literal> (for System V shared memory allocated via
|
||||||
|
<function>shmget</function>) and <literal>windows</literal> (for Windows
|
||||||
|
shared memory). Not all values are supported on all platforms; the
|
||||||
|
first supported option is the default for that platform. The use of
|
||||||
|
the <literal>sysv</literal> option, which is not the default on any
|
||||||
|
platform, is generally discouraged because it typically requires
|
||||||
|
non-default kernel settings to allow for large allocations (see <xref
|
||||||
|
linkend="sysvipc"/>).
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry id="guc-dynamic-shared-memory-type" xreflabel="dynamic_shared_memory_type">
|
<varlistentry id="guc-dynamic-shared-memory-type" xreflabel="dynamic_shared_memory_type">
|
||||||
<term><varname>dynamic_shared_memory_type</varname> (<type>enum</type>)
|
<term><varname>dynamic_shared_memory_type</varname> (<type>enum</type>)
|
||||||
<indexterm>
|
<indexterm>
|
||||||
|
@ -638,9 +638,12 @@ psql: could not connect to server: No such file or directory
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Upon starting the server, <productname>PostgreSQL</productname> normally allocates
|
By default, <productname>PostgreSQL</productname> allocates
|
||||||
a very small amount of System V shared memory, as well as a much larger
|
a very small amount of System V shared memory, as well as a much larger
|
||||||
amount of POSIX (<function>mmap</function>) shared memory.
|
amount of anonymous <function>mmap</function> shared memory.
|
||||||
|
Alternatively, a single large System V shared memory region can be used
|
||||||
|
(see <xref linkend="guc-shared-memory-type"/>).
|
||||||
|
|
||||||
In addition a significant number of semaphores, which can be either
|
In addition a significant number of semaphores, which can be either
|
||||||
System V or POSIX style, are created at server startup. Currently,
|
System V or POSIX style, are created at server startup. Currently,
|
||||||
POSIX semaphores are used on Linux and FreeBSD systems while other
|
POSIX semaphores are used on Linux and FreeBSD systems while other
|
||||||
@ -752,8 +755,10 @@ psql: could not connect to server: No such file or directory
|
|||||||
<productname>PostgreSQL</productname> requires a few bytes of System V shared memory
|
<productname>PostgreSQL</productname> requires a few bytes of System V shared memory
|
||||||
(typically 48 bytes, on 64-bit platforms) for each copy of the server.
|
(typically 48 bytes, on 64-bit platforms) for each copy of the server.
|
||||||
On most modern operating systems, this amount can easily be allocated.
|
On most modern operating systems, this amount can easily be allocated.
|
||||||
However, if you are running many copies of the server, or if other
|
However, if you are running many copies of the server or you explicitly
|
||||||
applications are also using System V shared memory, it may be necessary to
|
configure the server to use large amounts of System V shared memory (see
|
||||||
|
<xref linkend="guc-shared-memory-type"/> and <xref
|
||||||
|
linkend="guc-dynamic-shared-memory-type"/>), it may be necessary to
|
||||||
increase <varname>SHMALL</varname>, which is the total amount of System V shared
|
increase <varname>SHMALL</varname>, which is the total amount of System V shared
|
||||||
memory system-wide. Note that <varname>SHMALL</varname> is measured in pages
|
memory system-wide. Note that <varname>SHMALL</varname> is measured in pages
|
||||||
rather than bytes on many systems.
|
rather than bytes on many systems.
|
||||||
@ -879,7 +884,7 @@ kern.ipc.semmns=512
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
You might also want to configure your kernel to lock shared
|
You might also want to configure your kernel to lock System V shared
|
||||||
memory into RAM and prevent it from being paged out to swap.
|
memory into RAM and prevent it from being paged out to swap.
|
||||||
This can be accomplished using the <command>sysctl</command>
|
This can be accomplished using the <command>sysctl</command>
|
||||||
setting <literal>kern.ipc.shm_use_phys</literal>.
|
setting <literal>kern.ipc.shm_use_phys</literal>.
|
||||||
@ -928,7 +933,7 @@ kern.ipc.semmns=512
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
You might also want to configure your kernel to lock shared
|
You might also want to configure your kernel to lock System V shared
|
||||||
memory into RAM and prevent it from being paged out to swap.
|
memory into RAM and prevent it from being paged out to swap.
|
||||||
This can be accomplished using the <command>sysctl</command>
|
This can be accomplished using the <command>sysctl</command>
|
||||||
setting <literal>kern.ipc.shm_use_phys</literal>.
|
setting <literal>kern.ipc.shm_use_phys</literal>.
|
||||||
|
@ -62,10 +62,11 @@
|
|||||||
* to a process after exec(). Since EXEC_BACKEND is intended only for
|
* to a process after exec(). Since EXEC_BACKEND is intended only for
|
||||||
* developer use, this shouldn't be a big problem. Because of this, we do
|
* developer use, this shouldn't be a big problem. Because of this, we do
|
||||||
* not worry about supporting anonymous shmem in the EXEC_BACKEND cases below.
|
* not worry about supporting anonymous shmem in the EXEC_BACKEND cases below.
|
||||||
|
*
|
||||||
|
* As of PostgreSQL 12, we regained the ability to use a large System V shared
|
||||||
|
* memory region even in non-EXEC_BACKEND builds, if shared_memory_type is set
|
||||||
|
* to sysv (though this is not the default).
|
||||||
*/
|
*/
|
||||||
#ifndef EXEC_BACKEND
|
|
||||||
#define USE_ANONYMOUS_SHMEM
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
typedef key_t IpcMemoryKey; /* shared memory key passed to shmget(2) */
|
typedef key_t IpcMemoryKey; /* shared memory key passed to shmget(2) */
|
||||||
@ -75,10 +76,8 @@ typedef int IpcMemoryId; /* shared memory ID returned by shmget(2) */
|
|||||||
unsigned long UsedShmemSegID = 0;
|
unsigned long UsedShmemSegID = 0;
|
||||||
void *UsedShmemSegAddr = NULL;
|
void *UsedShmemSegAddr = NULL;
|
||||||
|
|
||||||
#ifdef USE_ANONYMOUS_SHMEM
|
|
||||||
static Size AnonymousShmemSize;
|
static Size AnonymousShmemSize;
|
||||||
static void *AnonymousShmem = NULL;
|
static void *AnonymousShmem = NULL;
|
||||||
#endif
|
|
||||||
|
|
||||||
static void *InternalIpcMemoryCreate(IpcMemoryKey memKey, Size size);
|
static void *InternalIpcMemoryCreate(IpcMemoryKey memKey, Size size);
|
||||||
static void IpcMemoryDetach(int status, Datum shmaddr);
|
static void IpcMemoryDetach(int status, Datum shmaddr);
|
||||||
@ -370,8 +369,6 @@ PGSharedMemoryIsInUse(unsigned long id1, unsigned long id2)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_ANONYMOUS_SHMEM
|
|
||||||
|
|
||||||
#ifdef MAP_HUGETLB
|
#ifdef MAP_HUGETLB
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -534,8 +531,6 @@ AnonymousShmemDetach(int status, Datum arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* USE_ANONYMOUS_SHMEM */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PGSharedMemoryCreate
|
* PGSharedMemoryCreate
|
||||||
*
|
*
|
||||||
@ -566,7 +561,7 @@ PGSharedMemoryCreate(Size size, bool makePrivate, int port,
|
|||||||
Size sysvsize;
|
Size sysvsize;
|
||||||
|
|
||||||
/* Complain if hugepages demanded but we can't possibly support them */
|
/* Complain if hugepages demanded but we can't possibly support them */
|
||||||
#if !defined(USE_ANONYMOUS_SHMEM) || !defined(MAP_HUGETLB)
|
#if !defined(MAP_HUGETLB)
|
||||||
if (huge_pages == HUGE_PAGES_ON)
|
if (huge_pages == HUGE_PAGES_ON)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||||
@ -576,7 +571,8 @@ PGSharedMemoryCreate(Size size, bool makePrivate, int port,
|
|||||||
/* Room for a header? */
|
/* Room for a header? */
|
||||||
Assert(size > MAXALIGN(sizeof(PGShmemHeader)));
|
Assert(size > MAXALIGN(sizeof(PGShmemHeader)));
|
||||||
|
|
||||||
#ifdef USE_ANONYMOUS_SHMEM
|
if (shared_memory_type == SHMEM_TYPE_MMAP)
|
||||||
|
{
|
||||||
AnonymousShmem = CreateAnonymousSegment(&size);
|
AnonymousShmem = CreateAnonymousSegment(&size);
|
||||||
AnonymousShmemSize = size;
|
AnonymousShmemSize = size;
|
||||||
|
|
||||||
@ -585,9 +581,9 @@ PGSharedMemoryCreate(Size size, bool makePrivate, int port,
|
|||||||
|
|
||||||
/* Now we need only allocate a minimal-sized SysV shmem block. */
|
/* Now we need only allocate a minimal-sized SysV shmem block. */
|
||||||
sysvsize = sizeof(PGShmemHeader);
|
sysvsize = sizeof(PGShmemHeader);
|
||||||
#else
|
}
|
||||||
|
else
|
||||||
sysvsize = size;
|
sysvsize = size;
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Make sure PGSharedMemoryAttach doesn't fail without need */
|
/* Make sure PGSharedMemoryAttach doesn't fail without need */
|
||||||
UsedShmemSegAddr = NULL;
|
UsedShmemSegAddr = NULL;
|
||||||
@ -687,14 +683,10 @@ PGSharedMemoryCreate(Size size, bool makePrivate, int port,
|
|||||||
* block. Otherwise, the System V shared memory block is only a shim, and
|
* block. Otherwise, the System V shared memory block is only a shim, and
|
||||||
* we must return a pointer to the real block.
|
* we must return a pointer to the real block.
|
||||||
*/
|
*/
|
||||||
#ifdef USE_ANONYMOUS_SHMEM
|
|
||||||
if (AnonymousShmem == NULL)
|
if (AnonymousShmem == NULL)
|
||||||
return hdr;
|
return hdr;
|
||||||
memcpy(AnonymousShmem, hdr, sizeof(PGShmemHeader));
|
memcpy(AnonymousShmem, hdr, sizeof(PGShmemHeader));
|
||||||
return (PGShmemHeader *) AnonymousShmem;
|
return (PGShmemHeader *) AnonymousShmem;
|
||||||
#else
|
|
||||||
return hdr;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef EXEC_BACKEND
|
#ifdef EXEC_BACKEND
|
||||||
@ -801,7 +793,6 @@ PGSharedMemoryDetach(void)
|
|||||||
UsedShmemSegAddr = NULL;
|
UsedShmemSegAddr = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_ANONYMOUS_SHMEM
|
|
||||||
if (AnonymousShmem != NULL)
|
if (AnonymousShmem != NULL)
|
||||||
{
|
{
|
||||||
if (munmap(AnonymousShmem, AnonymousShmemSize) < 0)
|
if (munmap(AnonymousShmem, AnonymousShmemSize) < 0)
|
||||||
@ -809,7 +800,6 @@ PGSharedMemoryDetach(void)
|
|||||||
AnonymousShmem, AnonymousShmemSize);
|
AnonymousShmem, AnonymousShmemSize);
|
||||||
AnonymousShmem = NULL;
|
AnonymousShmem = NULL;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -46,6 +46,8 @@
|
|||||||
#include "storage/spin.h"
|
#include "storage/spin.h"
|
||||||
#include "utils/snapmgr.h"
|
#include "utils/snapmgr.h"
|
||||||
|
|
||||||
|
/* GUCs */
|
||||||
|
int shared_memory_type = DEFAULT_SHARED_MEMORY_TYPE;
|
||||||
|
|
||||||
shmem_startup_hook_type shmem_startup_hook = NULL;
|
shmem_startup_hook_type shmem_startup_hook = NULL;
|
||||||
|
|
||||||
|
@ -453,6 +453,19 @@ const struct config_enum_entry ssl_protocol_versions_info[] = {
|
|||||||
{NULL, 0, false}
|
{NULL, 0, false}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct config_enum_entry shared_memory_options[] = {
|
||||||
|
#ifndef WIN32
|
||||||
|
{ "sysv", SHMEM_TYPE_SYSV, false},
|
||||||
|
#endif
|
||||||
|
#ifndef EXEC_BACKEND
|
||||||
|
{ "mmap", SHMEM_TYPE_MMAP, false},
|
||||||
|
#endif
|
||||||
|
#ifdef WIN32
|
||||||
|
{ "windows", SHMEM_TYPE_WINDOWS, false},
|
||||||
|
#endif
|
||||||
|
{NULL, 0, false}
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Options for enum values stored in other modules
|
* Options for enum values stored in other modules
|
||||||
*/
|
*/
|
||||||
@ -4327,6 +4340,16 @@ static struct config_enum ConfigureNamesEnum[] =
|
|||||||
NULL, NULL, NULL
|
NULL, NULL, NULL
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
{"shared_memory_type", PGC_POSTMASTER, RESOURCES_MEM,
|
||||||
|
gettext_noop("Selects the shared memory implementation used for the main shared memory region."),
|
||||||
|
NULL
|
||||||
|
},
|
||||||
|
&shared_memory_type,
|
||||||
|
DEFAULT_SHARED_MEMORY_TYPE, shared_memory_options,
|
||||||
|
NULL, NULL, NULL
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
{"wal_sync_method", PGC_SIGHUP, WAL_SETTINGS,
|
{"wal_sync_method", PGC_SIGHUP, WAL_SETTINGS,
|
||||||
gettext_noop("Selects the method used for forcing WAL updates to disk."),
|
gettext_noop("Selects the method used for forcing WAL updates to disk."),
|
||||||
|
@ -129,6 +129,12 @@
|
|||||||
#maintenance_work_mem = 64MB # min 1MB
|
#maintenance_work_mem = 64MB # min 1MB
|
||||||
#autovacuum_work_mem = -1 # min 1MB, or -1 to use maintenance_work_mem
|
#autovacuum_work_mem = -1 # min 1MB, or -1 to use maintenance_work_mem
|
||||||
#max_stack_depth = 2MB # min 100kB
|
#max_stack_depth = 2MB # min 100kB
|
||||||
|
#shared_memory_type = mmap # the default is the first option
|
||||||
|
# supported by the operating system:
|
||||||
|
# mmap
|
||||||
|
# sysv
|
||||||
|
# windows
|
||||||
|
# (change requires restart)
|
||||||
#dynamic_shared_memory_type = posix # the default is the first option
|
#dynamic_shared_memory_type = posix # the default is the first option
|
||||||
# supported by the operating system:
|
# supported by the operating system:
|
||||||
# posix
|
# posix
|
||||||
|
@ -41,7 +41,8 @@ typedef struct PGShmemHeader /* standard header for all Postgres shmem */
|
|||||||
#endif
|
#endif
|
||||||
} PGShmemHeader;
|
} PGShmemHeader;
|
||||||
|
|
||||||
/* GUC variable */
|
/* GUC variables */
|
||||||
|
extern int shared_memory_type;
|
||||||
extern int huge_pages;
|
extern int huge_pages;
|
||||||
|
|
||||||
/* Possible values for huge_pages */
|
/* Possible values for huge_pages */
|
||||||
@ -52,6 +53,14 @@ typedef enum
|
|||||||
HUGE_PAGES_TRY
|
HUGE_PAGES_TRY
|
||||||
} HugePagesType;
|
} HugePagesType;
|
||||||
|
|
||||||
|
/* Possible values for shared_memory_type */
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
SHMEM_TYPE_WINDOWS,
|
||||||
|
SHMEM_TYPE_SYSV,
|
||||||
|
SHMEM_TYPE_MMAP
|
||||||
|
} PGShmemType;
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
extern unsigned long UsedShmemSegID;
|
extern unsigned long UsedShmemSegID;
|
||||||
#else
|
#else
|
||||||
@ -59,6 +68,14 @@ extern HANDLE UsedShmemSegID;
|
|||||||
#endif
|
#endif
|
||||||
extern void *UsedShmemSegAddr;
|
extern void *UsedShmemSegAddr;
|
||||||
|
|
||||||
|
#if !defined(WIN32) && !defined(EXEC_BACKEND)
|
||||||
|
#define DEFAULT_SHARED_MEMORY_TYPE SHMEM_TYPE_MMAP
|
||||||
|
#elif !defined(WIN32)
|
||||||
|
#define DEFAULT_SHARED_MEMORY_TYPE SHMEM_TYPE_SYSV
|
||||||
|
#else
|
||||||
|
#define DEFAULT_SHARED_MEMORY_TYPE SHMEM_TYPE_WINDOWS
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef EXEC_BACKEND
|
#ifdef EXEC_BACKEND
|
||||||
extern void PGSharedMemoryReAttach(void);
|
extern void PGSharedMemoryReAttach(void);
|
||||||
extern void PGSharedMemoryNoReAttach(void);
|
extern void PGSharedMemoryNoReAttach(void);
|
||||||
|
Reference in New Issue
Block a user