1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-28 23:42:10 +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:
Thomas Munro
2019-02-03 09:55:39 +01:00
parent 0d1fe9f74e
commit f1bebef60e
7 changed files with 101 additions and 33 deletions

View File

@ -62,10 +62,11 @@
* 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) */
@ -75,10 +76,8 @@ typedef int IpcMemoryId; /* shared memory ID returned by 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);
@ -370,8 +369,6 @@ PGSharedMemoryIsInUse(unsigned long id1, unsigned long id2)
return true;
}
#ifdef USE_ANONYMOUS_SHMEM
#ifdef MAP_HUGETLB
/*
@ -534,8 +531,6 @@ AnonymousShmemDetach(int status, Datum arg)
}
}
#endif /* USE_ANONYMOUS_SHMEM */
/*
* PGSharedMemoryCreate
*
@ -566,7 +561,7 @@ PGSharedMemoryCreate(Size size, bool makePrivate, int port,
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),
@ -576,18 +571,19 @@ PGSharedMemoryCreate(Size size, bool makePrivate, int port,
/* 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;
@ -687,14 +683,10 @@ PGSharedMemoryCreate(Size size, bool makePrivate, int port,
* 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
@ -801,7 +793,6 @@ PGSharedMemoryDetach(void)
UsedShmemSegAddr = NULL;
}
#ifdef USE_ANONYMOUS_SHMEM
if (AnonymousShmem != NULL)
{
if (munmap(AnonymousShmem, AnonymousShmemSize) < 0)
@ -809,7 +800,6 @@ PGSharedMemoryDetach(void)
AnonymousShmem, AnonymousShmemSize);
AnonymousShmem = NULL;
}
#endif
}

View File

@ -46,6 +46,8 @@
#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;

View File

@ -453,6 +453,19 @@ const struct config_enum_entry ssl_protocol_versions_info[] = {
{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
*/
@ -4327,6 +4340,16 @@ static struct config_enum ConfigureNamesEnum[] =
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."),

View File

@ -129,6 +129,12 @@
#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

View File

@ -41,7 +41,8 @@ typedef struct PGShmemHeader /* standard header for all Postgres shmem */
#endif
} PGShmemHeader;
/* GUC variable */
/* GUC variables */
extern int shared_memory_type;
extern int huge_pages;
/* Possible values for huge_pages */
@ -52,6 +53,14 @@ typedef enum
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
@ -59,6 +68,14 @@ extern HANDLE UsedShmemSegID;
#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);