Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitf2df286

Browse files
authored
Merge pull request#531 from postgrespro/REL_2_5-PBCKP-236
[PBCKP-236] merge into REL_2_5
2 parents97355f1 +26f9992 commitf2df286

File tree

5 files changed

+231
-14
lines changed

5 files changed

+231
-14
lines changed

‎src/pg_probackup.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -348,8 +348,8 @@ typedef enum ShowFormat
348348
#definePROGRAM_VERSION"2.5.8"
349349

350350
/* update when remote agent API or behaviour changes */
351-
#defineAGENT_PROTOCOL_VERSION20501
352-
#defineAGENT_PROTOCOL_VERSION_STR "2.5.1"
351+
#defineAGENT_PROTOCOL_VERSION20509
352+
#defineAGENT_PROTOCOL_VERSION_STR "2.5.9"
353353

354354
/* update only when changing storage format */
355355
#defineSTORAGE_FORMAT_VERSION "2.4.4"
@@ -888,6 +888,11 @@ extern bool tliIsPartOfHistory(const parray *timelines, TimeLineID tli);
888888
externDestDirIncrCompatibilitycheck_incremental_compatibility(constchar*pgdata,uint64system_identifier,
889889
IncrRestoreModeincremental_mode);
890890

891+
/* in remote.c */
892+
externvoidcheck_remote_agent_compatibility(intagent_version,
893+
char*compatibility_str,size_tcompatibility_str_max_size);
894+
externsize_tprepare_compatibility_str(char*compatibility_buf,size_tcompatibility_buf_size);
895+
891896
/* in merge.c */
892897
externvoiddo_merge(InstanceState*instanceState,time_tbackup_id,boolno_validate,boolno_sync);
893898
externvoidmerge_backups(pgBackup*backup,pgBackup*next_backup);

‎src/utils/file.c

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -269,17 +269,22 @@ fio_write_all(int fd, void const* buf, size_t size)
269269
}
270270

271271
/* Get version of remote agent */
272-
int
273-
fio_get_agent_version(void)
272+
void
273+
fio_get_agent_version(int*protocol,char*payload_buf,size_tpayload_buf_size)
274274
{
275275
fio_headerhdr;
276276
hdr.cop=FIO_AGENT_VERSION;
277277
hdr.size=0;
278278

279279
IO_CHECK(fio_write_all(fio_stdout,&hdr,sizeof(hdr)),sizeof(hdr));
280280
IO_CHECK(fio_read_all(fio_stdin,&hdr,sizeof(hdr)),sizeof(hdr));
281+
if (hdr.size>payload_buf_size)
282+
{
283+
elog(ERROR,"Corrupted remote compatibility protocol: insufficient payload_buf_size=%zu",payload_buf_size);
284+
}
281285

282-
returnhdr.arg;
286+
*protocol=hdr.arg;
287+
IO_CHECK(fio_read_all(fio_stdin,payload_buf,hdr.size),hdr.size);
283288
}
284289

285290
/* Open input stream. Remote file is fetched to the in-memory buffer and then accessed through Linux fmemopen */
@@ -3322,9 +3327,16 @@ fio_communicate(int in, int out)
33223327
IO_CHECK(fio_write_all(out,buf,hdr.size),hdr.size);
33233328
break;
33243329
caseFIO_AGENT_VERSION:
3325-
hdr.arg=AGENT_PROTOCOL_VERSION;
3326-
IO_CHECK(fio_write_all(out,&hdr,sizeof(hdr)),sizeof(hdr));
3327-
break;
3330+
{
3331+
size_tpayload_size=prepare_compatibility_str(buf,buf_size);
3332+
3333+
hdr.arg=AGENT_PROTOCOL_VERSION;
3334+
hdr.size=payload_size;
3335+
3336+
IO_CHECK(fio_write_all(out,&hdr,sizeof(hdr)),sizeof(hdr));
3337+
IO_CHECK(fio_write_all(out,buf,payload_size),payload_size);
3338+
break;
3339+
}
33283340
caseFIO_STAT:/* Get information about file with specified path */
33293341
hdr.size=sizeof(st);
33303342
rc=hdr.arg ?stat(buf,&st) :lstat(buf,&st);

‎src/utils/file.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ extern fio_location MyLocation;
9191
externvoidfio_redirect(intin,intout,interr);
9292
externvoidfio_communicate(intin,intout);
9393

94-
externintfio_get_agent_version(void);
94+
externvoidfio_get_agent_version(int*protocol,char*payload_buf,size_tpayload_buf_size);
9595
externFILE*fio_fopen(charconst*name,charconst*mode,fio_locationlocation);
9696
externsize_tfio_fwrite(FILE*f,voidconst*buf,size_tsize);
9797
externssize_tfio_fwrite_async_compressed(FILE*f,voidconst*buf,size_tsize,intcompress_alg);

‎src/utils/remote.c

Lines changed: 124 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -238,10 +238,113 @@ bool launch_agent(void)
238238
fio_redirect(infd[0],outfd[1],errfd[0]);/* write to stdout */
239239
}
240240

241-
/* Make sure that remote agent has the same version
242-
* TODO: we must also check PG version and fork edition
243-
*/
244-
agent_version=fio_get_agent_version();
241+
242+
/* Make sure that remote agent has the same version, fork and other features to be binary compatible */
243+
{
244+
charpayload_buf[1024];
245+
fio_get_agent_version(&agent_version,payload_buf,sizeofpayload_buf);
246+
check_remote_agent_compatibility(agent_version,payload_buf,sizeofpayload_buf);
247+
}
248+
249+
return true;
250+
}
251+
252+
#ifdefPGPRO_EDITION
253+
/* PGPRO 10-13 checks to be "(certified)", with exceptional case PGPRO_11 conforming to "(standard certified)" */
254+
staticboolcheck_certified()
255+
{
256+
returnstrstr(PGPRO_VERSION_STR,"(certified)")||
257+
strstr(PGPRO_VERSION_STR,"(standard certified)");
258+
}
259+
#endif
260+
261+
staticchar*extract_pg_edition_str()
262+
{
263+
staticchar*vanilla="vanilla";
264+
#ifdefPGPRO_EDITION
265+
staticchar*_1C="1C";
266+
staticchar*std="standard";
267+
staticchar*ent="enterprise";
268+
staticchar*std_cert="standard-certified";
269+
staticchar*ent_cert="enterprise-certified";
270+
271+
if (strcmp(PGPRO_EDITION,_1C)==0)
272+
returnvanilla;
273+
274+
if (PG_VERSION_NUM<100000)
275+
returnPGPRO_EDITION;
276+
277+
/* these "certified" checks are applicable to PGPRO from 10 up to 12 versions.
278+
* 13+ certified versions are compatible to non-certified ones */
279+
if (PG_VERSION_NUM<130000&&check_certified())
280+
{
281+
if (strcmp(PGPRO_EDITION,std)==0)
282+
returnstd_cert;
283+
elseif (strcmp(PGPRO_EDITION,ent)==0)
284+
returnent_cert;
285+
else
286+
Assert("Bad #define PGPRO_EDITION value"==0);
287+
}
288+
289+
returnPGPRO_EDITION;
290+
#else
291+
returnvanilla;
292+
#endif
293+
}
294+
295+
#defineCOMPATIBILITY_VAL_STR(macro) { #macro, macro, 0 }
296+
#defineCOMPATIBILITY_VAL_INT(macro) { #macro, NULL, macro }
297+
298+
#defineCOMPATIBILITY_VAL_SEPARATOR "="
299+
#defineCOMPATIBILITY_LINE_SEPARATOR "\n"
300+
301+
/*
302+
* Compose compatibility string to be sent by pg_probackup agent
303+
* through ssh and to be verified by pg_probackup peer.
304+
* Compatibility string contains postgres essential vars as strings
305+
* in format "var_name" + COMPATIBILITY_VAL_SEPARATOR + "var_value" + COMPATIBILITY_LINE_SEPARATOR
306+
*/
307+
size_tprepare_compatibility_str(char*compatibility_buf,size_tcompatibility_buf_size)
308+
{
309+
typedefstructcompatibility_param_tag {
310+
constchar*name;
311+
constchar*strval;
312+
intintval;
313+
}compatibility_param;
314+
315+
compatibility_paramcompatibility_params[]= {
316+
COMPATIBILITY_VAL_STR(PG_MAJORVERSION),
317+
{"edition",extract_pg_edition_str(),0 },
318+
COMPATIBILITY_VAL_INT(SIZEOF_VOID_P),
319+
};
320+
321+
size_tresult_size=0;
322+
*compatibility_buf='\0';
323+
324+
for (inti=0;i< (sizeofcompatibility_params /sizeof(compatibility_param));i++)
325+
{
326+
if (compatibility_params[i].strval!=NULL)
327+
result_size+=snprintf(compatibility_buf+result_size,compatibility_buf_size-result_size,
328+
"%s"COMPATIBILITY_VAL_SEPARATOR"%s"COMPATIBILITY_LINE_SEPARATOR,
329+
compatibility_params[i].name,
330+
compatibility_params[i].strval);
331+
else
332+
result_size+=snprintf(compatibility_buf+result_size,compatibility_buf_size-result_size,
333+
"%s"COMPATIBILITY_VAL_SEPARATOR"%d"COMPATIBILITY_LINE_SEPARATOR,
334+
compatibility_params[i].name,
335+
compatibility_params[i].intval);
336+
Assert(result_size<compatibility_buf_size);
337+
}
338+
returnresult_size+1;
339+
}
340+
341+
/*
342+
* Check incoming remote agent's compatibility params for equality to local ones.
343+
*/
344+
voidcheck_remote_agent_compatibility(intagent_version,char*compatibility_str,size_tcompatibility_str_max_size)
345+
{
346+
elog(LOG,"Agent version=%d\n",agent_version);
347+
245348
if (agent_version!=AGENT_PROTOCOL_VERSION)
246349
{
247350
charagent_version_str[1024];
@@ -255,5 +358,21 @@ bool launch_agent(void)
255358
agent_version_str,AGENT_PROTOCOL_VERSION_STR);
256359
}
257360

258-
return true;
361+
/* checking compatibility params */
362+
if (strnlen(compatibility_str,compatibility_str_max_size)==compatibility_str_max_size)
363+
{
364+
elog(ERROR,"Corrupted remote compatibility protocol: compatibility string has no terminating \\0");
365+
}
366+
367+
elog(LOG,"Agent compatibility params:\n%s",compatibility_str);
368+
369+
{
370+
charbuf[1024];
371+
372+
prepare_compatibility_str(buf,sizeofbuf);
373+
if(strcmp(compatibility_str,buf))
374+
{
375+
elog(ERROR,"Incompatible remote agent params, expected:\n%s, actual:\n:%s",buf,compatibility_str);
376+
}
377+
}
259378
}

‎tests/compatibility.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,89 @@
88
module_name='compatibility'
99

1010

11+
defcheck_manual_tests_enabled():
12+
return'PGPROBACKUP_MANUAL'inos.environandos.environ['PGPROBACKUP_MANUAL']=='ON'
13+
14+
15+
defcheck_ssh_agent_path_exists():
16+
return'PGPROBACKUP_SSH_AGENT_PATH'inos.environ
17+
18+
1119
classCompatibilityTest(ProbackupTest,unittest.TestCase):
1220

21+
defsetUp(self):
22+
self.fname=self.id().split('.')[3]
23+
24+
# @unittest.expectedFailure
25+
@unittest.skipUnless(check_manual_tests_enabled(),'skip manual test')
26+
@unittest.skipUnless(check_ssh_agent_path_exists(),'skip no ssh agent path exist')
27+
# @unittest.skip("skip")
28+
deftest_catchup_with_different_remote_major_pg(self):
29+
"""
30+
Decription in jira issue PBCKP-236
31+
This test exposures ticket error using pg_probackup builds for both PGPROEE11 and PGPROEE9_6
32+
33+
Prerequisites:
34+
- pg_probackup git tag for PBCKP 2.5.1
35+
- master pg_probackup build should be made for PGPROEE11
36+
- agent pg_probackup build should be made for PGPROEE9_6
37+
38+
Calling probackup PGPROEE9_6 pg_probackup agent from PGPROEE11 pg_probackup master for DELTA backup causes
39+
the PBCKP-236 problem
40+
41+
Please give env variables PROBACKUP_MANUAL=ON;PGPROBACKUP_SSH_AGENT_PATH=<pg_probackup_ssh_agent_path>
42+
for the test
43+
44+
Please make path for agent's pgprobackup_ssh_agent_path = '/home/avaness/postgres/postgres.build.ee.9.6/bin/'
45+
without pg_probackup executable
46+
"""
47+
48+
self.verbose=True
49+
self.remote=True
50+
# please use your own local path like
51+
# pgprobackup_ssh_agent_path = '/home/avaness/postgres/postgres.build.clean/bin/'
52+
pgprobackup_ssh_agent_path=os.environ['PGPROBACKUP_SSH_AGENT_PATH']
53+
54+
src_pg=self.make_simple_node(
55+
base_dir=os.path.join(module_name,self.fname,'src'),
56+
set_replication=True,
57+
)
58+
src_pg.slow_start()
59+
src_pg.safe_psql(
60+
"postgres",
61+
"CREATE TABLE ultimate_question AS SELECT 42 AS answer")
62+
63+
# do full catchup
64+
dst_pg=self.make_empty_node(os.path.join(module_name,self.fname,'dst'))
65+
self.catchup_node(
66+
backup_mode='FULL',
67+
source_pgdata=src_pg.data_dir,
68+
destination_node=dst_pg,
69+
options=['-d','postgres','-p',str(src_pg.port),'--stream']
70+
)
71+
72+
dst_options= {'port':str(dst_pg.port)}
73+
self.set_auto_conf(dst_pg,dst_options)
74+
dst_pg.slow_start()
75+
dst_pg.stop()
76+
77+
src_pg.safe_psql(
78+
"postgres",
79+
"CREATE TABLE ultimate_question2 AS SELECT 42 AS answer")
80+
81+
# do delta catchup with remote pg_probackup agent with another postgres major version
82+
# this DELTA backup should fail without PBCKP-236 patch.
83+
self.catchup_node(
84+
backup_mode='DELTA',
85+
source_pgdata=src_pg.data_dir,
86+
destination_node=dst_pg,
87+
# here's substitution of --remoge-path pg_probackup agent compiled with another postgres version
88+
options=['-d','postgres','-p',str(src_pg.port),'--stream','--remote-path='+pgprobackup_ssh_agent_path]
89+
)
90+
91+
# Clean after yourself
92+
self.del_test_dir(module_name,self.fname)
93+
1394
# @unittest.expectedFailure
1495
# @unittest.skip("skip")
1596
deftest_backward_compatibility_page(self):

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp