diff --git a/doc/src/sgml/ref/initdb.sgml b/doc/src/sgml/ref/initdb.sgml
index 585665f161..67c1c6d8dc 100644
--- a/doc/src/sgml/ref/initdb.sgml
+++ b/doc/src/sgml/ref/initdb.sgml
@@ -390,6 +390,45 @@ PostgreSQL documentation
     </variablelist>
    </para>
 
+   <para>
+    Other options for testing 64-bit XIDs:
+
+    <variablelist>
+     <varlistentry>
+      <term><option>-m <replaceable class="parameter">START_MX_ID</replaceable></option></term>
+      <term><option>--multixact-id=<replaceable class="parameter">START_MX_ID</replaceable></option></term>
+      <listitem>
+       <para>
+        Specifies a start multixact id value in the decimal format for new db instance to test 64-bit xids,
+        default value is <literal>0</literal>.
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry>
+      <term><option>-o <replaceable class="parameter">START_MX_OFFSET</replaceable></option></term>
+      <term><option>--multixact-offset=<replaceable class="parameter">START_MX_OFFSET</replaceable></option></term>
+      <listitem>
+       <para>
+        Specifies a start multixact offset value in the decimal format for new db instance to test 64-bit xids,
+        default value is <literal>0</literal>.
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry>
+      <term><option>-x <replaceable class="parameter">START_XID</replaceable></option></term>
+      <term><option>--xid=<replaceable class="parameter">START_XID</replaceable></option></term>
+      <listitem>
+       <para>
+        Specifies a start xid value in the decimal for new db instance to test 64-bit xids,
+        default value is <literal>0</literal>.
+       </para>
+      </listitem>
+     </varlistentry>
+    </variablelist>
+   </para>
+
    <para>
     Other options:
 
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 2caaa49360..24250bbc67 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -710,6 +710,9 @@ void
 BootStrapCLOG(void)
 {
 	int			slotno;
+	int64		pageno;
+
+	pageno = TransactionIdToPage(ShmemVariableCache->nextXid);
 
 	LWLockAcquire(CLogControlLock, LW_EXCLUSIVE);
 
@@ -720,6 +723,16 @@ BootStrapCLOG(void)
 	SimpleLruWritePage(ClogCtl, slotno);
 	Assert(!ClogCtl->shared->page_dirty[slotno]);
 
+	if (pageno != 0)
+	{
+		/* Create and zero the first page of the commit log */
+		slotno = ZeroCLOGPage(pageno, false);
+
+		/* Make sure it's written out */
+		SimpleLruWritePage(ClogCtl, slotno);
+		Assert(!ClogCtl->shared->page_dirty[slotno]);
+	}
+
 	LWLockRelease(CLogControlLock);
 }
 
diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c
index 0e7827022a..3239d7bf9c 100644
--- a/src/backend/access/transam/multixact.c
+++ b/src/backend/access/transam/multixact.c
@@ -1666,6 +1666,8 @@ void
 BootStrapMultiXact(void)
 {
 	int			slotno;
+	int64		multiOffsetPageno;
+	int64		multiMemberPageno;
 
 	LWLockAcquire(MultiXactOffsetControlLock, LW_EXCLUSIVE);
 
@@ -1676,6 +1678,17 @@ BootStrapMultiXact(void)
 	SimpleLruWritePage(MultiXactOffsetCtl, slotno);
 	Assert(!MultiXactOffsetCtl->shared->page_dirty[slotno]);
 
+	multiOffsetPageno = MultiXactIdToOffsetPage(MultiXactState->nextMXact - 1);
+	if (multiOffsetPageno != 0)
+	{
+		/* Create and zero the first page of the offsets log */
+		slotno = ZeroMultiXactOffsetPage(multiOffsetPageno, false);
+
+		/* Make sure it's written out */
+		SimpleLruWritePage(MultiXactOffsetCtl, slotno);
+		Assert(!MultiXactOffsetCtl->shared->page_dirty[slotno]);
+	}
+
 	LWLockRelease(MultiXactOffsetControlLock);
 
 	LWLockAcquire(MultiXactMemberControlLock, LW_EXCLUSIVE);
@@ -1687,7 +1700,32 @@ BootStrapMultiXact(void)
 	SimpleLruWritePage(MultiXactMemberCtl, slotno);
 	Assert(!MultiXactMemberCtl->shared->page_dirty[slotno]);
 
+	multiMemberPageno = MXOffsetToMemberPage(MultiXactState->nextOffset - 1);
+	if (multiMemberPageno != 0)
+	{
+		/* Create and zero the first page of the members log */
+		slotno = ZeroMultiXactMemberPage(multiMemberPageno, false);
+
+		/* Make sure it's written out */
+		SimpleLruWritePage(MultiXactMemberCtl, slotno);
+		Assert(!MultiXactMemberCtl->shared->page_dirty[slotno]);
+	}
+
 	LWLockRelease(MultiXactMemberControlLock);
+
+	/*
+	 * If we're starting not from zero offset, initilize dummy multixact to
+	 * evade too long loop in PerformMembersTruncation().
+	 */
+	if (MultiXactState->nextOffset > 0 && MultiXactState->nextMXact > 0)
+	{
+		RecordNewMultiXact(FirstMultiXactId,
+						   MultiXactState->nextOffset,
+						   0, NULL);
+		RecordNewMultiXact(MultiXactState->nextMXact - 1,
+						   MultiXactState->nextOffset,
+						   0, NULL);
+	}
 }
 
 /*
diff --git a/src/backend/access/transam/subtrans.c b/src/backend/access/transam/subtrans.c
index de79619d08..06fa4526ca 100644
--- a/src/backend/access/transam/subtrans.c
+++ b/src/backend/access/transam/subtrans.c
@@ -210,11 +210,14 @@ void
 BootStrapSUBTRANS(void)
 {
 	int			slotno;
+	int64		pageno;
+
+	pageno = TransactionIdToPage(ShmemVariableCache->nextXid);
 
 	LWLockAcquire(SubtransControlLock, LW_EXCLUSIVE);
 
 	/* Create and zero the first page of the subtrans log */
-	slotno = ZeroSUBTRANSPage(0);
+	slotno = ZeroSUBTRANSPage(pageno);
 
 	/* Make sure it's written out */
 	SimpleLruWritePage(SubTransCtl, slotno);
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index b9bdf7914b..96a3bafec6 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -106,6 +106,10 @@ int			CommitDelay = 0;	/* precommit delay in microseconds */
 int			CommitSiblings = 5; /* # concurrent xacts needed to sleep */
 int			wal_retrieve_retry_interval = 5000;
 
+TransactionId   start_xid = 0;
+MultiXactId     start_mx_id = 0;
+MultiXactOffset   start_mx_offset = 0;
+
 #ifdef WAL_DEBUG
 bool		XLOG_DEBUG = false;
 #endif
@@ -5053,10 +5057,10 @@ BootStrapXLOG(void)
 	checkPoint.ThisTimeLineID = ThisTimeLineID;
 	checkPoint.PrevTimeLineID = ThisTimeLineID;
 	checkPoint.fullPageWrites = fullPageWrites;
-	checkPoint.nextXid = FirstNormalTransactionId + 1;
+	checkPoint.nextXid = Max(FirstNormalTransactionId + 1, start_xid);
 	checkPoint.nextOid = FirstBootstrapObjectId;
-	checkPoint.nextMulti = FirstMultiXactId + 1;
-	checkPoint.nextMultiOffset = 1;
+	checkPoint.nextMulti = Max(FirstMultiXactId + 1, start_mx_id);
+	checkPoint.nextMultiOffset = Max(start_mx_offset, 1);
 	checkPoint.oldestXid = checkPoint.nextXid - 1;
 	checkPoint.oldestXidDB = TemplateDbOid;
 	checkPoint.oldestMulti = checkPoint.nextMulti - 1;
diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c
index 3a3ca5c4c6..36311c2474 100644
--- a/src/backend/bootstrap/bootstrap.c
+++ b/src/backend/bootstrap/bootstrap.c
@@ -223,7 +223,10 @@ AuxiliaryProcessMain(int argc, char *argv[])
 	/* If no -x argument, we are a CheckerProcess */
 	MyAuxProcType = CheckerProcess;
 
-	while ((flag = getopt(argc, argv, "B:c:d:D:Fkr:x:X:-:")) != -1)
+	start_xid = 0;
+	start_mx_id = 0;
+	start_mx_offset = 0;
+	while ((flag = getopt(argc, argv, "B:c:d:D:Fkm:o:r:z:x:X:-:")) != -1)
 	{
 		switch (flag)
 		{
@@ -252,9 +255,30 @@ AuxiliaryProcessMain(int argc, char *argv[])
 			case 'k':
 				bootstrap_data_checksum_version = PG_DATA_CHECKSUM_VERSION;
 				break;
+			case 'm':
+				if (sscanf(optarg, XID_FMT, &start_mx_id) != 1
+					|| !StartMultiXactIdIsValid(start_mx_id))
+					ereport(ERROR,
+						(errcode(ERRCODE_SYNTAX_ERROR),
+						errmsg("invalid start multixact id value")));
+				break;
+			case 'o':
+				if (sscanf(optarg, XID_FMT, &start_mx_offset) != 1
+					|| !StartMultiXactOffsetIsValid(start_mx_offset))
+					ereport(ERROR,
+						(errcode(ERRCODE_SYNTAX_ERROR),
+						errmsg("invalid start multixact offset value")));
+				break;
 			case 'r':
 				strlcpy(OutputFileName, optarg, MAXPGPATH);
 				break;
+			case 'z':
+				if (sscanf(optarg, XID_FMT, &start_xid) != 1
+					|| !StartTransactionIdIsValid(start_xid))
+					ereport(ERROR,
+						(errcode(ERRCODE_SYNTAX_ERROR),
+						errmsg("invalid start xid value")));
+				break;
 			case 'x':
 				MyAuxProcType = atoi(optarg);
 				break;
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 2efd3b75b1..00a6a161eb 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -144,6 +144,9 @@ static bool data_checksums = false;
 static char *xlog_dir = NULL;
 static char *str_wal_segment_size_mb = NULL;
 static int	wal_segment_size_mb;
+static TransactionId start_xid = 0;
+static MultiXactId start_mx_id = 0;
+static MultiXactOffset start_mx_offset = 0;
 
 
 /* internal vars */
@@ -1381,10 +1384,13 @@ bootstrap_template1(void)
 	unsetenv("PGCLIENTENCODING");
 
 	snprintf(cmd, sizeof(cmd),
-			 "\"%s\" --boot -x1 -X %u %s %s %s",
+			 "\"%s\" --boot -x1 -X %u %s %s " XID_FMT " %s " XID_FMT " %s " XID_FMT " %s %s",
 			 backend_exec,
 			 wal_segment_size_mb * (1024 * 1024),
 			 data_checksums ? "-k" : "",
+			 "-z", start_xid,
+			 "-m", start_mx_id,
+			 "-o", start_mx_offset,
 			 boot_options,
 			 debug ? "-d 5" : "");
 
@@ -2323,13 +2329,21 @@ 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(_("  -x, --xid=START_XID       specify start xid value in decimal format for new db instance to test 64-bit xids,\n"
+			 "                            default value is 0, max value is 2^62-1\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"));
 	printf(_("  -L DIRECTORY              where to find the input files\n"));
+	printf(_("  -m, --multixact-id=START_MX_ID\n"
+			 "                            specify start multixact id value in decimal format for new db instance\n"
+			 "                            to test 64-bit xids, default value is 0, max value is 2^62-1\n"));
 	printf(_("  -n, --no-clean            do not clean up after errors\n"));
 	printf(_("  -N, --no-sync             do not wait for changes to be written safely to disk\n"));
+	printf(_("  -o, --multixact-offset=START_MX_OFFSET\n"
+			 "                            specify start multixact offset value in decimal format for new db instance\n"
+			 "                            to test 64-bit xids, default value is 0, max value is 2^62-1\n"));
 	printf(_("  -s, --show                show internal settings\n"));
 	printf(_("  -S, --sync-only           only sync data directory\n"));
 	printf(_("\nOther options:\n"));
@@ -3016,6 +3030,9 @@ main(int argc, char *argv[])
 		{"waldir", required_argument, NULL, 'X'},
 		{"wal-segsize", required_argument, NULL, 12},
 		{"data-checksums", no_argument, NULL, 'k'},
+		{"xid", required_argument, NULL, 'x'},
+		{"multixact-id", required_argument, NULL, 'm'},
+		{"multixact-offset", required_argument, NULL, 'o'},
 		{NULL, 0, NULL, 0}
 	};
 
@@ -3057,7 +3074,7 @@ main(int argc, char *argv[])
 
 	/* process command-line options */
 
-	while ((c = getopt_long(argc, argv, "dD:E:kL:nNU:WA:sST:X:", long_options, &option_index)) != -1)
+	while ((c = getopt_long(argc, argv, "dD:E:kL:m:nNU:WA:o:sST:X:x:", long_options, &option_index)) != -1)
 	{
 		switch (c)
 		{
@@ -3096,6 +3113,20 @@ main(int argc, char *argv[])
 				debug = true;
 				printf(_("Running in debug mode.\n"));
 				break;
+			case 'm':
+				if (sscanf(optarg, XID_FMT, &start_mx_id) != 1)
+				{
+					fprintf(stderr, "%s: invalid decimal START_MX_ID value\n",
+							progname);
+					exit(1);
+				}
+				if (!StartMultiXactIdIsValid(start_mx_id))
+				{
+					fprintf(stderr, "%s: out-of-range START_MX_ID value (the value must be less than 2^62)\n",
+							progname);
+					exit(1);
+				}
+				break;
 			case 'n':
 				noclean = true;
 				printf(_("Running in no-clean mode.  Mistakes will not be cleaned up.\n"));
@@ -3103,6 +3134,20 @@ main(int argc, char *argv[])
 			case 'N':
 				do_sync = false;
 				break;
+			case 'o':
+				if (sscanf(optarg, XID_FMT, &start_mx_offset) != 1)
+				{
+					fprintf(stderr, "%s: invalid decimal START_MX_OFFSET value\n",
+							progname);
+					exit(1);
+				}
+				if (!StartMultiXactOffsetIsValid(start_mx_offset))
+				{
+					fprintf(stderr, "%s: out-of-range START_MX_OFFSET value (the value must be less than 2^62)\n",
+							progname);
+					exit(1);
+				}
+				break;
 			case 'S':
 				sync_only = true;
 				break;
@@ -3148,6 +3193,20 @@ main(int argc, char *argv[])
 			case 'X':
 				xlog_dir = pg_strdup(optarg);
 				break;
+			case 'x':
+				if (sscanf(optarg, XID_FMT, &start_xid) != 1)
+				{
+					fprintf(stderr, "%s: invalid decimal START_XID value\n",
+							progname);
+					exit(1);
+				}
+				if (!StartTransactionIdIsValid(start_xid))
+				{
+					fprintf(stderr, "%s: out-of-range START_XID value (the value must be less than 2^62)\n",
+							progname);
+					exit(1);
+				}
+				break;
 			case 12:
 				str_wal_segment_size_mb = pg_strdup(optarg);
 				break;
diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h
index 3c9d3401df..69978958b4 100644
--- a/src/include/access/xlog.h
+++ b/src/include/access/xlog.h
@@ -131,6 +131,14 @@ typedef enum WalLevel
 
 extern PGDLLIMPORT int wal_level;
 
+/*
+ * these parameters specifies starting xid, multixact id and multixact offset
+ *             for testing 64 bit xids
+ */
+extern TransactionId  start_xid;
+extern MultiXactId    start_mx_id;
+extern MultiXactOffset  start_mx_offset;
+
 /* Is WAL archiving enabled (always or only while server is running normally)? */
 #define XLogArchivingActive() \
 	(AssertMacro(XLogArchiveMode == ARCHIVE_MODE_OFF || wal_level >= WAL_LEVEL_REPLICA), XLogArchiveMode > ARCHIVE_MODE_OFF)
diff --git a/src/test/perl/PostgresNode.pm b/src/test/perl/PostgresNode.pm
index 80f68df246..879f6a9bbe 100644
--- a/src/test/perl/PostgresNode.pm
+++ b/src/test/perl/PostgresNode.pm
@@ -410,6 +410,7 @@ sub init
 	mkdir $self->archive_dir;
 
 	TestLib::system_or_bail('initdb', '-D', $pgdata, '-A', 'trust', '-N',
+		'-x', '1249835483136', '-m', '2422361554944', '-o', '3594887626752',
 		@{ $params{extra} });
 	TestLib::system_or_bail($ENV{PG_REGRESS}, '--config-auth', $pgdata);
 
diff --git a/src/test/regress/pg_regress.c b/src/test/regress/pg_regress.c
index a1ee1041b4..e075551390 100644
--- a/src/test/regress/pg_regress.c
+++ b/src/test/regress/pg_regress.c
@@ -2275,7 +2275,7 @@ regression_main(int argc, char *argv[], init_function ifunc, test_function tfunc
 		/* initdb */
 		header(_("initializing database system"));
 		snprintf(buf, sizeof(buf),
-				 "\"%s%sinitdb\" -D \"%s/data\" --no-clean --no-sync%s%s > \"%s/log/initdb.log\" 2>&1",
+				 "\"%s%sinitdb\" -D \"%s/data\" -x 1249835483136 -m 2422361554944 -o 3594887626752 --no-clean --no-sync%s%s > \"%s/log/initdb.log\" 2>&1",
 				 bindir ? bindir : "",
 				 bindir ? "/" : "",
 				 temp_instance,
