Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 1e8c9ae

Browse files
committed
Support multiple compression algorithms
1 parent 58f0fe3 commit 1e8c9ae

File tree

9 files changed

+274
-112
lines changed

9 files changed

+274
-112
lines changed

doc/src/sgml/libpq.sgml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1139,8 +1139,11 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
11391139
<term><literal>compression</literal></term>
11401140
<listitem>
11411141
<para>
1142-
Request compression of libpq traffic. If server is supporting compression, then all libpq messages send both from client to server and
1143-
visa versa will be compressed. Right now compression algorithm is hardcoded: is it is either zlib (default), either zstd (if Postgres was
1142+
Request compression of libpq traffic. Client sends to the server list of compression algorithms, supported by client library.
1143+
If server supports one of this algorithms, then it acknowledges use of this algorithm and then all libpq messages send both from client to server and
1144+
visa versa will be compressed. If server is not supporting any of the suggested algorithms, then it replies with 'n' (no compression)
1145+
message and it is up to the client whether to continue work without compression or report error.
1146+
Supported compression algorithms are chosen at configure time. Right now two libraries are supported: zlib (default) and zstd (if Postgres was
11441147
configured with --with-zstd option). In both cases streaming mode is used.
11451148
</para>
11461149
</listitem>

doc/src/sgml/protocol.sgml

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@
9797
Compression is especial useful for importing/exporting data to/from database using COPY command
9898
and for replication (both physical and logical). Also compression can reduce server response time
9999
in case of queries returning large amount of data (for example returning JSON, BLOBs, text,...)
100-
Right now compression algorithm is hardcoded: is it is either zlib (default), either zstd (if Postgres was
100+
Right now two libraries are supported: zlib (default) and zstd (if Postgres was
101101
configured with --with-zstd option). In both cases streaming mode is used.
102102
</para>
103103

@@ -272,13 +272,15 @@
272272
</varlistentry>
273273

274274
<varlistentry>
275-
<term>CompressionOk</term>
275+
<term>CompressionAck</term>
276276
<listitem>
277277
<para>
278278
Server acknowledge using compression for client-server communication protocol.
279279
Compression can be requested by client by including "compression" option in connection string.
280-
Right now compression algorithm is hardcoded, but in future client and server may negotiate to
281-
choose proper compression algorithm.
280+
Client sends to the server list of compression algorithms, supported by client library.
281+
If server supports one of this algorithms, then it acknowledges use of this algorithm and then all libpq messages send both from client to server and
282+
visa versa will be compressed. If server is not supporting any of the suggested algorithms, then it replies with 'n' (no compression)
283+
message and it is up to the client whether to continue work without compression or report error.
282284
</para>
283285
</listitem>
284286
</varlistentry>
@@ -3421,7 +3423,7 @@ AuthenticationSASLFinal (B)
34213423

34223424
<varlistentry>
34233425
<term>
3424-
CompressionOk (B)
3426+
CompressionAck (B)
34253427
</term>
34263428
<listitem>
34273429
<para>
@@ -3433,7 +3435,11 @@ CompressionOk (B)
34333435
</term>
34343436
<listitem>
34353437
<para>
3436-
Acknowledge use of compression for protocol data. After receiving this message bother server and client are switched to compression mode
3438+
Acknowledge use of compression for protocol data. Client sends to the server list of compression algorithms, supported by client library.
3439+
If server supports one of this algorithms, then it responds with CompressionAck with identifier (letter) of first such algorithm.
3440+
If server is not supporting any of the suggested algorithms, then it replies with 'n' (no compression) algorithm.
3441+
It is up to the client whether to continue work without compression or report error.
3442+
After receiving this message with algorithm identifer aother than 'n', both server and client are switched to compression mode
34373443
and exchange compressed messages.
34383444
</para>
34393445
</listitem>
@@ -3454,7 +3460,7 @@ CompressionOk (B)
34543460
</term>
34553461
<listitem>
34563462
<para>
3457-
Used compression algorithm. Right now the following streaming compression algorithms are supported: 'f' - Facebook zstd, 'z' - zlib.
3463+
Used compression algorithm. Right now the following streaming compression algorithms are supported: 'f' - Facebook zstd, 'z' - zlib, 'n' - no compresion.
34583464
</para>
34593465
</listitem>
34603466
</varlistentry>
@@ -5888,9 +5894,8 @@ StartupMessage (F)
58885894
</term>
58895895
<listitem>
58905896
<para>
5891-
Request compression of libpq traffic. Value can be
5892-
<literal>0</literal>, <literal>1</literal>, <literal>true</literal>,
5893-
<literal>false</literal>, <literal>on</literal>, <literal>off.</literal>.
5897+
Request compression of libpq traffic. Value is list of compression algorithms supported by client:
5898+
<literal>'f'</literal> - Facebook zstd, <literal>'z'</literal> - zlib, <literal>'n'</literal> - no compresion.
58945899
By default compression is disabled.
58955900
</para>
58965901
</listitem>

src/backend/libpq/pqcomm.c

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -199,21 +199,38 @@ WaitEventSet *FeBeWaitSet;
199199
int
200200
pq_configure(Port* port)
201201
{
202-
if (port->use_compression)
202+
char server_compression_algorithms[ZPQ_MAX_ALGORITHMS];
203+
char* client_compression_algorithms = port->compression_algorithms;
204+
char compression_algorithm = ZPQ_NO_COMPRESSION;
205+
char compression[6] = {'z',0,0,0,5,0}; /* message length = 5 */
206+
int rc;
207+
208+
zpq_get_supported_algorithms(server_compression_algorithms);
209+
210+
if (client_compression_algorithms)
203211
{
204-
char compression[6] = {'z',0,0,0,5,0}; /* message length = 5 */
205-
int rc;
206-
compression[5] = zpq_algorithm();
207-
/* Switch on compression at client side */
208-
socket_set_nonblocking(false);
209-
while ((rc = secure_write(MyProcPort, compression, sizeof(compression))) < 0
210-
&& errno == EINTR);
211-
if ((size_t)rc != sizeof(compression))
212-
return -1;
213-
214-
/* initialize compression */
215-
PqStream = zpq_create((zpq_tx_func)secure_write, (zpq_rx_func)secure_read, MyProcPort);
212+
while (*client_compression_algorithms != '\0')
213+
{
214+
if (strchr(server_compression_algorithms, *client_compression_algorithms))
215+
{
216+
compression_algorithm = *client_compression_algorithms;
217+
break;
218+
}
219+
client_compression_algorithms += 1;
220+
}
216221
}
222+
223+
compression[5] = compression_algorithm;
224+
/* Switch on compression at client side */
225+
socket_set_nonblocking(false);
226+
while ((rc = secure_write(MyProcPort, compression, sizeof(compression))) < 0
227+
&& errno == EINTR);
228+
if ((size_t)rc != sizeof(compression))
229+
return -1;
230+
231+
/* initialize compression */
232+
if (zpq_set_algorithm(compression_algorithm))
233+
PqStream = zpq_create((zpq_tx_func)secure_write, (zpq_rx_func)secure_read, MyProcPort);
217234
return 0;
218235
}
219236

@@ -256,7 +273,6 @@ pq_init(void)
256273
NULL, NULL);
257274
AddWaitEventToSet(FeBeWaitSet, WL_LATCH_SET, -1, MyLatch, NULL);
258275
AddWaitEventToSet(FeBeWaitSet, WL_POSTMASTER_DEATH, -1, NULL, NULL);
259-
260276
}
261277

262278
/* --------------------------------

src/backend/postmaster/postmaster.c

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2047,15 +2047,7 @@ ProcessStartupPacket(Port *port, bool SSLdone)
20472047
else if (strcmp(nameptr, "user") == 0)
20482048
port->user_name = pstrdup(valptr);
20492049
else if (strcmp(nameptr, "compression") == 0)
2050-
{
2051-
if (!parse_bool(valptr, &port->use_compression))
2052-
ereport(FATAL,
2053-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2054-
errmsg("invalid boolean value for parameter \"%s\": \"%s\"",
2055-
"compression",
2056-
valptr),
2057-
errhint("Valid values are: \"false\", \"off\", 0, \"true\", \"on\", 1.")));
2058-
}
2050+
port->compression_algorithms = pstrdup(valptr);
20592051
else if (strcmp(nameptr, "options") == 0)
20602052
port->cmdline_options = pstrdup(valptr);
20612053
else if (strcmp(nameptr, "replication") == 0)

0 commit comments

Comments
 (0)