diff --git a/doc/src/sgml/ref/initdb.sgml b/doc/src/sgml/ref/initdb.sgml
new file mode 100644
index 6efb2e4..e4b1a04
*** a/doc/src/sgml/ref/initdb.sgml
--- b/doc/src/sgml/ref/initdb.sgml
*************** PostgreSQL documentation
*** 376,381 ****
--- 376,420 ----
     </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:
  
      <variablelist>
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
new file mode 100644
index 5575b94..b29cf6c
*** a/src/backend/access/transam/clog.c
--- b/src/backend/access/transam/clog.c
*************** void
*** 704,709 ****
--- 704,712 ----
  BootStrapCLOG(void)
  {
  	int			slotno;
+ 	int64		pageno;
+ 
+ 	pageno = TransactionIdToPage(ShmemVariableCache->nextXid);
  
  	LWLockAcquire(CLogControlLock, LW_EXCLUSIVE);
  
*************** BootStrapCLOG(void)
*** 714,719 ****
--- 717,732 ----
  	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
new file mode 100644
index 20aba1a..3c3a96f
*** a/src/backend/access/transam/multixact.c
--- b/src/backend/access/transam/multixact.c
*************** void
*** 1666,1671 ****
--- 1666,1673 ----
  BootStrapMultiXact(void)
  {
  	int			slotno;
+ 	int64		multiOffsetPageno;
+ 	int64		multiMemberPageno;
  
  	LWLockAcquire(MultiXactOffsetControlLock, LW_EXCLUSIVE);
  
*************** BootStrapMultiXact(void)
*** 1676,1681 ****
--- 1678,1694 ----
  	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);
*************** BootStrapMultiXact(void)
*** 1687,1693 ****
--- 1700,1731 ----
  	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
new file mode 100644
index cc9eee6..8797a52
*** a/src/backend/access/transam/subtrans.c
--- b/src/backend/access/transam/subtrans.c
*************** void
*** 210,220 ****
  BootStrapSUBTRANS(void)
  {
  	int			slotno;
  
  	LWLockAcquire(SubtransControlLock, LW_EXCLUSIVE);
  
  	/* Create and zero the first page of the subtrans log */
! 	slotno = ZeroSUBTRANSPage(0);
  
  	/* Make sure it's written out */
  	SimpleLruWritePage(SubTransCtl, slotno);
--- 210,223 ----
  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(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
new file mode 100644
index c4e494a..6fabdc3
*** a/src/backend/access/transam/xlog.c
--- b/src/backend/access/transam/xlog.c
*************** int			CommitDelay = 0;	/* precommit dela
*** 106,111 ****
--- 106,115 ----
  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
*************** BootStrapXLOG(void)
*** 5008,5017 ****
  	checkPoint.ThisTimeLineID = ThisTimeLineID;
  	checkPoint.PrevTimeLineID = ThisTimeLineID;
  	checkPoint.fullPageWrites = fullPageWrites;
! 	checkPoint.nextXid = FirstNormalTransactionId + 1;
  	checkPoint.nextOid = FirstBootstrapObjectId;
! 	checkPoint.nextMulti = FirstMultiXactId + 1;
! 	checkPoint.nextMultiOffset = 0;
  	checkPoint.oldestXid = checkPoint.nextXid - 1;
  	checkPoint.oldestXidDB = TemplateDbOid;
  	checkPoint.oldestMulti = checkPoint.nextMulti - 1;
--- 5012,5021 ----
  	checkPoint.ThisTimeLineID = ThisTimeLineID;
  	checkPoint.PrevTimeLineID = ThisTimeLineID;
  	checkPoint.fullPageWrites = fullPageWrites;
! 	checkPoint.nextXid = Max(FirstNormalTransactionId + 1, start_xid);
  	checkPoint.nextOid = FirstBootstrapObjectId;
! 	checkPoint.nextMulti = Max(FirstMultiXactId + 1, start_mx_id);
! 	checkPoint.nextMultiOffset = start_mx_offset;
  	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
new file mode 100644
index 509d620..9e0afb9
*** a/src/backend/bootstrap/bootstrap.c
--- b/src/backend/bootstrap/bootstrap.c
*************** AuxiliaryProcessMain(int argc, char *arg
*** 222,228 ****
  	/* If no -x argument, we are a CheckerProcess */
  	MyAuxProcType = CheckerProcess;
  
! 	while ((flag = getopt(argc, argv, "B:c:d:D:Fkr:x:-:")) != -1)
  	{
  		switch (flag)
  		{
--- 222,231 ----
  	/* If no -x argument, we are a CheckerProcess */
  	MyAuxProcType = CheckerProcess;
  
! 	start_xid = 0;
! 	start_mx_id = 0;
! 	start_mx_offset = 0;
! 	while ((flag = getopt(argc, argv, "B:c:d:D:Fkm:o:r:X:x:-:")) != -1)
  	{
  		switch (flag)
  		{
*************** AuxiliaryProcessMain(int argc, char *arg
*** 251,259 ****
--- 254,283 ----
  			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 'X':
+ 				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
new file mode 100644
index 9d1e5d7..65a0207
*** a/src/bin/initdb/initdb.c
--- b/src/bin/initdb/initdb.c
*************** static bool sync_only = false;
*** 141,146 ****
--- 141,149 ----
  static bool show_setting = false;
  static bool data_checksums = false;
  static char *xlog_dir = NULL;
+ static TransactionId start_xid = 0;
+ static MultiXactId start_mx_id = 0;
+ static MultiXactOffset start_mx_offset = 0;
  
  
  /* internal vars */
*************** bootstrap_template1(void)
*** 1352,1360 ****
  	unsetenv("PGCLIENTENCODING");
  
  	snprintf(cmd, sizeof(cmd),
! 			 "\"%s\" --boot -x1 %s %s %s",
  			 backend_exec,
  			 data_checksums ? "-k" : "",
  			 boot_options,
  			 debug ? "-d 5" : "");
  
--- 1355,1366 ----
  	unsetenv("PGCLIENTENCODING");
  
  	snprintf(cmd, sizeof(cmd),
! 			 "\"%s\" --boot -x1 %s %s " XID_FMT " %s " XID_FMT " %s " XID_FMT " %s %s",
  			 backend_exec,
  			 data_checksums ? "-k" : "",
+ 			 "-X", start_xid,
+ 			 "-m", start_mx_id,
+ 			 "-o", start_mx_offset,
  			 boot_options,
  			 debug ? "-d 5" : "");
  
*************** usage(const char *progname)
*** 2293,2304 ****
--- 2299,2318 ----
  	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(_("\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"));
*************** main(int argc, char *argv[])
*** 2983,2988 ****
--- 2997,3005 ----
  		{"no-sync", no_argument, NULL, 'N'},
  		{"sync-only", no_argument, NULL, 'S'},
  		{"waldir", required_argument, NULL, 'X'},
+ 		{"xid", required_argument, NULL, 'x'},
+ 		{"multixact-id", required_argument, NULL, 'm'},
+ 		{"multixact-offset", required_argument, NULL, 'o'},
  		{"data-checksums", no_argument, NULL, 'k'},
  		{NULL, 0, NULL, 0}
  	};
*************** main(int argc, char *argv[])
*** 3025,3031 ****
  
  	/* process command-line options */
  
! 	while ((c = getopt_long(argc, argv, "dD:E:kL:nNU:WA:sST:X:", long_options, &option_index)) != -1)
  	{
  		switch (c)
  		{
--- 3042,3048 ----
  
  	/* process command-line options */
  
! 	while ((c = getopt_long(argc, argv, "dD:E:kL:m:nNU:WA:o:sST:X:x:", long_options, &option_index)) != -1)
  	{
  		switch (c)
  		{
*************** main(int argc, char *argv[])
*** 3064,3069 ****
--- 3081,3100 ----
  				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"));
*************** main(int argc, char *argv[])
*** 3071,3076 ****
--- 3102,3121 ----
  			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;
*************** main(int argc, char *argv[])
*** 3116,3121 ****
--- 3161,3180 ----
  			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;
  			default:
  				/* getopt_long already emitted a complaint */
  				fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h
new file mode 100644
index e9ad3d6..3c2ac50
*** a/src/include/access/xlog.h
--- b/src/include/access/xlog.h
*************** typedef enum WalLevel
*** 130,135 ****
--- 130,143 ----
  
  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
new file mode 100644
index edcac6f..4c7b7ac
*** a/src/test/perl/PostgresNode.pm
--- b/src/test/perl/PostgresNode.pm
*************** sub init
*** 410,415 ****
--- 410,416 ----
  	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
new file mode 100644
index abb742b..b4a3db7
*** a/src/test/regress/pg_regress.c
--- b/src/test/regress/pg_regress.c
*************** regression_main(int argc, char *argv[], 
*** 2246,2252 ****
  		/* 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",
  				 bindir ? bindir : "",
  				 bindir ? "/" : "",
  				 temp_instance,
--- 2246,2252 ----
  		/* initdb */
  		header(_("initializing database system"));
  		snprintf(buf, sizeof(buf),
! 				 "\"%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,
