Skip to content

Commit 01e57ea

Browse files
committed
Merge branch 'master' into issue_79
2 parents 6179808 + 87f214e commit 01e57ea

File tree

6 files changed

+92
-6
lines changed

6 files changed

+92
-6
lines changed

src/pg_probackup.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ main(int argc, char *argv[])
314314
uint32 agent_version = parse_program_version(remote_agent);
315315
elog(agent_version < AGENT_PROTOCOL_VERSION ? ERROR : WARNING,
316316
"Agent version %s doesn't match master pg_probackup version %s",
317-
remote_agent, PROGRAM_VERSION);
317+
PROGRAM_VERSION, remote_agent);
318318
}
319319
fio_communicate(STDIN_FILENO, STDOUT_FILENO);
320320
return 0;

src/utils/file.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ static __thread unsigned long fio_fdset = 0;
2020
static __thread void* fio_stdin_buffer;
2121
static __thread int fio_stdout = 0;
2222
static __thread int fio_stdin = 0;
23+
static __thread int fio_stderr = 0;
2324

2425
fio_location MyLocation;
2526

@@ -38,10 +39,29 @@ typedef struct
3839
#define fio_fileno(f) (((size_t)f - 1) | FIO_PIPE_MARKER)
3940

4041
/* Use specified file descriptors as stdin/stdout for FIO functions */
41-
void fio_redirect(int in, int out)
42+
void fio_redirect(int in, int out, int err)
4243
{
4344
fio_stdin = in;
4445
fio_stdout = out;
46+
fio_stderr = err;
47+
}
48+
49+
void fio_error(int rc, int size, char const* file, int line)
50+
{
51+
if (remote_agent)
52+
{
53+
fprintf(stderr, "%s:%d: proceeds %d bytes instead of %d: %s\n", file, line, rc, size, rc >= 0 ? "end of data" : strerror(errno));
54+
exit(EXIT_FAILURE);
55+
}
56+
else
57+
{
58+
char buf[PRINTF_BUF_SIZE];
59+
int err_size = read(fio_stderr, buf, sizeof(buf));
60+
if (err_size > 0)
61+
elog(ERROR, "Agent error: %s", buf);
62+
else
63+
elog(ERROR, "Communication error: %s", rc >= 0 ? "end of data" : strerror(errno));
64+
}
4565
}
4666

4767
/* Check if file descriptor is local or remote (created by FIO) */

src/utils/file.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ typedef enum
4949
#define PAGE_CHECKSUM_MISMATCH (-256)
5050

5151
#define SYS_CHECK(cmd) do if ((cmd) < 0) { fprintf(stderr, "%s:%d: (%s) %s\n", __FILE__, __LINE__, #cmd, strerror(errno)); exit(EXIT_FAILURE); } while (0)
52-
#define IO_CHECK(cmd, size) do { int _rc = (cmd); if (_rc != (size)) { if (remote_agent) { fprintf(stderr, "%s:%d: proceeds %d bytes instead of %d: %s\n", __FILE__, __LINE__, _rc, (int)(size), _rc >= 0 ? "end of data" : strerror(errno)); exit(EXIT_FAILURE); } else elog(ERROR, "Communication error: %s", _rc >= 0 ? "end of data" : strerror(errno)); } } while (0)
52+
#define IO_CHECK(cmd, size) do { int _rc = (cmd); if (_rc != (size)) fio_error(_rc, size, __FILE__, __LINE__); } while (0)
5353

5454
typedef struct
5555
{
@@ -64,7 +64,7 @@ extern fio_location MyLocation;
6464
/* Check if FILE handle is local or remote (created by FIO) */
6565
#define fio_is_remote_file(file) ((size_t)(file) <= FIO_FDMAX)
6666

67-
extern void fio_redirect(int in, int out);
67+
extern void fio_redirect(int in, int out, int err);
6868
extern void fio_communicate(int in, int out);
6969

7070
extern FILE* fio_fopen(char const* name, char const* mode, fio_location location);
@@ -77,6 +77,7 @@ extern int fio_fseek(FILE* f, off_t offs);
7777
extern int fio_ftruncate(FILE* f, off_t size);
7878
extern int fio_fclose(FILE* f);
7979
extern int fio_ffstat(FILE* f, struct stat* st);
80+
extern void fio_error(int rc, int size, char const* file, int line);
8081

8182
struct pgFile;
8283
extern int fio_send_pages(FILE* in, FILE* out, struct pgFile *file, XLogRecPtr horizonLsn,

src/utils/remote.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ bool launch_agent(void)
110110
int ssh_argc;
111111
int outfd[2];
112112
int infd[2];
113+
int errfd[2];
113114

114115
ssh_argc = 0;
115116
#ifdef WIN32
@@ -195,20 +196,25 @@ bool launch_agent(void)
195196
#else
196197
SYS_CHECK(pipe(infd));
197198
SYS_CHECK(pipe(outfd));
199+
SYS_CHECK(pipe(errfd));
198200

199201
SYS_CHECK(child_pid = fork());
200202

201203
if (child_pid == 0) { /* child */
202204
SYS_CHECK(close(STDIN_FILENO));
203205
SYS_CHECK(close(STDOUT_FILENO));
206+
SYS_CHECK(close(STDERR_FILENO));
204207

205208
SYS_CHECK(dup2(outfd[0], STDIN_FILENO));
206209
SYS_CHECK(dup2(infd[1], STDOUT_FILENO));
210+
SYS_CHECK(dup2(errfd[1], STDERR_FILENO));
207211

208212
SYS_CHECK(close(infd[0]));
209213
SYS_CHECK(close(infd[1]));
210214
SYS_CHECK(close(outfd[0]));
211215
SYS_CHECK(close(outfd[1]));
216+
SYS_CHECK(close(errfd[0]));
217+
SYS_CHECK(close(errfd[1]));
212218

213219
if (execvp(ssh_argv[0], ssh_argv) < 0)
214220
return false;
@@ -217,9 +223,10 @@ bool launch_agent(void)
217223
elog(LOG, "Spawn agent %d version %s", child_pid, PROGRAM_VERSION);
218224
SYS_CHECK(close(infd[1])); /* These are being used by the child */
219225
SYS_CHECK(close(outfd[0]));
226+
SYS_CHECK(close(errfd[1]));
220227
/*atexit(kill_child);*/
221228

222-
fio_redirect(infd[0], outfd[1]); /* write to stdout */
229+
fio_redirect(infd[0], outfd[1], errfd[0]); /* write to stdout */
223230
}
224231
return true;
225232
}

tests/pgpro560.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from .helpers.ptrack_helpers import ProbackupTest, ProbackupException
44
from datetime import datetime, timedelta
55
import subprocess
6+
from time import sleep
67

78

89
module_name = 'pgpro560'
@@ -98,6 +99,8 @@ def test_pgpro560_systemid_mismatch(self):
9899
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(
99100
repr(e.message), self.cmd))
100101

102+
sleep(1)
103+
101104
try:
102105
self.backup_node(
103106
backup_dir, 'node1', node2,

tests/validate.py

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3499,7 +3499,7 @@ def test_validate_target_lsn(self):
34993499

35003500
# @unittest.expectedFailure
35013501
# @unittest.skip("skip")
3502-
def test_recovery_target_backup_victim(self):
3502+
def test_recovery_target_time_backup_victim(self):
35033503
"""
35043504
Check that for validation to recovery target
35053505
probackup chooses valid backup
@@ -3555,6 +3555,61 @@ def test_recovery_target_backup_victim(self):
35553555
backup_dir, 'node',
35563556
options=['--recovery-target-time={0}'.format(target_time)])
35573557

3558+
# @unittest.expectedFailure
3559+
# @unittest.skip("skip")
3560+
def test_recovery_target_lsn_backup_victim(self):
3561+
"""
3562+
Check that for validation to recovery target
3563+
probackup chooses valid backup
3564+
https://github.com/postgrespro/pg_probackup/issues/104
3565+
"""
3566+
fname = self.id().split('.')[3]
3567+
backup_dir = os.path.join(self.tmp_path, module_name, fname, 'backup')
3568+
node = self.make_simple_node(
3569+
base_dir=os.path.join(module_name, fname, 'node'),
3570+
set_replication=True,
3571+
initdb_params=['--data-checksums'])
3572+
3573+
self.init_pb(backup_dir)
3574+
self.add_instance(backup_dir, 'node', node)
3575+
self.set_archiving(backup_dir, 'node', node)
3576+
node.slow_start()
3577+
3578+
# FULL backup
3579+
self.backup_node(backup_dir, 'node', node)
3580+
3581+
node.safe_psql(
3582+
"postgres",
3583+
"create table t_heap as select 1 as id, md5(i::text) as text, "
3584+
"md5(repeat(i::text,10))::tsvector as tsvector "
3585+
"from generate_series(0,10000) i")
3586+
3587+
node.safe_psql(
3588+
"postgres",
3589+
"create table t_heap1 as select 1 as id, md5(i::text) as text, "
3590+
"md5(repeat(i::text,10))::tsvector as tsvector "
3591+
"from generate_series(0,100) i")
3592+
3593+
gdb = self.backup_node(backup_dir, 'node', node, gdb=True)
3594+
3595+
gdb.set_breakpoint('pg_stop_backup')
3596+
gdb.run_until_break()
3597+
gdb.remove_all_breakpoints()
3598+
gdb._execute('signal SIGINT')
3599+
gdb.continue_execution_until_error()
3600+
3601+
backup_id = self.show_pb(backup_dir, 'node')[1]['id']
3602+
3603+
self.assertEqual(
3604+
'ERROR',
3605+
self.show_pb(backup_dir, 'node', backup_id)['status'],
3606+
'Backup STATUS should be "ERROR"')
3607+
3608+
target_lsn = self.show_pb(backup_dir, 'node', backup_id)['start-lsn']
3609+
3610+
self.validate_pb(
3611+
backup_dir, 'node',
3612+
options=['--recovery-target-lsn={0}'.format(target_lsn)])
35583613

35593614
# validate empty backup list
35603615
# page from future during validate

0 commit comments

Comments
 (0)