aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2015-12-14 18:21:42 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2015-12-14 18:21:42 -0500
commit4b021aa6103f49bece51d58fd5e307d4d03380bc (patch)
tree5c1b30322be83a2269d765daf9317a4641389b41 /src
parent188675256e15f7ad4d24ae976d1bb5fbb84f43e1 (diff)
downloadpostgresql-4b021aa6103f49bece51d58fd5e307d4d03380bc.tar.gz
postgresql-4b021aa6103f49bece51d58fd5e307d4d03380bc.zip
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
Diffstat (limited to 'src')
-rw-r--r--src/bin/pg_rewind/pg_rewind.c68
-rw-r--r--src/bin/pg_rewind/t/005_same_timeline.pl14
2 files changed, 52 insertions, 30 deletions
diff --git a/src/bin/pg_rewind/pg_rewind.c b/src/bin/pg_rewind/pg_rewind.c
index a2d9ca36aa1..cf5f8487f4b 100644
--- a/src/bin/pg_rewind/pg_rewind.c
+++ b/src/bin/pg_rewind/pg_rewind.c
@@ -212,40 +212,45 @@ main(int argc, char **argv)
* do.
*/
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
{
- 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);
+ findCommonAncestorTimeline(&divergerec, &lastcommontli);
+ printf(_("servers diverged at WAL position %X/%X on timeline %u\n"),
+ (uint32) (divergerec >> 32), (uint32) divergerec, lastcommontli);
/*
- * 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.
+ * 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 (chkptendrec == divergerec)
- rewind_needed = false;
- else
+ if (ControlFile_target.checkPoint >= divergerec)
+ {
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)
@@ -374,10 +379,11 @@ sanityChecks(void)
/*
* Target cluster better not be running. This doesn't guard against
* someone starting the cluster concurrently. Also, this is probably more
- * strict than necessary; it's OK if the master was not shut down cleanly,
- * as long as it isn't running at the moment.
+ * strict than necessary; it's OK if the target node was not shut down
+ * 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");
/*
@@ -385,7 +391,9 @@ sanityChecks(void)
* server is shut down. There isn't any very strong reason for this
* 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");
}
diff --git a/src/bin/pg_rewind/t/005_same_timeline.pl b/src/bin/pg_rewind/t/005_same_timeline.pl
new file mode 100644
index 00000000000..8ca442671cd
--- /dev/null
+++ b/src/bin/pg_rewind/t/005_same_timeline.pl
@@ -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');