diff --git a/src/backend/storage/ipc/dsm.c b/src/backend/storage/ipc/dsm.c
index 327d685..efbd2dd 100644
--- a/src/backend/storage/ipc/dsm.c
+++ b/src/backend/storage/ipc/dsm.c
@@ -886,6 +886,40 @@ dsm_keep_mapping(dsm_segment *seg)
 }
 
 /*
+ * Keep a dynamic shared memory segment until end of postmaster.
+ *
+ * This function should not be called more than once per segment,
+ * calling it more number of times will create unnecessary handles
+ * which will consume more memory for no good reason. Though this
+ * behaviour is specific to windows, there is no real benefit for
+ * calling it more than once on other platforms either.
+ *
+ * By default, segments are owned by the current resource owner,
+ * which typically means they stick around for the duration of the
+ * current query only.
+ */
+void
+dsm_keep_segment(dsm_segment *seg)
+{
+	/*
+	 * Bump reference count for this segment in shared memory. This will
+	 * ensure that even if there is no session which is attached to this
+	 * segment, it will stay till postmaster lifetime.
+	 */
+	LWLockAcquire(DynamicSharedMemoryControlLock, LW_EXCLUSIVE);
+	dsm_control->item[seg->control_slot].refcnt++;
+	LWLockRelease(DynamicSharedMemoryControlLock);
+
+	dsm_copy_impl_handle(seg->impl_private, seg->handle);
+
+	if (seg->resowner != NULL)
+	{
+		ResourceOwnerForgetDSM(seg->resowner, seg);
+		seg->resowner = NULL;
+	}
+}
+
+/*
  * Find an existing mapping for a shared memory segment, if there is one.
  */
 dsm_segment *
diff --git a/src/backend/storage/ipc/dsm_impl.c b/src/backend/storage/ipc/dsm_impl.c
index a8d8a64..b6bc93a 100644
--- a/src/backend/storage/ipc/dsm_impl.c
+++ b/src/backend/storage/ipc/dsm_impl.c
@@ -67,6 +67,7 @@
 #include "storage/fd.h"
 #include "utils/guc.h"
 #include "utils/memutils.h"
+#include "postmaster/postmaster.h"
 
 #ifdef USE_DSM_POSIX
 static bool dsm_impl_posix(dsm_op op, dsm_handle handle, Size request_size,
@@ -113,6 +114,8 @@ int dynamic_shared_memory_type;
 /* Size of buffer to be used for zero-filling. */
 #define ZBUFFER_SIZE				8192
 
+#define SEGMENT_NAME_PREFIX			"Global/PostgreSQL"
+
 /*------
  * Perform a low-level shared memory operation in a platform-specific way,
  * as dictated by the selected implementation.  Each implementation is
@@ -635,7 +638,7 @@ dsm_impl_windows(dsm_op op, dsm_handle handle, Size request_size,
 	 * convention similar to main shared memory. We can change here once
 	 * issue mentioned in GetSharedMemName is resolved.
 	 */
-	snprintf(name, 64, "Global/PostgreSQL.%u", handle);
+	snprintf(name, 64, "%s.%u", SEGMENT_NAME_PREFIX, handle);
 
 	/*
 	 * Handle teardown cases.  Since Windows automatically destroys the object
@@ -982,6 +985,48 @@ dsm_impl_mmap(dsm_op op, dsm_handle handle, Size request_size,
 }
 #endif
 
+#ifdef WIN32
+/*
+ * The purpose of this function is to duplicate segment handle for
+ * postmaster process, as it automatically drops segment if all
+ * referring sessions end. Copying segment handle for postmaster
+ * process ensures that it will retain the segment for postmaster
+ * lifetime. This is a typical behavior for windows, other platforms
+ * don't need to make any such copy.
+ */
+void dsm_copy_impl_handle(void *impl_private, dsm_handle handle)
+{
+	HANDLE		hmap;
+
+	if (!DuplicateHandle(GetCurrentProcess(),
+						 impl_private,
+						 PostmasterHandle,
+						 &hmap,
+						 0,
+						 FALSE,
+						 DUPLICATE_SAME_ACCESS))
+	{
+		char		name[64];
+
+		snprintf(name, 64, "%s.%u", SEGMENT_NAME_PREFIX, handle);
+		_dosmaperr(GetLastError());
+		ereport(ERROR,
+				(errcode_for_dynamic_shared_memory(),
+				 errmsg("could not retain segment \"%s\" for postmaster lifetime: %m",
+						name)));
+	}
+}
+#else
+/*
+ * For non-windows platform, this function is no-op.
+ */
+void dsm_copy_impl_handle(void *impl_private, dsm_handle handle)
+{
+	/* no-op */
+}
+
+#endif
+
 static int
 errcode_for_dynamic_shared_memory()
 {
diff --git a/src/include/storage/dsm.h b/src/include/storage/dsm.h
index 71901bf..16afef3 100644
--- a/src/include/storage/dsm.h
+++ b/src/include/storage/dsm.h
@@ -30,6 +30,7 @@ extern void dsm_detach(dsm_segment *seg);
 
 /* Resource management functions. */
 extern void dsm_keep_mapping(dsm_segment *seg);
+extern void dsm_keep_segment(dsm_segment *seg);
 extern dsm_segment *dsm_find_mapping(dsm_handle h);
 
 /* Informational functions. */
diff --git a/src/include/storage/dsm_impl.h b/src/include/storage/dsm_impl.h
index f2d0c64..bfed25d 100644
--- a/src/include/storage/dsm_impl.h
+++ b/src/include/storage/dsm_impl.h
@@ -72,4 +72,7 @@ extern bool dsm_impl_op(dsm_op op, dsm_handle handle, Size request_size,
 /* Some implementations cannot resize segments.  Can this one? */
 extern bool dsm_impl_can_resize(void);
 
+/* create a copy of implementation specific handle in postmaster process. */
+extern void dsm_copy_impl_handle(void *impl_private, dsm_handle handle);
+
 #endif   /* DSM_IMPL_H */
