Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,21 @@ include $(top_srcdir)/contrib/contrib-global.mk
endif

PG_CPPFLAGS = -I$(libpq_srcdir) ${PTHREAD_CFLAGS} -Isrc -I$(srchome)/$(subdir)/src

# LZ4 compression library detection
LZ4_LIBS =
ifneq ($(shell pkg-config --exists liblz4 2>/dev/null && echo yes),)
PG_CPPFLAGS += -DHAVE_LIBLZ4 $(shell pkg-config --cflags liblz4)
LZ4_LIBS = $(shell pkg-config --libs liblz4)
else
ifneq ($(wildcard /usr/include/lz4.h),)
PG_CPPFLAGS += -DHAVE_LIBLZ4
LZ4_LIBS = -llz4
endif
endif

override CPPFLAGS := -DFRONTEND $(CPPFLAGS) $(PG_CPPFLAGS)
PG_LIBS_INTERNAL = $(libpq_pgport) ${PTHREAD_CFLAGS}
PG_LIBS_INTERNAL = $(libpq_pgport) ${PTHREAD_CFLAGS} $(LZ4_LIBS)

src/utils/configuration.o: src/datapagemap.h
src/archive.o: src/instr_time.h
Expand Down
20 changes: 13 additions & 7 deletions doc/pgprobackup.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3014,7 +3014,7 @@ content-crc = 802820606
<listitem>
<para>
<literal>compress-alg</literal> — compression algorithm used during backup. Possible values:
<literal>zlib</literal>, <literal>pglz</literal>, <literal>none</literal>.
<literal>zlib</literal>, <literal>pglz</literal>, <literal>lz4</literal>, <literal>none</literal>.
</para>
</listitem>
<listitem>
Expand Down Expand Up @@ -5885,11 +5885,15 @@ pg_probackup catchup -b <replaceable>catchup_mode</replaceable>
<para>
Defines the algorithm to use for compressing data files.
Possible values are <literal>zlib</literal>,
<literal>pglz</literal>, and <literal>none</literal>. If set
to <literal>zlib</literal> or <literal>pglz</literal>, this option enables compression. By default,
<literal>pglz</literal>, <literal>lz4</literal>, and <literal>none</literal>. If set
to <literal>zlib</literal>, <literal>pglz</literal>, or <literal>lz4</literal>, this option enables compression. By default,
compression is disabled. For the
<xref linkend="pbk-archive-push"/> command, the
<literal>pglz</literal> compression algorithm is not supported.
<literal>pglz</literal> and <literal>lz4</literal> compression algorithms are not supported.
</para>
<para>
The <literal>lz4</literal> algorithm requires the <literal>liblz4</literal> library
to be installed at build time.
</para>
<para>
Default: <literal>none</literal>
Expand All @@ -5901,9 +5905,11 @@ pg_probackup catchup -b <replaceable>catchup_mode</replaceable>
<term><option>--compress-level=<replaceable>compression_level</replaceable></option></term>
<listitem>
<para>
Defines compression level (0 through 9, 0 being no compression
and 9 being best compression). This option can be used
together with the <option>--compress-algorithm</option> option.
Defines compression level. For <literal>zlib</literal> and <literal>pglz</literal>,
valid values are 0 through 9 (0 being no compression and 9 being best compression).
For <literal>lz4</literal>, valid values are 0 through 12: level 0 uses fast LZ4 compression,
levels 1-12 use LZ4_HC (high compression) mode with increasing compression ratio.
This option can be used together with the <option>--compress-algorithm</option> option.
</para>
<para>
Default: <literal>1</literal>
Expand Down
4 changes: 4 additions & 0 deletions src/catalog.c
Original file line number Diff line number Diff line change
Expand Up @@ -2882,6 +2882,8 @@ parse_compress_alg(const char *arg)
return ZLIB_COMPRESS;
else if (pg_strncasecmp("pglz", arg, len) == 0)
return PGLZ_COMPRESS;
else if (pg_strncasecmp("lz4", arg, len) == 0)
return LZ4_COMPRESS;
else if (pg_strncasecmp("none", arg, len) == 0)
return NONE_COMPRESS;
else
Expand All @@ -2902,6 +2904,8 @@ deparse_compress_alg(int alg)
return "zlib";
case PGLZ_COMPRESS:
return "pglz";
case LZ4_COMPRESS:
return "lz4";
}

return NULL;
Expand Down
64 changes: 64 additions & 0 deletions src/data.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@
#include <zlib.h>
#endif

#ifdef HAVE_LIBLZ4
#include <lz4.h>
#include <lz4hc.h>
#endif

#include "utils/thread.h"

/* Union to ease operations on relation pages */
Expand Down Expand Up @@ -58,6 +63,45 @@ zlib_decompress(void *dst, size_t dst_size, void const *src, size_t src_size)
}
#endif

#ifdef HAVE_LIBLZ4
/*
* Implementation of LZ4 compression method.
* Uses LZ4_HC (high compression) mode when level is specified,
* otherwise uses fast LZ4 compression.
*/
static int32
lz4_compress(void *dst, size_t dst_size, void const *src, size_t src_size,
int level)
{
int compressed_size;

/*
* Level 1-12: use LZ4_HC for better compression ratio.
* Level 0 or unspecified: use fast LZ4_compress_default.
*/
if (level >= LZ4_COMPRESS_LEVEL_MIN && level <= LZ4_COMPRESS_LEVEL_MAX)
compressed_size = LZ4_compress_HC((const char *) src, (char *) dst,
(int) src_size, (int) dst_size, level);
else
compressed_size = LZ4_compress_default((const char *) src, (char *) dst,
(int) src_size, (int) dst_size);

return compressed_size > 0 ? compressed_size : -1;
}

/* Implementation of LZ4 decompression method */
static int32
lz4_decompress(void *dst, size_t dst_size, void const *src, size_t src_size)
{
int decompressed_size;

decompressed_size = LZ4_decompress_safe((const char *) src, (char *) dst,
(int) src_size, (int) dst_size);

return decompressed_size > 0 ? decompressed_size : -1;
}
#endif

/*
* Compresses source into dest using algorithm. Returns the number of bytes
* written in the destination buffer, or -1 if compression fails.
Expand All @@ -83,6 +127,16 @@ do_compress(void *dst, size_t dst_size, void const *src, size_t src_size,
#endif
case PGLZ_COMPRESS:
return pglz_compress(src, src_size, dst, PGLZ_strategy_always);
#ifdef HAVE_LIBLZ4
case LZ4_COMPRESS:
{
int32 ret;
ret = lz4_compress(dst, dst_size, src, src_size, level);
if (ret < 0 && errormsg)
*errormsg = "LZ4 compression failed";
return ret;
}
#endif
}

return -1;
Expand Down Expand Up @@ -119,6 +173,16 @@ do_decompress(void *dst, size_t dst_size, void const *src, size_t src_size,
return pglz_decompress(src, src_size, dst, dst_size, true);
#else
return pglz_decompress(src, src_size, dst, dst_size);
#endif
#ifdef HAVE_LIBLZ4
case LZ4_COMPRESS:
{
int32 ret;
ret = lz4_decompress(dst, dst_size, src, src_size);
if (ret < 0 && errormsg)
*errormsg = "LZ4 decompression failed";
return ret;
}
#endif
}

Expand Down
6 changes: 3 additions & 3 deletions src/help.c
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ help_backup(void)
printf(_("\n Compression options:\n"));
printf(_(" --compress alias for --compress-algorithm='zlib' and --compress-level=1\n"));
printf(_(" --compress-algorithm=compress-algorithm\n"));
printf(_(" available options: 'zlib', 'pglz', 'none' (default: none)\n"));
printf(_(" available options: 'zlib', 'pglz', 'lz4', 'none' (default: none)\n"));
printf(_(" --compress-level=compress-level\n"));
printf(_(" level of compression [0-9] (default: 1)\n"));

Expand Down Expand Up @@ -909,7 +909,7 @@ help_set_config(void)
printf(_("\n Compression options:\n"));
printf(_(" --compress alias for --compress-algorithm='zlib' and --compress-level=1\n"));
printf(_(" --compress-algorithm=compress-algorithm\n"));
printf(_(" available options: 'zlib','pglz','none' (default: 'none')\n"));
printf(_(" available options: 'zlib','pglz','lz4','none' (default: 'none')\n"));
printf(_(" --compress-level=compress-level\n"));
printf(_(" level of compression [0-9] (default: 1)\n"));

Expand Down Expand Up @@ -1052,7 +1052,7 @@ help_archive_push(void)
printf(_("\n Compression options:\n"));
printf(_(" --compress alias for --compress-algorithm='zlib' and --compress-level=1\n"));
printf(_(" --compress-algorithm=compress-algorithm\n"));
printf(_(" available options: 'zlib','pglz','none' (default: 'none')\n"));
printf(_(" available options: 'zlib','pglz','lz4','none' (default: 'none')\n"));
printf(_(" --compress-level=compress-level\n"));
printf(_(" level of compression [0-9] (default: 1)\n"));

Expand Down
15 changes: 14 additions & 1 deletion src/pg_probackup.c
Original file line number Diff line number Diff line change
Expand Up @@ -1154,7 +1154,15 @@ compress_init(ProbackupSubcmd const subcmd)
"compress-algorithm option");
}

if (instance_config.compress_level < 0 || instance_config.compress_level > 9)
/* Validate compression level based on algorithm */
if (instance_config.compress_alg == LZ4_COMPRESS)
{
if (instance_config.compress_level < 0 ||
instance_config.compress_level > LZ4_COMPRESS_LEVEL_MAX)
elog(ERROR, "--compress-level for LZ4 must be in range 0-%d",
LZ4_COMPRESS_LEVEL_MAX);
}
else if (instance_config.compress_level < 0 || instance_config.compress_level > 9)
elog(ERROR, "--compress-level value must be in the range from 0 to 9");

if (instance_config.compress_alg == ZLIB_COMPRESS && instance_config.compress_level == 0)
Expand All @@ -1166,6 +1174,11 @@ compress_init(ProbackupSubcmd const subcmd)
if (instance_config.compress_alg == ZLIB_COMPRESS)
elog(ERROR, "This build does not support zlib compression");
else
#endif
#ifndef HAVE_LIBLZ4
if (instance_config.compress_alg == LZ4_COMPRESS)
elog(ERROR, "This build does not support LZ4 compression");
else
#endif
if (instance_config.compress_alg == PGLZ_COMPRESS && num_threads > 1)
elog(ERROR, "Multithread backup does not support pglz compression");
Expand Down
5 changes: 5 additions & 0 deletions src/pg_probackup.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,13 @@ typedef enum CompressAlg
NONE_COMPRESS,
PGLZ_COMPRESS,
ZLIB_COMPRESS,
LZ4_COMPRESS,
} CompressAlg;

/* LZ4 compression level limits (LZ4_HC mode) */
#define LZ4_COMPRESS_LEVEL_MIN 1
#define LZ4_COMPRESS_LEVEL_MAX 12

typedef enum ForkName
{
none,
Expand Down
Loading