v20-0010-Add-version-check-for-executables-and-standby-se.patch
application/octet-stream
Filename: v20-0010-Add-version-check-for-executables-and-standby-se.patch
Type: application/octet-stream
Part: 9
Message:
RE: speed up a logical replica setup
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v20-0010
Subject: Add version check for executables and standby server
| File | + | − |
|---|---|---|
| doc/src/sgml/ref/pg_createsubscriber.sgml | 6 | 0 |
| src/bin/pg_basebackup/pg_createsubscriber.c | 67 | 0 |
From 54098217b07bb49f724f57aa29f5da36e85ee0af Mon Sep 17 00:00:00 2001
From: Shlok Kyal <shlok.kyal.oss@gmail.com>
Date: Wed, 14 Feb 2024 16:27:15 +0530
Subject: [PATCH v20 10/12] Add version check for executables and standby
server
Add version check for executables and standby server
---
doc/src/sgml/ref/pg_createsubscriber.sgml | 6 ++
src/bin/pg_basebackup/pg_createsubscriber.c | 67 +++++++++++++++++++++
2 files changed, 73 insertions(+)
diff --git a/doc/src/sgml/ref/pg_createsubscriber.sgml b/doc/src/sgml/ref/pg_createsubscriber.sgml
index 63086a8e98..579e50a0a0 100644
--- a/doc/src/sgml/ref/pg_createsubscriber.sgml
+++ b/doc/src/sgml/ref/pg_createsubscriber.sgml
@@ -120,6 +120,12 @@ PostgreSQL documentation
databases and walsenders.
</para>
</listitem>
+ <listitem>
+ <para>
+ Both the target and source instances must have same major versions with
+ <application>pg_createsubscriber</application>.
+ </para>
+ </listitem>
</itemizedlist>
<note>
diff --git a/src/bin/pg_basebackup/pg_createsubscriber.c b/src/bin/pg_basebackup/pg_createsubscriber.c
index 0a70f00252..db088024d3 100644
--- a/src/bin/pg_basebackup/pg_createsubscriber.c
+++ b/src/bin/pg_basebackup/pg_createsubscriber.c
@@ -23,6 +23,7 @@
#include "common/file_perm.h"
#include "common/logging.h"
#include "common/restricted_token.h"
+#include "common/string.h"
#include "fe_utils/recovery_gen.h"
#include "fe_utils/simple_list.h"
#include "getopt_long.h"
@@ -63,6 +64,7 @@ static char *get_pub_base_conninfo(char *conninfo, char **dbname);
static char *construct_sub_conninfo(char *username, unsigned short subport,
char *socketdir);
static char *get_bin_directory(const char *path);
+static void check_exec(const char *dir, const char *program);
static bool check_data_directory(const char *datadir);
static char *concat_conninfo_dbname(const char *conninfo, const char *dbname);
static LogicalRepInfo *store_pub_sub_info(SimpleStringList dbnames,
@@ -277,6 +279,11 @@ get_bin_directory(const char *path)
pg_log_debug("pg_ctl path is: %s/%s", dirname, "pg_ctl");
pg_log_debug("pg_resetwal path is: %s/%s", dirname, "pg_resetwal");
+ /* Check version of binaries */
+ check_exec(dirname, "postgres");
+ check_exec(dirname, "pg_ctl");
+ check_exec(dirname, "pg_resetwal");
+
return dirname;
}
@@ -290,6 +297,8 @@ check_data_directory(const char *datadir)
{
struct stat statbuf;
char versionfile[MAXPGPATH];
+ FILE *ver_fd;
+ char rawline[64];
pg_log_info("checking if directory \"%s\" is a cluster data directory",
datadir);
@@ -313,6 +322,31 @@ check_data_directory(const char *datadir)
return false;
}
+ /* Check standby server version */
+ if ((ver_fd = fopen(versionfile, "r")) == NULL)
+ pg_fatal("could not open file \"%s\" for reading: %m", versionfile);
+
+ /* Version number has to be the first line read */
+ if (!fgets(rawline, sizeof(rawline), ver_fd))
+ {
+ if (!ferror(ver_fd))
+ pg_fatal("unexpected empty file \"%s\"", versionfile);
+ else
+ pg_fatal("could not read file \"%s\": %m", versionfile);
+ }
+
+ /* Strip trailing newline and carriage return */
+ (void) pg_strip_crlf(rawline);
+
+ if (strcmp(rawline, PG_MAJORVERSION) != 0)
+ {
+ pg_log_error("standby server is of wrong version");
+ pg_log_error_detail("File \"%s\" contains \"%s\", which is not compatible with this program's version \"%s\".",
+ versionfile, rawline, PG_MAJORVERSION);
+ exit(1);
+ }
+
+ fclose(ver_fd);
return true;
}
@@ -1581,6 +1615,39 @@ construct_sub_conninfo(char *username, unsigned short subport, char *sockdir)
return ret;
}
+/*
+ * Make sure the given program has the same version with pg_createsubscriber.
+ */
+static void
+check_exec(const char *dir, const char *program)
+{
+ char path[MAXPGPATH];
+ char *line;
+ char cmd[MAXPGPATH];
+ char versionstr[128];
+
+ snprintf(path, sizeof(path), "%s/%s", dir, program);
+
+ if (validate_exec(path) != 0)
+ pg_fatal("check for \"%s\" failed: %m", path);
+
+ snprintf(cmd, sizeof(cmd), "\"%s\" -V", path);
+
+ if ((line = pipe_read_line(cmd)) == NULL)
+ pg_fatal("check for \"%s\" failed: cannot execute", path);
+
+ pg_strip_crlf(line);
+
+ snprintf(versionstr, sizeof(versionstr), "%s (PostgreSQL) " PG_VERSION,
+ program);
+
+ if (strcmp(line, versionstr) != 0)
+ pg_fatal("check for \"%s\" failed: incorrect version: found \"%s\", expected \"%s\"",
+ path, line, versionstr);
+
+ pg_free(line);
+}
+
int
main(int argc, char **argv)
{
--
2.43.0