16MB超のデータ送信時の複数Packet送信
以下はmysql-5.0.18/sql/net_serv.ccのmy_net_read関数をいろいろ端折って読みやすくしたもの(Compressの部分を割愛、および整形)
#define MAX_PACKET_LENGTH (256L*256L*256L-1) ulong my_net_read(NET *net) { ulong len,complen; len = my_real_read(net,&complen); if (len == MAX_PACKET_LENGTH) { /* First packet of a multi-packet. Concatenate the packets */ ulong save_pos = net->where_b; ulong total_length=0; do { net->where_b += len; total_length += len; len = my_real_read(net,&complen); } while (len == MAX_PACKET_LENGTH); if (len != packet_error) len+= total_length; net->where_b = save_pos; } net->read_pos = net->buff + net->where_b; if (len != packet_error) net->read_pos[len]=0; /* Safeguard for mysql_use_result */ return len; }
my_real_read関数に委譲して、読み込んだサイズがMAX_PACKET_LENGTH(=16MB-1B)であった場合には,連続した次のPacketがあるものと判断してWhile文で終わるまでmy_real_read関数を呼びつづけて全ての送信データを読む.
一方Connector/J 5.1.0のMysqlIO.javaのsend(Buffer,int)メソッドでは
protected int maxThreeBytes = 255 * 255 * 255; ---- if ((this.serverMajorVersion >= 4) && (packetLen >= this.maxThreeBytes)) { sendSplitPackets(packet); } else {
ジャスト16MBであった場合に複数のPacketとして送信する.
Packet分割の謎はこれで十分だと思う.実験でも確認したけれど.