From f8119d20ead0bfd3741f075521cf23222a8a4125 Mon Sep 17 00:00:00 2001 From: Ian Barwick Date: Wed, 30 Sep 2015 11:48:09 +0900 Subject: [PATCH] Handle tablespace mapping in 9.5 and later in --rsync-only mode 9.5 introduces the tablespace_map file, which is created on the upstream node while a backup is running. We need to overwrite this with the provided values. Note that we only write explicitly-provided values to the tablespace_map file, however the existing symlinks for non-specified tablespaces will have been copied anyway. Fixes Github #119. --- repmgr.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 78 insertions(+), 15 deletions(-) diff --git a/repmgr.c b/repmgr.c index 6956b136..1e9f46cb 100644 --- a/repmgr.c +++ b/repmgr.c @@ -54,6 +54,10 @@ #define RECOVERY_FILE "recovery.conf" +#ifndef TABLESPACE_MAP +#define TABLESPACE_MAP "tablespace_map" +#endif + #define NO_ACTION 0 /* Dummy default action */ #define MASTER_REGISTER 1 #define STANDBY_REGISTER 2 @@ -1285,6 +1289,15 @@ do_standby_clone(void) if (runtime_options.rsync_only) { + PQExpBufferData tablespace_map; + bool tablespace_map_rewrite = false; + + /* For 9.5 and greater, create our own tablespace_map file */ + if (server_version_num >= 90500) + { + initPQExpBuffer(&tablespace_map); + } + /* * From pg 9.1 default is to wait for a sync standby to ack, avoid that by * turning off sync rep for this session @@ -1359,6 +1372,7 @@ do_standby_clone(void) initPQExpBuffer(&tblspc_dir_dst); initPQExpBuffer(&tblspc_oid); + appendPQExpBuffer(&tblspc_oid, "%s", PQgetvalue(res, i, 0)); appendPQExpBuffer(&tblspc_dir_src, "%s", PQgetvalue(res, i, 1)); @@ -1393,31 +1407,80 @@ do_standby_clone(void) tblspc_dir_src.data, tblspc_dir_dst.data, true, server_version_num); - /* Update symlink in pg_tblspc */ + + /* Update symlinks in pg_tblspc */ if (mapping_found == true) { - PQExpBufferData tblspc_symlink; - - initPQExpBuffer(&tblspc_symlink); - appendPQExpBuffer(&tblspc_symlink, "%s/pg_tblspc/%s", - local_data_directory, - tblspc_oid.data); - - if (unlink(tblspc_symlink.data) < 0 && errno != ENOENT) + /* 9.5 and later - create a tablespace_map file */ + if (server_version_num >= 90500) { - log_err(_("unable to remove tablespace symlink %s\n"), tblspc_symlink.data); - exit(ERR_BAD_CONFIG); + tablespace_map_rewrite = true; + appendPQExpBuffer(&tablespace_map, + "%s %s\n", + tblspc_oid.data, + tblspc_dir_dst.data); } - if (symlink(tblspc_dir_dst.data, tblspc_symlink.data) < 0) + /* Pre-9.5, we have to manipulate the symlinks in pg_tblspc/ ourselves */ + else { - log_err(_("unable to create tablespace symlink from %s to %s\n"), tblspc_symlink.data, tblspc_dir_dst.data); - exit(ERR_BAD_CONFIG); - } + PQExpBufferData tblspc_symlink; + initPQExpBuffer(&tblspc_symlink); + appendPQExpBuffer(&tblspc_symlink, "%s/pg_tblspc/%s", + local_data_directory, + tblspc_oid.data); + + if (unlink(tblspc_symlink.data) < 0 && errno != ENOENT) + { + log_err(_("unable to remove tablespace symlink %s\n"), tblspc_symlink.data); + exit(ERR_BAD_CONFIG); + } + if (symlink(tblspc_dir_dst.data, tblspc_symlink.data) < 0) + { + log_err(_("unable to create tablespace symlink from %s to %s\n"), tblspc_symlink.data, tblspc_dir_dst.data); + exit(ERR_BAD_CONFIG); + } + + + } } } + + if(server_version_num >= 90500 && tablespace_map_rewrite == true) + { + PQExpBufferData tablespace_map_filename; + FILE *tablespace_map_file; + initPQExpBuffer(&tablespace_map_filename); + appendPQExpBuffer(&tablespace_map_filename, "%s/%s", + local_data_directory, + TABLESPACE_MAP); + + /* Unlink any existing file (it should be there, but we don't care if it isn't) */ + if (unlink(tablespace_map_filename.data) < 0 && errno != ENOENT) + { + log_err(_("unable to remove tablespace_map file %s\n"), tablespace_map_filename.data); + exit(ERR_BAD_CONFIG); + } + + tablespace_map_file = fopen(tablespace_map_filename.data, "w"); + if (tablespace_map_file == NULL) + { + log_err(_("unable to create tablespace_map file '%s'\n"), tablespace_map_filename.data); + exit(ERR_BAD_CONFIG); + } + + if (fputs(tablespace_map.data, tablespace_map_file) == EOF) + { + log_err(_("unable to write to tablespace_map file '%s'\n"), tablespace_map_filename.data); + fclose(tablespace_map_file); + exit(ERR_BAD_CONFIG); + } + + fclose(tablespace_map_file); + } + PQclear(res); } else