Data-only pg_rewind, take 2

Started by Chris Traversalmost 7 years ago6 messages
#1Chris Travers
chris.travers@adjust.com
1 attachment(s)

Hi;

Attached is my second attempt at the pg_rewind change which allows one to
include only a minimal set. To my understanding, all past feedback has
been addressed.

The current patch does not change default behavior at present. It does add
a --data-only flag which allows pg_rewind to only rewind minimal files to
work. I believe this would generally be a good practice though maybe there
is some disagreement on that.

I have not run pg_indent because of the large number of other changes but
if that is desired at some point I can do that.

I also added test cases and some docs. I don't know if the docs are
sufficient. Feedback is appreciated. This is of course submitted for v13.

--
Best Regards,
Chris Travers
Head of Database

Tel: +49 162 9037 210 | Skype: einhverfr | www.adjust.com
Saarbrücker Straße 37a, 10405 Berlin

Attachments:

rewind_data_only_mode.patchapplication/octet-stream; name=rewind_data_only_mode.patchDownload
commit 0acb3def366c4795970ca1b53bf1918f7c85b924
Author: Chris Traverswq <chris.travers@gmail.com>
Date:   Sun Mar 17 17:32:01 2019 +0800

    Initial patch submission

diff --git a/doc/src/sgml/ref/pg_rewind.sgml b/doc/src/sgml/ref/pg_rewind.sgml
index 53a64ee29e..105ad13aad 100644
--- a/doc/src/sgml/ref/pg_rewind.sgml
+++ b/doc/src/sgml/ref/pg_rewind.sgml
@@ -48,16 +48,26 @@ PostgreSQL documentation
   </para>
 
   <para>
-   The result is equivalent to replacing the target data directory with the
-   source one. Only changed blocks from relation files are copied;
-   all other files are copied in full, including configuration files. The
-   advantage of <application>pg_rewind</application> over taking a new base backup, or
-   tools like <application>rsync</application>, is that <application>pg_rewind</application> does
-   not require reading through unchanged blocks in the cluster. This makes
+   The result is equivalent to replacing the data-related files in the  target
+   data directory with the source one. Only changed blocks from relation files
+   are copied; all other files relating to control or WAL information are copied
+   in full. The advantage of <application>pg_rewind</application> over taking a new base
+   backup, or tools like <application>rsync</application>, is that <application>pg_rewind</application>
+   does not require reading through unchanged blocks in the cluster. This makes
    it a lot faster when the database is large and only a small
    fraction of blocks differ between the clusters.
   </para>
 
+  <para>
+    A second advantage is predictability.  <application>pg_rewind</application> is aware of
+    what directories are relevant to restoring replication and which ones are not.
+    The result is that you get something of a guaranteed state at the end.  Log
+    files on the source are unlikely to clobber those on the client.  The
+    <filename>postgresql.conf.auto</filename> is unlikely to be copied over.  Replication
+    slot information is removed (and must be added again), and so forth.  Your
+    system is as it had been before, but the data is synchronized from the master.
+  </para>
+
   <para>
    <application>pg_rewind</application> examines the timeline histories of the source
    and target clusters to determine the point where they diverged, and
@@ -244,7 +254,7 @@ PostgreSQL documentation
 
    <para>
     The basic idea is to copy all file system-level changes from the source
-    cluster to the target cluster:
+    cluster to the target cluster if they implicate the data stored:
    </para>
 
    <procedure>
diff --git a/src/bin/pg_rewind/copy_fetch.c b/src/bin/pg_rewind/copy_fetch.c
index a283405f6c..7c42e96474 100644
--- a/src/bin/pg_rewind/copy_fetch.c
+++ b/src/bin/pg_rewind/copy_fetch.c
@@ -21,9 +21,31 @@
 #include "logging.h"
 #include "pg_rewind.h"
 
-static void recurse_dir(const char *datadir, const char *path,
+void recurse_dir(const char *datadir, const char *path,
 			process_file_callback_t callback);
 
+/* List of directories to synchronize:
+ * base data dirs (and ablespaces)
+ * wal/transaction data
+ * and that is it.
+ *
+ * This array is null-terminated to make
+ * it easy to expand
+ */
+
+const char *rewind_dirs[] = {
+    "base",         // Default tablespace
+    "global",       // global tablespace
+    "pg_commit_ts", // In case we need to do PITR before up to sync
+    "pg_logical",   // WAL related and no good reason to exclude
+    "pg_multixact", // WAL related and may need for vacuum-related reasons
+    "pg_tblspc",    // Pther tablespaces
+    "pg_twophase",  // mostly to *clear*
+    "pg_wal",       // WAL
+    "pg_xact",      // Commits of transactions
+    NULL
+};
+
 static void execute_pagemap(datapagemap_t *pagemap, const char *path);
 
 /*
@@ -31,18 +53,21 @@ static void execute_pagemap(datapagemap_t *pagemap, const char *path);
  * for each file.
  */
 void
-traverse_datadir(const char *datadir, process_file_callback_t callback)
+traverse_rewinddirs(const char *datadir, process_file_callback_t callback)
 {
-	recurse_dir(datadir, NULL, callback);
+	int i;
+	for(i = 0; rewind_dirs[i] != NULL; i++){
+		recurse_dir(datadir, rewind_dirs[i], callback);
+	}
 }
 
 /*
- * recursive part of traverse_datadir
+ * recursive part of traverse_rewinddirs
  *
  * parentpath is the current subdirectory's path relative to datadir,
  * or NULL at the top level.
  */
-static void
+void
 recurse_dir(const char *datadir, const char *parentpath,
 			process_file_callback_t callback)
 {
diff --git a/src/bin/pg_rewind/fetch.c b/src/bin/pg_rewind/fetch.c
index 03a5fd675f..df42f6c4c6 100644
--- a/src/bin/pg_rewind/fetch.c
+++ b/src/bin/pg_rewind/fetch.c
@@ -27,8 +27,12 @@
 void
 fetchSourceFileList(void)
 {
-	if (datadir_source)
-		traverse_datadir(datadir_source, &process_source_file);
+	if (datadir_source){
+		if(data_only)
+			traverse_rewinddirs(datadir_source, &process_source_file);
+		else
+			recurse_dir(datadir_source, NULL, &process_source_file);
+	}
 	else
 		libpqProcessFileList();
 }
diff --git a/src/bin/pg_rewind/fetch.h b/src/bin/pg_rewind/fetch.h
index a694e8b157..b76fa62313 100644
--- a/src/bin/pg_rewind/fetch.h
+++ b/src/bin/pg_rewind/fetch.h
@@ -36,9 +36,11 @@ extern void libpqConnect(const char *connstr);
 extern XLogRecPtr libpqGetCurrentXlogInsertLocation(void);
 
 /* in copy_fetch.c */
+extern const char *rewind_dirs[];
 extern void copy_executeFileMap(filemap_t *map);
 
 typedef void (*process_file_callback_t) (const char *path, file_type_t type, size_t size, const char *link_target);
-extern void traverse_datadir(const char *datadir, process_file_callback_t callback);
+extern void recurse_dir(const char *datadir, const char *path, process_file_callback_t callback);
+extern void traverse_rewinddirs(const char *datadir, process_file_callback_t callback);
 
 #endif							/* FETCH_H */
diff --git a/src/bin/pg_rewind/libpq_fetch.c b/src/bin/pg_rewind/libpq_fetch.c
index d06e277432..7fb5fdc6c6 100644
--- a/src/bin/pg_rewind/libpq_fetch.c
+++ b/src/bin/pg_rewind/libpq_fetch.c
@@ -153,8 +153,8 @@ libpqProcessFileList(void)
 {
 	PGresult   *res;
 	const char *sql;
-	int			i;
-
+	int			i, p;
+	
 	/*
 	 * Create a recursive directory listing of the whole data directory.
 	 *
@@ -169,7 +169,8 @@ libpqProcessFileList(void)
 		"WITH RECURSIVE files (path, filename, size, isdir) AS (\n"
 		"  SELECT '' AS path, filename, size, isdir FROM\n"
 		"  (SELECT pg_ls_dir('.', true, false) AS filename) AS fn,\n"
-		"        pg_stat_file(fn.filename, true) AS this\n"
+		"   LATERAL pg_stat_file(fn.filename, true) AS this\n"
+		"  WHERE filename = $1 OR $2\n"
 		"  UNION ALL\n"
 		"  SELECT parent.path || parent.filename || '/' AS path,\n"
 		"         fn, this.size, this.isdir\n"
@@ -183,44 +184,59 @@ libpqProcessFileList(void)
 		"FROM files\n"
 		"LEFT OUTER JOIN pg_tablespace ON files.path = 'pg_tblspc/'\n"
 		"                             AND oid::text = files.filename\n";
-	res = PQexec(conn, sql);
 
-	if (PQresultStatus(res) != PGRES_TUPLES_OK)
-		pg_fatal("could not fetch file list: %s",
-				 PQresultErrorMessage(res));
+	/* Going through the directories in a loop.  Doing it this way
+	 * makes it easier to add more inclusions later.
+	 *
+	 * Note that the query filters out on top-level directories before
+	 * recursion so this will not give us problems in terms of listing
+	 * lots of files many times.
+	 */
+	for (p = 0; rewind_dirs[p] != NULL; ++p)
+	{
+		const char *paths[2];
+		paths[0] = rewind_dirs[p];
+		paths[1] = data_only ? "f" : "t";
+		res = PQexecParams(conn, sql,  2, NULL, paths, NULL, NULL, 0);
 
-	/* sanity check the result set */
-	if (PQnfields(res) != 4)
-		pg_fatal("unexpected result set while fetching file list\n");
+		if (PQresultStatus(res) != PGRES_TUPLES_OK)
+			pg_fatal("could not fetch file list: %s",
+				 PQresultErrorMessage(res));
 
-	/* Read result to local variables */
-	for (i = 0; i < PQntuples(res); i++)
-	{
-		char	   *path = PQgetvalue(res, i, 0);
-		int64		filesize = atol(PQgetvalue(res, i, 1));
-		bool		isdir = (strcmp(PQgetvalue(res, i, 2), "t") == 0);
-		char	   *link_target = PQgetvalue(res, i, 3);
-		file_type_t type;
+		/* sanity check the result set */
+		if (PQnfields(res) != 4)
+			pg_fatal("unexpected result set while fetching file list\n");
 
-		if (PQgetisnull(res, 0, 1))
+		/* Read result to local variables */
+		for (i = 0; i < PQntuples(res); i++)
 		{
-			/*
-			 * The file was removed from the server while the query was
-			 * running. Ignore it.
-			 */
-			continue;
+			char	   *path = PQgetvalue(res, i, 0);
+			int64		filesize = atol(PQgetvalue(res, i, 1));
+			bool		isdir = (strcmp(PQgetvalue(res, i, 2), "t") == 0);
+			char	   *link_target = PQgetvalue(res, i, 3);
+			file_type_t type;
+
+			if (PQgetisnull(res, 0, 1))
+			{
+				/*
+				 * The file was removed from the server while the query was
+				 * running. Ignore it.
+				 */
+				continue;
+			}
+
+			if (link_target[0])
+				type = FILE_TYPE_SYMLINK;
+			else if (isdir)
+				type = FILE_TYPE_DIRECTORY;
+			else
+				type = FILE_TYPE_REGULAR;
+			process_source_file(path, type, filesize, link_target);
 		}
-
-		if (link_target[0])
-			type = FILE_TYPE_SYMLINK;
-		else if (isdir)
-			type = FILE_TYPE_DIRECTORY;
-		else
-			type = FILE_TYPE_REGULAR;
-
-		process_source_file(path, type, filesize, link_target);
+		PQclear(res);
+		if (!data_only)
+			break;
 	}
-	PQclear(res);
 }
 
 /*----
diff --git a/src/bin/pg_rewind/pg_rewind.c b/src/bin/pg_rewind/pg_rewind.c
index 7f1d6bf48a..3fbaeb71f8 100644
--- a/src/bin/pg_rewind/pg_rewind.c
+++ b/src/bin/pg_rewind/pg_rewind.c
@@ -57,6 +57,7 @@ bool		debug = false;
 bool		showprogress = false;
 bool		dry_run = false;
 bool		do_sync = true;
+bool		data_only = false;
 
 /* Target history */
 TimeLineHistoryEntry *targetHistory;
@@ -72,6 +73,7 @@ usage(const char *progname)
 	printf(_("      --source-pgdata=DIRECTORY  source data directory to synchronize with\n"));
 	printf(_("      --source-server=CONNSTR    source server to synchronize with\n"));
 	printf(_("  -n, --dry-run                  stop before modifying anything\n"));
+	printf(_("      --data-only                only rewind data files\n"));
 	printf(_("  -N, --no-sync                  do not wait for changes to be written\n"));
 	printf(_("                                 safely to disk\n"));
 	printf(_("  -P, --progress                 write progress messages\n"));
@@ -95,6 +97,7 @@ main(int argc, char **argv)
 		{"no-sync", no_argument, NULL, 'N'},
 		{"progress", no_argument, NULL, 'P'},
 		{"debug", no_argument, NULL, 3},
+		{"data-only", no_argument, NULL, 4},
 		{NULL, 0, NULL, 0}
 	};
 	int			option_index;
@@ -163,6 +166,9 @@ main(int argc, char **argv)
 			case 2:				/* --source-server */
 				connstr_source = pg_strdup(optarg);
 				break;
+			case 4:
+				data_only = true;
+				break;
 		}
 	}
 
@@ -308,7 +314,10 @@ main(int argc, char **argv)
 	pg_log(PG_PROGRESS, "reading source file list\n");
 	fetchSourceFileList();
 	pg_log(PG_PROGRESS, "reading target file list\n");
-	traverse_datadir(datadir_target, &process_target_file);
+	if(data_only)
+		traverse_rewinddirs(datadir_target, &process_target_file);
+	else
+		recurse_dir(datadir_target, NULL, &process_target_file);
 
 	/*
 	 * Read the target WAL from last checkpoint before the point of fork, to
diff --git a/src/bin/pg_rewind/pg_rewind.h b/src/bin/pg_rewind/pg_rewind.h
index 83b2898b8b..87996aedd4 100644
--- a/src/bin/pg_rewind/pg_rewind.h
+++ b/src/bin/pg_rewind/pg_rewind.h
@@ -25,6 +25,7 @@ extern bool debug;
 extern bool showprogress;
 extern bool dry_run;
 extern int	WalSegSz;
+extern bool data_only;
 
 /* Target history */
 extern TimeLineHistoryEntry *targetHistory;
diff --git a/src/bin/pg_rewind/t/006_extrafiles_min.pl b/src/bin/pg_rewind/t/006_extrafiles_min.pl
new file mode 100644
index 0000000000..c2d5e7853f
--- /dev/null
+++ b/src/bin/pg_rewind/t/006_extrafiles_min.pl
@@ -0,0 +1,95 @@
+# Test how pg_rewind reacts to extra files and directories in the data dirs.
+
+use strict;
+use warnings;
+use TestLib;
+use Test::More tests => 4;
+use Data::Dumper;
+
+use File::Find;
+
+use FindBin;
+use lib $FindBin::RealBin;
+
+use RewindTest;
+
+
+sub run_test
+{
+	my $test_mode = shift;
+
+	RewindTest::setup_cluster($test_mode);
+	RewindTest::start_master();
+
+	my $test_master_datadir = $node_master->data_dir;
+
+	# Create a subdir and files that will be present in both
+	mkdir "$test_master_datadir/tst_both_dir";
+	append_to_file "$test_master_datadir/tst_both_dir/both_file1", "in both1";
+	append_to_file "$test_master_datadir/tst_both_dir/both_file2", "in both2";
+	mkdir "$test_master_datadir/tst_both_dir/both_subdir/";
+	append_to_file "$test_master_datadir/tst_both_dir/both_subdir/both_file3",
+	  "in both3";
+
+	RewindTest::create_standby($test_mode);
+
+	# Create different subdirs and files in master and standby
+	my $test_standby_datadir = $node_standby->data_dir;
+
+	mkdir "$test_standby_datadir/tst_standby_dir";
+	append_to_file "$test_standby_datadir/tst_standby_dir/standby_file1",
+	  "in standby1";
+	append_to_file "$test_standby_datadir/tst_standby_dir/standby_file2",
+	  "in standby2";
+	mkdir "$test_standby_datadir/tst_standby_dir/standby_subdir/";
+	append_to_file
+	  "$test_standby_datadir/tst_standby_dir/standby_subdir/standby_file3",
+	  "in standby3";
+
+	mkdir "$test_master_datadir/tst_master_dir";
+	append_to_file "$test_master_datadir/tst_master_dir/master_file1",
+	  "in master1";
+	append_to_file "$test_master_datadir/tst_master_dir/master_file2",
+	  "in master2";
+	mkdir "$test_master_datadir/tst_master_dir/master_subdir/";
+	append_to_file
+	  "$test_master_datadir/tst_master_dir/master_subdir/master_file3",
+	  "in master3";
+
+	RewindTest::promote_standby();
+	RewindTest::run_pg_rewind($test_mode, 1);
+
+	# List files in the data directory after rewind.
+	my @paths;
+	find(
+		sub {
+			push @paths, $File::Find::name
+			  if $File::Find::name =~ m/.*tst_.*/;
+		},
+		$test_master_datadir);
+	@paths = sort @paths;
+	is_deeply(
+		\@paths,
+		[
+			"$test_master_datadir/tst_both_dir",
+			"$test_master_datadir/tst_both_dir/both_file1",
+			"$test_master_datadir/tst_both_dir/both_file2",
+			"$test_master_datadir/tst_both_dir/both_subdir",
+			"$test_master_datadir/tst_both_dir/both_subdir/both_file3",
+			"$test_master_datadir/tst_master_dir",
+			"$test_master_datadir/tst_master_dir/master_file1",
+			"$test_master_datadir/tst_master_dir/master_file2",
+			"$test_master_datadir/tst_master_dir/master_subdir",
+			"$test_master_datadir/tst_master_dir/master_subdir/master_file3"
+		],
+		"file lists match") or diag(Dumper(\@paths));
+
+	RewindTest::clean_rewind_test();
+	return;
+}
+
+# Run the test in both modes.
+run_test('local');
+run_test('remote');
+
+exit(0);
diff --git a/src/bin/pg_rewind/t/RewindTest.pm b/src/bin/pg_rewind/t/RewindTest.pm
index 85cae7e47b..5137c812c5 100644
--- a/src/bin/pg_rewind/t/RewindTest.pm
+++ b/src/bin/pg_rewind/t/RewindTest.pm
@@ -200,6 +200,7 @@ sub promote_standby
 sub run_pg_rewind
 {
 	my $test_mode       = shift;
+	my $data_only       = shift;
 	my $master_pgdata   = $node_master->data_dir;
 	my $standby_pgdata  = $node_standby->data_dir;
 	my $standby_connstr = $node_standby->connstr('postgres');
@@ -232,7 +233,8 @@ sub run_pg_rewind
 				"--debug",
 				"--source-pgdata=$standby_pgdata",
 				"--target-pgdata=$master_pgdata",
-				"--no-sync"
+				"--no-sync",
+				($data_only ? '--data-only' : ())
 			],
 			'pg_rewind local');
 	}
@@ -245,7 +247,8 @@ sub run_pg_rewind
 				'pg_rewind',       "--debug",
 				"--source-server", $standby_connstr,
 				"--target-pgdata=$master_pgdata",
-				"--no-sync"
+				"--no-sync",
+				($data_only ? '--data-only' : ())
 			],
 			'pg_rewind remote');
 	}
#2Michael Paquier
michael@paquier.xyz
In reply to: Chris Travers (#1)
Re: Data-only pg_rewind, take 2

On Sun, Mar 17, 2019 at 09:00:57PM +0800, Chris Travers wrote:

I also added test cases and some docs. I don't know if the docs are
sufficient. Feedback is appreciated.

To be honest, I don't think that this approach is a good idea per the
same reasons as mentioned the last time, as this can cause pg_rewind
to break if any newly-added folder in the data directory has
non-replaceable data which is needed at the beginning of recovery and
cannot be automatically rebuilt. So that's one extra maintenance
burden to worry about.

Here is the reference of the last thread about the same topic:
/messages/by-id/CAN-RpxD8Y7hMOjzd93hOqV6n8kPEo5cmW9gYm+8JirTPiFnmmQ@mail.gmail.com
--
Michael

#3Stephen Frost
sfrost@snowman.net
In reply to: Michael Paquier (#2)
Re: Data-only pg_rewind, take 2

Greetings,

* Michael Paquier (michael@paquier.xyz) wrote:

On Sun, Mar 17, 2019 at 09:00:57PM +0800, Chris Travers wrote:

I also added test cases and some docs. I don't know if the docs are
sufficient. Feedback is appreciated.

To be honest, I don't think that this approach is a good idea per the
same reasons as mentioned the last time, as this can cause pg_rewind
to break if any newly-added folder in the data directory has
non-replaceable data which is needed at the beginning of recovery and
cannot be automatically rebuilt. So that's one extra maintenance
burden to worry about.

The right approach to deal with that is to have a canonical list of
those, isn't it? So that we have one place to update that takes care to
make sure that all of the tools realize what's actually needed.

In general, I agree completely with Chris on the reasoning behind this
patch and that we really should try to avoid copying random files and
directories that have shown up in the data directory during a pg_rewind.
Having regular expressions and other such things just strike me as a
really bad idea for a low-level tool like pg_rewind- if users have
dropped other stuff in the data directory that they want copied around
between systems then it should be on them to make that happen, not
expect pg_rewind to copy them..

Thanks!

Stephen

#4Chris Travers
chris.travers@adjust.com
In reply to: Michael Paquier (#2)
Re: Data-only pg_rewind, take 2

On Mon, Mar 18, 2019 at 4:09 AM Michael Paquier <michael@paquier.xyz> wrote:

On Sun, Mar 17, 2019 at 09:00:57PM +0800, Chris Travers wrote:

I also added test cases and some docs. I don't know if the docs are
sufficient. Feedback is appreciated.

To be honest, I don't think that this approach is a good idea per the
same reasons as mentioned the last time, as this can cause pg_rewind
to break if any newly-added folder in the data directory has
non-replaceable data which is needed at the beginning of recovery and
cannot be automatically rebuilt. So that's one extra maintenance
burden to worry about.

Actually I think this is safe. Let me go through the cases not handled in
the current behavior at all:

1. For rpms we distribute, we clobber db logs, which means we overwrite
application logs on the failed system with copes of logs from a replica.
This means that after you rewind, you lose the ability to figure out what
went wrong. This is an exquisitely bad idea unless you like data loss, and
since this location is configurable you can't just say "well we put our
logs here so we are excluding them." Making this configured per rewind run
strikes me as error-prone and something that will may lead to hidden
interference with postmortems in the future, and postmortems are vitally
important in terms of running database clusters with any sort of
reliability guarantees.

2. With the PostgreSQL.conf.auto now having recovery.conf info, you have
some very significant failure cases with regard to replication and
accidentally clobbering these.

On to the corner cases with --data-only enabled and the implications as I
see them since this preserves files on the old master but does not copy
them from the replica:

1. If the changes are not wal logged (let's say CSVs created using a file
foreign data wrapper), then deleting the files on rewind is where you can
lose data, and --data-only avoids this, so here you *avoid* data loss where
you put state files on the systems and do not rewind them because they were
not wal-logged. However the files still exist on the old master and are
not deleted, so the data can easily be restored at that point. Now, we can
say, probably, that putting data files in $PGDATA that are not wal-logged
is a bad idea. But even if you put them somewhere else, pg_rewind isn't
going to magically move them over to the replica for you.

2. If the changes *are* wal-logged, then you have a problem with
--data-only which is not present without it, namely that files can get out
of sync with their wal-logged updates. So in this case, --data-dir is
*not* safe.

So here I think we have to issue a choice. For now I don't feel
comfortable changing the default behavior, but the default behavior could
cause data loss in certain cases (including the ones I think you are
concerned about). Maybe it would be better if I document the above points?

Here is the reference of the last thread about the same topic:

/messages/by-id/CAN-RpxD8Y7hMOjzd93hOqV6n8kPEo5cmW9gYm+8JirTPiFnmmQ@mail.gmail.com
--
Michael
-----BEGIN PGP SIGNATURE-----

iQIzBAABCgAdFiEEG72nH6vTowiyblFKnvQgOdbyQH0FAlyPGgYACgkQnvQgOdby
QH0ekRAAiXcZRcDZwwwdbdlIpkniE/SuG5gaS7etUcAW88m8Vts5r4QoAEwUwGhg
EZzuOb77OKvti7lmOZkBgC0VB1PmFku+mIdqJtzvdcSDdlOkABcLaw4JRrm//2/7
jAi5Jw4um1EAz38dZXcWYwORavyo/4tR2S1PCyBA35F704w2NILAEDiq233P/ALf
M3cOjgwiFIPf0v9PJIfYsl56sIwqW4rofPH63V6teaz5W8Qf2zHSsG5CeNqnEix0
QZwwlzuhtAUYINab3oN3qMtF2q9vzJWCoSprzxx1qYrzPHEX8EMot0+L7YPdaAp0
xyiUKSzy1rXtpoW0rsJ7w5bdrh1gS7HzprCEtqRZGe6NlVDcNjXfJIG9sT6hMWYS
GTNbVH5VpKziw3byT8JpyqR38+iFqeXoLd1PEVadYjP62qOWbK8P2wokQwM+7EcK
Hpr8jrvgV5x8IEnhR4bPyTqjORCJMBGTXCNgT99cPYpuVSasr/0IsBC/RtmQfRB9
xhK0/qp5koQbX+mbLK11XsaFS9JAL2DNmSQg8TqICtV3bb0UTThs331XgjEjlOpm
1RjM6Tzwqq2is04mkkT+DtRAOclQuL8wWJWU5rr4fMKHCeFxtvUfwTyKlo2u+mI0
x7YZhd4AFCM14ga2Ko/qiGqeOWR5Y0RvYANmnmjG5bxQGi+Dtek=
=LNZB
-----END PGP SIGNATURE-----

--
Best Regards,
Chris Travers
Head of Database

Tel: +49 162 9037 210 | Skype: einhverfr | www.adjust.com
Saarbrücker Straße 37a, 10405 Berlin

#5Thomas Munro
thomas.munro@gmail.com
In reply to: Chris Travers (#4)
Re: Data-only pg_rewind, take 2

On Mon, Mar 18, 2019 at 8:46 PM Chris Travers <chris.travers@adjust.com> wrote:

On Mon, Mar 18, 2019 at 4:09 AM Michael Paquier <michael@paquier.xyz> wrote:

On Sun, Mar 17, 2019 at 09:00:57PM +0800, Chris Travers wrote:

I also added test cases and some docs. I don't know if the docs are
sufficient. Feedback is appreciated.

To be honest, I don't think that this approach is a good idea per the
same reasons as mentioned the last time, as this can cause pg_rewind
to break if any newly-added folder in the data directory has
non-replaceable data which is needed at the beginning of recovery and
cannot be automatically rebuilt. So that's one extra maintenance
burden to worry about.

Actually I think this is safe. Let me go through the cases not handled in the current behavior at all:

Hi Chris,

Could you please post a rebase? This has fairly thoroughly bitrotted.
The Commitfest is here, so now would be an excellent time for people
to be able to apply and test the patch.

Thanks,

--
Thomas Munro
https://enterprisedb.com

#6Thomas Munro
thomas.munro@gmail.com
In reply to: Thomas Munro (#5)
Re: Data-only pg_rewind, take 2

On Mon, Jul 8, 2019 at 7:04 PM Thomas Munro <thomas.munro@gmail.com> wrote:

On Mon, Mar 18, 2019 at 8:46 PM Chris Travers <chris.travers@adjust.com> wrote:

On Mon, Mar 18, 2019 at 4:09 AM Michael Paquier <michael@paquier.xyz> wrote:

On Sun, Mar 17, 2019 at 09:00:57PM +0800, Chris Travers wrote:

I also added test cases and some docs. I don't know if the docs are
sufficient. Feedback is appreciated.

To be honest, I don't think that this approach is a good idea per the
same reasons as mentioned the last time, as this can cause pg_rewind
to break if any newly-added folder in the data directory has
non-replaceable data which is needed at the beginning of recovery and
cannot be automatically rebuilt. So that's one extra maintenance
burden to worry about.

Actually I think this is safe. Let me go through the cases not handled in the current behavior at all:

Hi Chris,

Could you please post a rebase? This has fairly thoroughly bitrotted.
The Commitfest is here, so now would be an excellent time for people
to be able to apply and test the patch.

Hi Chris,

I set this to "Returned with feedback" due to lack of response. If
you'd prefer to move it to the next CF instead because you're planning
to work on it in time for the September CF, that might still be
possible, otherwise of course please create a new entry when you're
ready. Thanks!

--
Thomas Munro
https://enterprisedb.com