Hello, How did this testing turn out?
Palle 3 jul 2014 kl. 12:15 skrev Tatsuo Ishii <is...@postgresql.org>: > Hi, > >> Hi, >> >> Attached you can find a short (compile tested only ) patch implementing >> a 'shared_memory_type' GUC, akin to 'dynamic_shared_memory_type'. Will >> only apply to 9.4, not 9.3, but it should be easy to convert for it. >> >> Greetings, >> >> Andres Freund > > I have rebased Andres's patch against 9.3-STABLE tree. Please take a > look at attached patches and let me know if you find anything strange. > > I am going to test the patch on a huge HP machine: DL980G7/64 > cores/2TB mem. With the patch I would be able to report back if using > SysV shared mem fixes the 9.3 performance problem. > > Best regards, > -- > Tatsuo Ishii > SRA OSS, Inc. Japan > English: http://www.sraoss.co.jp/index_en.php > Japanese:http://www.sraoss.co.jp > diff --git a/src/backend/port/sysv_shmem.c b/src/backend/port/sysv_shmem.c > index f746c81..e82054a 100644 > --- a/src/backend/port/sysv_shmem.c > +++ b/src/backend/port/sysv_shmem.c > @@ -72,6 +72,7 @@ static void IpcMemoryDetach(int status, Datum shmaddr); > static void IpcMemoryDelete(int status, Datum shmId); > static PGShmemHeader *PGSharedMemoryAttach(IpcMemoryKey key, > IpcMemoryId *shmid); > +static void *CreateAnonymousSegment(Size *size); > > > /* > @@ -389,49 +390,19 @@ PGSharedMemoryCreate(Size size, bool makePrivate, int > port) > * developer use, this shouldn't be a big problem. > */ > #ifndef EXEC_BACKEND > + if (shared_memory_type == SHMEM_TYPE_MMAP) > { > - long pagesize = sysconf(_SC_PAGE_SIZE); > - > - /* > - * Ensure request size is a multiple of pagesize. > - * > - * pagesize will, for practical purposes, always be a power of > two. > - * But just in case it isn't, we do it this way instead of using > - * TYPEALIGN(). > - */ > - if (pagesize > 0 && size % pagesize != 0) > - size += pagesize - (size % pagesize); > - > - /* > - * We assume that no one will attempt to run PostgreSQL 9.3 or > later > - * on systems that are ancient enough that anonymous shared > memory is > - * not supported, such as pre-2.4 versions of Linux. If that > turns > - * out to be false, we might need to add a run-time test here > and do > - * this only if the running kernel supports it. > - */ > - AnonymousShmem = mmap(NULL, size, PROT_READ | PROT_WRITE, > PG_MMAP_FLAGS, > - -1, 0); > - if (AnonymousShmem == MAP_FAILED) > - { > - int saved_errno = errno; > - > - ereport(FATAL, > - (errmsg("could not map anonymous shared > memory: %m"), > - (saved_errno == ENOMEM) ? > - errhint("This error usually means that > PostgreSQL's request " > - "for a shared memory segment exceeded > available memory " > - "or swap space. To reduce the request > size (currently " > - "%lu bytes), reduce PostgreSQL's > shared memory usage, " > - "perhaps by reducing > shared_buffers or " > - "max_connections.", > - (unsigned long) size) : 0)); > - } > + AnonymousShmem = CreateAnonymousSegment(&size); > AnonymousShmemSize = size; > - > /* Now we need only allocate a minimal-sized SysV shmem block. > */ > sysvsize = sizeof(PGShmemHeader); > } > + else > #endif > + { > + Assert(shared_memory_type == SHMEM_TYPE_SYSV); > + sysvsize = size; > + } > > /* Make sure PGSharedMemoryAttach doesn't fail without need */ > UsedShmemSegAddr = NULL; > @@ -631,3 +602,47 @@ PGSharedMemoryAttach(IpcMemoryKey key, IpcMemoryId > *shmid) > > return hdr; > } > + > +/* > + * Creates an anonymous mmap()ed shared memory segment. > + * > + * Pass the requested size in *size. This function will modify *size to the > + * actual size of the allocation, if it ends up allocating a segment that is > + * larger than requested. > + */ > +#ifndef EXEC_BACKEND > +static void * > +CreateAnonymousSegment(Size *size) > +{ > + Size allocsize = *size; > + void *ptr = MAP_FAILED; > + int mmap_errno = 0; > + > + /* > + * use the original size, not the rounded up value, when falling back > + * to non-huge pages. > + */ > + allocsize = *size; > + ptr = mmap(NULL, allocsize, PROT_READ | PROT_WRITE, > + PG_MMAP_FLAGS, -1, 0); > + mmap_errno = errno; > + > + if (ptr == MAP_FAILED) > + { > + errno = mmap_errno; > + ereport(FATAL, > + (errmsg("could not map anonymous shared memory: > %m"), > + (mmap_errno == ENOMEM) ? > + errhint("This error usually means that > PostgreSQL's request " > + "for a shared memory segment exceeded > available memory, " > + "swap space or huge pages. To reduce > the request size " > + "(currently %zu bytes), reduce > PostgreSQL's shared " > + "memory usage, perhaps by reducing > shared_buffers or " > + "max_connections.", > + *size) : 0)); > + } > + > + *size = allocsize; > + return ptr; > +} > +#endif > diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c > index 918ac51..51dccdc 100644 > --- a/src/backend/storage/ipc/ipci.c > +++ b/src/backend/storage/ipc/ipci.c > @@ -39,6 +39,8 @@ > #include "storage/sinvaladt.h" > #include "storage/spin.h" > > +/* GUCs */ > +int shared_memory_type = DEFAULT_SHARED_MEMORY_TYPE; > > shmem_startup_hook_type shmem_startup_hook = NULL; > > diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c > index 2b6527f..2945a68 100644 > --- a/src/backend/utils/misc/guc.c > +++ b/src/backend/utils/misc/guc.c > @@ -61,6 +61,7 @@ > #include "replication/walreceiver.h" > #include "replication/walsender.h" > #include "storage/bufmgr.h" > +#include "storage/pg_shmem.h" > #include "storage/standby.h" > #include "storage/fd.h" > #include "storage/proc.h" > @@ -378,6 +379,19 @@ static const struct config_enum_entry > synchronous_commit_options[] = { > {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 > */ > @@ -3328,6 +3342,16 @@ static struct config_enum ConfigureNamesEnum[] = > }, > > { > + {"shared_memory_type", PGC_POSTMASTER, RESOURCES_MEM, > + gettext_noop("Selects the shared memory implementation > used."), > + 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."), > NULL > diff --git a/src/backend/utils/misc/postgresql.conf.sample > b/src/backend/utils/misc/postgresql.conf.sample > index 18196f8..022cf4d 100644 > --- a/src/backend/utils/misc/postgresql.conf.sample > +++ b/src/backend/utils/misc/postgresql.conf.sample > @@ -124,6 +124,13 @@ > #maintenance_work_mem = 16MB # min 1MB > #max_stack_depth = 2MB # min 100kB > > +#shared_memory_type = mmap # the default is the first option > + # supported by the operating system: > + # mmap > + # sysv > + # windows > +#dynamic_shared_memory_type = posix # the default is the first option > + > # - Disk - > > #temp_file_limit = -1 # limits per-session temp file space > diff --git a/src/include/storage/pg_shmem.h b/src/include/storage/pg_shmem.h > index 6ece82b..9c3b6d9 100644 > --- a/src/include/storage/pg_shmem.h > +++ b/src/include/storage/pg_shmem.h > @@ -38,6 +38,27 @@ typedef struct PGShmemHeader /* standard header for > all Postgres shmem */ > #endif > } PGShmemHeader; > > +/* GUC variable */ > +extern int huge_pages; > +/* Possible values for shared_memory_type */ > +typedef enum > +{ > + SHMEM_TYPE_WINDOWS, > + SHMEM_TYPE_SYSV, > + SHMEM_TYPE_MMAP > +} PGShmemType; > + > +#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 > + > +/* GUC variables */ > +extern int shared_memory_type; > +extern int huge_pages; > > #ifdef EXEC_BACKEND > #ifndef WIN32
signature.asc
Description: Message signed with OpenPGP using GPGMail