Skip to content

Commit 1d57f39

Browse files
authored
parseComBinlogDumpGTID: GTID payload is always 5.6 flavor (#17605)
Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com>
1 parent 55b6865 commit 1d57f39

File tree

4 files changed

+59
-11
lines changed

4 files changed

+59
-11
lines changed

go/mysql/binlog_dump.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,13 @@ func (c *Conn) parseComBinlogDumpGTID(data []byte) (logFile string, logPos uint6
7676
if !ok {
7777
return logFile, logPos, position, readPacketErr
7878
}
79-
if gtid := string(data[pos : pos+int(dataSize)]); gtid != "" {
80-
position, err = replication.DecodePosition(gtid)
79+
if gtidBytes := data[pos : pos+int(dataSize)]; len(gtidBytes) != 0 {
80+
gtid, err := replication.NewMysql56GTIDSetFromSIDBlock(gtidBytes)
8181
if err != nil {
82-
return logFile, logPos, position, err
82+
return logFile, logPos, position, vterrors.Wrapf(err, "error parsing GTID from BinlogDumpGTID packet")
8383
}
84+
// ComBinlogDumpGTID is a MySQL specific protocol. The GTID flavor is necessarily MySQL 56
85+
position = replication.Position{GTIDSet: gtid}
8486
}
8587
if flags2&BinlogDumpNonBlock != 0 {
8688
return logFile, logPos, position, io.EOF

go/mysql/flavor_mysql.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,10 @@ func (mysqlFlavor) sendBinlogDumpCommand(c *Conn, serverID uint32, binlogFilenam
218218
}
219219

220220
// Build the command.
221-
sidBlock := gtidSet.SIDBlock()
221+
var sidBlock []byte
222+
if gtidSet != nil {
223+
sidBlock = gtidSet.SIDBlock()
224+
}
222225
var flags2 uint16
223226
if binlogFilename != "" {
224227
flags2 |= BinlogThroughPosition

go/mysql/replication.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@ func (c *Conn) AnalyzeSemiSyncAckRequest(buf []byte) (strippedBuf []byte, ackReq
8181
// WriteComBinlogDumpGTID writes a ComBinlogDumpGTID command.
8282
// Only works with MySQL 5.6+ (and not MariaDB).
8383
// See http://dev.mysql.com/doc/internals/en/com-binlog-dump-gtid.html for syntax.
84-
func (c *Conn) WriteComBinlogDumpGTID(serverID uint32, binlogFilename string, binlogPos uint64, flags uint16, gtidSet []byte) error {
84+
// sidBlock must be the result of a gtidSet.SIDBlock() function.
85+
func (c *Conn) WriteComBinlogDumpGTID(serverID uint32, binlogFilename string, binlogPos uint64, flags uint16, sidBlock []byte) error {
8586
c.sequence = 0
8687
length := 1 + // ComBinlogDumpGTID
8788
2 + // flags
@@ -90,16 +91,16 @@ func (c *Conn) WriteComBinlogDumpGTID(serverID uint32, binlogFilename string, bi
9091
len(binlogFilename) + // binlog-filename
9192
8 + // binlog-pos
9293
4 + // data-size
93-
len(gtidSet) // data
94+
len(sidBlock) // data
9495
data, pos := c.startEphemeralPacketWithHeader(length)
9596
pos = writeByte(data, pos, ComBinlogDumpGTID) // nolint
9697
pos = writeUint16(data, pos, flags) // nolint
9798
pos = writeUint32(data, pos, serverID) // nolint
9899
pos = writeUint32(data, pos, uint32(len(binlogFilename))) // nolint
99100
pos = writeEOFString(data, pos, binlogFilename) // nolint
100101
pos = writeUint64(data, pos, binlogPos) // nolint
101-
pos = writeUint32(data, pos, uint32(len(gtidSet))) // nolint
102-
pos += copy(data[pos:], gtidSet) // nolint
102+
pos = writeUint32(data, pos, uint32(len(sidBlock))) // nolint
103+
pos += copy(data[pos:], sidBlock) // nolint
103104
if err := c.writeEphemeralPacket(); err != nil {
104105
return sqlerror.NewSQLErrorf(sqlerror.CRServerGone, sqlerror.SSUnknownSQLState, "%v", err)
105106
}

go/mysql/replication_test.go

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"github.com/stretchr/testify/assert"
2525
"github.com/stretchr/testify/require"
2626

27+
"vitess.io/vitess/go/mysql/replication"
2728
"vitess.io/vitess/go/test/utils"
2829

2930
binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata"
@@ -88,14 +89,50 @@ func TestComBinlogDumpGTID(t *testing.T) {
8889
cConn.Close()
8990
}()
9091

92+
t.Run("WriteComBinlogDumpGTIDEmptyGTID", func(t *testing.T) {
93+
// Write ComBinlogDumpGTID packet, read it, compare.
94+
var flags uint16 = 0x0d0e
95+
err := cConn.WriteComBinlogDumpGTID(0x01020304, "moofarm", 0x05060708090a0b0c, flags, []byte{})
96+
assert.NoError(t, err)
97+
data, err := sConn.ReadPacket()
98+
require.NoError(t, err, "sConn.ReadPacket - ComBinlogDumpGTID failed: %v", err)
99+
require.NotEmpty(t, data)
100+
require.EqualValues(t, data[0], ComBinlogDumpGTID)
101+
102+
expectedData := []byte{
103+
ComBinlogDumpGTID,
104+
0x0e, 0x0d, // flags
105+
0x04, 0x03, 0x02, 0x01, // server-id
106+
0x07, 0x00, 0x00, 0x00, // binlog-filename-len
107+
'm', 'o', 'o', 'f', 'a', 'r', 'm', // bilog-filename
108+
0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, // binlog-pos
109+
0x00, 0x00, 0x00, 0x00, // data-size is zero, no GTID payload
110+
}
111+
assert.Equal(t, expectedData, data)
112+
logFile, logPos, pos, err := sConn.parseComBinlogDumpGTID(data)
113+
require.NoError(t, err, "parseComBinlogDumpGTID failed: %v", err)
114+
assert.Equal(t, "moofarm", logFile)
115+
assert.Equal(t, uint64(0x05060708090a0b0c), logPos)
116+
assert.True(t, pos.IsZero())
117+
})
118+
119+
sConn.sequence = 0
120+
91121
t.Run("WriteComBinlogDumpGTID", func(t *testing.T) {
92122
// Write ComBinlogDumpGTID packet, read it, compare.
93123
var flags uint16 = 0x0d0e
94124
assert.Equal(t, flags, flags|BinlogThroughGTID)
95-
err := cConn.WriteComBinlogDumpGTID(0x01020304, "moofarm", 0x05060708090a0b0c, flags, []byte{0xfa, 0xfb})
125+
gtidSet, err := replication.ParseMysql56GTIDSet("16b1039f-22b6-11ed-b765-0a43f95f28a3:1-243")
126+
require.NoError(t, err)
127+
sidBlock := gtidSet.SIDBlock()
128+
assert.Len(t, sidBlock, 48)
129+
130+
err = cConn.WriteComBinlogDumpGTID(0x01020304, "moofarm", 0x05060708090a0b0c, flags, sidBlock)
96131
assert.NoError(t, err)
97132
data, err := sConn.ReadPacket()
98133
require.NoError(t, err, "sConn.ReadPacket - ComBinlogDumpGTID failed: %v", err)
134+
require.NotEmpty(t, data)
135+
require.EqualValues(t, data[0], ComBinlogDumpGTID)
99136

100137
expectedData := []byte{
101138
ComBinlogDumpGTID,
@@ -104,10 +141,15 @@ func TestComBinlogDumpGTID(t *testing.T) {
104141
0x07, 0x00, 0x00, 0x00, // binlog-filename-len
105142
'm', 'o', 'o', 'f', 'a', 'r', 'm', // bilog-filename
106143
0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, // binlog-pos
107-
0x02, 0x00, 0x00, 0x00, // data-size
108-
0xfa, 0xfb, // data
144+
0x30, 0x00, 0x00, 0x00, // data-size
109145
}
146+
expectedData = append(expectedData, sidBlock...) // data
110147
assert.Equal(t, expectedData, data)
148+
logFile, logPos, pos, err := sConn.parseComBinlogDumpGTID(data)
149+
require.NoError(t, err, "parseComBinlogDumpGTID failed: %v", err)
150+
assert.Equal(t, "moofarm", logFile)
151+
assert.Equal(t, uint64(0x05060708090a0b0c), logPos)
152+
assert.Equal(t, gtidSet, pos.GTIDSet)
111153
})
112154

113155
sConn.sequence = 0

0 commit comments

Comments
 (0)