diff --git a/src/port/pgmkdirp.c b/src/port/pgmkdirp.c
index 7d7cea4dd0e..3e6b06fce79 100644
--- a/src/port/pgmkdirp.c
+++ b/src/port/pgmkdirp.c
@@ -56,7 +56,6 @@
 int
 pg_mkdir_p(char *path, int omode)
 {
-	struct stat sb;
 	mode_t		numask,
 				oumask;
 	int			last,
@@ -119,24 +118,46 @@ pg_mkdir_p(char *path, int omode)
 		if (last)
 			(void) umask(oumask);
 
-		/* check for pre-existing directory */
-		if (stat(path, &sb) == 0)
+		if (mkdir(path, last ? omode : S_IRWXU | S_IRWXG | S_IRWXO) < 0)
 		{
-			if (!S_ISDIR(sb.st_mode))
+			/*
+			 * If we got EEXIST because there's already a directory there,
+			 * don't complain.
+			 */
+#ifndef WIN32
+			int			save_errno = errno;
+			struct stat sb;
+
+			if (save_errno != EEXIST ||
+				stat(path, &sb) != 0 ||
+				!S_ISDIR(sb.st_mode))
 			{
-				if (last)
-					errno = EEXIST;
-				else
-					errno = ENOTDIR;
+				/* Don't let stat replace mkdir's errno */
+				errno = save_errno;
 				retval = -1;
 				break;
 			}
+#else							/* WIN32 */
+			/*
+			 * On Windows, stat() opens a handle and can transiently fail on a
+			 * directory another process is concurrently creating.  Probe with
+			 * a path-based attribute query instead: it requests only
+			 * FILE_READ_ATTRIBUTES and is exempt from share-mode denial, so
+			 * it reliably sees a concurrently-created directory.  We assume
+			 * GetFileAttributes() won't change errno.
+			 */
+			DWORD		attr = GetFileAttributes(path);
+
+			if (errno != EEXIST ||
+				attr == INVALID_FILE_ATTRIBUTES ||
+				!(attr & FILE_ATTRIBUTE_DIRECTORY))
+			{
+				retval = -1;
+				break;
+			}
+#endif							/* WIN32 */
 		}
-		else if (mkdir(path, last ? omode : S_IRWXU | S_IRWXG | S_IRWXO) < 0)
-		{
-			retval = -1;
-			break;
-		}
+
 		if (!last)
 			*p = '/';
 	}
