@@ -40,6 +40,7 @@ static void digestControlFile(ControlFileData *ControlFile, char *source,
4040static void syncTargetDirectory (void );
4141static void sanityChecks (void );
4242static void findCommonAncestorTimeline (XLogRecPtr * recptr ,int * tliIndex );
43+ static void ensureCleanShutdown (const char * argv0 );
4344
4445static ControlFileData ControlFile_target ;
4546static ControlFileData ControlFile_source ;
@@ -79,6 +80,7 @@ usage(const char *progname)
7980printf (_ (" -N, --no-sync do not wait for changes to be written\n"
8081" safely to disk\n" ));
8182printf (_ (" -P, --progress write progress messages\n" ));
83+ printf (_ (" --no-ensure-shutdown do not automatically fix unclean shutdown\n" ));
8284printf (_ (" --debug write a lot of debug messages\n" ));
8385printf (_ (" -V, --version output version information, then exit\n" ));
8486printf (_ (" -?, --help show this help, then exit\n" ));
@@ -94,6 +96,7 @@ main(int argc, char **argv)
9496{"target-pgdata" ,required_argument ,NULL ,'D' },
9597{"source-pgdata" ,required_argument ,NULL ,1 },
9698{"source-server" ,required_argument ,NULL ,2 },
99+ {"no-ensure-shutdown" ,no_argument ,NULL ,44 },
97100{"version" ,no_argument ,NULL ,'V' },
98101{"dry-run" ,no_argument ,NULL ,'n' },
99102{"no-sync" ,no_argument ,NULL ,'N' },
@@ -110,6 +113,7 @@ main(int argc, char **argv)
110113XLogRecPtr chkptredo ;
111114size_t size ;
112115char * buffer ;
116+ bool no_ensure_shutdown = false;
113117bool rewind_needed ;
114118XLogRecPtr endrec ;
115119TimeLineID endtli ;
@@ -169,6 +173,9 @@ main(int argc, char **argv)
169173case 2 :/* --source-server */
170174connstr_source = pg_strdup (optarg );
171175break ;
176+ case 4 :
177+ no_ensure_shutdown = true;
178+ break ;
172179}
173180}
174181
@@ -241,6 +248,24 @@ main(int argc, char **argv)
241248digestControlFile (& ControlFile_target ,buffer ,size );
242249pg_free (buffer );
243250
251+ /*
252+ * If the target instance was not cleanly shut down, run a single-user
253+ * postgres session really quickly and reload the control file to get the
254+ * new state. Note if no_ensure_shutdown is specified, pg_rewind won't do
255+ * that automatically. That means users need to do themselves in advance,
256+ * else pg_rewind will soon quit, see sanityChecks().
257+ */
258+ if (!no_ensure_shutdown &&
259+ ControlFile_target .state != DB_SHUTDOWNED &&
260+ ControlFile_target .state != DB_SHUTDOWNED_IN_RECOVERY )
261+ {
262+ ensureCleanShutdown (argv [0 ]);
263+
264+ buffer = slurpFile (datadir_target ,"global/pg_control" ,& size );
265+ digestControlFile (& ControlFile_target ,buffer ,size );
266+ pg_free (buffer );
267+ }
268+
244269buffer = fetchFile ("global/pg_control" ,& size );
245270digestControlFile (& ControlFile_source ,buffer ,size );
246271pg_free (buffer );
@@ -748,3 +773,58 @@ syncTargetDirectory(void)
748773
749774fsync_pgdata (datadir_target ,PG_VERSION_NUM );
750775}
776+
777+ /*
778+ * Ensure clean shutdown of target instance by launching single-user mode
779+ * postgres to do crash recovery.
780+ */
781+ static void
782+ ensureCleanShutdown (const char * argv0 )
783+ {
784+ int ret ;
785+ #define MAXCMDLEN (2 * MAXPGPATH)
786+ char exec_path [MAXPGPATH ];
787+ char cmd [MAXCMDLEN ];
788+
789+ /* locate postgres binary */
790+ if ((ret = find_other_exec (argv0 ,"postgres" ,
791+ PG_BACKEND_VERSIONSTR ,
792+ exec_path ))< 0 )
793+ {
794+ char full_path [MAXPGPATH ];
795+
796+ if (find_my_exec (argv0 ,full_path )< 0 )
797+ strlcpy (full_path ,progname ,sizeof (full_path ));
798+
799+ if (ret == -1 )
800+ pg_fatal ("The program \"%s\" is needed by %s but was\n"
801+ "not found in the same directory as \"%s\".\n"
802+ "Check your installation." ,
803+ "postgres" ,progname ,full_path );
804+ else
805+ pg_fatal ("The program \"%s\" was found by \"%s\" but was\n"
806+ "not the same version as %s.\n"
807+ "Check your installation." ,
808+ "postgres" ,full_path ,progname );
809+ }
810+
811+ pg_log_info ("executing \"%s\" for target server to complete crash recovery" ,
812+ exec_path );
813+
814+ /*
815+ * Skip processing if requested, but only after ensuring presence of
816+ * postgres.
817+ */
818+ if (dry_run )
819+ return ;
820+
821+ /* finally run postgres in single-user mode */
822+ snprintf (cmd ,MAXCMDLEN ,"\"%s\" --single -D \"%s\" template1 < \"%s\"" ,
823+ exec_path ,datadir_target ,DEVNULL );
824+
825+ if (system (cmd )!= 0 )
826+ {
827+ pg_log_error ("postgres single-user mode of target instance failed" );
828+ pg_fatal ("Command was: %s" ,cmd );
829+ }
830+ }