承接上文,深入剖析 Slave IO 連接建立後的兩個關鍵命令:註冊從庫身份、請求主庫推送 binlog。
1 byte 0x15 (COM_REGISTER_SLAVE)
4 uint32 server_id (slave 的 server-id,my.cnf 配置)
1 byte slave_hostname_len
N string slave_hostname
1 byte slave_user_len
N string slave_user (主庫授權的 replication 用戶)
1 byte slave_password_len
N string slave_password
2 uint16 slave_mysql_port
4 uint32 replication_rank (已廢棄,固定 0)
4 uint32 master_id (固定 0,由主庫填充)
// sql/slave.cc: register_slave_on_master()
int4store(pos, server_id); pos += 4;
pos = net_store_data(pos, report_host, report_host_len);
pos = net_store_data(pos, report_user, report_user_len);
pos = net_store_data(pos, report_password, report_password_len);
int2store(pos, report_port); pos += 2;
int4store(pos, 0); pos += 4; // rpl_recovery_rank
int4store(pos, 0); pos += 4; // master_id
simple_command(mysql, COM_REGISTER_SLAVE, buffer, length, 1);
net_store_data 先寫長度(1 字節),再寫內容。simple_command 封裝 net_write_command 添加協議頭(長度 3B + 序號 1B)。
| 命令 | 值 | 適用場景 | 包結構 |
|---|---|---|---|
| COM_BINLOG_DUMP | 0x12 | 傳統位置基礎複製(主流) | pos(4) + flags(2) + server_id(4) + filename(EOF) |
| COM_BINLOG_DUMP_GTID | 0x1E | GTID 模式複製 (5.6.5+) | flags(2) + server_id(4) + sid_map + gtid_set |
1 byte 0x12 (COM_BINLOG_DUMP)
4 uint32 binlog_pos (請求起始位置,mi->get_master_log_pos())
2 uint16 flags (通常 BINLOG_DUMP_NON_BLOCK = 0x01)
4 uint32 server_id (slave 的 server-id)
N string[EOF] binlog_filename (mi->get_master_log_name(), 如 mysql-bin.000001)
// sql/slave.cc: request_dump()
int4store(ptr, mi->get_master_log_pos()); ptr += 4;
int2store(ptr, binlog_flags); ptr += 2; // BINLOG_DUMP_NON_BLOCK
int4store(ptr, server_id); ptr += 4;
memcpy(ptr, mi->get_master_log_name(), BINLOG_NAME_INFO_SIZE); // 通常 60 字節
simple_command(mysql, COM_BINLOG_DUMP, buffer, length, 1);
所有命令包統一前綴:
3 byte payload_length (小端序,最大 16MB-1)
1 byte sequence_id (從 0 遞增,重置於新命令)
N byte payload (命令碼 + 參數)
超過 16MB 自動分片:每片 16MB,序號遞增,最後一片長度 < 16MB。
| 標志 | 值 | 含義 |
|---|---|---|
| BINLOG_DUMP_NON_BLOCK | 0x01 | 非阻塞模式:主庫無新 binlog 時立即返回 EOF 包,不等待 |
| CLIENT_PROTOCOL_41 | 0x00000200 | 4.1 協議,認證響應包必須設置 |
| CLIENT_PLUGIN_AUTH | 0x00080000 | 支持插件認證,包含 plugin_name |
| CLIENT_CONNECT_WITH_DB | 0x00000008 | 認證包攜帶默認庫 |
# 抓取 3306 端口協議包
tcpdump -i eth0 -nn -s 0 -X port 3306 -w mysql_repl.pcap
# Wireshark 過濾
mysql.protocol.cmd == 0x12 # Binlog Dump
mysql.protocol.cmd == 0x15 # Register Slave
理解註冊與 Dump 協議,可實現:自定義複製代理、binlog 解析工具、異構同步中間件、複製延遲監控探針。