Fix bug in archive streamer with LZ4 decompression · postgres/postgres@3369a3b · GitHub | Latest TMZ Celebrity News & Gossip | Watch TMZ Live
Skip to content

Commit 3369a3b

Browse files
committed
Fix bug in archive streamer with LZ4 decompression
When decompressing some input data, the calculation for the initial starting point and the initial size were incorrect, potentially leading to failures when decompressing contents with LZ4. These initialization points are fixed in this commit, bringing the logic closer to what exists for gzip and zstd. The contents of the compressed data is clear (for example backups taken with LZ4 can still be decompressed with a "lz4" command), only the decompression part reading the input data was impacted by this issue. This code path impacts pg_basebackup and pg_verifybackup, which can use the LZ4 decompression routines with an archive streamer, or any tools that try to use the archive streamers in src/fe_utils/. The issue is easier to reproduce with files that have a low-compression rate, like ones filled with random data, for a size of at least 512kB, but this could happen with anything as long as it is stored in a data folder. Some tests are added based on this idea, with a file filled with random bytes grabbed from the backend, written at the root of the data folder. This is proving good enough to reproduce the original problem. Author: Mikhail Gribkov <youzhick@gmail.com> Discussion: https://postgr.es/m/CAMEv5_uQS1Hg6KCaEP2JkrTBbZ-nXQhxomWrhYQvbdzR-zy-wA@mail.gmail.com Backpatch-through: 15
1 parent b45242f commit 3369a3b

File tree

3 files changed

+46
-2
lines changed

3 files changed

+46
-2
lines changed

src/bin/pg_verifybackup/t/008_untar.pl

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,22 @@
1616
$primary->init(allows_streaming => 1);
1717
$primary->start;
1818

19+
# Create file with some random data and an arbitrary size, useful to check
20+
# the solidity of the compression and decompression logic. The size of the
21+
# file is chosen to be around 640kB. This has proven to be large enough to
22+
# detect some issues related to LZ4, and low enough to not impact the runtime
23+
# of the test significantly.
24+
my $junk_data = $primary->safe_psql(
25+
'postgres', qq(
26+
SELECT string_agg(encode(sha256(i::bytea), 'hex'), '')
27+
FROM generate_series(1, 10240) s(i);));
28+
my $data_dir = $primary->data_dir;
29+
my $junk_file = "$data_dir/junk";
30+
open my $jf, '>', $junk_file
31+
or die "Could not create junk file: $!";
32+
print $jf $junk_data;
33+
close $jf;
34+
1935
# Create a tablespace directory.
2036
my $source_ts_path = PostgreSQL::Test::Utils::tempdir_short();
2137

@@ -52,6 +68,12 @@
5268
'backup_archive' => [ 'base.tar.lz4', "$tsoid.tar.lz4" ],
5369
'enabled' => check_pg_config("#define USE_LZ4 1")
5470
},
71+
{
72+
'compression_method' => 'lz4',
73+
'backup_flags' => [ '--compress', 'server-lz4:5' ],
74+
'backup_archive' => [ 'base.tar.lz4', "$tsoid.tar.lz4" ],
75+
'enabled' => check_pg_config("#define USE_LZ4 1")
76+
},
5577
{
5678
'compression_method' => 'zstd',
5779
'backup_flags' => [ '--compress', 'server-zstd' ],

src/bin/pg_verifybackup/t/010_client_untar.pl

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,22 @@
1515
$primary->init(allows_streaming => 1);
1616
$primary->start;
1717

18+
# Create file with some random data and an arbitrary size, useful to check
19+
# the solidity of the compression and decompression logic. The size of the
20+
# file is chosen to be around 640kB. This has proven to be large enough to
21+
# detect some issues related to LZ4, and low enough to not impact the runtime
22+
# of the test significantly.
23+
my $junk_data = $primary->safe_psql(
24+
'postgres', qq(
25+
SELECT string_agg(encode(sha256(i::bytea), 'hex'), '')
26+
FROM generate_series(1, 10240) s(i);));
27+
my $data_dir = $primary->data_dir;
28+
my $junk_file = "$data_dir/junk";
29+
open my $jf, '>', $junk_file
30+
or die "Could not create junk file: $!";
31+
print $jf $junk_data;
32+
close $jf;
33+
1834
my $backup_path = $primary->backup_dir . '/client-backup';
1935
my $extract_path = $primary->backup_dir . '/extracted-backup';
2036

@@ -37,6 +53,12 @@
3753
'backup_archive' => 'base.tar.lz4',
3854
'enabled' => check_pg_config("#define USE_LZ4 1")
3955
},
56+
{
57+
'compression_method' => 'lz4',
58+
'backup_flags' => [ '--compress', 'client-lz4:1' ],
59+
'backup_archive' => 'base.tar.lz4',
60+
'enabled' => check_pg_config("#define USE_LZ4 1")
61+
},
4062
{
4163
'compression_method' => 'zstd',
4264
'backup_flags' => [ '--compress', 'client-zstd:5' ],

src/fe_utils/astreamer_lz4.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -322,9 +322,9 @@ astreamer_lz4_decompressor_content(astreamer *streamer,
322322

323323
mystreamer = (astreamer_lz4_frame *) streamer;
324324
next_in = (uint8 *) data;
325-
next_out = (uint8 *) mystreamer->base.bbs_buffer.data;
325+
next_out = (uint8 *) mystreamer->base.bbs_buffer.data + mystreamer->bytes_written;
326326
avail_in = len;
327-
avail_out = mystreamer->base.bbs_buffer.maxlen;
327+
avail_out = mystreamer->base.bbs_buffer.maxlen - mystreamer->bytes_written;
328328

329329
while (avail_in > 0)
330330
{

0 commit comments

Comments
 (0)

TMZ Celebrity News – Breaking Stories, Videos & Gossip

Looking for the latest TMZ celebrity news? You've come to the right place. From shocking Hollywood scandals to exclusive videos, TMZ delivers it all in real time.

Whether it’s a red carpet slip-up, a viral paparazzi moment, or a legal drama involving your favorite stars, TMZ news is always first to break the story. Stay in the loop with daily updates, insider tips, and jaw-dropping photos.

🎥 Watch TMZ Live

TMZ Live brings you daily celebrity news and interviews straight from the TMZ newsroom. Don’t miss a beat—watch now and see what’s trending in Hollywood.