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

Attachment: signature.asc
Description: Message signed with OpenPGP using GPGMail

Reply via email to