MySQL 8.4.2
Source Code Documentation
Compressed Packet

The compressed packet consists of a Compressed Packet Header and a payload which is either a Compressed Payload or Uncompressed Payload.

See also
compress_packet, CLIENT_COMPRESS

Compressed Packet Header

TypeNameDescription
int<3> length of compressed payload raw packet length minus the size of the compressed packet header (7 bytes) itself.
int<1> compressed sequence id Sequence ID of the compressed packets, reset in the same way as the Protocol::Packet, but incremented independently
int<3> length of uncompressed payload Length of payload before compression

Compressed Payload

If the length of length of payload before compression is more than 0 the Compressed Packet Header is followed by the compressed payload.

Depending on which capability flags are set it uses the deflate algorithm as described in RFC 1951 and implemented in zlib or Zstandard.

When using zlib, the header of the compressed packet has the parameters of the uncompress() function in mind:

ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
const Bytef *source, uLong sourceLen));
repeated Source source
Definition: replication_asynchronous_connection_failover.proto:42

The payload can be anything from a piece of a MySQL Packet to several MySQL Packets. The client or server may bundle several MySQL packets, compress it and send it as one compressed packet.

Example: One MySQL Packet

A COM_QUERY for select "012345678901234567890123456789012345" without CLIENT_COMPRESS has a payload length of 46 bytes and looks like:

2e 00 00 00 03 73 65 6c 65 63 74 20 22 30 31 32 .....select "012
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 3456789012345678
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 9012345678901234
35 22 5"

With CLIENT_COMPRESS the packet is:

22 00 00 00 32 00 00 78 9c d3 63 60 60 60 2e 4e "...2..x..c```.N
cd 49 4d 2e 51 50 32 30 34 32 36 31 35 33 b7 b0 .IM.QP20426153..
c4 cd 52 02 00 0c d1 0a 6c ..R.....l
comp-lengthseq-iduncomp-lenCompressed Payload
22 00 000032 00 00compress("\x2e\x00\x00\x00\x03select ...")`

The compressed packet is 41 bytes long and splits into:

raw packet length -> 41
compressed payload length = 22 00 00 -> 34 (41 - 7)
sequence id = 00 -> 0
uncompressed payload length = 32 00 00 -> 50
bool length(const dd::Spatial_reference_system *srs, const Geometry *g1, double *length, bool *null) noexcept
Computes the length of linestrings and multilinestrings.
Definition: length.cc:76
long long sequence(UDF_INIT *initid, UDF_ARGS *args, unsigned char *, unsigned char *)
Definition: udf_example.cc:568

Example: Several MySQL Packets

Executing SELECT repeat("a", 50) results in uncompressed ProtocolText::Resultset like:

01 00 00 01 01 25 00 00 02 03 64 65 66 00 00 00 .....%....def...
0f 72 65 70 65 61 74 28 22 61 22 2c 20 35 30 29 .repeat("a", 50)
00 0c 08 00 32 00 00 00 fd 01 00 1f 00 00 05 00 ....2...........
00 03 fe 00 00 02 00 33 00 00 04 32 61 61 61 61 .......3...2aaaa
61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
61 61 61 61 61 61 61 61 61 61 61 61 61 61 05 00 aaaaaaaaaaaaaa..
00 05 fe 00 00 02 00 .......

which consists of 5 Protocol::Packet :

  • 01 00 00 01 01
  • 25 00 00 02 03 64 65 66 00 00 00 0f 72 65 70 65 61 74 28 22 61 22 2c 20 35 30 29 00 0c 08 00 32 00 00 00 fd 01 00 1f 00 00
  • 05 00 00 03 fe 00 00 02 00
  • 33 00 00 04 32 61 61 61 61 ...
  • 05 00 00 05 fe 00 00 02 00

If compression is enabled a compressed packet containing the compressed version of all 5 packets is sent to the client:

4a 00 00 01 77 00 00 78 9c 63 64 60 60 64 54 65 J...w..x.cd``dTe
60 60 62 4e 49 4d 63 60 60 e0 2f 4a 2d 48 4d 2c ``bNIMc``./J-HM,
d1 50 4a 54 d2 51 30 35 d0 64 e0 e1 60 30 02 8a .PJT.Q05.d..`0..
ff 65 64 90 67 60 60 65 60 60 fe 07 54 cc 60 cc .ed.g``e``..T.`.
c0 c0 62 94 48 32 00 ea 67 05 eb 07 00 8d f9 1c ..b.H2..g.......
64 d
#define d1
#define d0
Note
sending a MySQL Packet of the size 224-5 to 224-1 via compression leads to at least one extra compressed packet. If the uncompressed MySQL Packet is like
fe ff ff 03 ... -- length = 2^24-2, sequence id = 3
compressing it would result in the length of payload before compression in the Compressed Packet Header being:
length of mysql packet payload: 2^24-2
length of mysql packet header: 4
length of payload before compression: 2^24+2
Definition: instrumented_condition_variable.h:32
which can not be represented in one compressed packet. Instead two or more packets have to be sent.

Uncompressed Payload

For small packets it may be to costly to compress the packet:

Sending a SELECT 1 query as Uncompressed Payload to the server looks like:

0d 00 00 00 00 00 00 09 00 00 00 03 53 45 4c 45 ............SELE
43 54 20 31 CT 1

decodes into:

raw packet length -> 20
compressed payload length = 0d 00 00 -> 13 (20 - 7)
sequence id = 00 -> 0
uncompressed payload length = 00 00 00 -> uncompressed

... with the uncompressed payload starting right after the 7 byte header:

09 00 00 00 03 53 45 4c 45 43 54 20 31 -- SELECT 1
const std::string SELECT("SELECT")
Name of the static privileges.