Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit5a1007a

Browse files
committed
Have the server properly terminate tar archives.
Earlier versions of PostgreSQL featured a version of pg_basebackupthat wanted to edit tar archives but was too dumb to parse themproperly. The server made things easier for the client by failingto add the two blocks of zero bytes that ought to end a tar file,leaving it up to the client to do that.But since commit23a1c65, wedon't need this hack any more, because pg_basebackup is now smarterand can parse tar files even if they are properly terminated! Sochange the server to always properly terminate the tar files. Olderversions of pg_basebackup can't talk to new servers anyway, sothere's no compatibility break.On the pg_basebackup side, we see still need to add the terminatingzero bytes if we're talking to an older server, but not when theserver is v15+. Hopefully at some point we'll be able to removesome of this compatibility cruft, but it seems best to hang on toit for now.In passing, add a file header comment to bbstreamer_tar.c, to makeit clearer what's going on here.Discussion:http://postgr.es/m/CA+TgmoZbNzsWwM4BE5Jb_qHncY817DYZwGf+2-7hkMQ27ZwsMQ@mail.gmail.com
1 parentee3a1a5 commit5a1007a

File tree

3 files changed

+45
-6
lines changed

3 files changed

+45
-6
lines changed

‎src/backend/replication/basebackup.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,16 @@ perform_base_backup(basebackup_options *opt, bbsink *sink)
374374
Assert(lnext(state.tablespaces,lc)==NULL);
375375
}
376376
else
377+
{
378+
/* Properly terminate the tarfile. */
379+
StaticAssertStmt(TAR_BLOCK_SIZE <=2*BLCKSZ,
380+
"BLCKSZ too small for 2 tar blocks");
381+
memset(sink->bbs_buffer,0,2*TAR_BLOCK_SIZE);
382+
bbsink_archive_contents(sink,2*TAR_BLOCK_SIZE);
383+
384+
/* OK, that's the end of the archive. */
377385
bbsink_end_archive(sink);
386+
}
378387
}
379388

380389
basebackup_progress_wait_wal_archive(&state);
@@ -611,6 +620,13 @@ perform_base_backup(basebackup_options *opt, bbsink *sink)
611620
sendFileWithContent(sink,pathbuf,"",&manifest);
612621
}
613622

623+
/* Properly terminate the tar file. */
624+
StaticAssertStmt(TAR_BLOCK_SIZE <=2*BLCKSZ,
625+
"BLCKSZ too small for 2 tar blocks");
626+
memset(sink->bbs_buffer,0,2*TAR_BLOCK_SIZE);
627+
bbsink_archive_contents(sink,2*TAR_BLOCK_SIZE);
628+
629+
/* OK, that's the end of the archive. */
614630
bbsink_end_archive(sink);
615631
}
616632

‎src/bin/pg_basebackup/bbstreamer_tar.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,16 @@
22
*
33
* bbstreamer_tar.c
44
*
5+
* This module implements three types of tar processing. A tar parser
6+
* expects unlabelled chunks of data (e.g. BBSTREAMER_UNKNOWN) and splits
7+
* it into labelled chunks (any other value of bbstreamer_archive_context).
8+
* A tar archiver does the reverse: it takes a bunch of labelled chunks
9+
* and produces a tarfile, optionally replacing member headers and trailers
10+
* so that upstream bbstreamer objects can perform surgery on the tarfile
11+
* contents without knowing the details of the tar format. A tar terminator
12+
* just adds two blocks of NUL bytes to the end of the file, since older
13+
* server versions produce files with this terminator omitted.
14+
*
515
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
616
*
717
* IDENTIFICATION

‎src/bin/pg_basebackup/pg_basebackup.c

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,12 @@ typedef void (*WriteDataCallback) (size_t nbytes, char *buf,
8585
*/
8686
#defineMINIMUM_VERSION_FOR_MANIFESTS130000
8787

88+
/*
89+
* Before v15, tar files received from the server will be improperly
90+
* terminated.
91+
*/
92+
#defineMINIMUM_VERSION_FOR_TERMINATED_TARFILE 150000
93+
8894
/*
8995
* Different ways to include WAL
9096
*/
@@ -166,7 +172,8 @@ static void progress_report(int tablespacenum, bool force, bool finished);
166172

167173
staticbbstreamer*CreateBackupStreamer(char*archive_name,char*spclocation,
168174
bbstreamer**manifest_inject_streamer_p,
169-
boolis_recovery_guc_supported);
175+
boolis_recovery_guc_supported,
176+
boolexpect_unterminated_tarfile);
170177
staticvoidReceiveTarFile(PGconn*conn,char*archive_name,char*spclocation,
171178
booltablespacenum);
172179
staticvoidReceiveTarCopyChunk(size_tr,char*copybuf,void*callback_data);
@@ -965,7 +972,8 @@ ReceiveCopyData(PGconn *conn, WriteDataCallback callback,
965972
staticbbstreamer*
966973
CreateBackupStreamer(char*archive_name,char*spclocation,
967974
bbstreamer**manifest_inject_streamer_p,
968-
boolis_recovery_guc_supported)
975+
boolis_recovery_guc_supported,
976+
boolexpect_unterminated_tarfile)
969977
{
970978
bbstreamer*streamer;
971979
bbstreamer*manifest_inject_streamer=NULL;
@@ -1074,12 +1082,13 @@ CreateBackupStreamer(char *archive_name, char *spclocation,
10741082
/*
10751083
* If we're doing anything that involves understanding the contents of
10761084
* the archive, we'll need to parse it. If not, we can skip parsing it,
1077-
* but the tar files the server sends are not properly terminated, so
1078-
* we'll need to add the terminator here.
1085+
* but old versions of the server send improperly terminated tarfiles,
1086+
* so if we're talking to such a server we'll need to add the terminator
1087+
* here.
10791088
*/
10801089
if (must_parse_archive)
10811090
streamer=bbstreamer_tar_parser_new(streamer);
1082-
else
1091+
elseif (expect_unterminated_tarfile)
10831092
streamer=bbstreamer_tar_terminator_new(streamer);
10841093

10851094
/* Return the results. */
@@ -1099,14 +1108,18 @@ ReceiveTarFile(PGconn *conn, char *archive_name, char *spclocation,
10991108
WriteTarStatestate;
11001109
bbstreamer*manifest_inject_streamer;
11011110
boolis_recovery_guc_supported;
1111+
boolexpect_unterminated_tarfile;
11021112

11031113
/* Pass all COPY data through to the backup streamer. */
11041114
memset(&state,0,sizeof(state));
11051115
is_recovery_guc_supported=
11061116
PQserverVersion(conn) >=MINIMUM_VERSION_FOR_RECOVERY_GUC;
1117+
expect_unterminated_tarfile=
1118+
PQserverVersion(conn)<MINIMUM_VERSION_FOR_TERMINATED_TARFILE;
11071119
state.streamer=CreateBackupStreamer(archive_name,spclocation,
11081120
&manifest_inject_streamer,
1109-
is_recovery_guc_supported);
1121+
is_recovery_guc_supported,
1122+
expect_unterminated_tarfile);
11101123
state.tablespacenum=tablespacenum;
11111124
ReceiveCopyData(conn,ReceiveTarCopyChunk,&state);
11121125
progress_filename=NULL;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp