Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitf3db7f1

Browse files
committed
Prevent running pg_resetwal/pg_resetxlog against wrong-version data dirs.
pg_resetwal (formerly pg_resetxlog) doesn't insist on finding a matchingversion number in pg_control, and that seems like an important thing topreserve since recovering from corrupt pg_control is a prime reason toneed to run it. However, that means you can try to run it against adata directory of a different major version, which is at best uselessand at worst disastrous. So as to provide some protection against thattype of pilot error, inspect PG_VERSION at startup and refuse to doanything if it doesn't match. PG_VERSION is read-only after initdb,so it's unlikely to get corrupted, and even if it were corrupted it wouldbe easy to fix by hand.This hazard has been there all along, so back-patch to all supportedbranches.Michael Paquier, with some kibitzing by meDiscussion:https://postgr.es/m/f4b8eb91-b934-8a0d-b3cc-68f06e2279d1@enterprisedb.com
1 parentce50945 commitf3db7f1

File tree

2 files changed

+74
-1
lines changed

2 files changed

+74
-1
lines changed

‎doc/src/sgml/ref/pg_resetwal.sgml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,11 @@ PostgreSQL documentation
281281
<command>pg_resetwal</command> to run. But before you do
282282
so, make doubly certain that there is no server process still alive.
283283
</para>
284+
285+
<para>
286+
<command>pg_resetwal</command> works only with servers of the same
287+
major version.
288+
</para>
284289
</refsect1>
285290

286291
<refsect1>

‎src/bin/pg_resetwal/pg_resetwal.c

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ static MultiXactOffset set_mxoff = (MultiXactOffset) -1;
7171
staticuint32minXlogTli=0;
7272
staticXLogSegNominXlogSegNo=0;
7373

74+
staticvoidCheckDataVersion(void);
7475
staticboolReadControlFile(void);
7576
staticvoidGuessControlValues(void);
7677
staticvoidPrintControlValues(boolguessed);
@@ -319,6 +320,9 @@ main(int argc, char *argv[])
319320
exit(1);
320321
}
321322

323+
/* Check that data directory matches our server version */
324+
CheckDataVersion();
325+
322326
/*
323327
* Check for a postmaster lock file --- if there is one, refuse to
324328
* proceed, on grounds we might be interfering with a live installation.
@@ -452,6 +456,70 @@ main(int argc, char *argv[])
452456
}
453457

454458

459+
/*
460+
* Look at the version string stored in PG_VERSION and decide if this utility
461+
* can be run safely or not.
462+
*
463+
* We don't want to inject pg_control and WAL files that are for a different
464+
* major version; that can't do anything good. Note that we don't treat
465+
* mismatching version info in pg_control as a reason to bail out, because
466+
* recovering from a corrupted pg_control is one of the main reasons for this
467+
* program to exist at all. However, PG_VERSION is unlikely to get corrupted,
468+
* and if it were it would be easy to fix by hand. So let's make this check
469+
* to prevent simple user errors.
470+
*/
471+
staticvoid
472+
CheckDataVersion(void)
473+
{
474+
constchar*ver_file="PG_VERSION";
475+
FILE*ver_fd;
476+
charrawline[64];
477+
intlen;
478+
479+
if ((ver_fd=fopen(ver_file,"r"))==NULL)
480+
{
481+
fprintf(stderr,_("%s: could not open file \"%s\" for reading: %s\n"),
482+
progname,ver_file,strerror(errno));
483+
exit(1);
484+
}
485+
486+
/* version number has to be the first line read */
487+
if (!fgets(rawline,sizeof(rawline),ver_fd))
488+
{
489+
if (!ferror(ver_fd))
490+
{
491+
fprintf(stderr,_("%s: unexpected empty file \"%s\"\n"),
492+
progname,ver_file);
493+
}
494+
else
495+
{
496+
fprintf(stderr,_("%s: could not read file \"%s\": %s\n"),
497+
progname,ver_file,strerror(errno));
498+
}
499+
exit(1);
500+
}
501+
502+
/* remove trailing newline, handling Windows newlines as well */
503+
len=strlen(rawline);
504+
if (len>0&&rawline[len-1]=='\n')
505+
{
506+
rawline[--len]='\0';
507+
if (len>0&&rawline[len-1]=='\r')
508+
rawline[--len]='\0';
509+
}
510+
511+
if (strcmp(rawline,PG_MAJORVERSION)!=0)
512+
{
513+
fprintf(stderr,_("%s: data directory is of wrong version\n"
514+
"File \"%s\" contains \"%s\", which is not compatible with this program's version \"%s\".\n"),
515+
progname,ver_file,rawline,PG_MAJORVERSION);
516+
exit(1);
517+
}
518+
519+
fclose(ver_fd);
520+
}
521+
522+
455523
/*
456524
* Try to read the existing pg_control file.
457525
*
@@ -521,7 +589,7 @@ ReadControlFile(void)
521589
}
522590

523591
/* Looks like it's a mess. */
524-
fprintf(stderr,_("%s: pg_control exists but is broken orunknown version; ignoring it\n"),
592+
fprintf(stderr,_("%s: pg_control exists but is broken orwrong version; ignoring it\n"),
525593
progname);
526594
return false;
527595
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp