@@ -64,6 +64,7 @@ static XLogSegNo newXlogSegNo; /* new XLOG segment # */
6464static bool guessed = false; /* T if we had to guess at any values */
6565static const char * progname ;
6666static uint32 set_xid_epoch = (uint32 ) - 1 ;
67+ static TransactionId set_oldest_xid = 0 ;
6768static TransactionId set_xid = 0 ;
6869static TransactionId set_oldest_commit_ts_xid = 0 ;
6970static TransactionId set_newest_commit_ts_xid = 0 ;
@@ -101,6 +102,7 @@ main(int argc, char *argv[])
101102 {"dry-run" , no_argument , NULL , 'n' },
102103 {"next-oid" , required_argument , NULL , 'o' },
103104 {"multixact-offset" , required_argument , NULL , 'O' },
105+ {"oldest-transaction-id" , required_argument , NULL , 'u' },
104106 {"next-transaction-id" , required_argument , NULL , 'x' },
105107 {"wal-segsize" , required_argument , NULL , 1 },
106108 {NULL , 0 , NULL , 0 }
@@ -135,7 +137,7 @@ main(int argc, char *argv[])
135137 }
136138
137139
138- while ((c = getopt_long (argc , argv , "c:D:e:fl:m:no:O:x:" , long_options , NULL )) != -1 )
140+ while ((c = getopt_long (argc , argv , "c:D:e:fl:m:no:O:u: x:" , long_options , NULL )) != -1 )
139141 {
140142 switch (c )
141143 {
@@ -168,6 +170,21 @@ main(int argc, char *argv[])
168170 }
169171 break ;
170172
173+ case 'u' :
174+ set_oldest_xid = strtoul (optarg , & endptr , 0 );
175+ if (endptr == optarg || * endptr != '\0' )
176+ {
177+ pg_log_error ("invalid argument for option %s" , "-u" );
178+ fprintf (stderr , _ ("Try \"%s --help\" for more information.\n" ), progname );
179+ exit (1 );
180+ }
181+ if (!TransactionIdIsNormal (set_oldest_xid ))
182+ {
183+ pg_log_error ("oldest transaction ID (-u) must be greater or equal to %u" , FirstNormalTransactionId );
184+ exit (1 );
185+ }
186+ break ;
187+
171188 case 'x' :
172189 set_xid = strtoul (optarg , & endptr , 0 );
173190 if (endptr == optarg || * endptr != '\0' )
@@ -176,9 +193,9 @@ main(int argc, char *argv[])
176193 fprintf (stderr , _ ("Try \"%s --help\" for more information.\n" ), progname );
177194 exit (1 );
178195 }
179- if (set_xid == 0 )
196+ if (! TransactionIdIsNormal ( set_xid ) )
180197 {
181- pg_log_error ("transaction ID (-x) must not be 0" );
198+ pg_log_error ("transaction ID (-x) must be greater or equal to %u" , FirstNormalTransactionId );
182199 exit (1 );
183200 }
184201 break ;
@@ -428,25 +445,17 @@ main(int argc, char *argv[])
428445 FullTransactionIdFromEpochAndXid (set_xid_epoch ,
429446 XidFromFullTransactionId (ControlFile .checkPointCopy .nextXid ));
430447
431- if (set_xid != 0 )
448+ if (set_oldest_xid != 0 )
432449 {
450+ ControlFile .checkPointCopy .oldestXid = set_oldest_xid ;
451+ ControlFile .checkPointCopy .oldestXidDB = InvalidOid ;
452+ }
453+
454+ if (set_xid != 0 )
433455 ControlFile .checkPointCopy .nextXid =
434456 FullTransactionIdFromEpochAndXid (EpochFromFullTransactionId (ControlFile .checkPointCopy .nextXid ),
435457 set_xid );
436458
437- /*
438- * For the moment, just set oldestXid to a value that will force
439- * immediate autovacuum-for-wraparound. It's not clear whether adding
440- * user control of this is useful, so let's just do something that's
441- * reasonably safe. The magic constant here corresponds to the
442- * maximum allowed value of autovacuum_freeze_max_age.
443- */
444- ControlFile .checkPointCopy .oldestXid = set_xid - 2000000000 ;
445- if (ControlFile .checkPointCopy .oldestXid < FirstNormalTransactionId )
446- ControlFile .checkPointCopy .oldestXid += FirstNormalTransactionId ;
447- ControlFile .checkPointCopy .oldestXidDB = InvalidOid ;
448- }
449-
450459 if (set_oldest_commit_ts_xid != 0 )
451460 ControlFile .checkPointCopy .oldestCommitTsXid = set_oldest_commit_ts_xid ;
452461 if (set_newest_commit_ts_xid != 0 )
@@ -1209,20 +1218,21 @@ usage(void)
12091218 printf (_ ("Usage:\n %s [OPTION]... DATADIR\n\n" ), progname );
12101219 printf (_ ("Options:\n" ));
12111220 printf (_ (" -c, --commit-timestamp-ids=XID,XID\n"
1212- " set oldest and newest transactions bearing\n"
1213- " commit timestamp (zero means no change)\n" ));
1214- printf (_ (" [-D, --pgdata=]DATADIR data directory\n" ));
1215- printf (_ (" -e, --epoch=XIDEPOCH set next transaction ID epoch\n" ));
1216- printf (_ (" -f, --force force update to be done\n" ));
1217- printf (_ (" -l, --next-wal-file=WALFILE set minimum starting location for new WAL\n" ));
1218- printf (_ (" -m, --multixact-ids=MXID,MXID set next and oldest multitransaction ID\n" ));
1219- printf (_ (" -n, --dry-run no update, just show what would be done\n" ));
1220- printf (_ (" -o, --next-oid=OID set next OID\n" ));
1221- printf (_ (" -O, --multixact-offset=OFFSET set next multitransaction offset\n" ));
1222- printf (_ (" -V, --version output version information, then exit\n" ));
1223- printf (_ (" -x, --next-transaction-id=XID set next transaction ID\n" ));
1224- printf (_ (" --wal-segsize=SIZE size of WAL segments, in megabytes\n" ));
1225- printf (_ (" -?, --help show this help, then exit\n" ));
1221+ " set oldest and newest transactions bearing\n"
1222+ " commit timestamp (zero means no change)\n" ));
1223+ printf (_ (" [-D, --pgdata=]DATADIR data directory\n" ));
1224+ printf (_ (" -e, --epoch=XIDEPOCH set next transaction ID epoch\n" ));
1225+ printf (_ (" -f, --force force update to be done\n" ));
1226+ printf (_ (" -l, --next-wal-file=WALFILE set minimum starting location for new WAL\n" ));
1227+ printf (_ (" -m, --multixact-ids=MXID,MXID set next and oldest multitransaction ID\n" ));
1228+ printf (_ (" -n, --dry-run no update, just show what would be done\n" ));
1229+ printf (_ (" -o, --next-oid=OID set next OID\n" ));
1230+ printf (_ (" -O, --multixact-offset=OFFSET set next multitransaction offset\n" ));
1231+ printf (_ (" -u, --oldest-transaction-id=XID set oldest transaction ID\n" ));
1232+ printf (_ (" -V, --version output version information, then exit\n" ));
1233+ printf (_ (" -x, --next-transaction-id=XID set next transaction ID\n" ));
1234+ printf (_ (" --wal-segsize=SIZE size of WAL segments, in megabytes\n" ));
1235+ printf (_ (" -?, --help show this help, then exit\n" ));
12261236 printf (_ ("\nReport bugs to <%s>.\n" ), PACKAGE_BUGREPORT );
12271237 printf (_ ("%s home page: <%s>\n" ), PACKAGE_NAME , PACKAGE_URL );
12281238}
0 commit comments