Skip to content

Commit 4b021aa

Browse files
committed
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 6b34e55, plus two changes from commit e50cda7 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
1 parent 1886752 commit 4b021aa

File tree

2 files changed

+52
-30
lines changed

2 files changed

+52
-30
lines changed

src/bin/pg_rewind/pg_rewind.c

Lines changed: 38 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -212,40 +212,45 @@ main(int argc, char **argv)
212212
* do.
213213
*/
214214
if (ControlFile_target.checkPointCopy.ThisTimeLineID == ControlFile_source.checkPointCopy.ThisTimeLineID)
215-
pg_fatal("source and target cluster are on the same timeline\n");
216-
217-
findCommonAncestorTimeline(&divergerec, &lastcommontli);
218-
printf(_("servers diverged at WAL position %X/%X on timeline %u\n"),
219-
(uint32) (divergerec >> 32), (uint32) divergerec, lastcommontli);
220-
221-
/*
222-
* Check for the possibility that the target is in fact a direct ancestor
223-
* of the source. In that case, there is no divergent history in the
224-
* target that needs rewinding.
225-
*/
226-
if (ControlFile_target.checkPoint >= divergerec)
227215
{
228-
rewind_needed = true;
216+
printf(_("source and target cluster are on the same timeline\n"));
217+
rewind_needed = false;
229218
}
230219
else
231220
{
232-
XLogRecPtr chkptendrec;
233-
234-
/* Read the checkpoint record on the target to see where it ends. */
235-
chkptendrec = readOneRecord(datadir_target,
236-
ControlFile_target.checkPoint,
237-
ControlFile_target.checkPointCopy.ThisTimeLineID);
221+
findCommonAncestorTimeline(&divergerec, &lastcommontli);
222+
printf(_("servers diverged at WAL position %X/%X on timeline %u\n"),
223+
(uint32) (divergerec >> 32), (uint32) divergerec, lastcommontli);
238224

239225
/*
240-
* If the histories diverged exactly at the end of the shutdown
241-
* checkpoint record on the target, there are no WAL records in the
242-
* target that don't belong in the source's history, and no rewind is
243-
* needed.
226+
* Check for the possibility that the target is in fact a direct ancestor
227+
* of the source. In that case, there is no divergent history in the
228+
* target that needs rewinding.
244229
*/
245-
if (chkptendrec == divergerec)
246-
rewind_needed = false;
247-
else
230+
if (ControlFile_target.checkPoint >= divergerec)
231+
{
248232
rewind_needed = true;
233+
}
234+
else
235+
{
236+
XLogRecPtr chkptendrec;
237+
238+
/* Read the checkpoint record on the target to see where it ends. */
239+
chkptendrec = readOneRecord(datadir_target,
240+
ControlFile_target.checkPoint,
241+
ControlFile_target.checkPointCopy.ThisTimeLineID);
242+
243+
/*
244+
* If the histories diverged exactly at the end of the shutdown
245+
* checkpoint record on the target, there are no WAL records in the
246+
* target that don't belong in the source's history, and no rewind is
247+
* needed.
248+
*/
249+
if (chkptendrec == divergerec)
250+
rewind_needed = false;
251+
else
252+
rewind_needed = true;
253+
}
249254
}
250255

251256
if (!rewind_needed)
@@ -374,18 +379,21 @@ sanityChecks(void)
374379
/*
375380
* Target cluster better not be running. This doesn't guard against
376381
* someone starting the cluster concurrently. Also, this is probably more
377-
* strict than necessary; it's OK if the master was not shut down cleanly,
378-
* as long as it isn't running at the moment.
382+
* strict than necessary; it's OK if the target node was not shut down
383+
* cleanly, as long as it isn't running at the moment.
379384
*/
380-
if (ControlFile_target.state != DB_SHUTDOWNED)
385+
if (ControlFile_target.state != DB_SHUTDOWNED &&
386+
ControlFile_target.state != DB_SHUTDOWNED_IN_RECOVERY)
381387
pg_fatal("target server must be shut down cleanly\n");
382388

383389
/*
384390
* When the source is a data directory, also require that the source
385391
* server is shut down. There isn't any very strong reason for this
386392
* limitation, but better safe than sorry.
387393
*/
388-
if (datadir_source && ControlFile_source.state != DB_SHUTDOWNED)
394+
if (datadir_source &&
395+
ControlFile_source.state != DB_SHUTDOWNED &&
396+
ControlFile_source.state != DB_SHUTDOWNED_IN_RECOVERY)
389397
pg_fatal("source data directory must be shut down cleanly\n");
390398
}
391399

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
use strict;
2+
use warnings;
3+
use TestLib;
4+
use Test::More tests => 1;
5+
6+
use RewindTest;
7+
8+
# Test that running pg_rewind if the two clusters are on the same
9+
# timeline runs successfully.
10+
11+
RewindTest::setup_cluster();
12+
RewindTest::start_master();
13+
RewindTest::create_standby();
14+
RewindTest::run_pg_rewind('local');

0 commit comments

Comments
 (0)