Description:
When using semi-sync, master sometimes reports the following message in error log:
```
[ERROR] Read semi-sync reply magic number error
[ERROR] mysqld: Got timeout reading communication packets
[ERROR] mysqld: Got packets out of order
[ERROR] mysqld: Got a packet bigger than 'max_allowed_packet' bytes
```
So we track the code of semi-sync, and find the master not handle ACK packet correctly:
plugin/semisync/semisync_master_ack_receiver.cc
```
void Ack_receiver::run() {
do {
net_clear(&net, 0);
len = my_net_read(&net);
if (likely(len != packet_error))
repl_semisync->reportReplyPacket(slave_obj.server_id, net.read_pos,
len);
else if (net.last_errno == ER_NET_READ_ERROR)
listener.clear_socket_info(i);
} while (net.vio->has_data(net.vio) && m_status == ST_UP);
}
```
When the ack packet is split into 2 TCP segments, and if the time interval between the 2 TCP segment is sent to master exceed 1ms, the my_net_read will read part bytes of the ACK packet, and return packet_error caused by wait timeout, leaving the rest bytes of ACK packet alone. So in the new next round, my_net_read will start from the rest bytes of the last ACK packet.
How to repeat:
Hard to repeat.
Suggested fix:
Allocate Net for each Slave, and keep the bytes it has read. net_clear only when read the full ACK packet.