commit f93daeba03a6910e6ac8a3cf262503504db1692f
Author: Alexander Korotkov <akorotkov@postgresql.org>
Date:   Mon Feb 10 21:35:43 2020 +0300

    Provide GUC for skipping shared buffers in core dump

diff --git a/configure b/configure
index 59e181a8855..0a7590f8c6e 100755
--- a/configure
+++ b/configure
@@ -16522,6 +16522,19 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
 fi
 
 
+ac_fn_c_check_decl "$LINENO" "MADV_DONTDUMP" "ac_cv_have_decl_MADV_DONTDUMP" "#include <sys/mman.h>
+"
+if test "x$ac_cv_have_decl_MADV_DONTDUMP" = xyes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_MADV_DONTDUMP $ac_have_decl
+_ACEOF
+
+
 # --------------------
 # Run tests below here
 # --------------------
diff --git a/configure.in b/configure.in
index 57346bc89bd..5cd355e160d 100644
--- a/configure.in
+++ b/configure.in
@@ -1896,6 +1896,8 @@ related to locating shared libraries.  Check the file 'config.log'
 for the exact reason.]])],
 [AC_MSG_RESULT([cross-compiling])])
 
+AC_CHECK_DECLS(MADV_DONTDUMP, [], [], [#include <sys/mman.h>])
+
 # --------------------
 # Run tests below here
 # --------------------
diff --git a/src/backend/port/sysv_shmem.c b/src/backend/port/sysv_shmem.c
index 198a6985bf3..42c98c05d30 100644
--- a/src/backend/port/sysv_shmem.c
+++ b/src/backend/port/sysv_shmem.c
@@ -37,6 +37,7 @@
 #include "storage/fd.h"
 #include "storage/ipc.h"
 #include "storage/pg_shmem.h"
+#include "utils/freepage.h"
 #include "utils/guc.h"
 #include "utils/pidfile.h"
 
@@ -98,6 +99,7 @@ void	   *UsedShmemSegAddr = NULL;
 
 static Size AnonymousShmemSize;
 static void *AnonymousShmem = NULL;
+static Size ShmemPageSize = FPM_PAGE_SIZE;
 
 static void *InternalIpcMemoryCreate(IpcMemoryKey memKey, Size size);
 static void IpcMemoryDetach(int status, Datum shmaddr);
@@ -556,6 +558,9 @@ CreateAnonymousSegment(Size *size)
 		if (huge_pages == HUGE_PAGES_TRY && ptr == MAP_FAILED)
 			elog(DEBUG1, "mmap(%zu) with MAP_HUGETLB failed, huge pages disabled: %m",
 				 allocsize);
+
+		if (ptr != MAP_FAILED)
+			ShmemPageSize = hugepagesize;
 	}
 #endif
 
@@ -900,3 +905,9 @@ PGSharedMemoryDetach(void)
 		AnonymousShmem = NULL;
 	}
 }
+
+Size
+PGSharedPageSize(void)
+{
+	return ShmemPageSize;
+}
diff --git a/src/backend/port/win32_shmem.c b/src/backend/port/win32_shmem.c
index 30b07303ff7..013ad6d58ad 100644
--- a/src/backend/port/win32_shmem.c
+++ b/src/backend/port/win32_shmem.c
@@ -16,6 +16,7 @@
 #include "storage/dsm.h"
 #include "storage/ipc.h"
 #include "storage/pg_shmem.h"
+#include "utils/freepage.h"
 
 /*
  * Early in a process's life, Windows asynchronously creates threads for the
@@ -42,6 +43,7 @@ void	   *ShmemProtectiveRegion = NULL;
 HANDLE		UsedShmemSegID = INVALID_HANDLE_VALUE;
 void	   *UsedShmemSegAddr = NULL;
 static Size UsedShmemSegSize = 0;
+static Size ShmemPageSize = FPM_PAGE_SIZE;
 
 static bool EnableLockPagesPrivilege(int elevel);
 static void pgwin32_SharedMemoryDelete(int status, Datum shmId);
@@ -319,6 +321,9 @@ retry:
 		break;
 	}
 
+	if (flProtect & SEC_LARGE_PAGES)
+		ShmemPageSize = largePageSize;
+
 	/*
 	 * If the last call in the loop still returned ERROR_ALREADY_EXISTS, this
 	 * shared memory segment exists and we assume it belongs to somebody else.
@@ -597,3 +602,9 @@ pgwin32_ReserveSharedMemoryRegion(HANDLE hChild)
 
 	return true;
 }
+
+Size
+PGSharedPageSize(void)
+{
+	return ShmemPageSize;
+}
diff --git a/src/backend/storage/buffer/buf_init.c b/src/backend/storage/buffer/buf_init.c
index af62d48c323..6bac5a6ae1f 100644
--- a/src/backend/storage/buffer/buf_init.c
+++ b/src/backend/storage/buffer/buf_init.c
@@ -14,14 +14,23 @@
  */
 #include "postgres.h"
 
+#if HAVE_DECL_MADV_DONTDUMP
+#include <errno.h>
+#include <sys/mman.h>
+#endif
+
 #include "storage/buf_internals.h"
 #include "storage/bufmgr.h"
+#include "storage/pg_shmem.h"
 
 BufferDescPadded *BufferDescriptors;
 char	   *BufferBlocks;
 LWLockMinimallyPadded *BufferIOLWLockArray = NULL;
 WritebackContext BackendWritebackContext;
 CkptSortItem *CkptBufferIds;
+#if HAVE_DECL_MADV_DONTDUMP
+bool		core_dump_no_shared_buffers;
+#endif
 
 
 /*
@@ -148,6 +157,26 @@ InitBufferPool(void)
 	/* Initialize per-backend file flush context */
 	WritebackContextInit(&BackendWritebackContext,
 						 &backend_flush_after);
+
+#if HAVE_DECL_MADV_DONTDUMP
+	if (core_dump_no_shared_buffers)
+	{
+		Size		pagesize = PGSharedPageSize();
+		Pointer		ptr = BufferBlocks;
+		Size		sz = NBuffers * (Size) BLCKSZ;
+
+		ptr = ptr + (pagesize - 1 - ((uintptr_t) (ptr - 1)) & (pagesize - 1));
+
+		sz -= ((Pointer) BufferBlocks - ptr);
+		sz -= sz & (pagesize - 1);
+
+		if (madvise(ptr, sz, MADV_DONTDUMP) != 0)
+		{
+			char *s = strerror(errno);
+			elog(LOG, "madvise error: %s", s);
+		}
+	}
+#endif
 }
 
 /*
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 8228e1f3903..c578528b0bb 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -2037,6 +2037,19 @@ static struct config_bool ConfigureNamesBool[] =
 		NULL, NULL, NULL
 	},
 
+#if HAVE_DECL_MADV_DONTDUMP
+	{
+		{"core_dump_no_shared_buffers", PGC_POSTMASTER, DEVELOPER_OPTIONS,
+			gettext_noop("Exclude shared buffers from core dumps."),
+			NULL,
+			GUC_NOT_IN_SAMPLE
+		},
+		&core_dump_no_shared_buffers,
+		false,
+		NULL, NULL, NULL
+	},
+#endif
+
 	/* End-of-list marker */
 	{
 		{NULL, 0, 0, NULL, NULL}, NULL, false, NULL, NULL, NULL
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index be39cfde4bb..350cf8d36ec 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -150,6 +150,10 @@
    to 0 if you don't. */
 #undef HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN
 
+/* Define to 1 if you have the declaration of HAVE_DECL_MADV_DONTDUMP and to 0 if you
+   don't. */
+#undef HAVE_DECL_MADV_DONTDUMP
+
 /* Define to 1 if you have the declaration of `posix_fadvise', and to 0 if you
    don't. */
 #undef HAVE_DECL_POSIX_FADVISE
diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h
index 73c7e9ba386..26e0436d3b7 100644
--- a/src/include/storage/bufmgr.h
+++ b/src/include/storage/bufmgr.h
@@ -65,6 +65,7 @@ extern int	bgwriter_flush_after;
 
 /* in buf_init.c */
 extern PGDLLIMPORT char *BufferBlocks;
+extern bool	core_dump_no_shared_buffers;
 
 /* in guc.c */
 extern int	effective_io_concurrency;
diff --git a/src/include/storage/pg_shmem.h b/src/include/storage/pg_shmem.h
index 0de26b34276..cc082ef6026 100644
--- a/src/include/storage/pg_shmem.h
+++ b/src/include/storage/pg_shmem.h
@@ -86,5 +86,6 @@ extern PGShmemHeader *PGSharedMemoryCreate(Size size,
 										   PGShmemHeader **shim);
 extern bool PGSharedMemoryIsInUse(unsigned long id1, unsigned long id2);
 extern void PGSharedMemoryDetach(void);
+extern Size PGSharedPageSize(void);
 
 #endif							/* PG_SHMEM_H */
