Re: Perfomance degradation 9.3 (vs 9.2) for FreeBSD

Поиск
Список
Период
Сортировка
От Tatsuo Ishii
Тема Re: Perfomance degradation 9.3 (vs 9.2) for FreeBSD
Дата
Msg-id 20140703.191532.933784435488339338.t-ishii@sraoss.co.jp
обсуждение исходный текст
Ответ на Re: Perfomance degradation 9.3 (vs 9.2) for FreeBSD  (Andres Freund <andres@2ndquadrant.com>)
Ответы Re: Perfomance degradation 9.3 (vs 9.2) for FreeBSD  (Palle Girgensohn <girgen@FreeBSD.org>)
Список 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 по дате отправления:

Предыдущее
От: Gavin Flower
Дата:
Сообщение: Re: gaussian distribution pgbench
Следующее
От: Kyotaro HORIGUCHI
Дата:
Сообщение: Re: WAL replay bugs