diff --git a/doc/src/sgml/ref/pg_resetwal.sgml b/doc/src/sgml/ref/pg_resetwal.sgml index 0d93b56ddd..defaf170dc 100644 --- a/doc/src/sgml/ref/pg_resetwal.sgml +++ b/doc/src/sgml/ref/pg_resetwal.sgml @@ -281,6 +281,11 @@ PostgreSQL documentation pg_resetwal to run. But before you do so, make doubly certain that there is no server process still alive. + + + pg_resetwal works only with servers of the same + major version. + diff --git a/src/bin/pg_resetwal/pg_resetwal.c b/src/bin/pg_resetwal/pg_resetwal.c index a3ecccb035..9c39422329 100644 --- a/src/bin/pg_resetwal/pg_resetwal.c +++ b/src/bin/pg_resetwal/pg_resetwal.c @@ -71,6 +71,7 @@ static MultiXactOffset set_mxoff = (MultiXactOffset) -1; static uint32 minXlogTli = 0; static XLogSegNo minXlogSegNo = 0; +static void CheckDataVersion(char *datadir); static bool ReadControlFile(void); static void GuessControlValues(void); static void PrintControlValues(bool guessed); @@ -294,6 +295,11 @@ main(int argc, char *argv[]) } /* + * Canonicalize path, which makes error and logging messages look nicer. + */ + canonicalize_path(DataDir); + + /* * Don't allow pg_resetwal to be run as root, to avoid overwriting the * ownership of files in the data directory. We need only check for root * -- any other user won't have sufficient permissions to modify files in @@ -340,6 +346,9 @@ main(int argc, char *argv[]) exit(1); } + /* Check version of server */ + CheckDataVersion(DataDir); + /* * Attempt to read the existing pg_control file */ @@ -453,6 +462,62 @@ main(int argc, char *argv[]) /* + * Look at the version string stored in PG_VERSION and decide if this + * utility can be safely run or not. + */ +static void +CheckDataVersion(char *datadir) +{ + FILE *ver_fd; + char ver_file[MAXPGPATH]; + char rawline[64]; + int len; + + snprintf(ver_file, MAXPGPATH, "%s/PG_VERSION", datadir); + if ((ver_fd = fopen(ver_file, "r")) == NULL) + { + fprintf(stderr, _("%s: could not open file \"%s\" for reading: %s\n"), + progname, ver_file, strerror(errno)); + exit(1); + } + + /* version number has to be the first line read */ + if (!fgets(rawline, sizeof(rawline), ver_fd)) + { + if (!ferror(ver_fd)) + { + fprintf(stderr, _("%s: unexpected empty file \"%s\"\n"), + progname, ver_file); + } + else + { + fprintf(stderr, _("%s: could not read file \"%s\": %s\n"), + progname, ver_file, strerror(errno)); + } + exit(1); + } + + /* remove trailing newline, handling Windows as well */ + len = strlen(rawline); + if (len > 0 && rawline[len - 1] == '\n') + { + rawline[--len] = '\0'; + if (len > 0 && rawline[len - 1] == '\r') + rawline[--len] = '\0'; + } + + if (strcmp(rawline, PG_MAJORVERSION) != 0) + { + fprintf(stderr, _("%s: unexpected version in file \"%s\": expected \"%s\" but found \"%s\"\n"), + progname, ver_file, PG_MAJORVERSION, rawline); + exit(1); + } + + fclose(ver_fd); +} + + +/* * Try to read the existing pg_control file. * * This routine is also responsible for updating old pg_control versions