diff --git a/configure b/configure
index 04d59bc..631c901 100755
--- a/configure
+++ b/configure
@@ -822,7 +822,6 @@ enable_tap_tests
 with_blocksize
 with_segsize
 with_wal_blocksize
-with_wal_segsize
 with_CC
 enable_depend
 enable_cassert
@@ -1520,8 +1519,6 @@ Optional Packages:
   --with-segsize=SEGSIZE  set table segment size in GB [1]
   --with-wal-blocksize=BLOCKSIZE
                           set WAL block size in kB [8]
-  --with-wal-segsize=SEGSIZE
-                          set WAL segment size in MB [16]
   --with-CC=CMD           set compiler (deprecated)
   --with-icu              build with ICU support
   --with-tcl              build Tcl modules (PL/Tcl)
@@ -3688,58 +3685,6 @@ cat >>confdefs.h <<_ACEOF
 #define XLOG_BLCKSZ ${XLOG_BLCKSZ}
 _ACEOF
 
-
-#
-# WAL segment size
-#
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for WAL segment size" >&5
-$as_echo_n "checking for WAL segment size... " >&6; }
-
-
-
-# Check whether --with-wal-segsize was given.
-if test "${with_wal_segsize+set}" = set; then :
-  withval=$with_wal_segsize;
-  case $withval in
-    yes)
-      as_fn_error $? "argument required for --with-wal-segsize option" "$LINENO" 5
-      ;;
-    no)
-      as_fn_error $? "argument required for --with-wal-segsize option" "$LINENO" 5
-      ;;
-    *)
-      wal_segsize=$withval
-      ;;
-  esac
-
-else
-  wal_segsize=16
-fi
-
-
-case ${wal_segsize} in
-  1) ;;
-  2) ;;
-  4) ;;
-  8) ;;
- 16) ;;
- 32) ;;
- 64) ;;
- 128) ;;
- 256) ;;
- 512) ;;
- 1024) ;;
-  *) as_fn_error $? "Invalid WAL segment size. Allowed values are 1,2,4,8,16,32,64,128,256,512,1024." "$LINENO" 5
-esac
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${wal_segsize}MB" >&5
-$as_echo "${wal_segsize}MB" >&6; }
-
-
-cat >>confdefs.h <<_ACEOF
-#define XLOG_SEG_SIZE (${wal_segsize} * 1024 * 1024)
-_ACEOF
-
-
 #
 # C compiler
 #
diff --git a/configure.in b/configure.in
index ed584f9..f3f89b9 100644
--- a/configure.in
+++ b/configure.in
@@ -344,37 +344,6 @@ AC_DEFINE_UNQUOTED([XLOG_BLCKSZ], ${XLOG_BLCKSZ}, [
 ])
 
 #
-# WAL segment size
-#
-AC_MSG_CHECKING([for WAL segment size])
-PGAC_ARG_REQ(with, wal-segsize, [SEGSIZE], [set WAL segment size in MB [16]],
-             [wal_segsize=$withval],
-             [wal_segsize=16])
-case ${wal_segsize} in
-  1) ;;
-  2) ;;
-  4) ;;
-  8) ;;
- 16) ;;
- 32) ;;
- 64) ;;
- 128) ;;
- 256) ;;
- 512) ;;
- 1024) ;;
-  *) AC_MSG_ERROR([Invalid WAL segment size. Allowed values are 1,2,4,8,16,32,64,128,256,512,1024.])
-esac
-AC_MSG_RESULT([${wal_segsize}MB])
-
-AC_DEFINE_UNQUOTED([XLOG_SEG_SIZE], [(${wal_segsize} * 1024 * 1024)], [
- XLOG_SEG_SIZE is the size of a single WAL file.  This must be a power of 2
- and larger than XLOG_BLCKSZ (preferably, a great deal larger than
- XLOG_BLCKSZ).
-
- Changing XLOG_SEG_SIZE requires an initdb.
-])
-
-#
 # C compiler
 #
 
diff --git a/doc/src/sgml/backup.sgml b/doc/src/sgml/backup.sgml
index 8cf63e4..c803dd3 100644
--- a/doc/src/sgml/backup.sgml
+++ b/doc/src/sgml/backup.sgml
@@ -562,7 +562,7 @@ tar -cf backup.tar /usr/local/pgsql/data
     produces an indefinitely long sequence of WAL records.  The system
     physically divides this sequence into WAL <firstterm>segment
     files</>, which are normally 16MB apiece (although the segment size
-    can be altered when building <productname>PostgreSQL</>).  The segment
+    can be altered during <application>initdb</>).  The segment
     files are given numeric names that reflect their position in the
     abstract WAL sequence.  When not using WAL archiving, the system
     normally creates just a few segment files and then
diff --git a/doc/src/sgml/installation.sgml b/doc/src/sgml/installation.sgml
index 26bfab1..7001bb7 100644
--- a/doc/src/sgml/installation.sgml
+++ b/doc/src/sgml/installation.sgml
@@ -1042,20 +1042,6 @@ su - postgres
       </varlistentry>
 
       <varlistentry>
-       <term><option>--with-wal-segsize=<replaceable>SEGSIZE</replaceable></option></term>
-       <listitem>
-        <para>
-         Set the <firstterm>WAL segment size</>, in megabytes.  This is
-         the size of each individual file in the WAL log.  It may be useful
-         to adjust this size to control the granularity of WAL log shipping.
-         The default size is 16 megabytes.
-         The value must be a power of 2 between 1 and 1024 (megabytes).
-         Note that changing this value requires an initdb.
-        </para>
-       </listitem>
-      </varlistentry>
-
-      <varlistentry>
        <term><option>--with-wal-blocksize=<replaceable>BLOCKSIZE</replaceable></option></term>
        <listitem>
         <para>
diff --git a/doc/src/sgml/ref/initdb.sgml b/doc/src/sgml/ref/initdb.sgml
index d9faa96..f37ba61 100644
--- a/doc/src/sgml/ref/initdb.sgml
+++ b/doc/src/sgml/ref/initdb.sgml
@@ -316,6 +316,20 @@ PostgreSQL documentation
      </varlistentry>
 
      <varlistentry>
+       <term><option>--wal-segsize=<replaceable>SEGSIZE</replaceable></option></term>
+       <listitem>
+        <para>
+         Set the <firstterm>WAL segment size</>, in megabytes.  This is
+         the size of each individual file in the WAL log.  It may be useful
+         to adjust this size to control the granularity of WAL log shipping.
+         The default size is 16 megabytes.
+         The value must be a power of 2 between 1 and 1024 (megabytes).
+         Note that this value is fixed for the lifetime of the database cluster.
+        </para>
+       </listitem>
+      </varlistentry>
+
+      <varlistentry>
       <term><option>-X <replaceable class="parameter">directory</replaceable></option></term>
       <term><option>--waldir=<replaceable class="parameter">directory</replaceable></option></term>
       <listitem>
diff --git a/doc/src/sgml/wal.sgml b/doc/src/sgml/wal.sgml
index a749b83..5ef119e 100644
--- a/doc/src/sgml/wal.sgml
+++ b/doc/src/sgml/wal.sgml
@@ -752,13 +752,12 @@
    <acronym>WAL</acronym> logs are stored in the directory
    <filename>pg_wal</filename> under the data directory, as a set of
    segment files, normally each 16 MB in size (but the size can be changed
-   by altering the <option>--with-wal-segsize</> configure option when
-   building the server).  Each segment is divided into pages, normally
-   8 kB each (this size can be changed via the <option>--with-wal-blocksize</>
-   configure option).  The log record headers are described in
-   <filename>access/xlogrecord.h</filename>; the record content is dependent
-   on the type of event that is being logged.  Segment files are given
-   ever-increasing numbers as names, starting at
+   by altering the <option>--wal-segsize</> initdb option).  Each segment is
+   divided into pages, normally 8 kB each (this size can be changed via the
+   <option>--with-wal-blocksize</> configure option).  The log record headers
+   are described in <filename>access/xlogrecord.h</filename>; the record content
+   is dependent on the type of event that is being logged.  Segment files are
+   given ever-increasing numbers as names, starting at
    <filename>000000010000000000000000</filename>.  The numbers do not wrap,
    but it will take a very, very long time to exhaust the
    available stock of numbers.
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 50fcbb7..45fb1fc 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -86,6 +86,7 @@ extern uint32 bootstrap_data_checksum_version;
 
 
 /* User-settable parameters */
+int			wal_segment_size = DEFAULT_XLOG_SEG_SIZE / XLOG_BLCKSZ;
 int			max_wal_size_mb = 1024;		/* 1 GB */
 int			min_wal_size_mb = 80;		/* 80 MB */
 int			wal_keep_segments = 0;
@@ -110,7 +111,8 @@ int			wal_retrieve_retry_interval = 5000;
 bool		XLOG_DEBUG = false;
 #endif
 
-uint32		XLogSegSize = XLOG_SEG_SIZE;
+uint32		XLogSegSize;
+
 /*
  * Number of WAL insertion locks to use. A higher value allows more insertions
  * to happen concurrently, but adds some CPU overhead to flushing the WAL,
@@ -734,14 +736,16 @@ static ControlFileData *ControlFile = NULL;
 	(((recptr) / XLOG_BLCKSZ) % (XLogCtl->XLogCacheBlck + 1))
 
 /*
- * These are the number of bytes in a WAL page and segment usable for WAL data.
+ * These are the number of bytes in a WAL page usable for WAL data.
  */
 #define UsableBytesInPage (XLOG_BLCKSZ - SizeOfXLogShortPHD)
-#define UsableBytesInSegment ((XLOG_SEG_SIZE / XLOG_BLCKSZ) * UsableBytesInPage - (SizeOfXLogLongPHD - SizeOfXLogShortPHD))
 
 /* Convert min_wal_size_mb and max wal_size_mb to equivalent segment count */
 #define ConvertToXSegs(x)	\
-	(x / (XLOG_SEG_SIZE / (1024 * 1024)))
+	(x / (wal_segment_size * XLOG_BLCKSZ/ (1024 * 1024)))
+
+/* The number of bytes in a WAL segment usable for WAL data. */
+static int	UsableBytesInSegment;
 
 /*
  * Private, possibly out-of-date copy of shared LogwrtResult.
@@ -4362,6 +4366,22 @@ rescanLatestTimeLine(void)
 }
 
 /*
+ * The actual XLogSegSize is only set after reading the ControlFile.
+ * Verify that min_wal_size and max_wal_size meet the minimum requirements.
+ */
+static void
+check_wal_size()
+{
+	if (ConvertToXSegs(min_wal_size_mb) < 2)
+		ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+						errmsg("\"min_wal_size\" is too low")));
+
+	if (ConvertToXSegs(max_wal_size_mb) < 2)
+		ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+						errmsg("\"max_wal_size\" is too low")));
+}
+
+/*
  * I/O routines for pg_control
  *
  * *ControlFile is a buffer in shared memory that holds an image of the
@@ -4464,6 +4484,8 @@ ReadControlFile(void)
 {
 	pg_crc32c	crc;
 	int			fd;
+	uint32		wal_segsz;
+	static char wal_segsz_str[20];
 
 	/*
 	 * Read data...
@@ -4566,13 +4588,6 @@ ReadControlFile(void)
 				  " but the server was compiled with XLOG_BLCKSZ %d.",
 				  ControlFile->xlog_blcksz, XLOG_BLCKSZ),
 				 errhint("It looks like you need to recompile or initdb.")));
-	if (ControlFile->xlog_seg_size != XLOG_SEG_SIZE)
-		ereport(FATAL,
-				(errmsg("database files are incompatible with server"),
-				 errdetail("The database cluster was initialized with XLOG_SEG_SIZE %d,"
-					   " but the server was compiled with XLOG_SEG_SIZE %d.",
-						   ControlFile->xlog_seg_size, XLOG_SEG_SIZE),
-				 errhint("It looks like you need to recompile or initdb.")));
 	if (ControlFile->nameDataLen != NAMEDATALEN)
 		ereport(FATAL,
 				(errmsg("database files are incompatible with server"),
@@ -4633,10 +4648,21 @@ ReadControlFile(void)
 				  " but the server was compiled without USE_FLOAT8_BYVAL."),
 				 errhint("It looks like you need to recompile or initdb.")));
 #endif
+	XLogSegSize = ControlFile->xlog_seg_size;
 
 	/* Make the initdb settings visible as GUC variables, too */
 	SetConfigOption("data_checksums", DataChecksumsEnabled() ? "yes" : "no",
 					PGC_INTERNAL, PGC_S_OVERRIDE);
+	wal_segsz = XLogSegSize / XLOG_BLCKSZ;
+	snprintf(wal_segsz_str, sizeof(wal_segsz_str), "%d", wal_segsz);
+	SetConfigOption("wal_segment_size", wal_segsz_str, PGC_INTERNAL,
+					PGC_S_OVERRIDE);
+
+	/* Check and update variables dependent on XLogSegSize */
+	check_wal_size();
+	UsableBytesInSegment = (wal_segment_size * UsableBytesInPage) -
+		(SizeOfXLogLongPHD - SizeOfXLogShortPHD);
+	CalculateCheckpointSegments();
 }
 
 void
@@ -4754,8 +4780,8 @@ XLOGChooseNumBuffers(void)
 	int			xbuffers;
 
 	xbuffers = NBuffers / 32;
-	if (xbuffers > XLOG_SEG_SIZE / XLOG_BLCKSZ)
-		xbuffers = XLOG_SEG_SIZE / XLOG_BLCKSZ;
+	if (xbuffers > wal_segment_size)
+		xbuffers = wal_segment_size;
 	if (xbuffers < 8)
 		xbuffers = 8;
 	return xbuffers;
@@ -4814,6 +4840,18 @@ XLOGShmemSize(void)
 	{
 		char		buf[32];
 
+		/*
+		 * The calculation of XLOGbuffers requires the run-time parameter
+		 * XLogSegSize which is set from the ControlFile. This value is
+		 * required to create the shared memory segment. Hence, temporarily
+		 * allocating space for reading ControlFile.
+		 */
+		if (!IsBootstrapProcessingMode())
+		{
+			ControlFile = palloc(sizeof(ControlFileData));
+			ReadControlFile();
+			pfree(ControlFile);
+		}
 		snprintf(buf, sizeof(buf), "%d", XLOGChooseNumBuffers());
 		SetConfigOption("wal_buffers", buf, PGC_POSTMASTER, PGC_S_OVERRIDE);
 	}
@@ -4959,6 +4997,16 @@ BootStrapXLOG(void)
 	struct timeval tv;
 	pg_crc32c	crc;
 
+	/* initdb passes the WAL segment size in an environment variable. */
+	XLogSegSize = pg_atoi(getenv("XLOG_SEG_SIZE"), sizeof(uint32), 0);
+
+	if (!IsValidXLogSegSize(XLogSegSize))
+	{
+		ereport(PANIC,
+				(errcode(ERRCODE_DATA_CORRUPTED),
+				 errmsg("Envoirnment variable XLOG_SEG_SIZE is corrupted")));
+	}
+
 	/*
 	 * Select a hopefully-unique system identifier code for this installation.
 	 * We use the result of gettimeofday(), including the fractional seconds
@@ -8137,6 +8185,9 @@ InitXLOGAccess(void)
 	ThisTimeLineID = XLogCtl->ThisTimeLineID;
 	Assert(ThisTimeLineID != 0 || IsBootstrapProcessingMode());
 
+	/* Set XLogSegSize */
+	XLogSegSize = ControlFile->xlog_seg_size;
+
 	/* Use GetRedoRecPtr to copy the RedoRecPtr safely */
 	(void) GetRedoRecPtr();
 	/* Also update our copy of doPageWrites. */
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 5446677..f9f358d 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -517,7 +517,6 @@ static int	block_size;
 static int	segment_size;
 static int	wal_block_size;
 static bool data_checksums;
-static int	wal_segment_size;
 static bool integer_datetimes;
 static bool assert_enabled;
 
@@ -715,9 +714,6 @@ typedef struct
 #if XLOG_BLCKSZ < 1024 || XLOG_BLCKSZ > (1024*1024)
 #error XLOG_BLCKSZ must be between 1KB and 1MB
 #endif
-#if XLOG_SEG_SIZE < (1024*1024) || XLOG_SEG_SIZE > (1024*1024*1024)
-#error XLOG_SEG_SIZE must be between 1MB and 1GB
-#endif
 
 static const char *memory_units_hint = gettext_noop("Valid units for this parameter are \"kB\", \"MB\", \"GB\", and \"TB\".");
 
@@ -2238,7 +2234,7 @@ static struct config_int ConfigureNamesInt[] =
 			GUC_UNIT_MB
 		},
 		&min_wal_size_mb,
-		5 * (XLOG_SEG_SIZE/ (1024 * 1024)), 2, MAX_KILOBYTES,
+		DEFAULT_MIN_WAL_SEGS * 16, 2, MAX_KILOBYTES,
 		NULL, NULL, NULL
 	},
 
@@ -2249,7 +2245,7 @@ static struct config_int ConfigureNamesInt[] =
 			GUC_UNIT_MB
 		},
 		&max_wal_size_mb,
-		64 * (XLOG_SEG_SIZE/ (1024 * 1024)), 2, MAX_KILOBYTES,
+		DEFAULT_MAX_WAL_SEGS * 16, 2, MAX_KILOBYTES,
 		NULL, assign_max_wal_size, NULL
 	},
 
@@ -2616,9 +2612,9 @@ static struct config_int ConfigureNamesInt[] =
 			GUC_UNIT_XBLOCKS | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
 		},
 		&wal_segment_size,
-		(XLOG_SEG_SIZE / XLOG_BLCKSZ),
-		(XLOG_SEG_SIZE / XLOG_BLCKSZ),
-		(XLOG_SEG_SIZE / XLOG_BLCKSZ),
+		DEFAULT_XLOG_SEG_SIZE / XLOG_BLCKSZ,
+		16,
+		INT_MAX,
 		NULL, NULL, NULL
 	},
 
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index 8a93bdc..06e7215 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -233,7 +233,7 @@
 
 #max_wal_senders = 10		# max number of walsender processes
 				# (change requires restart)
-#wal_keep_segments = 0		# in logfile segments, 16MB each; 0 disables
+#wal_keep_segments = 0		# in logfile segments; 0 disables
 #wal_sender_timeout = 60s	# in milliseconds; 0 disables
 
 #max_replication_slots = 10	# max number of replication slots
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 8dde1e8..df0009e 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -52,6 +52,7 @@
 #include <fcntl.h>
 #include <sys/stat.h>
 #include <unistd.h>
+#include <math.h>
 #include <signal.h>
 #include <time.h>
 
@@ -59,6 +60,7 @@
 #include "sys/mman.h"
 #endif
 
+#include "access/xlog_internal.h"
 #include "catalog/catalog.h"
 #include "catalog/pg_authid.h"
 #include "catalog/pg_class.h"
@@ -141,6 +143,8 @@ static bool sync_only = false;
 static bool show_setting = false;
 static bool data_checksums = false;
 static char *xlog_dir = "";
+static char *str_wal_segment_size = "";
+static int	wal_segment_size;
 
 
 /* internal vars */
@@ -1000,6 +1004,30 @@ test_config_settings(void)
 }
 
 /*
+ * Calculate the default wal_size in proper unit.
+ */
+static char *
+pretty_wal_size(int segment_count)
+{
+	double		val = wal_segment_size / (1024 * 1024) * segment_count;
+	double		temp_val;
+	char	   *result = malloc(10);
+
+	/*
+	 * The wal_segment_size ranges from 1MB to 1GB and the default
+	 * segment_count is 5 for min_wal_size and 64 for max_wal_size, so the
+	 * final values can range from 5MB to 64GB.
+	 */
+	temp_val = val/1024;
+	if (ceilf(temp_val) == temp_val)
+		snprintf(result, 10, "%dGB", (int) temp_val);
+	else
+		snprintf(result, 10, "%dMB", (int) val);
+
+	return result;
+}
+
+/*
  * set up all the config files
  */
 static void
@@ -1043,6 +1071,15 @@ setup_config(void)
 	conflines = replace_token(conflines, "#port = 5432", repltok);
 #endif
 
+	/* Set default max_wal_size and min_wal_size based on wal_segment_size */
+	snprintf(repltok, sizeof(repltok), "min_wal_size = %s",
+			 pretty_wal_size(DEFAULT_MIN_WAL_SEGS));
+	conflines = replace_token(conflines, "#min_wal_size = 80MB", repltok);
+
+	snprintf(repltok, sizeof(repltok), "max_wal_size = %s",
+			 pretty_wal_size(DEFAULT_MAX_WAL_SEGS));
+	conflines = replace_token(conflines, "#max_wal_size = 1GB", repltok);
+
 	snprintf(repltok, sizeof(repltok), "lc_messages = '%s'",
 			 escape_quotes(lc_messages));
 	conflines = replace_token(conflines, "#lc_messages = 'C'", repltok);
@@ -1350,6 +1387,9 @@ bootstrap_template1(void)
 	snprintf(cmd, sizeof(cmd), "LC_CTYPE=%s", lc_ctype);
 	putenv(pg_strdup(cmd));
 
+	snprintf(cmd, sizeof(cmd), "XLOG_SEG_SIZE=%d", wal_segment_size);
+	putenv(pg_strdup(cmd));
+
 	unsetenv("LC_ALL");
 
 	/* Also ensure backend isn't confused by this environment var: */
@@ -2276,6 +2316,7 @@ usage(const char *progname)
 	printf(_("  -U, --username=NAME       database superuser name\n"));
 	printf(_("  -W, --pwprompt            prompt for a password for the new superuser\n"));
 	printf(_("  -X, --waldir=WALDIR       location for the write-ahead log directory\n"));
+	printf(_("      --wal-segsize=SIZE    size of wal segment size\n"));
 	printf(_("\nLess commonly used options:\n"));
 	printf(_("  -d, --debug               generate lots of debugging output\n"));
 	printf(_("  -k, --data-checksums      use data page checksums\n"));
@@ -2965,6 +3006,7 @@ main(int argc, char *argv[])
 		{"no-sync", no_argument, NULL, 'N'},
 		{"sync-only", no_argument, NULL, 'S'},
 		{"waldir", required_argument, NULL, 'X'},
+		{"wal-segsize", required_argument, NULL, 12},
 		{"data-checksums", no_argument, NULL, 'k'},
 		{NULL, 0, NULL, 0}
 	};
@@ -3098,6 +3140,9 @@ main(int argc, char *argv[])
 			case 'X':
 				xlog_dir = pg_strdup(optarg);
 				break;
+			case 12:
+				str_wal_segment_size = pg_strdup(optarg);
+				break;
 			default:
 				/* getopt_long already emitted a complaint */
 				fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
@@ -3160,6 +3205,31 @@ main(int argc, char *argv[])
 
 	check_need_password(authmethodlocal, authmethodhost);
 
+	if (str_wal_segment_size == NULL || !strlen(str_wal_segment_size))
+		wal_segment_size = DEFAULT_XLOG_SEG_SIZE;
+	else
+	{
+		char	   *endptr;
+
+		/* Check if argument only has numeric value */
+		wal_segment_size = strtol(str_wal_segment_size, &endptr, 10);
+		if (*endptr != '\0')
+		{
+			fprintf(stderr, _("%s: --wal-segsize only accepts power 2 integer values between 1 and 1024\n"), progname);
+			exit(1);
+		}
+
+		/* Convert wal_segment_size from MB to bytes */
+		wal_segment_size = wal_segment_size * 1024 * 1024;
+
+		/* Check if wal_segment_size is valid */
+		if (!IsValidXLogSegSize(wal_segment_size))
+		{
+			fprintf(stderr, _("%s: Invalid WAL segment size %s\n"), progname, str_wal_segment_size);
+			exit(1);
+		}
+
+	}
 	get_restricted_token(progname);
 
 	setup_pgdata();
diff --git a/src/bin/pg_test_fsync/pg_test_fsync.c b/src/bin/pg_test_fsync/pg_test_fsync.c
index d65c0ab..b262ae8 100644
--- a/src/bin/pg_test_fsync/pg_test_fsync.c
+++ b/src/bin/pg_test_fsync/pg_test_fsync.c
@@ -62,7 +62,7 @@ static const char *progname;
 
 static int	secs_per_test = 5;
 static int	needs_unlink = 0;
-static char full_buf[XLOG_SEG_SIZE],
+static char full_buf[DEFAULT_XLOG_SEG_SIZE],
 		   *buf,
 		   *filename = FSYNC_FILENAME;
 static struct timeval start_t,
@@ -204,7 +204,7 @@ prepare_buf(void)
 	int			ops;
 
 	/* write random data into buffer */
-	for (ops = 0; ops < XLOG_SEG_SIZE; ops++)
+	for (ops = 0; ops < DEFAULT_XLOG_SEG_SIZE; ops++)
 		full_buf[ops] = random();
 
 	buf = (char *) TYPEALIGN(XLOG_BLCKSZ, full_buf);
@@ -221,7 +221,7 @@ test_open(void)
 	if ((tmpfile = open(filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR)) == -1)
 		die("could not open output file");
 	needs_unlink = 1;
-	if (write(tmpfile, full_buf, XLOG_SEG_SIZE) != XLOG_SEG_SIZE)
+	if (write(tmpfile, full_buf, DEFAULT_XLOG_SEG_SIZE) != DEFAULT_XLOG_SEG_SIZE)
 		die("write failed");
 
 	/* fsync now so that dirty buffers don't skew later tests */
diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h
index d23aab5..efb13d5 100644
--- a/src/include/access/xlog.h
+++ b/src/include/access/xlog.h
@@ -94,6 +94,7 @@ extern PGDLLIMPORT XLogRecPtr XactLastCommitEnd;
 extern bool reachedConsistency;
 
 /* these variables are GUC parameters related to XLOG */
+extern int	wal_segment_size;
 extern int	min_wal_size_mb;
 extern int	max_wal_size_mb;
 extern int	wal_keep_segments;
diff --git a/src/include/access/xlog_internal.h b/src/include/access/xlog_internal.h
index 00682fc..80cd3b4 100644
--- a/src/include/access/xlog_internal.h
+++ b/src/include/access/xlog_internal.h
@@ -90,6 +90,23 @@ typedef XLogLongPageHeaderData *XLogLongPageHeader;
  * by XLOG_SEG_SIZE.
  */
 extern uint32 XLogSegSize;
+#define XLOG_SEG_SIZE XLogSegSize
+
+/* XLogSegSize can range from 1MB to 1GB */
+#define XLogSegMinSize 1024 * 1024
+#define XLogSegMaxSize 1024 * 1024 * 1024
+
+/* Default number of min and max wal segments */
+#define DEFAULT_MIN_WAL_SEGS 5
+#define DEFAULT_MAX_WAL_SEGS 64
+
+/*	Check if the given size is a valid XLogSegSize */
+#define IsPower2(x) ((x & (x-1)) == 0)
+#define IsValidXLogSegSize(size) \
+	 ((size % (1024 * 1024) == 0) && \
+	  IsPower2(size / (1024 * 1024)) && \
+	  (size >= XLogSegMinSize && size <= XLogSegMaxSize))
+
 #define XLogSegmentsPerXLogId	(UINT64CONST(0x100000000) / XLOG_SEG_SIZE)
 
 #define XLogSegNoOffsetToRecPtr(segno, offset, dest) \
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index e1c1c9e..d110992 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -902,13 +902,6 @@
    */
 #undef XLOG_BLCKSZ
 
-/* XLOG_SEG_SIZE is the size of a single WAL file. This must be a power of 2
-   and larger than XLOG_BLCKSZ (preferably, a great deal larger than
-   XLOG_BLCKSZ). Changing XLOG_SEG_SIZE requires an initdb. */
-#undef XLOG_SEG_SIZE
-
-
-
 /* Number of bits in a file offset, on hosts where this is settable. */
 #undef _FILE_OFFSET_BITS
 
diff --git a/src/include/pg_config_manual.h b/src/include/pg_config_manual.h
index f3b3529..9158f77 100644
--- a/src/include/pg_config_manual.h
+++ b/src/include/pg_config_manual.h
@@ -14,6 +14,12 @@
  */
 
 /*
+ * This default value is used for wal_segment_size during initdb when no other
+ * value is specified with --walsegsize option.
+ */
+#define DEFAULT_XLOG_SEG_SIZE	(16*1024*1024)
+
+/*
  * Maximum length for identifiers (e.g. table names, column names,
  * function names).  Names actually are limited to one less byte than this,
  * because the length must include a trailing zero byte.
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index abac2c7..9433d35 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -178,8 +178,6 @@ s{PG_VERSION_STR "[^"]+"}{__STRINGIFY(x) #x\n#define __STRINGIFY2(z) __STRINGIFY
 		  1024, "\n";
 		print $o "#define XLOG_BLCKSZ ",
 		  1024 * $self->{options}->{wal_blocksize}, "\n";
-		print $o "#define XLOG_SEG_SIZE (", $self->{options}->{wal_segsize},
-		  " * 1024 * 1024)\n";
 
 		if ($self->{options}->{float4byval})
 		{
