📄 pg_resetxlog.c
字号:
progname); return false;}/* * Guess at pg_control values when we can't read the old ones. */static voidGuessControlValues(void){ uint64 sysidentifier; struct timeval tv; char *localeptr; /* * Set up a completely default set of pg_control values. */ guessed = true; memset(&ControlFile, 0, sizeof(ControlFile)); ControlFile.pg_control_version = PG_CONTROL_VERSION; ControlFile.catalog_version_no = CATALOG_VERSION_NO; /* * Create a new unique installation identifier, since we can no longer use * any old XLOG records. See notes in xlog.c about the algorithm. */ gettimeofday(&tv, NULL); sysidentifier = ((uint64) tv.tv_sec) << 32; sysidentifier |= (uint32) (tv.tv_sec | tv.tv_usec); ControlFile.system_identifier = sysidentifier; ControlFile.checkPointCopy.redo.xlogid = 0; ControlFile.checkPointCopy.redo.xrecoff = SizeOfXLogLongPHD; ControlFile.checkPointCopy.undo = ControlFile.checkPointCopy.redo; ControlFile.checkPointCopy.ThisTimeLineID = 1; ControlFile.checkPointCopy.nextXid = (TransactionId) 514; /* XXX */ ControlFile.checkPointCopy.nextOid = FirstBootstrapObjectId; ControlFile.checkPointCopy.nextMulti = FirstMultiXactId; ControlFile.checkPointCopy.nextMultiOffset = 0; ControlFile.checkPointCopy.time = time(NULL); ControlFile.state = DB_SHUTDOWNED; ControlFile.time = time(NULL); ControlFile.logId = 0; ControlFile.logSeg = 1; ControlFile.checkPoint = ControlFile.checkPointCopy.redo; ControlFile.maxAlign = MAXIMUM_ALIGNOF; ControlFile.floatFormat = FLOATFORMAT_VALUE; ControlFile.blcksz = BLCKSZ; ControlFile.relseg_size = RELSEG_SIZE; ControlFile.xlog_seg_size = XLOG_SEG_SIZE; ControlFile.nameDataLen = NAMEDATALEN; ControlFile.indexMaxKeys = INDEX_MAX_KEYS;#ifdef HAVE_INT64_TIMESTAMP ControlFile.enableIntTimes = TRUE;#else ControlFile.enableIntTimes = FALSE;#endif ControlFile.localeBuflen = LOCALE_NAME_BUFLEN; localeptr = setlocale(LC_COLLATE, ""); if (!localeptr) { fprintf(stderr, _("%s: invalid LC_COLLATE setting\n"), progname); exit(1); } StrNCpy(ControlFile.lc_collate, localeptr, LOCALE_NAME_BUFLEN); localeptr = setlocale(LC_CTYPE, ""); if (!localeptr) { fprintf(stderr, _("%s: invalid LC_CTYPE setting\n"), progname); exit(1); } StrNCpy(ControlFile.lc_ctype, localeptr, LOCALE_NAME_BUFLEN); /* * XXX eventually, should try to grovel through old XLOG to develop more * accurate values for TimeLineID, nextXID, etc. */}/* * Print the guessed pg_control values when we had to guess. * * NB: this display should be just those fields that will not be * reset by RewriteControlFile(). */static voidPrintControlValues(bool guessed){ char sysident_str[32]; if (guessed) printf(_("Guessed pg_control values:\n\n")); else printf(_("pg_control values:\n\n")); /* * Format system_identifier separately to keep platform-dependent format * code out of the translatable message string. */ snprintf(sysident_str, sizeof(sysident_str), UINT64_FORMAT, ControlFile.system_identifier); printf(_("pg_control version number: %u\n"), ControlFile.pg_control_version); printf(_("Catalog version number: %u\n"), ControlFile.catalog_version_no); printf(_("Database system identifier: %s\n"), sysident_str); printf(_("Current log file ID: %u\n"), ControlFile.logId); printf(_("Next log file segment: %u\n"), ControlFile.logSeg); printf(_("Latest checkpoint's TimeLineID: %u\n"), ControlFile.checkPointCopy.ThisTimeLineID); printf(_("Latest checkpoint's NextXID: %u\n"), ControlFile.checkPointCopy.nextXid); printf(_("Latest checkpoint's NextOID: %u\n"), ControlFile.checkPointCopy.nextOid); printf(_("Latest checkpoint's NextMultiXactId: %u\n"), ControlFile.checkPointCopy.nextMulti); printf(_("Latest checkpoint's NextMultiOffset: %u\n"), ControlFile.checkPointCopy.nextMultiOffset); printf(_("Maximum data alignment: %u\n"), ControlFile.maxAlign); /* we don't print floatFormat since can't say much useful about it */ printf(_("Database block size: %u\n"), ControlFile.blcksz); printf(_("Blocks per segment of large relation: %u\n"), ControlFile.relseg_size); printf(_("Maximum length of identifiers: %u\n"), ControlFile.nameDataLen); printf(_("Maximum columns in an index: %u\n"), ControlFile.indexMaxKeys); printf(_("Date/time type storage: %s\n"), (ControlFile.enableIntTimes ? _("64-bit integers") : _("floating-point numbers"))); printf(_("Maximum length of locale name: %u\n"), ControlFile.localeBuflen); printf(_("LC_COLLATE: %s\n"), ControlFile.lc_collate); printf(_("LC_CTYPE: %s\n"), ControlFile.lc_ctype);}/* * Write out the new pg_control file. */static voidRewriteControlFile(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; /* adjust in case we are changing segment size */ newXlogSeg *= ControlFile.xlog_seg_size; newXlogSeg = (newXlogSeg + XLogSegSize - 1) / XLogSegSize; /* be sure we wrap around correctly at end of a logfile */ NextLogSeg(newXlogId, newXlogSeg); /* Now we can force the recorded xlog seg size to the right thing. */ ControlFile.xlog_seg_size = XLogSegSize; ControlFile.checkPointCopy.redo.xlogid = newXlogId; ControlFile.checkPointCopy.redo.xrecoff = newXlogSeg * XLogSegSize + SizeOfXLogLongPHD; 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_CRC32(ControlFile.crc); COMP_CRC32(ControlFile.crc, (char *) &ControlFile, offsetof(ControlFileData, crc)); FIN_CRC32(ControlFile.crc); /* * We write out BLCKSZ bytes into pg_control, zero-padding the excess over * sizeof(ControlFileData). This reduces the odds of premature-EOF errors * when reading pg_control. We'll still fail when we check the contents * of the file, but hopefully with a more specific error than "couldn't * read pg_control". */ if (sizeof(ControlFileData) > BLCKSZ) { fprintf(stderr, _("%s: internal error -- sizeof(ControlFileData) is too large ... fix xlog.c\n"), progname); exit(1); } memset(buffer, 0, BLCKSZ); memcpy(buffer, &ControlFile, sizeof(ControlFileData)); unlink(XLOG_CONTROL_FILE); fd = open(XLOG_CONTROL_FILE, O_RDWR | O_CREAT | O_EXCL | PG_BINARY, S_IRUSR | S_IWUSR); if (fd < 0) { fprintf(stderr, _("%s: could not create pg_control file: %s\n"), progname, strerror(errno)); exit(1); } errno = 0; if (write(fd, buffer, BLCKSZ) != BLCKSZ) { /* if write didn't set errno, assume problem is no disk space */ if (errno == 0) errno = ENOSPC; fprintf(stderr, _("%s: could not write pg_control file: %s\n"), progname, strerror(errno)); exit(1); } if (fsync(fd) != 0) { fprintf(stderr, _("%s: fsync error: %s\n"), progname, strerror(errno)); exit(1); } close(fd);}/* * Remove existing XLOG files */static voidKillExistingXLOG(void){ DIR *xldir; struct dirent *xlde; char path[MAXPGPATH]; xldir = opendir(XLOGDIR); if (xldir == NULL) { fprintf(stderr, _("%s: could not open directory \"%s\": %s\n"), progname, XLOGDIR, strerror(errno)); exit(1); } errno = 0; while ((xlde = readdir(xldir)) != NULL) { if (strlen(xlde->d_name) == 24 && strspn(xlde->d_name, "0123456789ABCDEF") == 24) { snprintf(path, MAXPGPATH, "%s/%s", XLOGDIR, xlde->d_name); if (unlink(path) < 0) { fprintf(stderr, _("%s: could not delete file \"%s\": %s\n"), progname, path, strerror(errno)); exit(1); } } errno = 0; }#ifdef WIN32 /* * This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but not in * released version */ if (GetLastError() == ERROR_NO_MORE_FILES) errno = 0;#endif if (errno) { fprintf(stderr, _("%s: could not read from directory \"%s\": %s\n"), progname, XLOGDIR, strerror(errno)); exit(1); } closedir(xldir);}/* * Write an empty XLOG file, containing only the checkpoint record * already set up in ControlFile. */static voidWriteEmptyXLOG(void){ char *buffer; XLogPageHeader page; XLogLongPageHeader longpage; XLogRecord *record; pg_crc32 crc; char path[MAXPGPATH]; int fd; int nbytes; /* Use malloc() to ensure buffer is MAXALIGNED */ buffer = (char *) malloc(BLCKSZ); page = (XLogPageHeader) buffer; memset(buffer, 0, BLCKSZ); /* Set up the XLOG page header */ page->xlp_magic = XLOG_PAGE_MAGIC; page->xlp_info = XLP_LONG_HEADER; page->xlp_tli = ControlFile.checkPointCopy.ThisTimeLineID; page->xlp_pageaddr.xlogid = ControlFile.checkPointCopy.redo.xlogid; page->xlp_pageaddr.xrecoff = ControlFile.checkPointCopy.redo.xrecoff - SizeOfXLogLongPHD; longpage = (XLogLongPageHeader) page; longpage->xlp_sysid = ControlFile.system_identifier; longpage->xlp_seg_size = XLogSegSize; /* Insert the initial checkpoint record */ record = (XLogRecord *) ((char *) page + SizeOfXLogLongPHD); record->xl_prev.xlogid = 0; record->xl_prev.xrecoff = 0; record->xl_xid = InvalidTransactionId; record->xl_tot_len = SizeOfXLogRecord + sizeof(CheckPoint); record->xl_len = sizeof(CheckPoint); record->xl_info = XLOG_CHECKPOINT_SHUTDOWN; record->xl_rmid = RM_XLOG_ID; memcpy(XLogRecGetData(record), &ControlFile.checkPointCopy, sizeof(CheckPoint)); INIT_CRC32(crc); COMP_CRC32(crc, &ControlFile.checkPointCopy, sizeof(CheckPoint)); COMP_CRC32(crc, (char *) record + sizeof(pg_crc32), SizeOfXLogRecord - sizeof(pg_crc32)); FIN_CRC32(crc); record->xl_crc = crc; /* Write the first page */ XLogFilePath(path, ControlFile.checkPointCopy.ThisTimeLineID, newXlogId, newXlogSeg); unlink(path); fd = open(path, O_RDWR | O_CREAT | O_EXCL | PG_BINARY, S_IRUSR | S_IWUSR); if (fd < 0) { fprintf(stderr, _("%s: could not open file \"%s\": %s\n"), progname, path, strerror(errno)); exit(1); } errno = 0; if (write(fd, buffer, BLCKSZ) != BLCKSZ) { /* if write didn't set errno, assume problem is no disk space */ if (errno == 0) errno = ENOSPC; fprintf(stderr, _("%s: could not write file \"%s\": %s\n"), progname, path, strerror(errno)); exit(1); } /* Fill the rest of the file with zeroes */ memset(buffer, 0, BLCKSZ); for (nbytes = BLCKSZ; nbytes < XLogSegSize; nbytes += BLCKSZ) { errno = 0; if (write(fd, buffer, BLCKSZ) != BLCKSZ) { if (errno == 0) errno = ENOSPC; fprintf(stderr, _("%s: could not write file \"%s\": %s\n"), progname, path, strerror(errno)); exit(1); } } if (fsync(fd) != 0) { fprintf(stderr, _("%s: fsync error: %s\n"), progname, strerror(errno)); exit(1); } close(fd);}static voidusage(void){ printf(_("%s resets the PostgreSQL transaction log.\n\n"), progname); printf(_("Usage:\n %s [OPTION]... DATADIR\n\n"), progname); printf(_("Options:\n")); printf(_(" -f force update to be done\n")); printf(_(" -l TLI,FILE,SEG force minimum WAL starting location for new transaction log\n")); printf(_(" -m XID set next multitransaction ID\n")); printf(_(" -n no update, just show extracted control values (for testing)\n")); printf(_(" -o OID set next OID\n")); printf(_(" -O OFFSET set next multitransaction offset\n")); printf(_(" -x XID set next transaction ID\n")); printf(_(" --help show this help, then exit\n")); printf(_(" --version output version information, then exit\n")); printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -