Skip to content

Commit 7d78d50

Browse files
knizhnikgsmolk
authored andcommitted
Decompress on agent's size
1 parent f165001 commit 7d78d50

File tree

4 files changed

+95
-39
lines changed

4 files changed

+95
-39
lines changed

src/data.c

+23-33
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ do_compress(void* dst, size_t dst_size, void const* src, size_t src_size,
8989
* Decompresses source into dest using algorithm. Returns the number of bytes
9090
* decompressed in the destination buffer, or -1 if decompression fails.
9191
*/
92-
static int32
92+
int32
9393
do_decompress(void* dst, size_t dst_size, void const* src, size_t src_size,
9494
CompressAlg alg, const char **errormsg)
9595
{
@@ -1047,9 +1047,9 @@ restore_data_file_internal(FILE *in, FILE *out, pgFile *file, uint32 backup_vers
10471047
{
10481048
off_t write_pos;
10491049
size_t read_len;
1050-
DataPage compressed_page; /* used as read buffer */
10511050
DataPage page;
1052-
int32 uncompressed_size = 0;
1051+
int32 compressed_size = 0;
1052+
bool is_compressed = false;
10531053

10541054
/* check for interrupt */
10551055
if (interrupted || thread_interrupted)
@@ -1090,14 +1090,16 @@ restore_data_file_internal(FILE *in, FILE *out, pgFile *file, uint32 backup_vers
10901090
* n_blocks attribute was available only in DELTA backups.
10911091
* File truncate in PAGE and PTRACK happened on the fly when
10921092
* special value PageIsTruncated is encountered.
1093-
* It is inefficient.
1093+
* It was inefficient.
10941094
*
10951095
* Nowadays every backup type has n_blocks, so instead
10961096
* writing and then truncating redundant data, writing
10971097
* is not happening in the first place.
10981098
* TODO: remove in 3.0.0
10991099
*/
1100-
if (header.compressed_size == PageIsTruncated)
1100+
compressed_size = header.compressed_size;
1101+
1102+
if (compressed_size == PageIsTruncated)
11011103
{
11021104
/*
11031105
* Block header contains information that this block was truncated.
@@ -1124,16 +1126,15 @@ restore_data_file_internal(FILE *in, FILE *out, pgFile *file, uint32 backup_vers
11241126
if (nblocks > 0 && blknum >= nblocks)
11251127
break;
11261128

1127-
if (header.compressed_size > BLCKSZ)
1129+
if (compressed_size > BLCKSZ)
11281130
elog(ERROR, "Size of a blknum %i exceed BLCKSZ", blknum);
11291131

11301132
/* read a page from file */
1131-
read_len = fread(compressed_page.data, 1,
1132-
MAXALIGN(header.compressed_size), in);
1133+
read_len = fread(page.data, 1, MAXALIGN(compressed_size), in);
11331134

1134-
if (read_len != MAXALIGN(header.compressed_size))
1135+
if (read_len != MAXALIGN(compressed_size))
11351136
elog(ERROR, "Cannot read block %u of \"%s\", read %zu of %d",
1136-
blknum, from_fullpath, read_len, header.compressed_size);
1137+
blknum, from_fullpath, read_len, compressed_size);
11371138

11381139
/*
11391140
* if page size is smaller than BLCKSZ, decompress the page.
@@ -1142,23 +1143,10 @@ restore_data_file_internal(FILE *in, FILE *out, pgFile *file, uint32 backup_vers
11421143
* page_may_be_compressed() function.
11431144
*/
11441145
if (header.compressed_size != BLCKSZ
1145-
|| page_may_be_compressed(compressed_page.data, file->compress_alg,
1146+
|| page_may_be_compressed(page.data, file->compress_alg,
11461147
backup_version))
11471148
{
1148-
const char *errormsg = NULL;
1149-
1150-
uncompressed_size = do_decompress(page.data, BLCKSZ,
1151-
compressed_page.data,
1152-
header.compressed_size,
1153-
file->compress_alg, &errormsg);
1154-
1155-
if (uncompressed_size < 0 && errormsg != NULL)
1156-
elog(WARNING, "An error occured during decompressing block %u of file \"%s\": %s",
1157-
blknum, from_fullpath, errormsg);
1158-
1159-
if (uncompressed_size != BLCKSZ)
1160-
elog(ERROR, "Page of file \"%s\" uncompressed to %d bytes. != BLCKSZ",
1161-
from_fullpath, uncompressed_size);
1149+
is_compressed = true;
11621150
}
11631151

11641152
write_pos = blknum * BLCKSZ;
@@ -1170,19 +1158,21 @@ restore_data_file_internal(FILE *in, FILE *out, pgFile *file, uint32 backup_vers
11701158
elog(ERROR, "Cannot seek block %u of \"%s\": %s",
11711159
blknum, to_fullpath, strerror(errno));
11721160

1173-
/* if we uncompressed the page - write page.data,
1174-
* if page wasn't compressed -
1175-
* write what we've read - compressed_page.data
1161+
/* If page is compressed and restore is in remote mode, send compressed
1162+
* page to the remote side.
11761163
*/
1177-
if (uncompressed_size == BLCKSZ)
1164+
if (is_compressed)
11781165
{
1179-
if (fio_fwrite(out, page.data, BLCKSZ) != BLCKSZ)
1180-
elog(ERROR, "Cannot write block %u of \"%s\": %s",
1181-
blknum, to_fullpath, strerror(errno));
1166+
ssize_t rc;
1167+
rc = fio_fwrite_compressed(out, page.data, compressed_size, file->compress_alg);
1168+
1169+
if (!fio_is_remote_file(out) && rc != BLCKSZ)
1170+
elog(ERROR, "Cannot write block %u of \"%s\": %s, size: %u",
1171+
blknum, to_fullpath, strerror(errno), compressed_size);
11821172
}
11831173
else
11841174
{
1185-
if (fio_fwrite(out, compressed_page.data, BLCKSZ) != BLCKSZ)
1175+
if (fio_fwrite(out, page.data, BLCKSZ) != BLCKSZ)
11861176
elog(ERROR, "Cannot write block %u of \"%s\": %s",
11871177
blknum, to_fullpath, strerror(errno));
11881178
}

src/pg_probackup.h

+6-4
Original file line numberDiff line numberDiff line change
@@ -216,8 +216,8 @@ typedef enum ShowFormat
216216
#define BYTES_INVALID (-1) /* file didn`t changed since previous backup, DELTA backup do not rely on it */
217217
#define FILE_NOT_FOUND (-2) /* file disappeared during backup */
218218
#define BLOCKNUM_INVALID (-1)
219-
#define PROGRAM_VERSION "2.2.7"
220-
#define AGENT_PROTOCOL_VERSION 20207
219+
#define PROGRAM_VERSION "2.2.8"
220+
#define AGENT_PROTOCOL_VERSION 20208
221221

222222

223223
typedef struct ConnectionOptions
@@ -898,8 +898,10 @@ extern long unsigned int base36dec(const char *text);
898898
extern uint32 parse_server_version(const char *server_version_str);
899899
extern uint32 parse_program_version(const char *program_version);
900900
extern bool parse_page(Page page, XLogRecPtr *lsn);
901-
int32 do_compress(void* dst, size_t dst_size, void const* src, size_t src_size,
902-
CompressAlg alg, int level, const char **errormsg);
901+
extern int32 do_compress(void* dst, size_t dst_size, void const* src, size_t src_size,
902+
CompressAlg alg, int level, const char **errormsg);
903+
extern int32 do_decompress(void* dst, size_t dst_size, void const* src, size_t src_size,
904+
CompressAlg alg, const char **errormsg);
903905

904906
extern void pretty_size(int64 size, char *buf, size_t len);
905907
extern void pretty_time_interval(int64 num_seconds, char *buf, size_t len);

src/utils/file.c

+63-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ void fio_error(int rc, int size, char const* file, int line)
5555
{
5656
if (remote_agent)
5757
{
58-
fprintf(stderr, "%s:%d: proceeds %d bytes instead of %d: %s\n", file, line, rc, size, rc >= 0 ? "end of data" : strerror(errno));
58+
fprintf(stderr, "%s:%d: processed %d bytes instead of %d: %s\n", file, line, rc, size, rc >= 0 ? "end of data" : strerror(errno));
5959
exit(EXIT_FAILURE);
6060
}
6161
else
@@ -611,6 +611,65 @@ ssize_t fio_write(int fd, void const* buf, size_t size)
611611
}
612612
}
613613

614+
static int32
615+
fio_decompress(void* dst, void const* src, size_t size, int compress_alg)
616+
{
617+
const char *errormsg = NULL;
618+
int32 uncompressed_size = do_decompress(dst, BLCKSZ,
619+
src,
620+
size,
621+
compress_alg, &errormsg);
622+
if (uncompressed_size < 0 && errormsg != NULL)
623+
{
624+
elog(WARNING, "An error occured during decompressing block: %s", errormsg);
625+
return -1;
626+
}
627+
628+
if (uncompressed_size != BLCKSZ)
629+
{
630+
elog(ERROR, "Page uncompressed to %d bytes != BLCKSZ",
631+
uncompressed_size);
632+
return -1;
633+
}
634+
return uncompressed_size;
635+
}
636+
637+
/* Write data to the file */
638+
ssize_t fio_fwrite_compressed(FILE* f, void const* buf, size_t size, int compress_alg)
639+
{
640+
if (fio_is_remote_file(f))
641+
{
642+
fio_header hdr;
643+
644+
hdr.cop = FIO_WRITE_COMPRESSED;
645+
hdr.handle = fio_fileno(f) & ~FIO_PIPE_MARKER;
646+
hdr.size = size;
647+
hdr.arg = compress_alg;
648+
649+
IO_CHECK(fio_write_all(fio_stdout, &hdr, sizeof(hdr)), sizeof(hdr));
650+
IO_CHECK(fio_write_all(fio_stdout, buf, size), size);
651+
652+
return size;
653+
}
654+
else
655+
{
656+
char uncompressed_buf[BLCKSZ];
657+
int32 uncompressed_size = fio_decompress(uncompressed_buf, buf, size, compress_alg);
658+
659+
return (uncompressed_size < 0)
660+
? uncompressed_size
661+
: fwrite(uncompressed_buf, 1, uncompressed_size, f);
662+
}
663+
}
664+
665+
static ssize_t
666+
fio_write_compressed_impl(int fd, void const* buf, size_t size, int compress_alg)
667+
{
668+
char uncompressed_buf[BLCKSZ];
669+
int32 uncompressed_size = fio_decompress(uncompressed_buf, buf, size, compress_alg);
670+
return fio_write_all(fd, uncompressed_buf, uncompressed_size);
671+
}
672+
614673
/* Read data from stdio file */
615674
ssize_t fio_fread(FILE* f, void* buf, size_t size)
616675
{
@@ -1447,6 +1506,9 @@ void fio_communicate(int in, int out)
14471506
case FIO_WRITE: /* Write to the current position in file */
14481507
IO_CHECK(fio_write_all(fd[hdr.handle], buf, hdr.size), hdr.size);
14491508
break;
1509+
case FIO_WRITE_COMPRESSED: /* Write to the current position in file */
1510+
IO_CHECK(fio_write_compressed_impl(fd[hdr.handle], buf, hdr.size, hdr.arg), BLCKSZ);
1511+
break;
14501512
case FIO_READ: /* Read from the current position in file */
14511513
if ((size_t)hdr.arg > buf_size) {
14521514
buf_size = hdr.arg;

src/utils/file.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ typedef enum
3434
FIO_READDIR,
3535
FIO_CLOSEDIR,
3636
FIO_SEND_PAGES,
37-
FIO_PAGE
37+
FIO_PAGE,
38+
FIO_WRITE_COMPRESSED,
3839
} fio_operations;
3940

4041
typedef enum
@@ -70,6 +71,7 @@ extern void fio_communicate(int in, int out);
7071

7172
extern FILE* fio_fopen(char const* name, char const* mode, fio_location location);
7273
extern size_t fio_fwrite(FILE* f, void const* buf, size_t size);
74+
extern ssize_t fio_fwrite_compressed(FILE* f, void const* buf, size_t size, int compress_alg);
7375
extern ssize_t fio_fread(FILE* f, void* buf, size_t size);
7476
extern int fio_pread(FILE* f, void* buf, off_t offs);
7577
extern int fio_fprintf(FILE* f, char const* arg, ...) pg_attribute_printf(2, 3);

0 commit comments

Comments
 (0)