それが僕には楽しかったんです。

僕と MySQL と時々 MariaDB

CLion を使って MySQL のビルド&デバッグを行う

はじめに

どうも、4連休のほとんどを MySQLデバッグで溶かしそうなけんつです。

MySQL を触っていると、SQL の実行結果が謎な時とか稀によくあると思っているのだがそのとき気軽に MySQLデバッグしたくないですか?したいですよね。という気持ちでこの記事を書いています。
というわけでやります。

対象バージョンは MySQL 8.0.21。
Clang, CMake, make, lldb などが入っている前提で話を進めます。
macOS Catalina も前提。おそらく Linux とかなら Clang ではなく gcc になるはずだが、CLion がよしなにやってくれるはず。

MySQL のビルド&デバッグをする

ソースコードを持ってきて展開する

まずはここから、github からでも wget でもどちらでもよい。
boost が同梱しているか、していないかあたりで cmake のオプションが変わってくるので注意。
そのあたりを考えるのが面倒なのでいつも boost 同梱版を wget で持ってきている。

$ wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-boost-8.0.21.tar.gz
$ tar xzvf mysql-boost-8.0.21.tar.gz

CLion で CMake を実行する

ここからは CLion 上の話になっていく。
まずは mysql-server をビルドするところから。気軽に Build から選択しても CMake Project がないと言われるので
Preferences -> Build, Execution, Deployment -> CMake からビルド時の設定を変更する。
以下の二つを設定した段階で、Apply を押すと自動的に CMake が走ってくれる。

CMake Options

CMake options を以下のように修正している。

-DWITH_DEBUG=1 -DWITH_BOOST=./boost -DFORCE_INSOURCE_BUILD=1

ここで大事なのは WITH_DEBUG オプションが有効になっていること。
これがないとデバッグモードで mysqld を起動できない。

Generation path

これはカレントディレクトリを指定しておく。

ビルド

ここは少し面倒で、初回起動時に初期化する必要があるのでターミナルで make を実行する。

mysql-8.0.20 $ make -j7

これがまたややしばらくかかるので待つ。

これが終わったら一度 mysqld を初期化する

mysql-8.0.20 $ ./bin/mysqld --initialize

このとき、標準I/O の最後の方に root ユーザのパスワードが書かれているので忘れずに確認する。

デバッグ

Preferences -> Build, Execution, Deployment -> Toolchains から CMake, LLDB などのバージョンを必要に応じて確認しておく。
バンドルされているっぽいのでこのあたりは自動的に設定されている場合が多い。

デバッグ設定の変更

Run -> EditConfigurations -> CMake Application を選び、そこから mysqld を選択して Apply する。

ブレークポイントを設定

sql/sql_parse.cc の 1178 行目にある do_command に設定すると、大体の処理はここを通るのでわかりやすい。

実行する

Run -> Debug を実行する。
このとき make が走り、コードに修正を加えたなら再度ビルドされる。

ビルド完了後に mysqld が実行されるが、Console が真っ赤に染まっても正常なログなので無視する。

mysql クライアントから接続する

すでに mysql コマンドがある場合はそれでも行けるが、なんらかの理由で接続できない場合は bin/mysql を利用することで接続できる。
そして SELECT 1; とか実行すればブレークポイントで止まるはず。

おわりに

これで MySQL の内部処理がみやすくなる。(はず
ビルドをターミナルから行うところが少しイケてない。

余談

VSCode でも可能で、こちらの記事が参考になる。
labs.gree.jp