88 static void usage(
void);
92 main(
int argc,
char *argv[])
94 static struct option long_options[] = {
111 bool noupdate =
false;
116 char *log_fname = NULL;
125 if (strcmp(argv[1],
"--help") == 0 || strcmp(argv[1],
"-?") == 0)
130 if (strcmp(argv[1],
"--version") == 0 || strcmp(argv[1],
"-V") == 0)
132 puts(
"pg_resetwal (PostgreSQL) " PG_VERSION);
138 while ((c =
getopt_long(argc, argv,
"c:D:e:fl:m:no:O:x:", long_options, NULL)) != -1)
156 if (endptr ==
optarg || *endptr !=
'\0')
166 pg_log_error(
"transaction ID epoch (-e) must not be -1");
173 if (endptr ==
optarg || *endptr !=
'\0')
188 if (endptr ==
optarg || *endptr !=
',')
195 if (endptr2 == endptr + 1 || *endptr2 !=
'\0')
205 pg_log_error(
"transaction ID (-c) must be either 0 or greater than or equal to 2");
212 pg_log_error(
"transaction ID (-c) must be either 0 or greater than or equal to 2");
219 if (endptr ==
optarg || *endptr !=
'\0')
234 if (endptr ==
optarg || *endptr !=
',')
241 set_oldestmxid = strtoul(endptr + 1, &endptr2, 0);
242 if (endptr2 == endptr + 1 || *endptr2 !=
'\0')
258 if (set_oldestmxid == 0)
260 pg_log_error(
"oldest multitransaction ID (-m) must not be 0");
267 if (endptr ==
optarg || *endptr !=
'\0')
275 pg_log_error(
"multitransaction offset (-O) must not be -1");
297 if (endptr ==
optarg || *endptr !=
'\0')
299 pg_log_error(
"argument of --wal-segsize must be a number");
304 pg_log_error(
"argument of --wal-segsize must be a power of 2 between 1 and 1024");
315 if (DataDir == NULL &&
optind < argc)
321 pg_log_error(
"too many command-line arguments (first is \"%s\")",
323 fprintf(stderr,
_(
"Try \"%s --help\" for more information.\n"),
345 pg_log_info(
"You must run %s as the PostgreSQL superuser.",
356 pg_log_error(
"could not read permissions of directory \"%s\": %m",
363 if (chdir(DataDir) < 0)
365 pg_log_error(
"could not change directory to \"%s\": %m",
377 if ((fd = open(
"postmaster.pid", O_RDONLY, 0)) < 0)
381 pg_log_error(
"could not open file \"%s\" for reading: %m",
388 pg_log_error(
"lock file \"%s\" exists",
"postmaster.pid");
389 pg_log_info(
"Is a server running? If not, delete the lock file and try again.");
407 if (log_fname != NULL)
419 if ((
guessed && !force) || noupdate)
487 if ((
guessed && !force) || noupdate)
492 printf(
_(
"\nIf these values seem acceptable, use -f to force reset.\n"));
504 printf(
_(
"The database server was not shut down cleanly.\n" 505 "Resetting the write-ahead log might cause data to be lost.\n" 506 "If you want to proceed anyway, use -f to force reset.\n"));
518 printf(
_(
"Write-ahead log reset\n"));
538 const char *ver_file =
"PG_VERSION";
542 if ((ver_fd = fopen(ver_file,
"r")) == NULL)
544 pg_log_error(
"could not open file \"%s\" for reading: %m",
550 if (!fgets(rawline,
sizeof(rawline), ver_fd))
555 pg_log_error(
"could not read file \"%s\": %m", ver_file);
562 if (strcmp(rawline, PG_MAJORVERSION) != 0)
565 pg_log_info(
"File \"%s\" contains \"%s\", which is not compatible with this program's version \"%s\".",
566 ver_file, rawline, PG_MAJORVERSION);
595 pg_log_error(
"could not open file \"%s\" for reading: %m",
598 pg_log_info(
"If you are sure the data directory path is correct, execute\n" 629 pg_log_warning(
"pg_control exists but has invalid CRC; proceed with caution");
633 memcpy(&ControlFile, buffer,
sizeof(ControlFile));
639 "pg_control specifies invalid WAL segment size (%d bytes); proceed with caution",
649 pg_log_warning(
"pg_control exists but is broken or wrong version; ignoring it");
660 uint64 sysidentifier;
667 memset(&ControlFile, 0,
sizeof(ControlFile));
677 sysidentifier = ((uint64) tv.tv_sec) << 32;
678 sysidentifier |= ((uint64) tv.tv_usec) << 12;
679 sysidentifier |= getpid() & 0xFFF;
715 ControlFile.
maxAlign = MAXIMUM_ALIGNOF;
717 ControlFile.
blcksz = BLCKSZ;
744 printf(
_(
"Guessed pg_control values:\n\n"));
746 printf(
_(
"Current pg_control values:\n\n"));
748 printf(
_(
"pg_control version number: %u\n"),
750 printf(
_(
"Catalog version number: %u\n"),
752 printf(
_(
"Database system identifier: %llu\n"),
754 printf(
_(
"Latest checkpoint's TimeLineID: %u\n"),
756 printf(
_(
"Latest checkpoint's full_page_writes: %s\n"),
758 printf(
_(
"Latest checkpoint's NextXID: %u:%u\n"),
761 printf(
_(
"Latest checkpoint's NextOID: %u\n"),
763 printf(
_(
"Latest checkpoint's NextMultiXactId: %u\n"),
765 printf(
_(
"Latest checkpoint's NextMultiOffset: %u\n"),
767 printf(
_(
"Latest checkpoint's oldestXID: %u\n"),
769 printf(
_(
"Latest checkpoint's oldestXID's DB: %u\n"),
771 printf(
_(
"Latest checkpoint's oldestActiveXID: %u\n"),
773 printf(
_(
"Latest checkpoint's oldestMultiXid: %u\n"),
775 printf(
_(
"Latest checkpoint's oldestMulti's DB: %u\n"),
777 printf(
_(
"Latest checkpoint's oldestCommitTsXid:%u\n"),
779 printf(
_(
"Latest checkpoint's newestCommitTsXid:%u\n"),
781 printf(
_(
"Maximum data alignment: %u\n"),
784 printf(
_(
"Database block size: %u\n"),
786 printf(
_(
"Blocks per segment of large relation: %u\n"),
788 printf(
_(
"WAL block size: %u\n"),
790 printf(
_(
"Bytes per WAL segment: %u\n"),
792 printf(
_(
"Maximum length of identifiers: %u\n"),
794 printf(
_(
"Maximum columns in an index: %u\n"),
796 printf(
_(
"Maximum size of a TOAST chunk: %u\n"),
798 printf(
_(
"Size of a large-object chunk: %u\n"),
801 printf(
_(
"Date/time type storage: %s\n"),
802 _(
"64-bit integers"));
803 printf(
_(
"Float8 argument passing: %s\n"),
804 (ControlFile.
float8ByVal ?
_(
"by value") :
_(
"by reference")));
805 printf(
_(
"Data page checksum version: %u\n"),
819 printf(
_(
"\n\nValues to be changed:\n\n"));
823 printf(
_(
"First log segment after reset: %s\n"), fname);
827 printf(
_(
"NextMultiXactId: %u\n"),
829 printf(
_(
"OldestMultiXid: %u\n"),
831 printf(
_(
"OldestMulti's DB: %u\n"),
837 printf(
_(
"NextMultiOffset: %u\n"),
853 printf(
_(
"OldestXID's DB: %u\n"),
859 printf(
_(
"NextXID epoch: %u\n"),
865 printf(
_(
"oldestCommitTsXid: %u\n"),
870 printf(
_(
"newestCommitTsXid: %u\n"),
876 printf(
_(
"Bytes per WAL segment: %u\n"),
937 uint64 segs_per_xlogid;
945 segs_per_xlogid = (UINT64CONST(0x0000000100000000) / ControlFile.
xlog_seg_size);
960 while (errno = 0, (xlde =
readdir(xldir)) != NULL)
975 sscanf(xlde->
d_name,
"%08X%08X%08X", &tli, &log, &seg);
976 segno = ((uint64) log) * segs_per_xlogid + seg;
1028 while (errno = 0, (xlde =
readdir(xldir)) != NULL)
1034 if (unlink(path) < 0)
1036 pg_log_error(
"could not delete file \"%s\": %m", path);
1062 #define ARCHSTATDIR XLOGDIR "/archive_status" 1075 while (errno = 0, (xlde =
readdir(xldir)) != NULL)
1084 if (unlink(path) < 0)
1086 pg_log_error(
"could not delete file \"%s\": %m", path);
1123 memset(buffer.
data, 0, XLOG_BLCKSZ);
1155 record->xl_crc = crc;
1163 fd = open(path, O_RDWR | O_CREAT | O_EXCL |
PG_BINARY,
1172 if (
write(fd, buffer.
data, XLOG_BLCKSZ) != XLOG_BLCKSZ)
1182 memset(buffer.
data, 0, XLOG_BLCKSZ);
1183 for (nbytes = XLOG_BLCKSZ; nbytes <
WalSegSz; nbytes += XLOG_BLCKSZ)
1186 if (
write(fd, buffer.
data, XLOG_BLCKSZ) != XLOG_BLCKSZ)
1211 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"));
1226 printf(
_(
"\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
1227 printf(
_(
"%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
static void PrintControlValues(bool guessed)
#define IsValidWalSegSize(size)
static MultiXactId set_mxid
int gettimeofday(struct timeval *tp, struct timezone *tzp)
#define TOAST_MAX_CHUNK_SIZE
int pg_strip_crlf(char *str)
static TransactionId set_xid
void * pg_malloc(size_t size)
TimeLineID minRecoveryPointTLI
static int set_wal_segsize
const char * get_progname(const char *argv0)
#define SizeOfXLogRecordDataHeaderShort
#define pg_log_error(...)
int getopt_long(int argc, char *const argv[], const char *optstring, const struct option *longopts, int *longindex)
void get_restricted_token(void)
TransactionId oldestActiveXid
static void PrintNewControlValues(void)
void pg_logging_init(const char *argv0)
static void FindEndOfXLOG(void)
#define DEFAULT_XLOG_SEG_SIZE
TimeLineID PrevTimeLineID
static void WriteEmptyXLOG(void)
#define CATALOG_VERSION_NO
#define PG_CONTROL_VERSION
XLogPageHeaderData * XLogPageHeader
uint32 pg_control_version
CheckPoint checkPointCopy
static void CheckDataVersion(void)
static int fd(const char *x, int i)
#define XidFromFullTransactionId(x)
static TransactionId set_newest_commit_ts_xid
static void KillExistingXLOG(void)
MultiXactOffset nextMultiOffset
void update_controlfile(const char *DataDir, ControlFileData *ControlFile, bool do_sync)
#define required_argument
TransactionId oldestCommitTsXid
static void KillExistingArchiveStatus(void)
#define FirstNormalTransactionId
#define IsXLogFileName(fname)
DIR * opendir(const char *)
static TransactionId set_oldest_commit_ts_xid
#define XLogFromFileName(fname, tli, logSegNo, wal_segsz_bytes)
uint32 data_checksum_version
#define XLOG_CHECKPOINT_SHUTDOWN
char * pg_strdup(const char *in)
#define InvalidTransactionId
#define FirstBootstrapObjectId
#define EQ_CRC32C(c1, c2)
static const char * progname
#define ngettext(s, p, n)
TransactionId newestCommitTsXid
#define PG_TEXTDOMAIN(domain)
#define FirstNormalUnloggedLSN
uint32 toast_max_chunk_size
#define EpochFromFullTransactionId(x)
#define XLOG_CONTROL_FILE
XLogRecPtr backupEndPoint
TransactionId MultiXactId
#define XLogSegNoOffsetToRecPtr(segno, offset, wal_segsz_bytes, dest)
bool track_commit_timestamp
int main(int argc, char *argv[])
static ControlFileData ControlFile
#define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
static void RewriteControlFile(void)
static MultiXactOffset set_mxoff
uint32 catalog_version_no
static FullTransactionId FullTransactionIdFromEpochAndXid(uint32 epoch, TransactionId xid)
struct dirent * readdir(DIR *)
#define PG_CONTROL_FILE_SIZE
struct CheckPoint CheckPoint
#define XLR_BLOCK_ID_DATA_SHORT
#define XLogFilePath(path, tli, logSegNo, wal_segsz_bytes)
static XLogSegNo newXlogSegNo
bool GetDataDirectoryCreatePerm(const char *dataDir)
static void GuessControlValues(void)
static bool read_controlfile(void)
#define IsPartialXLogFileName(fname)
TimeLineID ThisTimeLineID
void set_pglocale_pgservice(const char *argv0, const char *app)
#define pg_log_warning(...)
#define FLOATFORMAT_VALUE
#define COMP_CRC32C(crc, data, len)
static XLogSegNo minXlogSegNo
XLogRecPtr backupStartPoint
#define offsetof(type, field)
XLogRecPtr minRecoveryPoint
FullTransactionId nextXid
static uint32 set_xid_epoch
#define SizeOfXLogLongPHD