aboutsummaryrefslogtreecommitdiff
path: root/src/bin/pg_rewind/file_ops.c
diff options
context:
space:
mode:
authorFujii Masao <fujii@postgresql.org>2018-03-29 04:00:21 +0900
committerFujii Masao <fujii@postgresql.org>2018-03-29 04:00:21 +0900
commit09e96b3f35627a2939e2effd8b98aaa934f59b32 (patch)
treeec89a7332b25c611ca11e7e50d6ea818f8163afb /src/bin/pg_rewind/file_ops.c
parentd92bc83c48bdea9888e64cf1e2edbac9693099c9 (diff)
downloadpostgresql-09e96b3f35627a2939e2effd8b98aaa934f59b32.tar.gz
postgresql-09e96b3f35627a2939e2effd8b98aaa934f59b32.zip
Fix handling of files that source server removes during pg_rewind is running.
After processing the filemap to build the list of chunks that will be fetched from the source to rewing the target server, it is possible that a file which was previously processed is removed from the source. A simple example of such an occurence is a WAL segment which gets recycled on the target in-between. When the filemap is processed, files not categorized as relation files are first truncated to prepare for its full copy of which is going to be taken from the source, divided into a set of junks. However, for a recycled WAL segment, this would result in a segment which has a zero-byte size. With such an empty file, post-rewind recovery thinks that records are saved but they are actually not because of the truncation which happened when processing the filemap, resulting in data loss. In order to fix the problem, make sure that files which are found as removed on the source when receiving chunks of them are as well deleted on the target server for consistency. Back-patch to 9.5 where pg_rewind was added. Author: Tsunakawa Takayuki Reviewed-by: Michael Paquier Reported-by: Tsunakawa Takayuki Discussion: https://postgr.es/m/0A3221C70F24FB45833433255569204D1F8DAAA2%40G01JPEXMBYT05
Diffstat (limited to 'src/bin/pg_rewind/file_ops.c')
-rw-r--r--src/bin/pg_rewind/file_ops.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/src/bin/pg_rewind/file_ops.c b/src/bin/pg_rewind/file_ops.c
index 705383d184f..f491ed7f5cc 100644
--- a/src/bin/pg_rewind/file_ops.c
+++ b/src/bin/pg_rewind/file_ops.c
@@ -29,7 +29,6 @@
static int dstfd = -1;
static char dstpath[MAXPGPATH] = "";
-static void remove_target_file(const char *path);
static void create_target_dir(const char *path);
static void remove_target_dir(const char *path);
static void create_target_symlink(const char *path, const char *link);
@@ -134,7 +133,7 @@ remove_target(file_entry_t *entry)
break;
case FILE_TYPE_REGULAR:
- remove_target_file(entry->path);
+ remove_target_file(entry->path, false);
break;
case FILE_TYPE_SYMLINK:
@@ -165,8 +164,12 @@ create_target(file_entry_t *entry)
}
}
-static void
-remove_target_file(const char *path)
+/*
+ * Remove a file from target data directory. If missing_ok is true, it
+ * is fine for the target file to not exist.
+ */
+void
+remove_target_file(const char *path, bool missing_ok)
{
char dstpath[MAXPGPATH];
@@ -175,8 +178,13 @@ remove_target_file(const char *path)
snprintf(dstpath, sizeof(dstpath), "%s/%s", datadir_target, path);
if (unlink(dstpath) != 0)
+ {
+ if (errno == ENOENT && missing_ok)
+ return;
+
pg_fatal("could not remove file \"%s\": %s\n",
dstpath, strerror(errno));
+ }
}
void