max_allowed_packet、巨大なデータをサーバへ送る場合

現在のMySQLプロトコル仕様により定められた,クライアントからサーバへ送ることができるPacketの最大サイズは16MBです(パケットの長さをサーバへ伝えるためのフィールドが24bitであるため).

しかしデフォルトでは,MySQLサーバ側が受信を許可するPacketの最大サイズは1MBとなっています.この設定値はサーバ変数max_allowed_packetを見ることで確認できます.

mysql> show variables like 'max_allowed_packet';
+--------------------+---------+
| Variable_name      | Value   |
+--------------------+---------+
| max_allowed_packet | 1048576 |
+--------------------+---------+

受信を許可するPacketの最大サイズを変更するためには,my.cnfに以下のように記述します.

[mysqld]
max_allowed_packet=16MB

サーバを再起動すると設定が反映されます.

mysql> show variables like 'max_allowed_packet';
+--------------------+----------+
| Variable_name      | Value    |
+--------------------+----------+
| max_allowed_packet | 16776192 |
+--------------------+----------+
1 row in set (0.00 sec)

ただしmy.cnfでmax_allowed_packet=20GBのような極端な値を設定しても

mysql> show variables like 'max_allowed_packet';
+--------------------+------------+
| Variable_name      | Value      |
+--------------------+------------+
| max_allowed_packet | 1073740800 |
+--------------------+------------+
1 row in set (0.00 sec)

1GBまでしか設定できないようです.(といっても16MB以上の設定は意味がないような気がします.)

例えば10GBの動画ファイルをMySQLサーバに格納したいというような場合,どのような動きになってくるでしょうか.使用するクライアント(コネクタ製品)が10GBのデータを適切に扱えるのであれば,恐らく16MBのいくつものPacketに分割されてサーバ側へ送られるのではないかと思います.Prepared Statementを使用する場合は,この16MBのパケットを送信する回数が無制限であるため10GBのデータを全てサーバ側へ送ることが可能だと思います.しかしPrepared Statementを用いなかった場合には,1度のクエリ実行で送ることのできるPacketの最大数256(各Packetのシーケンス番号を記述するフィールドはMySQLプロトコルでは8bitとなっている)であるために,全体で4GB(=16MB * 256)を超えるデータ送信は行えません.

(↑↑↑ 推測込み、若干自信なし)



とまあ考えてみた.ちょっと実験やってみないと自信無し.まあとりあえずPreparedStatementの各パラメータ設定用のPacketにはシーケンス番号というのが無いってことでOKなのかな? ってやっぱり自信無しww

で,気になる本命はC/Jが50MBのデータ送信をアプリから要求された場合に,ちゃんと複数回Packetを送ってくれるのかどうかだ.ざっと目を通した感じ,そのためにfor文やらwhile文で繰り返し送信する個所が見当たらなかったので(^^;; 見落としであって欲しい.