Re: Perfomance degradation 9.3 (vs 9.2) for FreeBSD - Mailing list pgsql-hackers
From | Tatsuo Ishii |
---|---|
Subject | Re: Perfomance degradation 9.3 (vs 9.2) for FreeBSD |
Date | |
Msg-id | 20140703.191532.933784435488339338.t-ishii@sraoss.co.jp Whole thread Raw |
In response to | Re: Perfomance degradation 9.3 (vs 9.2) for FreeBSD (Andres Freund <andres@2ndquadrant.com>) |
Responses |
Re: Perfomance degradation 9.3 (vs 9.2) for FreeBSD
|
List | pgsql-hackers |
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);staticPGShmemHeader *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 bea 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 forcingWAL 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
pgsql-hackers by date: