diff --git a/Makefile b/Makefile index 480b6a874..90930f3b2 100644 --- a/Makefile +++ b/Makefile @@ -1,17 +1,18 @@ all: build GO111MODULE=on +MYSQL_VERSION ?= 8.0 +GO ?= go build: - go build -o bin/go-mysqlbinlog cmd/go-mysqlbinlog/main.go - go build -o bin/go-mysqldump cmd/go-mysqldump/main.go - go build -o bin/go-canal cmd/go-canal/main.go - go build -o bin/go-binlogparser cmd/go-binlogparser/main.go + ${GO} build -o bin/go-mysqlbinlog cmd/go-mysqlbinlog/main.go + ${GO} build -o bin/go-mysqldump cmd/go-mysqldump/main.go + ${GO} build -o bin/go-canal cmd/go-canal/main.go + ${GO} build -o bin/go-binlogparser cmd/go-binlogparser/main.go test: - go test --race -timeout 2m ./... + ${GO} test --race -timeout 2m ./... -MYSQL_VERSION ?= 8.0 test-local: docker run --rm -d --network=host --name go-mysql-server \ -e MYSQL_ALLOW_EMPTY_PASSWORD=true \ @@ -19,12 +20,12 @@ test-local: -v $${PWD}/docker/resources/replication.cnf:/etc/mysql/conf.d/replication.cnf \ mysql:$(MYSQL_VERSION) docker/resources/waitfor.sh 127.0.0.1 3306 \ - && go test -race -v -timeout 2m ./... + && ${GO} test -race -v -timeout 2m ./... docker stop go-mysql-server fmt: golangci-lint run --fix clean: - go clean -i ./... + ${GO} clean -i ./... @rm -rf ./bin diff --git a/replication/event.go b/replication/event.go index b9e13bf1a..6fb614f61 100644 --- a/replication/event.go +++ b/replication/event.go @@ -1,6 +1,7 @@ package replication import ( + "bytes" "encoding/binary" "encoding/hex" "fmt" @@ -145,9 +146,8 @@ func calcVersionProduct(server string) int { } type FormatDescriptionEvent struct { - Version uint16 - //len = 50 - ServerVersion []byte + Version uint16 + ServerVersion string CreateTimestamp uint32 EventHeaderLength uint8 EventTypeHeaderLengths []byte @@ -161,8 +161,8 @@ func (e *FormatDescriptionEvent) Decode(data []byte) error { e.Version = binary.LittleEndian.Uint16(data[pos:]) pos += 2 - e.ServerVersion = make([]byte, 50) - copy(e.ServerVersion, data[pos:]) + serverVersionRaw := make([]byte, 50) + copy(serverVersionRaw, data[pos:]) pos += 50 e.CreateTimestamp = binary.LittleEndian.Uint32(data[pos:]) @@ -175,13 +175,18 @@ func (e *FormatDescriptionEvent) Decode(data []byte) error { return errors.Errorf("invalid event header length %d, must 19", e.EventHeaderLength) } - server := string(e.ServerVersion) + serverVersionLength := bytes.Index(serverVersionRaw, []byte{0x0}) + if serverVersionLength < 0 { + e.ServerVersion = string(serverVersionRaw) + } else { + e.ServerVersion = string(serverVersionRaw[:serverVersionLength]) + } checksumProduct := checksumVersionProductMysql - if strings.Contains(strings.ToLower(server), "mariadb") { + if strings.Contains(strings.ToLower(e.ServerVersion), "mariadb") { checksumProduct = checksumVersionProductMariaDB } - if calcVersionProduct(string(e.ServerVersion)) >= checksumProduct { + if calcVersionProduct(e.ServerVersion) >= checksumProduct { // here, the last 5 bytes is 1 byte check sum alg type and 4 byte checksum if exists e.ChecksumAlgorithm = data[len(data)-5] e.EventTypeHeaderLengths = data[pos : len(data)-5] diff --git a/replication/parser_test.go b/replication/parser_test.go index d1774f8c7..165038109 100644 --- a/replication/parser_test.go +++ b/replication/parser_test.go @@ -12,7 +12,7 @@ func TestIndexOutOfRange(t *testing.T) { parser.format = &FormatDescriptionEvent{ Version: 0x4, - ServerVersion: []uint8{0x35, 0x2e, 0x36, 0x2e, 0x32, 0x30, 0x2d, 0x6c, 0x6f, 0x67, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, + ServerVersion: "8.0.11", CreateTimestamp: 0x0, EventHeaderLength: 0x13, EventTypeHeaderLengths: []uint8{0x38, 0xd, 0x0, 0x8, 0x0, 0x12, 0x0, 0x4, 0x4, 0x4, 0x4, 0x12, 0x0, 0x0, 0x5c, 0x0, 0x4, 0x1a, 0x8, 0x0, 0x0, 0x0, 0x8, 0x8, 0x8, 0x2, 0x0, 0x0, 0x0, 0xa, 0xa, 0xa, 0x19, 0x19, 0x0, 0x12, 0x34, 0x0, 0xa, 0x28, 0x0}, @@ -48,7 +48,7 @@ func TestParseEvent(t *testing.T) { parser := NewBinlogParser() parser.format = &FormatDescriptionEvent{ Version: 0x4, - ServerVersion: []uint8{0x35, 0x2e, 0x36, 0x2e, 0x32, 0x30, 0x2d, 0x6c, 0x6f, 0x67, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, + ServerVersion: "8.0.11", CreateTimestamp: 0x0, EventHeaderLength: 0x13, EventTypeHeaderLengths: []uint8{0x38, 0xd, 0x0, 0x8, 0x0, 0x12, 0x0, 0x4, 0x4, 0x4, 0x4, 0x12, 0x0, 0x0, 0x5c, 0x0, 0x4, 0x1a, 0x8, 0x0, 0x0, 0x0, 0x8, 0x8, 0x8, 0x2, 0x0, 0x0, 0x0, 0xa, 0xa, 0xa, 0x19, 0x19, 0x0, 0x12, 0x34, 0x0, 0xa, 0x28, 0x0},