Skip to content

Commit b2de45f

Browse files
committed
pg_basebackup: Avoid unclean failure with server-compression and -D -.
Fail with a suitable error message instead. We can't inject the backup manifest into the output tarfile without decompressing it, and if we did that, we'd have to recompress the tarfile afterwards to produce the result the user is expecting. While we have enough infrastructure in pg_basebackup now to accomplish that whole series of steps without much additional code, it seems like excessively surprising behavior. The user probably did not select server-side compression with the idea that the client was going to end up decompressing it and then recompressing. Report from Justin Pryzby. Fix by me. Discussion: http://postgr.es/m/CA+Tgmob6Rnjz-Qv32h3yJn8nnUkLhrtQDAS4y5AtsgtorAFHRA@mail.gmail.com
1 parent e94bb14 commit b2de45f

File tree

1 file changed

+21
-3
lines changed

1 file changed

+21
-3
lines changed

src/bin/pg_basebackup/pg_basebackup.c

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1208,7 +1208,8 @@ CreateBackupStreamer(char *archive_name, char *spclocation,
12081208
bool is_tar,
12091209
is_tar_gz,
12101210
is_tar_lz4,
1211-
is_tar_zstd;
1211+
is_tar_zstd,
1212+
is_compressed_tar;
12121213
bool must_parse_archive;
12131214
int archive_name_len = strlen(archive_name);
12141215

@@ -1235,6 +1236,24 @@ CreateBackupStreamer(char *archive_name, char *spclocation,
12351236
is_tar_zstd = (archive_name_len > 8 &&
12361237
strcmp(archive_name + archive_name_len - 4, ".zst") == 0);
12371238

1239+
/* Is this any kind of compressed tar? */
1240+
is_compressed_tar = is_tar_gz || is_tar_lz4 || is_tar_zstd;
1241+
1242+
/*
1243+
* Injecting the manifest into a compressed tar file would be possible if
1244+
* we decompressed it, parsed the tarfile, generated a new tarfile, and
1245+
* recompressed it, but compressing and decompressing multiple times just
1246+
* to inject the manifest seems inefficient enough that it's probably not
1247+
* what the user wants. So, instead, reject the request and tell the user
1248+
* to specify something more reasonable.
1249+
*/
1250+
if (inject_manifest && is_compressed_tar)
1251+
{
1252+
pg_log_error("cannot inject manifest into a compressed tarfile");
1253+
pg_log_info("use client-side compression, send the output to a directory rather than standard output, or use --no-manifest");
1254+
exit(1);
1255+
}
1256+
12381257
/*
12391258
* We have to parse the archive if (1) we're suppose to extract it, or if
12401259
* (2) we need to inject backup_manifest or recovery configuration into it.
@@ -1244,8 +1263,7 @@ CreateBackupStreamer(char *archive_name, char *spclocation,
12441263
(spclocation == NULL && writerecoveryconf));
12451264

12461265
/* At present, we only know how to parse tar archives. */
1247-
if (must_parse_archive && !is_tar && !is_tar_gz && !is_tar_lz4
1248-
&& !is_tar_zstd)
1266+
if (must_parse_archive && !is_tar && !is_compressed_tar)
12491267
{
12501268
pg_log_error("unable to parse archive: %s", archive_name);
12511269
pg_log_info("only tar archives can be parsed");

0 commit comments

Comments
 (0)