tombo2-progress’s diary

できるだけ毎日1時間を切り取ってここに晒す。誤字脱字気にしない。日本語が崩壊するのも気にしない。最終的にまとめて本ブログに書く

引き続きpacketについて

  • int<3> payload_length
  • int<1> sequence_id
  • string payload [len=payload_length]

packetの説明にある型にかんしてはここ https://dev.mysql.com/doc/internals/en/describing-packets.html

sequence_idについてはhttps://dev.mysql.com/doc/internals/en/sequence-id.htmlでパケットごとに1加算、wrap aroundする。 Command phaseで新しいコマンドが始まったら0にリセットされるとある。

ドキュメントの章立て良くない気がするんだけど、Connection Lifecycleのところで、2つのphaseに分けれられるように書かれている。

Connection Phase

https://dev.mysql.com/doc/internals/en/connection-phase.html ここの簡易状態遷移図がわかりやすい

実際のパケットの中身はここ

https://dev.mysql.com/doc/internals/en/connection-phase-packets.html

Command Phase

https://dev.mysql.com/doc/internals/en/command-phase.html

クライアントはsequence_idを[00]で送る。 コマンドフェーズであれば、payloadの先頭のバイトでコマンドのタイプが分かる。

prepared statement, stored procedureもそれぞれcommand phaseでのコマンドタイプで判断できそうだけど、command phase, connection phaseをどうやって区別するかがわからない。connectionの途中や、command phaseからパケットを見ることもあり得るのでどうしたものか?

パケットのキャプチャをしているツールを参考にしてみる。

tools

  • tshark

tshark -i en0 -d tcp.port==3306,mysql -T fields -e mysql.query 'port 3306'

こんな感じでmysql.queryを持ってこれた。簡単。com_queryでないパケットでも1行分の空行が出るので、それだけ無視してあげて、あとはqueryベースでフィルタすることだけ考えれば良い。