Index: contrib/pg_resetxlog/README.pg_resetxlog
===================================================================
RCS file: /cvsroot/pgsql/contrib/pg_resetxlog/README.pg_resetxlog,v
retrieving revision 1.1
diff -c -r1.1 README.pg_resetxlog
*** contrib/pg_resetxlog/README.pg_resetxlog	2001/03/14 00:57:43	1.1
--- contrib/pg_resetxlog/README.pg_resetxlog	2002/01/10 06:09:04
***************
*** 21,26 ****
--- 21,29 ----
  Then run pg_resetxlog, and finally install and start the new version of
  the database software.
  
+ A tertiary purpose it its use by pg_upgrade to set the next transaction
+ id in pg_control.
+ 
  To run the program, make sure your postmaster is not running, then
  (as the Postgres admin user) do
  
Index: contrib/pg_resetxlog/pg_resetxlog.c
===================================================================
RCS file: /cvsroot/pgsql/contrib/pg_resetxlog/pg_resetxlog.c,v
retrieving revision 1.10
diff -c -r1.10 pg_resetxlog.c
*** contrib/pg_resetxlog/pg_resetxlog.c	2001/11/05 17:46:23	1.10
--- contrib/pg_resetxlog/pg_resetxlog.c	2002/01/10 06:09:05
***************
*** 709,742 ****
   * Write out the new pg_control file.
   */
  static void
! RewriteControlFile(void)
  {
  	int			fd;
  	char		buffer[BLCKSZ]; /* need not be aligned */
  
! 	/*
! 	 * Adjust fields as needed to force an empty XLOG starting at the next
! 	 * available segment.
! 	 */
! 	newXlogId = ControlFile.logId;
! 	newXlogSeg = ControlFile.logSeg;
! 	/* be sure we wrap around correctly at end of a logfile */
! 	NextLogSeg(newXlogId, newXlogSeg);
! 
! 	ControlFile.checkPointCopy.redo.xlogid = newXlogId;
! 	ControlFile.checkPointCopy.redo.xrecoff =
! 		newXlogSeg * XLogSegSize + SizeOfXLogPHD;
! 	ControlFile.checkPointCopy.undo = ControlFile.checkPointCopy.redo;
! 	ControlFile.checkPointCopy.time = time(NULL);
! 
! 	ControlFile.state = DB_SHUTDOWNED;
! 	ControlFile.time = time(NULL);
! 	ControlFile.logId = newXlogId;
! 	ControlFile.logSeg = newXlogSeg + 1;
! 	ControlFile.checkPoint = ControlFile.checkPointCopy.redo;
! 	ControlFile.prevCheckPoint.xlogid = 0;
! 	ControlFile.prevCheckPoint.xrecoff = 0;
! 
  	/* Contents are protected with a CRC */
  	INIT_CRC64(ControlFile.crc);
  	COMP_CRC64(ControlFile.crc,
--- 709,747 ----
   * Write out the new pg_control file.
   */
  static void
! RewriteControlFile(TransactionId set_xid)
  {
  	int			fd;
  	char		buffer[BLCKSZ]; /* need not be aligned */
  
! 	if (set_xid == 0)
! 	{
! 		/*
! 		 * Adjust fields as needed to force an empty XLOG starting at the next
! 		 * available segment.
! 		 */
! 		newXlogId = ControlFile.logId;
! 		newXlogSeg = ControlFile.logSeg;
! 		/* be sure we wrap around correctly at end of a logfile */
! 		NextLogSeg(newXlogId, newXlogSeg);
! 	
! 		ControlFile.checkPointCopy.redo.xlogid = newXlogId;
! 		ControlFile.checkPointCopy.redo.xrecoff =
! 			newXlogSeg * XLogSegSize + SizeOfXLogPHD;
! 		ControlFile.checkPointCopy.undo = ControlFile.checkPointCopy.redo;
! 		ControlFile.checkPointCopy.time = time(NULL);
! 	
! 		ControlFile.state = DB_SHUTDOWNED;
! 		ControlFile.time = time(NULL);
! 		ControlFile.logId = newXlogId;
! 		ControlFile.logSeg = newXlogSeg + 1;
! 		ControlFile.checkPoint = ControlFile.checkPointCopy.redo;
! 		ControlFile.prevCheckPoint.xlogid = 0;
! 		ControlFile.prevCheckPoint.xrecoff = 0;
! 	}
! 	else
! 		ControlFile.checkPointCopy.nextXid = set_xid;
! 	
  	/* Contents are protected with a CRC */
  	INIT_CRC64(ControlFile.crc);
  	COMP_CRC64(ControlFile.crc,
***************
*** 926,934 ****
  static void
  usage(void)
  {
! 	fprintf(stderr, "Usage: pg_resetxlog [-f] [-n] PGDataDirectory\n\n"
! 			"  -f\tforce update to be done\n"
! 			"  -n\tno update, just show extracted pg_control values (for testing)\n");
  	exit(1);
  }
  
--- 931,940 ----
  static void
  usage(void)
  {
! 	fprintf(stderr, "Usage: pg_resetxlog [-f] [-n] [-x xid] PGDataDirectory\n"
! 			" -f\tforce update to be done\n"
! 			" -n\tno update, just show extracted pg_control values (for testing)\n"
! 			" -x XID\tset XID in pg_control\n");
  	exit(1);
  }
  
***************
*** 939,944 ****
--- 945,951 ----
  	int			argn;
  	bool		force = false;
  	bool		noupdate = false;
+ 	TransactionId set_xid = 0;
  	int			fd;
  	char		path[MAXPGPATH];
  
***************
*** 950,955 ****
--- 957,974 ----
  			force = true;
  		else if (strcmp(argv[argn], "-n") == 0)
  			noupdate = true;
+ 		else if (strcmp(argv[argn], "-x") == 0)
+ 		{
+ 			argn++;
+ 			if (argn == argc)
+ 				usage();
+ 			set_xid = strtoul(argv[argn], NULL, 0);
+ 			if (set_xid == 0)
+ 			{
+ 				fprintf(stderr, "XID can not be 0.");
+ 				exit(1);
+ 			}
+ 		}
  		else
  			usage();
  	}
***************
*** 993,998 ****
--- 1012,1031 ----
  		GuessControlValues();
  
  	/*
+ 	 * Set XID in pg_control and exit
+ 	 */
+ 	if (set_xid)
+ 	{
+ 		if (guessed)
+ 		{
+ 			printf("\npg_control appears corrupt.  Can not update XID.\n");
+ 			exit(1);
+ 		}
+ 		RewriteControlFile(set_xid);
+ 		exit(0);
+ 	}
+ 
+ 	/*
  	 * If we had to guess anything, and -f was not given, just print the
  	 * guessed values and exit.  Also print if -n is given.
  	 */
***************
*** 1018,1024 ****
  	/*
  	 * Else, do the dirty deed.
  	 */
! 	RewriteControlFile();
  	KillExistingXLOG();
  	WriteEmptyXLOG();
  
--- 1051,1057 ----
  	/*
  	 * Else, do the dirty deed.
  	 */
! 	RewriteControlFile(0);
  	KillExistingXLOG();
  	WriteEmptyXLOG();
  
