aboutsummaryrefslogtreecommitdiff
path: root/src/bin/pg_resetxlog/pg_resetxlog.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin/pg_resetxlog/pg_resetxlog.c')
-rw-r--r--src/bin/pg_resetxlog/pg_resetxlog.c83
1 files changed, 29 insertions, 54 deletions
diff --git a/src/bin/pg_resetxlog/pg_resetxlog.c b/src/bin/pg_resetxlog/pg_resetxlog.c
index 5ecf5c49304..554e08c98cb 100644
--- a/src/bin/pg_resetxlog/pg_resetxlog.c
+++ b/src/bin/pg_resetxlog/pg_resetxlog.c
@@ -60,8 +60,7 @@ extern char *optarg;
static ControlFileData ControlFile; /* pg_control values */
-static uint32 newXlogId,
- newXlogSeg; /* ID/Segment of new XLOG segment */
+static XLogSegNo newXlogSegNo; /* new XLOG segment # */
static bool guessed = false; /* T if we had to guess at any values */
static const char *progname;
@@ -87,12 +86,9 @@ main(int argc, char *argv[])
Oid set_oid = 0;
MultiXactId set_mxid = 0;
MultiXactOffset set_mxoff = (MultiXactOffset) -1;
- uint32 minXlogTli = 0,
- minXlogId = 0,
- minXlogSeg = 0;
+ uint32 minXlogTli = 0;
+ XLogSegNo minXlogSegNo = 0;
char *endptr;
- char *endptr2;
- char *endptr3;
char *DataDir;
int fd;
char path[MAXPGPATH];
@@ -204,27 +200,13 @@ main(int argc, char *argv[])
break;
case 'l':
- minXlogTli = strtoul(optarg, &endptr, 0);
- if (endptr == optarg || *endptr != ',')
- {
- fprintf(stderr, _("%s: invalid argument for option -l\n"), progname);
- fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
- exit(1);
- }
- minXlogId = strtoul(endptr + 1, &endptr2, 0);
- if (endptr2 == endptr + 1 || *endptr2 != ',')
- {
- fprintf(stderr, _("%s: invalid argument for option -l\n"), progname);
- fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
- exit(1);
- }
- minXlogSeg = strtoul(endptr2 + 1, &endptr3, 0);
- if (endptr3 == endptr2 + 1 || *endptr3 != '\0')
+ if (strspn(optarg, "01234567890ABCDEFabcdef") != 24)
{
fprintf(stderr, _("%s: invalid argument for option -l\n"), progname);
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
exit(1);
}
+ XLogFromFileName(optarg, &minXlogTli, &minXlogSegNo);
break;
default:
@@ -295,7 +277,7 @@ main(int argc, char *argv[])
GuessControlValues();
/*
- * Also look at existing segment files to set up newXlogId/newXlogSeg
+ * Also look at existing segment files to set up newXlogSegNo
*/
FindEndOfXLOG();
@@ -335,13 +317,8 @@ main(int argc, char *argv[])
if (minXlogTli > ControlFile.checkPointCopy.ThisTimeLineID)
ControlFile.checkPointCopy.ThisTimeLineID = minXlogTli;
- if (minXlogId > newXlogId ||
- (minXlogId == newXlogId &&
- minXlogSeg > newXlogSeg))
- {
- newXlogId = minXlogId;
- newXlogSeg = minXlogSeg;
- }
+ if (minXlogSegNo > newXlogSegNo)
+ newXlogSegNo = minXlogSegNo;
/*
* If we had to guess anything, and -f was not given, just print the
@@ -545,6 +522,7 @@ static void
PrintControlValues(bool guessed)
{
char sysident_str[32];
+ char fname[MAXFNAMELEN];
if (guessed)
printf(_("Guessed pg_control values:\n\n"));
@@ -558,10 +536,10 @@ PrintControlValues(bool guessed)
snprintf(sysident_str, sizeof(sysident_str), UINT64_FORMAT,
ControlFile.system_identifier);
- printf(_("First log file ID after reset: %u\n"),
- newXlogId);
- printf(_("First log file segment after reset: %u\n"),
- newXlogSeg);
+ XLogFileName(fname, ControlFile.checkPointCopy.ThisTimeLineID, newXlogSegNo);
+
+ printf(_("First log segment after reset: %s\n"),
+ fname);
printf(_("pg_control version number: %u\n"),
ControlFile.pg_control_version);
printf(_("Catalog version number: %u\n"),
@@ -624,11 +602,10 @@ RewriteControlFile(void)
/*
* Adjust fields as needed to force an empty XLOG starting at
- * newXlogId/newXlogSeg.
+ * newXlogSegNo.
*/
- ControlFile.checkPointCopy.redo.xlogid = newXlogId;
- ControlFile.checkPointCopy.redo.xrecoff =
- newXlogSeg * XLogSegSize + SizeOfXLogLongPHD;
+ XLogSegNoOffsetToRecPtr(newXlogSegNo, SizeOfXLogLongPHD,
+ ControlFile.checkPointCopy.redo);
ControlFile.checkPointCopy.time = (pg_time_t) time(NULL);
ControlFile.state = DB_SHUTDOWNED;
@@ -728,14 +705,17 @@ FindEndOfXLOG(void)
{
DIR *xldir;
struct dirent *xlde;
+ uint64 segs_per_xlogid;
+ uint64 xlogbytepos;
/*
* Initialize the max() computation using the last checkpoint address from
* old pg_control. Note that for the moment we are working with segment
* numbering according to the old xlog seg size.
*/
- newXlogId = ControlFile.checkPointCopy.redo.xlogid;
- newXlogSeg = ControlFile.checkPointCopy.redo.xrecoff / ControlFile.xlog_seg_size;
+ segs_per_xlogid = (0x100000000L / ControlFile.xlog_seg_size);
+ newXlogSegNo = ((uint64) ControlFile.checkPointCopy.redo.xlogid) * segs_per_xlogid
+ + (ControlFile.checkPointCopy.redo.xrecoff / ControlFile.xlog_seg_size);
/*
* Scan the pg_xlog directory to find existing WAL segment files. We
@@ -759,8 +739,10 @@ FindEndOfXLOG(void)
unsigned int tli,
log,
seg;
+ XLogSegNo segno;
sscanf(xlde->d_name, "%08X%08X%08X", &tli, &log, &seg);
+ segno = ((uint64) log) * segs_per_xlogid + seg;
/*
* Note: we take the max of all files found, regardless of their
@@ -768,12 +750,8 @@ FindEndOfXLOG(void)
* timelines other than the target TLI, but this seems safer.
* Better too large a result than too small...
*/
- if (log > newXlogId ||
- (log == newXlogId && seg > newXlogSeg))
- {
- newXlogId = log;
- newXlogSeg = seg;
- }
+ if (segno > newXlogSegNo)
+ newXlogSegNo = segno;
}
errno = 0;
}
@@ -799,11 +777,9 @@ FindEndOfXLOG(void)
* Finally, convert to new xlog seg size, and advance by one to ensure we
* are in virgin territory.
*/
- newXlogSeg *= ControlFile.xlog_seg_size;
- newXlogSeg = (newXlogSeg + XLogSegSize - 1) / XLogSegSize;
-
- /* be sure we wrap around correctly at end of a logfile */
- NextLogSeg(newXlogId, newXlogSeg);
+ xlogbytepos = newXlogSegNo * ControlFile.xlog_seg_size;
+ newXlogSegNo = (xlogbytepos + XLogSegSize - 1) / XLogSegSize;
+ newXlogSegNo++;
}
@@ -972,8 +948,7 @@ WriteEmptyXLOG(void)
record->xl_crc = crc;
/* Write the first page */
- XLogFilePath(path, ControlFile.checkPointCopy.ThisTimeLineID,
- newXlogId, newXlogSeg);
+ XLogFilePath(path, ControlFile.checkPointCopy.ThisTimeLineID, newXlogSegNo);
unlink(path);