Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

replication: Handle empty previous gtid #951

Closed
wants to merge 5 commits into from

Conversation

dveeden
Copy link
Collaborator

@dveeden dveeden commented Nov 20, 2024

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]

This event is from MySQL 9.1.0

mysql-9.1.0> show binlog events from 127 limit 1;
+---------------+-----+----------------+-----------+-------------+------+
| Log_name      | Pos | Event_type     | Server_id | End_log_pos | Info |
+---------------+-----+----------------+-----------+-------------+------+
| binlog.000001 | 127 | Previous_gtids |         1 |         158 |      |
+---------------+-----+----------------+-----------+-------------+------+
1 row in set (0.00 sec)

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/[email protected]/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/[email protected]/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/[email protected]/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/[email protected]/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.

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/[email protected]/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/[email protected]/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/[email protected]/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/[email protected]/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.
@dveeden
Copy link
Collaborator Author

dveeden commented Nov 20, 2024

This is with syncer.StartSyncGTID() and the gtidSet set to the last GTID processed by the MySQL server.

@dveeden dveeden marked this pull request as draft November 20, 2024 12:06
@dveeden dveeden closed this Nov 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant