diff --git a/src/backend/utils/misc/guc-file.l b/src/backend/utils/misc/guc-file.l
index e6e11090abdced9d9c767927081f4edc3d3a2a00..bb9207a777a9da8823f983976f83169813428e6b 100644
--- a/src/backend/utils/misc/guc-file.l
+++ b/src/backend/utils/misc/guc-file.l
@@ -45,6 +45,8 @@ static unsigned int ConfigFileLineno;
 static const char *GUC_flex_fatal_errmsg;
 static sigjmp_buf *GUC_flex_fatal_jmp;
 
+static void FreeConfigVariable(ConfigVariable *item);
+
 /* flex fails to supply a prototype for yylex, so provide one */
 int GUC_yylex(void);
 
@@ -151,14 +153,66 @@ ProcessConfigFile(GucContext context)
 	 * file is in the data directory, we can't read it until the DataDir has
 	 * been set.
 	 */
-	if (DataDir &&
-		!ParseConfigFile(PG_AUTOCONF_FILENAME, NULL, false, 0, elevel,
-						 &head, &tail))
+	if (DataDir)
 	{
-		/* Syntax error(s) detected in the file, so bail out */
-		error = true;
-		ErrorConfFile = PG_AUTOCONF_FILENAME;
-		goto cleanup_list;
+		if (!ParseConfigFile(PG_AUTOCONF_FILENAME, NULL, false, 0, elevel,
+							 &head, &tail))
+		{
+			/* Syntax error(s) detected in the file, so bail out */
+			error = true;
+			ErrorConfFile = PG_AUTOCONF_FILENAME;
+			goto cleanup_list;
+		}
+	}
+	else
+	{
+		ConfigVariable *prev = NULL;
+
+		/*
+		 * Pick up only the data_directory if DataDir is not set, which
+		 * means that the configuration file is read for the first time and
+		 * PG_AUTOCONF_FILENAME file cannot be read yet. In this case,
+		 * we shouldn't pick any settings except the data_directory
+		 * from postgresql.conf because they might be overwritten
+		 * with the settings in PG_AUTOCONF_FILENAME file which will be
+		 * read later. OTOH, since it's ensured that data_directory doesn't
+		 * exist in PG_AUTOCONF_FILENAME file, it will never be overwritten
+		 * later.
+		 */
+		for (item = head; item;)
+		{
+			ConfigVariable *ptr = item;
+
+			item = item->next;
+			if (strcmp(ptr->name, "data_directory") != 0)
+			{
+				if (prev == NULL)
+					head = ptr->next;
+				else
+				{
+					prev->next = ptr->next;
+					/*
+					 * On removing last item in list, we need to update tail
+					 * to ensure that list will be maintianed.
+					 */
+					if (prev->next == NULL)
+						tail = prev;
+				}
+				FreeConfigVariable(ptr);
+			}
+			else
+				prev = ptr;
+		}
+
+		/*
+		 * Quick exit if data_directory is not present in list.
+		 *
+		 * Don't remember when we last successfully loaded the config file in
+		 * this case because that time will be set soon by subsequent load of
+		 * the config file.
+		 */
+		if (head == NULL)
+			return;
 	}
 
 	/*
@@ -677,7 +731,7 @@ ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel,
 							*tail_p = prev_item;
 					}
 
-					pfree(cur_item);
+					FreeConfigVariable(cur_item);
 					break;
 				}
 			}
@@ -857,6 +911,21 @@ cleanup:
 	return status;
 }
 
+/*
+ * Free a ConfigVariable
+ */
+static void
+FreeConfigVariable(ConfigVariable *item)
+{
+	if (item != NULL)
+	{
+		pfree(item->name);
+		pfree(item->value);
+		pfree(item->filename);
+		pfree(item);
+	}
+}
+
 /*
  * Free a list of ConfigVariables, including the names and the values
  */
@@ -870,10 +939,7 @@ FreeConfigVariables(ConfigVariable *list)
 	{
 		ConfigVariable *next = item->next;
 
-		pfree(item->name);
-		pfree(item->value);
-		pfree(item->filename);
-		pfree(item);
+		FreeConfigVariable(item);
 		item = next;
 	}
 }
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 9aa1bc4702a4191f4518e9d25c32f90126364c13..60e4354f6bc023fd83a21ea87cc867bba0aa8a1e 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -4339,6 +4339,13 @@ SelectConfigFiles(const char *userDoption, const char *progname)
 		return false;
 	}
 
+	/*
+	 * Read the configuration file for the first time. This time only
+	 * data_directory parameter is picked up to determine the data directory
+	 * so that we can read PG_AUTOCONF_FILENAME file next time. Then don't
+	 * forget to read the configuration file again later to pick up all the
+	 * parameters.
+	 */
 	ProcessConfigFile(PGC_POSTMASTER);
 
 	/*