</listitem>
</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">
<term><varname>dynamic_shared_memory_type</varname> (<type>enum</type>)
<indexterm>
</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
- 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
System V or POSIX style, are created at server startup. Currently,
POSIX semaphores are used on Linux and FreeBSD systems while other
<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.
On most modern operating systems, this amount can easily be allocated.
- However, if you are running many copies of the server, or if other
- applications are also using System V shared memory, it may be necessary to
+ However, if you are running many copies of the server or you explicitly
+ 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
memory system-wide. Note that <varname>SHMALL</varname> is measured in pages
rather than bytes on many systems.
</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.
This can be accomplished using the <command>sysctl</command>
setting <literal>kern.ipc.shm_use_phys</literal>.
</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.
This can be accomplished using the <command>sysctl</command>
setting <literal>kern.ipc.shm_use_phys</literal>.
* 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
* 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) */
unsigned long UsedShmemSegID = 0;
void *UsedShmemSegAddr = NULL;
-#ifdef USE_ANONYMOUS_SHMEM
static Size AnonymousShmemSize;
static void *AnonymousShmem = NULL;
-#endif
static void *InternalIpcMemoryCreate(IpcMemoryKey memKey, Size size);
static void IpcMemoryDetach(int status, Datum shmaddr);
return true;
}
-#ifdef USE_ANONYMOUS_SHMEM
-
#ifdef MAP_HUGETLB
/*
}
}
-#endif /* USE_ANONYMOUS_SHMEM */
-
/*
* PGSharedMemoryCreate
*
Size sysvsize;
/* 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)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
/* Room for a header? */
Assert(size > MAXALIGN(sizeof(PGShmemHeader)));
-#ifdef USE_ANONYMOUS_SHMEM
- AnonymousShmem = CreateAnonymousSegment(&size);
- AnonymousShmemSize = size;
+ if (shared_memory_type == SHMEM_TYPE_MMAP)
+ {
+ AnonymousShmem = CreateAnonymousSegment(&size);
+ AnonymousShmemSize = size;
- /* Register on-exit routine to unmap the anonymous segment */
- on_shmem_exit(AnonymousShmemDetach, (Datum) 0);
+ /* Register on-exit routine to unmap the anonymous segment */
+ on_shmem_exit(AnonymousShmemDetach, (Datum) 0);
- /* Now we need only allocate a minimal-sized SysV shmem block. */
- sysvsize = sizeof(PGShmemHeader);
-#else
- sysvsize = size;
-#endif
+ /* Now we need only allocate a minimal-sized SysV shmem block. */
+ sysvsize = sizeof(PGShmemHeader);
+ }
+ else
+ sysvsize = size;
/* Make sure PGSharedMemoryAttach doesn't fail without need */
UsedShmemSegAddr = NULL;
* block. Otherwise, the System V shared memory block is only a shim, and
* we must return a pointer to the real block.
*/
-#ifdef USE_ANONYMOUS_SHMEM
if (AnonymousShmem == NULL)
return hdr;
memcpy(AnonymousShmem, hdr, sizeof(PGShmemHeader));
return (PGShmemHeader *) AnonymousShmem;
-#else
- return hdr;
-#endif
}
#ifdef EXEC_BACKEND
UsedShmemSegAddr = NULL;
}
-#ifdef USE_ANONYMOUS_SHMEM
if (AnonymousShmem != NULL)
{
if (munmap(AnonymousShmem, AnonymousShmemSize) < 0)
AnonymousShmem, AnonymousShmemSize);
AnonymousShmem = NULL;
}
-#endif
}
#include "storage/spin.h"
#include "utils/snapmgr.h"
+/* GUCs */
+int shared_memory_type = DEFAULT_SHARED_MEMORY_TYPE;
shmem_startup_hook_type shmem_startup_hook = NULL;
{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
*/
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,
gettext_noop("Selects the method used for forcing WAL updates to disk."),
#maintenance_work_mem = 64MB # min 1MB
#autovacuum_work_mem = -1 # min 1MB, or -1 to use maintenance_work_mem
#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
# supported by the operating system:
# posix
#endif
} PGShmemHeader;
-/* GUC variable */
+/* GUC variables */
+extern int shared_memory_type;
extern int huge_pages;
/* Possible values for huge_pages */
HUGE_PAGES_TRY
} HugePagesType;
+/* Possible values for shared_memory_type */
+typedef enum
+{
+ SHMEM_TYPE_WINDOWS,
+ SHMEM_TYPE_SYSV,
+ SHMEM_TYPE_MMAP
+} PGShmemType;
+
#ifndef WIN32
extern unsigned long UsedShmemSegID;
#else
#endif
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
extern void PGSharedMemoryReAttach(void);
extern void PGSharedMemoryNoReAttach(void);