1
0
mirror of https://github.com/postgres/postgres.git synced 2025-05-02 11:44:50 +03:00

pg_rewind: Don't error if the two clusters are already on the same timeline

This previously resulted in an error and a nonzero exit status, but
after discussion this should rather be a noop with a zero exit status.

This is a back-patch of commit 6b34e5563849edc12896bf5754e8fe7b88012697,
plus two changes from commit e50cda78404d6400b1326a996a4fabb144871151
that teach pg_rewind to allow the initial control file states to be
DB_SHUTDOWNED_IN_RECOVERY as well as DB_SHUTDOWNED.  That's necessary
to get the additional regression test case to pass, and the old behavior
seems like rather a foot-gun anyway.

Peter Eisentraut and Tom Lane
This commit is contained in:
Tom Lane 2015-12-14 18:21:42 -05:00
parent 188675256e
commit 4b021aa610
2 changed files with 52 additions and 30 deletions

View File

@ -212,40 +212,45 @@ main(int argc, char **argv)
* do. * do.
*/ */
if (ControlFile_target.checkPointCopy.ThisTimeLineID == ControlFile_source.checkPointCopy.ThisTimeLineID) if (ControlFile_target.checkPointCopy.ThisTimeLineID == ControlFile_source.checkPointCopy.ThisTimeLineID)
pg_fatal("source and target cluster are on the same timeline\n");
findCommonAncestorTimeline(&divergerec, &lastcommontli);
printf(_("servers diverged at WAL position %X/%X on timeline %u\n"),
(uint32) (divergerec >> 32), (uint32) divergerec, lastcommontli);
/*
* Check for the possibility that the target is in fact a direct ancestor
* of the source. In that case, there is no divergent history in the
* target that needs rewinding.
*/
if (ControlFile_target.checkPoint >= divergerec)
{ {
rewind_needed = true; printf(_("source and target cluster are on the same timeline\n"));
rewind_needed = false;
} }
else else
{ {
XLogRecPtr chkptendrec; findCommonAncestorTimeline(&divergerec, &lastcommontli);
printf(_("servers diverged at WAL position %X/%X on timeline %u\n"),
/* Read the checkpoint record on the target to see where it ends. */ (uint32) (divergerec >> 32), (uint32) divergerec, lastcommontli);
chkptendrec = readOneRecord(datadir_target,
ControlFile_target.checkPoint,
ControlFile_target.checkPointCopy.ThisTimeLineID);
/* /*
* If the histories diverged exactly at the end of the shutdown * Check for the possibility that the target is in fact a direct ancestor
* checkpoint record on the target, there are no WAL records in the * of the source. In that case, there is no divergent history in the
* target that don't belong in the source's history, and no rewind is * target that needs rewinding.
* needed.
*/ */
if (chkptendrec == divergerec) if (ControlFile_target.checkPoint >= divergerec)
rewind_needed = false; {
else
rewind_needed = true; rewind_needed = true;
}
else
{
XLogRecPtr chkptendrec;
/* Read the checkpoint record on the target to see where it ends. */
chkptendrec = readOneRecord(datadir_target,
ControlFile_target.checkPoint,
ControlFile_target.checkPointCopy.ThisTimeLineID);
/*
* If the histories diverged exactly at the end of the shutdown
* checkpoint record on the target, there are no WAL records in the
* target that don't belong in the source's history, and no rewind is
* needed.
*/
if (chkptendrec == divergerec)
rewind_needed = false;
else
rewind_needed = true;
}
} }
if (!rewind_needed) if (!rewind_needed)
@ -374,10 +379,11 @@ sanityChecks(void)
/* /*
* Target cluster better not be running. This doesn't guard against * Target cluster better not be running. This doesn't guard against
* someone starting the cluster concurrently. Also, this is probably more * someone starting the cluster concurrently. Also, this is probably more
* strict than necessary; it's OK if the master was not shut down cleanly, * strict than necessary; it's OK if the target node was not shut down
* as long as it isn't running at the moment. * cleanly, as long as it isn't running at the moment.
*/ */
if (ControlFile_target.state != DB_SHUTDOWNED) if (ControlFile_target.state != DB_SHUTDOWNED &&
ControlFile_target.state != DB_SHUTDOWNED_IN_RECOVERY)
pg_fatal("target server must be shut down cleanly\n"); pg_fatal("target server must be shut down cleanly\n");
/* /*
@ -385,7 +391,9 @@ sanityChecks(void)
* server is shut down. There isn't any very strong reason for this * server is shut down. There isn't any very strong reason for this
* limitation, but better safe than sorry. * limitation, but better safe than sorry.
*/ */
if (datadir_source && ControlFile_source.state != DB_SHUTDOWNED) if (datadir_source &&
ControlFile_source.state != DB_SHUTDOWNED &&
ControlFile_source.state != DB_SHUTDOWNED_IN_RECOVERY)
pg_fatal("source data directory must be shut down cleanly\n"); pg_fatal("source data directory must be shut down cleanly\n");
} }

View File

@ -0,0 +1,14 @@
use strict;
use warnings;
use TestLib;
use Test::More tests => 1;
use RewindTest;
# Test that running pg_rewind if the two clusters are on the same
# timeline runs successfully.
RewindTest::setup_cluster();
RewindTest::start_master();
RewindTest::create_standby();
RewindTest::run_pg_rewind('local');