-
Notifications
You must be signed in to change notification settings - Fork 87
REL_2_5-PBCKP-236 #531
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
REL_2_5-PBCKP-236 #531
Changes from 16 commits
25fc034
f78c63c
1dfa5b9
c3d3c02
46b7079
f5fde7e
497751c
eefd887
0604cce
f61be78
b2091cd
5659884
35df506
b3351b5
6e67123
1ce38ed
c526597
03d55d0
d808a16
26f9992
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -238,10 +238,104 @@ bool launch_agent(void) | |
fio_redirect(infd[0], outfd[1], errfd[0]); /* write to stdout */ | ||
} | ||
|
||
/* Make sure that remote agent has the same version | ||
* TODO: we must also check PG version and fork edition | ||
*/ | ||
agent_version = fio_get_agent_version(); | ||
|
||
/* Make sure that remote agent has the same version, fork and other features to be binary compatible */ | ||
{ | ||
char payload_buf[1024]; | ||
fio_get_agent_version(&agent_version, payload_buf, sizeof payload_buf); | ||
check_remote_agent_compatibility(agent_version, payload_buf, sizeof payload_buf); | ||
} | ||
|
||
return true; | ||
} | ||
|
||
#ifdef PGPRO_EDITION | ||
/* PGPRO 10-13 checks to be "(certified)", with exceptional case PGPRO_11 conforming to "(standard certified)" */ | ||
static bool check_certified() | ||
{ | ||
return strstr(PGPRO_VERSION_STR, "(certified)") || | ||
strstr(PGPRO_VERSION_STR, ("(standard certified)")); | ||
} | ||
#endif | ||
|
||
static char* extract_pg_edition_str() | ||
{ | ||
static char *_1C = "1C"; | ||
static char *vanilla = "vanilla"; | ||
static char *std = "standard"; | ||
static char *ent = "enterprise"; | ||
static char *std_cert = "standard-certified"; | ||
static char *ent_cert = "enterprise-certified"; | ||
|
||
#ifdef PGPRO_EDITION | ||
if (strcmp(PGPRO_EDITION, _1C) == 0) | ||
return vanilla; | ||
|
||
if (PG_VERSION_NUM < 100000) | ||
return PGPRO_EDITION; | ||
|
||
/* these "certified" checks are applicable to PGPRO from 10 up to 12 versions. | ||
* 13+ certified versions are compatible to non-certified ones */ | ||
if (PG_VERSION_NUM < 130000 && check_certified()) | ||
{ | ||
if (strcmp(PGPRO_EDITION, std) == 0) | ||
return std_cert; | ||
else if (strcmp(PGPRO_EDITION, ent) == 0) | ||
return ent_cert; | ||
else | ||
Assert("Bad #define PGPRO_EDITION value" == 0); | ||
} | ||
|
||
return PGPRO_EDITION; | ||
#else | ||
return vanilla; | ||
#endif | ||
} | ||
|
||
#define COMPATIBILITY_VAL_STR(macro) { #macro, macro, 0 } | ||
#define COMPATIBILITY_VAL_INT(macro) { #macro, NULL, macro } | ||
|
||
/* | ||
* Compose compatibility string to be sent by pg_probackup agent | ||
* through ssh and to be verified by pg_probackup peer. | ||
* Compatibility string contains postgres essential vars as strings | ||
* in format "var_name" + COMPATIBILITY_VAL_SEPARATOR + "var_value" + COMPATIBILITY_LINE_SEPARATOR | ||
*/ | ||
size_t prepare_compatibility_str(char* compatibility_buf, size_t compatibility_buf_size) | ||
{ | ||
struct { const char* name; const char* strval; int intval; } compatibility_params[] = { | ||
COMPATIBILITY_VAL_STR(PG_MAJORVERSION), | ||
{ "edition", extract_pg_edition_str(), 0 }, | ||
COMPATIBILITY_VAL_INT(SIZEOF_VOID_P), | ||
}; | ||
|
||
size_t result_size = 0; | ||
*compatibility_buf = '\0'; | ||
|
||
for (int i = 0; i < sizeof compatibility_params; i+=2) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Было правильно, зря убрал. |
||
{ | ||
if (compatibility_params[i].strval != NULL) | ||
result_size += snprintf(compatibility_buf + result_size, compatibility_buf_size - result_size, | ||
"%s=%s/n", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Слэш в другую сторону. И ниже тоже. |
||
compatibility_params[i].name, | ||
compatibility_params[i].strval); | ||
else | ||
result_size += snprintf(compatibility_buf + result_size, compatibility_buf_size - result_size, | ||
"%s=%d/n", | ||
compatibility_params[i].name, | ||
compatibility_params[i].intval); | ||
Assert(result_size < compatibility_buf_size); | ||
} | ||
return result_size + 1; | ||
} | ||
|
||
/* | ||
* Check incoming remote agent's compatibility params for equality to local ones. | ||
*/ | ||
void check_remote_agent_compatibility(int agent_version, char *compatibility_str, size_t compatibility_str_max_size) | ||
{ | ||
elog(LOG, "Agent version=%d\n", agent_version); | ||
|
||
if (agent_version != AGENT_PROTOCOL_VERSION) | ||
{ | ||
char agent_version_str[1024]; | ||
|
@@ -255,5 +349,21 @@ bool launch_agent(void) | |
agent_version_str, AGENT_PROTOCOL_VERSION_STR); | ||
} | ||
|
||
return true; | ||
/* checking compatibility params */ | ||
if (strnlen(compatibility_str, compatibility_str_max_size) == compatibility_str_max_size) | ||
{ | ||
elog(ERROR, "Corrupted remote compatibility protocol: compatibility string has no terminating \\0"); | ||
} | ||
|
||
elog(LOG, "Agent compatibility params:\n%s", compatibility_str); | ||
|
||
{ | ||
char buf[1024]; | ||
|
||
prepare_compatibility_str(buf, sizeof buf); | ||
if(strcmp(compatibility_str, buf)) | ||
{ | ||
elog(ERROR, "Incompatible remote agent params, expected:\n%s, actual:\n:%s", buf, compatibility_str); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,6 +10,72 @@ | |
|
||
class CompatibilityTest(ProbackupTest, unittest.TestCase): | ||
|
||
def setUp(self): | ||
self.fname = self.id().split('.')[3] | ||
|
||
# @unittest.expectedFailure | ||
# @unittest.skip("skip") | ||
def test_catchup_with_different_remote_major_pg(self): | ||
""" | ||
Decription in jira issue PBCKP-236 | ||
This test requires builds both PGPROEE11 and PGPROEE9_6 | ||
|
||
prerequisites: | ||
- git tag for PBCKP 2.5.1 | ||
- master probackup build should be inside PGPROEE11 | ||
- agent probackup build is inside PGPROEE9_6 | ||
|
||
calling probackup PGPROEE9_6 agent from PGPROEE11 probackup master for DELTA backup causes the PBCKP-236 problem | ||
|
||
please correct path for agent's pg_path_remote_version = '/home/avaness/postgres/postgres.build.ee.9.6/bin/' | ||
""" | ||
|
||
self.verbose = True | ||
self.remote = True | ||
# please use your own local path | ||
pg_path_remote_version = '/home/avaness/postgres/postgres.build.clean/bin' | ||
|
||
src_pg = self.make_simple_node( | ||
base_dir=os.path.join(module_name, self.fname, 'src'), | ||
set_replication=True, | ||
) | ||
src_pg.slow_start() | ||
src_pg.safe_psql( | ||
"postgres", | ||
"CREATE TABLE ultimate_question AS SELECT 42 AS answer") | ||
|
||
# do full catchup | ||
dst_pg = self.make_empty_node(os.path.join(module_name, self.fname, 'dst')) | ||
self.catchup_node( | ||
backup_mode = 'FULL', | ||
source_pgdata = src_pg.data_dir, | ||
destination_node = dst_pg, | ||
options=['-d', 'postgres', '-p', str(src_pg.port), '--stream'] | ||
) | ||
|
||
dst_options = {} | ||
dst_options['port'] = str(dst_pg.port) | ||
self.set_auto_conf(dst_pg, dst_options) | ||
dst_pg.slow_start() | ||
dst_pg.stop() | ||
|
||
src_pg.safe_psql( | ||
"postgres", | ||
"CREATE TABLE ultimate_question2 AS SELECT 42 AS answer") | ||
|
||
# do delta catchup with remote pg_probackup agent with another postgres major version | ||
# this DELTA backup should fail without PBCKP-236 patch. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. А тест не должен падать в любом случае? По крайней мере, кажется что с патчем-то он точно должен падать. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. должен, он вообще не должен срабатывать, так как ссылается на абсолютный путь на бинарь другой версии. мне не понятно почему CI не репортит это. на планерке спрошу гипотезы. |
||
self.catchup_node( | ||
backup_mode = 'DELTA', | ||
source_pgdata = src_pg.data_dir, | ||
destination_node = dst_pg, | ||
# here's substitution of --remoge-path pg_probackup agent compiled with another postgres version | ||
options=['-d', 'postgres', '-p', str(src_pg.port), '--stream', '--remote-path=' + pg_path_remote_version] | ||
) | ||
|
||
# Clean after yourself | ||
self.del_test_dir(module_name, self.fname) | ||
|
||
# @unittest.expectedFailure | ||
# @unittest.skip("skip") | ||
def test_backward_compatibility_page(self): | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А зачем тут скобочки вокруг строки?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PGPRO_VERSION_STR выглядит как "PostgresPro 11.17.1 (certified) on x86_64-pc-linux-gnu, ...", скобочки отсюда, чтобы быть более strict.