diff --git a/configure b/configure
index 0f143a0..341b462 100755
--- a/configure
+++ b/configure
@@ -816,7 +816,6 @@ enable_tap_tests
 with_blocksize
 with_segsize
 with_wal_blocksize
-with_wal_segsize
 with_CC
 enable_depend
 enable_cassert
@@ -1508,8 +1507,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-tcl              build Tcl modules (PL/Tcl)
   --with-tclconfig=DIR    tclConfig.sh is in DIR
@@ -3674,54 +3671,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) ;;
-  *) as_fn_error $? "Invalid WAL segment size. Allowed values are 1,2,4,8,16,32,64." "$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 b9831bc..8be3185 100644
--- a/configure.in
+++ b/configure.in
@@ -344,33 +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) ;;
-  *) AC_MSG_ERROR([Invalid WAL segment size. Allowed values are 1,2,4,8,16,32,64.])
-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/installation.sgml b/doc/src/sgml/installation.sgml
index 4431ed7..09ab77f 100644
--- a/doc/src/sgml/installation.sgml
+++ b/doc/src/sgml/installation.sgml
@@ -1053,20 +1053,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 64 (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/wal.sgml b/doc/src/sgml/wal.sgml
index 346aa76..7f95863 100644
--- a/doc/src/sgml/wal.sgml
+++ b/doc/src/sgml/wal.sgml
@@ -752,7 +752,7 @@
    <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
+   by altering the <option>--with-wal-segsize</> initdb 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
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index aa9ee5a..c880b14 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -106,6 +106,8 @@ int			wal_retrieve_retry_interval = 5000;
 bool		XLOG_DEBUG = false;
 #endif
 
+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,
@@ -4274,6 +4276,8 @@ ReadControlFile(void)
 {
 	pg_crc32c	crc;
 	int			fd;
+	uint32		wal_segsz;
+	static char wal_segsz_str[20];
 
 	/*
 	 * Read data...
@@ -4374,13 +4378,7 @@ 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.")));
+	XLogSegSize = ControlFile->xlog_seg_size;
 	if (ControlFile->nameDataLen != NAMEDATALEN)
 		ereport(FATAL,
 				(errmsg("database files are incompatible with server"),
@@ -4461,6 +4459,12 @@ ReadControlFile(void)
 	/* Make the initdb settings visible as GUC variables, too */
 	SetConfigOption("data_checksums", DataChecksumsEnabled() ? "yes" : "no",
 					PGC_INTERNAL, PGC_S_OVERRIDE);
+
+	wal_segsz = XLOG_SEG_SIZE / 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);
+
 }
 
 void
@@ -4768,6 +4772,13 @@ BootStrapXLOG(void)
 	pg_crc32c	crc;
 
 	/*
+	 * initdb passes the WAL segment size in an environment variable. We don't
+	 * bother doing any sanity checking, we already check in initdb that the
+	 * user gives a sane value.
+	 */
+	XLogSegSize = pg_atoi(getenv("XLOG_SEG_SIZE"), sizeof(uint32), 0);
+
+	/*
 	 * Select a hopefully-unique system identifier code for this installation.
 	 * We use the result of gettimeofday(), including the fractional seconds
 	 * field, as being about as unique as we can easily get.  (Think not to
@@ -7910,6 +7921,9 @@ InitXLOGAccess(void)
 	ThisTimeLineID = XLogCtl->ThisTimeLineID;
 	Assert(ThisTimeLineID != 0 || IsBootstrapProcessingMode());
 
+	/* Same for XLOG_SEG_SIZE */
+	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/replication/repl_gram.y b/src/backend/replication/repl_gram.y
index e75516c..94853e0 100644
--- a/src/backend/replication/repl_gram.y
+++ b/src/backend/replication/repl_gram.y
@@ -61,6 +61,7 @@ Node *replication_parse_result;
 /* Keyword tokens. */
 %token K_BASE_BACKUP
 %token K_IDENTIFY_SYSTEM
+%token K_SHOW_WAL_SEGSZ
 %token K_START_REPLICATION
 %token K_CREATE_REPLICATION_SLOT
 %token K_DROP_REPLICATION_SLOT
@@ -82,7 +83,7 @@ Node *replication_parse_result;
 %type <node>	command
 %type <node>	base_backup start_replication start_logical_replication
 				create_replication_slot drop_replication_slot identify_system
-				timeline_history
+				timeline_history show_wal_segsz
 %type <list>	base_backup_opt_list
 %type <defelt>	base_backup_opt
 %type <uintval>	opt_timeline
@@ -112,6 +113,7 @@ command:
 			| create_replication_slot
 			| drop_replication_slot
 			| timeline_history
+			| show_wal_segsz
 			;
 
 /*
@@ -125,6 +127,16 @@ identify_system:
 			;
 
 /*
+ * SHOW_WAL_SEGSZ
+ */
+show_wal_segsz:
+			K_SHOW_WAL_SEGSZ
+				{
+					$$ = (Node *) makeNode(ShowWalSegSzCmd);
+				}
+			;
+
+/*
  * BASE_BACKUP [LABEL '<label>'] [PROGRESS] [FAST] [WAL] [NOWAIT]
  * [MAX_RATE %d] [TABLESPACE_MAP]
  */
diff --git a/src/backend/replication/repl_scanner.l b/src/backend/replication/repl_scanner.l
index 9f50ce6..f6cf993 100644
--- a/src/backend/replication/repl_scanner.l
+++ b/src/backend/replication/repl_scanner.l
@@ -83,6 +83,7 @@ identifier		{ident_start}{ident_cont}*
 BASE_BACKUP			{ return K_BASE_BACKUP; }
 FAST			{ return K_FAST; }
 IDENTIFY_SYSTEM		{ return K_IDENTIFY_SYSTEM; }
+SHOW_WAL_SEGSZ		{ return K_SHOW_WAL_SEGSZ; }
 LABEL			{ return K_LABEL; }
 NOWAIT			{ return K_NOWAIT; }
 PROGRESS			{ return K_PROGRESS; }
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index d80bcc0..4d2d832 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -293,6 +293,41 @@ WalSndShutdown(void)
 	abort();					/* keep the compiler quiet */
 }
 
+static void
+FetchWalSegSz(void)
+{
+	StringInfoData buf;
+	char		wal_segsz[32];
+	Size		len;
+
+	snprintf(wal_segsz, sizeof(wal_segsz), "%u", XLOG_SEG_SIZE);
+
+	/* Send a RowDescription message */
+	pq_beginmessage(&buf, 'T');
+	pq_sendint(&buf, 1, 2);		/* 1 field */
+
+	/* first field */
+	pq_sendstring(&buf, "wal_segment_size");	/* col name */
+	pq_sendint(&buf, 0, 4);		/* table oid */
+	pq_sendint(&buf, 0, 2);		/* attnum */
+	pq_sendint(&buf, INT4OID, 4);		/* type oid */
+	pq_sendint(&buf, -1, 2);	/* typlen */
+	pq_sendint(&buf, 0, 4);		/* typmod */
+	pq_sendint(&buf, 0, 2);		/* format code */
+	pq_endmessage(&buf);
+
+	/* Send a DataRow message */
+	pq_beginmessage(&buf, 'D');
+	pq_sendint(&buf, 1, 2);		/* # of columns */
+
+	/* column 1: Wal segment size */
+	len = strlen(wal_segsz);
+	pq_sendint(&buf, len, 4);
+	pq_sendbytes(&buf, (char *) &wal_segsz, len);
+
+	pq_endmessage(&buf);
+}
+
 /*
  * Handle the IDENTIFY_SYSTEM command.
  */
@@ -1338,6 +1373,10 @@ exec_replication_command(const char *cmd_string)
 			IdentifySystem();
 			break;
 
+		case T_ShowWalSegSzCmd:
+			FetchWalSegSz();
+			break;
+
 		case T_BaseBackupCmd:
 			SendBaseBackup((BaseBackupCmd *) cmd_node);
 			break;
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index a025117..fd008ed 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -31,6 +31,7 @@
 #include "access/transam.h"
 #include "access/twophase.h"
 #include "access/xact.h"
+#include "access/xlog_internal.h"
 #include "catalog/namespace.h"
 #include "commands/async.h"
 #include "commands/prepare.h"
@@ -164,6 +165,8 @@ static bool check_timezone_abbreviations(char **newval, void **extra, GucSource
 static void assign_timezone_abbreviations(const char *newval, void *extra);
 static void pg_timezone_abbrev_initialize(void);
 static const char *show_archive_command(void);
+static const char *show_max_wal_size(void);
+static const char *show_min_wal_size(void);
 static void assign_tcp_keepalives_idle(int newval, void *extra);
 static void assign_tcp_keepalives_interval(int newval, void *extra);
 static void assign_tcp_keepalives_count(int newval, void *extra);
@@ -707,9 +710,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\".");
 
@@ -730,11 +730,6 @@ static const unit_conversion memory_unit_conversion_table[] =
 	{"MB", GUC_UNIT_XBLOCKS, 1024 / (XLOG_BLCKSZ / 1024)},
 	{"kB", GUC_UNIT_XBLOCKS, -(XLOG_BLCKSZ / 1024)},
 
-	{"TB", GUC_UNIT_XSEGS, (1024 * 1024 * 1024) / (XLOG_SEG_SIZE / 1024)},
-	{"GB", GUC_UNIT_XSEGS, (1024 * 1024) / (XLOG_SEG_SIZE / 1024)},
-	{"MB", GUC_UNIT_XSEGS, -(XLOG_SEG_SIZE / (1024 * 1024))},
-	{"kB", GUC_UNIT_XSEGS, -(XLOG_SEG_SIZE / 1024)},
-
 	{""}						/* end of table marker */
 };
 
@@ -2230,23 +2225,21 @@ static struct config_int ConfigureNamesInt[] =
 	{
 		{"min_wal_size", PGC_SIGHUP, WAL_CHECKPOINTS,
 			gettext_noop("Sets the minimum size to shrink the WAL to."),
-			NULL,
-			GUC_UNIT_XSEGS
+			NULL
 		},
 		&min_wal_size,
 		5, 2, INT_MAX,
-		NULL, NULL, NULL
+		NULL, NULL, show_min_wal_size
 	},
 
 	{
 		{"max_wal_size", PGC_SIGHUP, WAL_CHECKPOINTS,
 			gettext_noop("Sets the WAL size that triggers a checkpoint."),
-			NULL,
-			GUC_UNIT_XSEGS
+			NULL
 		},
 		&max_wal_size,
 		64, 2, INT_MAX,
-		NULL, assign_max_wal_size, NULL
+		NULL, assign_max_wal_size, show_max_wal_size
 	},
 
 	{
@@ -2588,9 +2581,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
 	},
 
@@ -8037,11 +8030,6 @@ GetConfigOptionByNum(int varnum, const char **values, bool *noshow)
 				snprintf(buffer, sizeof(buffer), "%dkB", XLOG_BLCKSZ / 1024);
 				values[2] = pstrdup(buffer);
 				break;
-			case GUC_UNIT_XSEGS:
-				snprintf(buffer, sizeof(buffer), "%dMB",
-						 XLOG_SEG_SIZE / (1024 * 1024));
-				values[2] = pstrdup(buffer);
-				break;
 			case GUC_UNIT_MS:
 				values[2] = "ms";
 				break;
@@ -10122,6 +10110,52 @@ show_archive_command(void)
 		return "(disabled)";
 }
 
+/*
+ * convert_unit
+ *
+ * This takes the value in kbytes and then returns value in user-readable format
+ */
+static const char *
+convert_unit(uint32 val)
+{
+	static char nbuf[NAMEDATALEN];
+
+	if (val / 1024 > 0)
+	{
+		val = val / 1024;
+		if (val / 1024 > 0)
+		{
+			val = val / 1024;
+			if (val / 1024 > 0)
+				snprintf(nbuf, sizeof(nbuf), "%dTB", (val / 1024));
+			else
+				snprintf(nbuf, sizeof(nbuf), "%dGB", val);
+		}
+		else
+			snprintf(nbuf, sizeof(nbuf), "%dMB", val);
+	}
+	else
+		snprintf(nbuf, sizeof(nbuf), "%dkB", val / 1024);
+
+	return nbuf;
+}
+
+static const char *
+show_max_wal_size(void)
+{
+	uint32		result = XLOG_SEG_SIZE / 1024 * max_wal_size;
+
+	return convert_unit(result);
+}
+
+static const char *
+show_min_wal_size(void)
+{
+	uint32		result = XLOG_SEG_SIZE / 1024 * min_wal_size;
+
+	return convert_unit(result);
+}
+
 static void
 assign_tcp_keepalives_idle(int newval, void *extra)
 {
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 24f9cc8..e43cabf 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -53,6 +53,7 @@
 #include <sys/stat.h>
 #include <unistd.h>
 #include <locale.h>
+#include <math.h>
 #include <signal.h>
 #include <time.h>
 
@@ -139,6 +140,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 */
@@ -1337,6 +1340,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: */
@@ -2417,6 +2423,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, --xlogdir=XLOGDIR     location for the transaction 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"));
@@ -3103,6 +3110,7 @@ main(int argc, char *argv[])
 		{"no-sync", no_argument, NULL, 'N'},
 		{"sync-only", no_argument, NULL, 'S'},
 		{"xlogdir", required_argument, NULL, 'X'},
+		{"wal-segsize", required_argument, NULL, 'Z'},
 		{"data-checksums", no_argument, NULL, 'k'},
 		{NULL, 0, NULL, 0}
 	};
@@ -3236,6 +3244,9 @@ main(int argc, char *argv[])
 			case 'X':
 				xlog_dir = pg_strdup(optarg);
 				break;
+			case 'Z':
+				str_wal_segment_size = pg_strdup(optarg);
+				break;
 			default:
 				/* getopt_long already emitted a complaint */
 				fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
@@ -3298,6 +3309,37 @@ 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
+	{
+		int			pow2 = 0;
+		int			i;
+
+		wal_segment_size = atoi(str_wal_segment_size);
+
+		/* Check the range of wal_segment_size */
+		if (wal_segment_size < 1 || wal_segment_size > 1024)
+		{
+			fprintf(stderr, _("%s: --wal-segsize value must be between 1 and 1024"), progname);
+			exit(1);
+		}
+
+		/* Check if wal_segment_size is in the power of 2 */
+		for (i = 0;; i++, pow2 = pow(2, i))
+			if (pow2 >= wal_segment_size)
+				break;
+
+		if (wal_segment_size != 1 && pow2 > wal_segment_size)
+		{
+			fprintf(stderr, _("%s: WAL segment size must be in the power of 2\n"), progname);
+			exit(1);
+		}
+
+		/* Convert wal_segment_size to bytes */
+		wal_segment_size = wal_segment_size * 1024 * 1024;
+
+	}
 	get_restricted_token(progname);
 
 	setup_pgdata();
diff --git a/src/bin/pg_basebackup/pg_basebackup.c b/src/bin/pg_basebackup/pg_basebackup.c
index f7ba9a9..d796d49 100644
--- a/src/bin/pg_basebackup/pg_basebackup.c
+++ b/src/bin/pg_basebackup/pg_basebackup.c
@@ -2328,6 +2328,9 @@ main(int argc, char **argv)
 		exit(1);
 	}
 
+	if (!SetXLogSegSize(conn))
+		disconnect_and_exit(1);
+
 	/* Create transaction log symlink, if required */
 	if (strcmp(xlog_dir, "") != 0)
 	{
diff --git a/src/bin/pg_basebackup/receivelog.h b/src/bin/pg_basebackup/receivelog.h
index b5913ea..e3f6c1c 100644
--- a/src/bin/pg_basebackup/receivelog.h
+++ b/src/bin/pg_basebackup/receivelog.h
@@ -16,6 +16,7 @@
 #include "walmethods.h"
 
 #include "access/xlogdefs.h"
+#include "access/xlog_internal.h"
 
 /*
  * Called before trying to read more data or when a segment is
@@ -52,4 +53,5 @@ extern bool CheckServerVersionForStreaming(PGconn *conn);
 extern bool ReceiveXlogStream(PGconn *conn,
 				  StreamCtl *stream);
 
+uint32		XLogSegSize;
 #endif   /* RECEIVELOG_H */
diff --git a/src/bin/pg_basebackup/streamutil.c b/src/bin/pg_basebackup/streamutil.c
index 595eaff..fe7ee8d 100644
--- a/src/bin/pg_basebackup/streamutil.c
+++ b/src/bin/pg_basebackup/streamutil.c
@@ -239,6 +239,46 @@ GetConnection(void)
 }
 
 /*
+ * Run the SHOW_WAL_SEGMENT_SIZE command to set the XLogSegSize
+ */
+bool
+SetXLogSegSize(PGconn *conn)
+{
+	PGresult   *res;
+	char	   *wal_segsz_str;
+
+	/* Check connection existence */
+	Assert(conn != NULL);
+
+	res = PQexec(conn, "SHOW_WAL_SEGSZ");
+	if (PQresultStatus(res) != PGRES_TUPLES_OK)
+	{
+		fprintf(stderr, _("%s: could not send replication command \"%s\": %s"),
+				progname, "SHOW_WAL_SEGSZ", PQerrorMessage(conn));
+
+		PQclear(res);
+		return false;
+	}
+	if (PQntuples(res) != 1 || PQnfields(res) < 1)
+	{
+		fprintf(stderr,
+				_("%s: could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields\n"),
+				progname, PQntuples(res), PQnfields(res), 1, 1);
+
+		PQclear(res);
+		return false;
+	}
+
+	/* Get system identifier */
+	wal_segsz_str = pg_strdup(PQgetvalue(res, 0, 0));
+
+	XLogSegSize = atoi(wal_segsz_str);
+
+	PQclear(res);
+	return true;
+}
+
+/*
  * Run IDENTIFY_SYSTEM through a given connection and give back to caller
  * some result information if requested:
  * - System identifier
diff --git a/src/bin/pg_basebackup/streamutil.h b/src/bin/pg_basebackup/streamutil.h
index d2d5a6d..55c5035 100644
--- a/src/bin/pg_basebackup/streamutil.h
+++ b/src/bin/pg_basebackup/streamutil.h
@@ -39,6 +39,7 @@ extern bool RunIdentifySystem(PGconn *conn, char **sysid,
 				  TimeLineID *starttli,
 				  XLogRecPtr *startpos,
 				  char **db_name);
+extern bool SetXLogSegSize(PGconn *conn);
 extern int64 feGetCurrentTimestamp(void);
 extern void feTimestampDifference(int64 start_time, int64 stop_time,
 					  long *secs, int *microsecs);
diff --git a/src/bin/pg_controldata/pg_controldata.c b/src/bin/pg_controldata/pg_controldata.c
index 20077a6..45bd5bb 100644
--- a/src/bin/pg_controldata/pg_controldata.c
+++ b/src/bin/pg_controldata/pg_controldata.c
@@ -27,6 +27,8 @@
 #include "pg_getopt.h"
 
 
+uint32		XLogSegSize;
+
 static void
 usage(const char *progname)
 {
@@ -163,6 +165,11 @@ main(int argc, char *argv[])
 				 "is expecting.  The results below are untrustworthy.\n\n"));
 
 	/*
+	 * Read the XLOG_SEG_SIZE
+	 */
+	XLogSegSize = ControlFile->xlog_seg_size;
+
+	/*
 	 * This slightly-chintzy coding will work as long as the control file
 	 * timestamps are within the range of time_t; that should be the case in
 	 * all foreseeable circumstances, so we don't bother importing the
diff --git a/src/bin/pg_resetxlog/pg_resetxlog.c b/src/bin/pg_resetxlog/pg_resetxlog.c
index 2b76f64..d4ca559 100644
--- a/src/bin/pg_resetxlog/pg_resetxlog.c
+++ b/src/bin/pg_resetxlog/pg_resetxlog.c
@@ -57,6 +57,7 @@
 #include "storage/large_object.h"
 #include "pg_getopt.h"
 
+uint32		XLogSegSize;
 
 static ControlFileData ControlFile;		/* pg_control values */
 static XLogSegNo newXlogSegNo;	/* new XLOG segment # */
@@ -94,6 +95,7 @@ main(int argc, char *argv[])
 	char	   *endptr;
 	char	   *endptr2;
 	char	   *DataDir = NULL;
+	char	   *log_fname = NULL;
 	int			fd;
 
 	set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_resetxlog"));
@@ -265,7 +267,7 @@ main(int argc, char *argv[])
 					fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
 					exit(1);
 				}
-				XLogFromFileName(optarg, &minXlogTli, &minXlogSegNo);
+				log_fname = pg_strdup(optarg);
 				break;
 
 			default:
@@ -347,6 +349,9 @@ main(int argc, char *argv[])
 	if (!ReadControlFile())
 		GuessControlValues();
 
+	if (log_fname != NULL)
+		XLogFromFileName(log_fname, &minXlogTli, &minXlogSegNo);
+
 	/*
 	 * Also look at existing segment files to set up newXlogSegNo
 	 */
@@ -510,6 +515,7 @@ ReadControlFile(void)
 		{
 			/* Valid data... */
 			memcpy(&ControlFile, buffer, sizeof(ControlFile));
+			XLogSegSize = ControlFile.xlog_seg_size;
 			return true;
 		}
 
@@ -517,6 +523,7 @@ ReadControlFile(void)
 				progname);
 		/* We will use the data anyway, but treat it as guessed. */
 		memcpy(&ControlFile, buffer, sizeof(ControlFile));
+		XLogSegSize = ControlFile.xlog_seg_size;
 		guessed = true;
 		return true;
 	}
diff --git a/src/bin/pg_rewind/pg_rewind.c b/src/bin/pg_rewind/pg_rewind.c
index dd62dd0..9d33874 100644
--- a/src/bin/pg_rewind/pg_rewind.c
+++ b/src/bin/pg_rewind/pg_rewind.c
@@ -44,6 +44,7 @@ static ControlFileData ControlFile_target;
 static ControlFileData ControlFile_source;
 
 const char *progname;
+uint32		XLogSegSize;
 
 /* Configuration options */
 char	   *datadir_target = NULL;
@@ -631,6 +632,11 @@ digestControlFile(ControlFileData *ControlFile, char *src, size_t size)
 
 	memcpy(ControlFile, src, sizeof(ControlFileData));
 
+	/*
+	 * Read the XLOG_SEG_SIZE
+	 */
+	XLogSegSize = ControlFile->xlog_seg_size;
+
 	/* Additional checks on control file */
 	checkControlFile(ControlFile);
 }
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/bin/pg_xlogdump/pg_xlogdump.c b/src/bin/pg_xlogdump/pg_xlogdump.c
index d070312..3a601ca 100644
--- a/src/bin/pg_xlogdump/pg_xlogdump.c
+++ b/src/bin/pg_xlogdump/pg_xlogdump.c
@@ -22,9 +22,11 @@
 #include "common/fe_memutils.h"
 #include "getopt_long.h"
 #include "rmgrdesc.h"
+#include "sys/stat.h"
 
 
 static const char *progname;
+uint32		XLogSegSize;
 
 typedef struct XLogDumpPrivate
 {
@@ -891,8 +893,10 @@ main(int argc, char **argv)
 	{
 		char	   *directory = NULL;
 		char	   *fname = NULL;
+		char	   *full_path = NULL;
 		int			fd;
 		XLogSegNo	segno;
+		struct stat fst;
 
 		split_path(argv[optind], &directory, &fname);
 
@@ -910,6 +914,15 @@ main(int argc, char **argv)
 			fatal_error("could not open file \"%s\"", fname);
 		close(fd);
 
+		if (private.inpath != NULL)
+			sprintf(full_path, "%s/%s", private.inpath, fname);
+		else
+			strcpy(full_path, fname);
+
+		stat(full_path, &fst);
+
+		XLogSegSize = (int) fst.st_size;
+
 		/* parse position from file */
 		XLogFromFileName(fname, &private.timeline, &segno);
 
diff --git a/src/include/access/xlog_internal.h b/src/include/access/xlog_internal.h
index ceb0462..829a909 100644
--- a/src/include/access/xlog_internal.h
+++ b/src/include/access/xlog_internal.h
@@ -89,7 +89,9 @@ typedef XLogLongPageHeaderData *XLogLongPageHeader;
  * The XLOG is split into WAL segments (physical files) of the size indicated
  * by XLOG_SEG_SIZE.
  */
-#define XLogSegSize		((uint32) XLOG_SEG_SIZE)
+
+extern uint32 XLogSegSize;
+#define XLOG_SEG_SIZE XLogSegSize
 #define XLogSegmentsPerXLogId	(UINT64CONST(0x100000000) / XLOG_SEG_SIZE)
 
 #define XLogSegNoOffsetToRecPtr(segno, offset, dest) \
diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h
index c514d3f..4b96399 100644
--- a/src/include/nodes/nodes.h
+++ b/src/include/nodes/nodes.h
@@ -464,6 +464,7 @@ typedef enum NodeTag
 	 * TAGS FOR REPLICATION GRAMMAR PARSE NODES (replnodes.h)
 	 */
 	T_IdentifySystemCmd,
+	T_ShowWalSegSzCmd,
 	T_BaseBackupCmd,
 	T_CreateReplicationSlotCmd,
 	T_DropReplicationSlotCmd,
diff --git a/src/include/nodes/replnodes.h b/src/include/nodes/replnodes.h
index 024b965..c278ea0 100644
--- a/src/include/nodes/replnodes.h
+++ b/src/include/nodes/replnodes.h
@@ -33,6 +33,15 @@ typedef struct IdentifySystemCmd
 	NodeTag		type;
 } IdentifySystemCmd;
 
+/* ---------------------------
+ *		SHOW_WAL_SEGSZ command
+ * ---------------------------
+ */
+typedef struct ShowWalSegSzCmd
+{
+	NodeTag		type;
+}	ShowWalSegSzCmd;
+
 
 /* ----------------------
  *		BASE_BACKUP command
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 42a3fc8..c6e51d3 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -909,13 +909,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 58b1db9..7a1ea23 100644
--- a/src/include/pg_config_manual.h
+++ b/src/include/pg_config_manual.h
@@ -14,6 +14,15 @@
  */
 
 /*
+ * DEFAULT_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 DEFAULT_XLOG_SEG_SIZE requires an initdb.
+ */
+#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 8217d06..25c638f 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -183,7 +183,7 @@ 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},
+		print O "#define DEFAULT_XLOG_SEG_SIZE (", $self->{options}->{wal_segsize},
 		  " * 1024 * 1024)\n";
 
 		if ($self->{options}->{float4byval})
