Skip to content

Commit

Permalink
server: support compressed MySQL protocol
Browse files Browse the repository at this point in the history
  • Loading branch information
dveeden committed May 3, 2023
1 parent 7eff8ce commit 6b44c45
Show file tree
Hide file tree
Showing 6 changed files with 230 additions and 32 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ require (
github.com/jingyugao/rowserrcheck v1.1.1
github.com/joho/sqltocsv v0.0.0-20210428211105-a6d6801d59df
github.com/kisielk/errcheck v1.6.3
github.com/klauspost/compress v1.15.13
github.com/klauspost/compress v1.16.5
github.com/kyoh86/exportloopref v0.1.11
github.com/lestrrat-go/jwx/v2 v2.0.6
github.com/mgechev/revive v1.3.1
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -604,8 +604,8 @@ github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0
github.com/klauspost/compress v1.10.5/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.12.2/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
github.com/klauspost/compress v1.15.13 h1:NFn1Wr8cfnenSJSA46lLq4wHCcBzKTSjnBIexDMMOV0=
github.com/klauspost/compress v1.15.13/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM=
github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI=
github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/cpuid v1.3.1 h1:5JNjFYYQrZeKRJ0734q51WCEEn2huer72Dc7K+R/b6s=
github.com/klauspost/cpuid v1.3.1/go.mod h1:bYW4mA6ZgKPob1/Dlai2LviZJO7KGI3uoWLd42rAQw4=
Expand Down
15 changes: 12 additions & 3 deletions parser/mysql/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ const (
ClientLongFlag // CLIENT_LONG_FLAG
ClientConnectWithDB // CLIENT_CONNECT_WITH_DB
ClientNoSchema // CLIENT_NO_SCHEMA
ClientCompress // CLIENT_COMPRESS, Not supported: https://github.com/pingcap/tidb/issues/22605
ClientCompress // CLIENT_COMPRESS
ClientODBC // CLIENT_ODBC
ClientLocalFiles // CLIENT_LOCAL_FILES
ClientIgnoreSpace // CLIENT_IGNORE_SPACE
Expand All @@ -160,8 +160,8 @@ const (
ClientHandleExpiredPasswords // CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS, Not supported: https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_basic_expired_passwords.html
ClientSessionTrack // CLIENT_SESSION_TRACK, Not supported: https://github.com/pingcap/tidb/issues/35309
ClientDeprecateEOF // CLIENT_DEPRECATE_EOF
// 1 << 25 == CLIENT_OPTIONAL_RESULTSET_METADATA
// 1 << 26 == CLIENT_ZSTD_COMPRESSION_ALGORITHM
ClientOptionalResultsetMetadata // CLIENT_OPTIONAL_RESULTSET_METADATA, Not supported: https://dev.mysql.com/doc/c-api/8.0/en/c-api-optional-metadata.html
ClientZstdCompressionAlgorithm // CLIENT_ZSTD_COMPRESSION_ALGORITHM
// 1 << 27 == CLIENT_QUERY_ATTRIBUTES
// 1 << 28 == MULTI_FACTOR_AUTHENTICATION
// 1 << 29 == CLIENT_CAPABILITY_EXTENSION
Expand Down Expand Up @@ -629,3 +629,12 @@ const (
CursorTypeForUpdate
CursorTypeScrollable
)

const (
// CompressionNone is no compression in use
CompressionNone = iota
// CompressionZlib is zlib/deflate
CompressionZlib
// CompressionZstd is Facebook's Zstandard
CompressionZstd
)
21 changes: 19 additions & 2 deletions server/conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ import (
"time"
"unsafe"

"github.com/klauspost/compress/zstd"
"github.com/pingcap/errors"
"github.com/pingcap/failpoint"
"github.com/pingcap/tidb/config"
Expand Down Expand Up @@ -279,6 +280,14 @@ func (cc *clientConn) handshake(ctx context.Context) error {
logutil.Logger(ctx).Debug("flush response to client failed", zap.Error(err))
return err
}

// With mysql --compression-algorithms=zlib,zstd both flags are set, the result is Zlib
if cc.capability&mysql.ClientCompress > 0 {
cc.pkt.SetCompressionAlgorithm(mysql.CompressionZlib)
} else if cc.capability&mysql.ClientZstdCompressionAlgorithm > 0 {
cc.pkt.SetCompressionAlgorithm(mysql.CompressionZstd)
}

return err
}

Expand Down Expand Up @@ -414,6 +423,7 @@ type handshakeResponse41 struct {
Auth []byte
AuthPlugin string
Attrs map[string]string
ZstdLevel zstd.EncoderLevel
}

// parseHandshakeResponseHeader parses the common header of SSLRequest and HandshakeResponse41.
Expand Down Expand Up @@ -502,18 +512,23 @@ func parseHandshakeResponseBody(ctx context.Context, packet *handshakeResponse41
// Defend some ill-formated packet, connection attribute is not important and can be ignored.
return nil
}
if num, null, off := parseLengthEncodedInt(data[offset:]); !null {
offset += off
if num, null, intOff := parseLengthEncodedInt(data[offset:]); !null {
offset += intOff // Length of variable length encoded integer itself in bytes
row := data[offset : offset+int(num)]
attrs, err := parseAttrs(row)
if err != nil {
logutil.Logger(ctx).Warn("parse attrs failed", zap.Error(err))
return nil
}
packet.Attrs = attrs
offset += int(num) // Length of attributes
}
}

if packet.Capability&mysql.ClientZstdCompressionAlgorithm > 0 {
packet.ZstdLevel = zstd.EncoderLevelFromZstd(int(data[offset]))
}

return nil
}

Expand Down Expand Up @@ -625,6 +640,7 @@ func (cc *clientConn) readOptionalSSLRequestAndHandshakeResponse(ctx context.Con
cc.dbname = resp.DBName
cc.collation = resp.Collation
cc.attrs = resp.Attrs
cc.pkt.zstdLevel = resp.ZstdLevel

err = cc.handleAuthPlugin(ctx, &resp)
if err != nil {
Expand Down Expand Up @@ -1163,6 +1179,7 @@ func (cc *clientConn) Run(ctx context.Context) {
}
cc.addMetrics(data[0], startTime, err)
cc.pkt.sequence = 0
cc.pkt.compressedSequence = 0
}
}

Expand Down
Loading

0 comments on commit 6b44c45

Please sign in to comment.