Skip to content

Commit 0f9a46d

Browse files
committedNov 20, 2024·
replication: Handle empty previous gtid
From `mysqlbinlog --read-from-remote-server --hexdump ...`: ``` # at 127 #241120 10:36:02 server id 1 end_log_pos 158 CRC32 0xa7f45443 # Position Timestamp Type Source ID Size Source Pos Flags # 0000007f 82 ad 3d 67 23 01 00 00 00 1f 00 00 00 9e 00 00 00 80 00 # 00000092 01 00 00 00 00 00 00 01 43 54 f4 a7 |........CT..| # Previous-GTIDs # [empty] ``` So the `uuidCount` is 1 (from `01 00 00 00 00 00 00 01`) Note that `43 54 f4 a7` is the `CRC32 0xa7f45443` checksum. Without this, this happens: ``` [2024/11/20 10:37:40] [error] binlogstreamer.go:78 close sync with err: Err: runtime error: slice bounds out of range [:24] with capacity 12 Stack: goroutine 8 [running]: github.com/go-mysql-org/go-mysql/mysql.Pstack(...) /home/dvaneeden/go/pkg/mod/github.com/go-mysql-org/go-mysql@v1.10.0/mysql/util.go:25 github.com/go-mysql-org/go-mysql/replication.(*BinlogSyncer).onStream.func1() /home/dvaneeden/go/pkg/mod/github.com/go-mysql-org/go-mysql@v1.10.0/replication/binlogsyncer.go:730 +0x7e panic({0x834dc0?, 0xc0000285e8?}) /usr/lib/golang/src/runtime/panic.go:785 +0x132 github.com/go-mysql-org/go-mysql/replication.(*PreviousGTIDsEvent).Decode(0xc0000228a0, {0xc00002e8f4, 0x0?, 0xc}) /home/dvaneeden/go/pkg/mod/github.com/go-mysql-org/go-mysql@v1.10.0/replication/event.go:239 +0x4ea github.com/go-mysql-org/go-mysql/replication.(*BinlogParser).parseEvent(0xc0000d2190, 0xc0000285d0, {0xc00002e8f4, 0xc, 0xc}, {0xc00002e8e1?, 0xc00008de58?, 0x407f47?}) /home/dvaneeden/go/pkg/mod/github.com/go-mysql-org/go-mysql@v1.10.0/replication/parser.go:328 +0x59f github.com/go-mysql-org/go-mysql/replication.(*BinlogParser).Parse(0xc0000d2190, {0xc00002e8e1, 0x1f, 0x1f}) ``` This is because it expects 8 bytes for the `uuidCount` an 16 bytes for the UUID, making 24 in total. But there is only 8 for the `uuidCount` and 4 for the checksum, resulting in a capacity of 12.
1 parent 95109e7 commit 0f9a46d

File tree

1 file changed

+10
-0
lines changed

1 file changed

+10
-0
lines changed
 

‎replication/event.go

+10
Original file line numberDiff line numberDiff line change
@@ -234,8 +234,18 @@ func (e *PreviousGTIDsEvent) Decode(data []byte) error {
234234
uuidCount := binary.LittleEndian.Uint16(data[pos : pos+8])
235235
pos += 8
236236

237+
if uuidCount <= 1 {
238+
if len(data) == 8 {
239+
return nil
240+
}
241+
fmt.Errorf("uuidCount %d doesn't match data length %d", uuidCount, len(data))
242+
}
243+
237244
previousGTIDSets := make([]string, uuidCount)
238245
for i := range previousGTIDSets {
246+
if len(data) < pos+16 {
247+
return fmt.Errorf("Failed to decode UUID")
248+
}
239249
uuid := e.decodeUuid(data[pos : pos+16])
240250
pos += 16
241251
sliceCount := binary.LittleEndian.Uint16(data[pos : pos+8])

0 commit comments

Comments
 (0)