MySQL8.0のデバッグビルドをわりと詳しく書いてみる
MySQLのデバッグビルドをやってみたので、その方法をまとめました。
参考になるブログなどは少なく、書いてある内容も暗黙知の部分が多く自分にはわからなかったので公式のドキュメントを読みながら進めました。
英語のドキュメントではありますが、わりと読めます。そしてGoogle翻訳つよい。ありがとう。
デバッグビルドしてVSCodeでデバッガーを動かすところまでの手順を紹介します。
環境
UbuntuとmacOSの両方で検証した。
基本的に同じ手順でできる。
Xcodeを使う場合はオプションで指定することでできる。
macOSはCatalina 10.15.6、Ubuntuは 18.04 20.04 でビルドが成功した。
事前準備
macはHomebrewとXcodeをインストールする。brewで必要なライブラリはインストールできる。 Linuxはaptを使ってインストールできる。
ビルドに必要なライブラリなど
ビルドに必要なライブラリはリファレンスマニュアルに記載がある。
MySQL :: MySQL 8.0 Reference Manual :: 2.9.2 Source Installation Prerequisites
- CMake
- GNU make 3.75 or higher.
- GCC 5.3
- OpenSSL 1.0.1 or higher
- The ncurses library
- Perl
- bison 2.1 or higher
これらのライブラリが必要になるので事前にインストールする。
- g++
- pkg-config
これらも特に記載がないが必要だった。
ncurses はそういう名前のライブラリをインストールするのではなく、コマンド群(ツール群)のようだ。以下のコマンドが使えればOK。UbuntuにもmacOSにも標準で入っているようだ。
captoinfo
, a termcap conversion toolclear
, utility for clearing the screeninfocmp
, the terminfo decompilertabs
, set tabs on a terminaltic
, the terminfo compilertoe
, list (table of) terminfo entriestput
, utility for retrieving terminal capabilities in shell scriptstset
, to initialize the terminal
インストールする
Ubuntuではaptを使ってインストールする。
apt update apt upgrade apt install cmake make gcc g++ openssl bison pkg-config
macOSの場合はXcodeをインストールすればCコンパイラはインストールされる。
gcc --version
やg++ --version
を実行すればXcodeのものが使われているのが確認できる。
他はbrewでインストールできる。
brew install cmake make openssl bison pkg-config
ソースコードを取得する
git clone --depth 1 https://github.com/mysql/mysql-server.git
すべてをクローンすると時間がかかる。最新のものだけでいい場合は --depth
オプションを使うと速い。
デバッグビルドする
git clone
が終わるとmysql-server/
ディレクトリが作られるのでソースコードのディレクトリに移動する。
cd mysql-server
ビルド用のディレクトリ bld/
を作成しそこで作業を行う。
mkdir bld cd bld
以降、bld/
ディレクトリでコマンド操作を行う。
CMake
CMakeのオプションはこちら。
MySQL :: MySQL 8.0 Reference Manual :: 2.9.7 MySQL Source-Configuration Options
cmakeする時にオプションでデバッグを指定することで、ビルド構成がデバッグ用となる。なのでデバッグビルドをするにはここのオプションが大事。
デバッグビルドするには -DWITH_DEBUG=ON
を指定すればよい。ほか DCMAKE_BUILD_TYPE=Debug
とすることでもデバッグビルドになる。
- DCMAKE_BUILD_TYPE=type
- Debug: Disable optimizations and generate debugging information. This build type is also used if the WITH_DEBUG option is enabled. That is, -DWITH_DEBUG=1 has the same effect as -DCMAKE_BUILD_TYPE=Debug.
デバッグ:最適化を無効にし、デバッグ情報を生成します。このビルドタイプは、WITH_DEBUGオプションが有効な場合にも使用されます。つまり、-DWITH_DEBUG = 1は-DCMAKE_BUILD_TYPE = Debugと同じ効果があります。 https://dev.mysql.com/doc/refman/8.0/en/source-configuration-options.html#option_cmake_cmake_build_type
また、Boostライブラリが必要なので -DDOWNLOAD_BOOST
-DWITH_BOOST
オプションを使って、自動ダウンロードと保存先を指定する。
$ cmake .. \ -DWITH_DEBUG=ON \ -DDOWNLOAD_BOOST=ON \ -DWITH_BOOST=../boost
bool型のオプションしてはON/OFF でも 1/0 でも良い。
Xcodeを使うには
Xcode を使う場合は -G Xcode
を追加すると、Xcode用にCMakeされる。その後 make
の代わりに xcodebuild
を実行するとXcodeでビルドされる。bld
ディレクトリを指定してXcodeを起動するとGUIでデバッグなどできそうな感じだったが、使い方がわからなかった。
エラーが出る時は
エラーの場合はメッセージが詳しく出るし、ライブラリが不足している場合はインストールする方法も表示されるので、メッセージをちゃんと読めば対応できるはず。英語に臆するな。
その後はCMakeのキャッシュを削除してからもう一度 cmake
しよう
make clean rm CMakeCache.txt
Make
Makeでデバッグビルドする。
make -j 8 || make -j 6 || make -j 4 || make
-j
オプションで並列ビルドができる。指定するのは並列数。マシンリソースによっては途中でエラーが出てしまう。もう一度 make
すれば続きをビルドしてくれるので、並列数を徐々に減らしながら make を続ける。
makeが完了すると bin/
ディレクトリにバイナリーが出力される。
ls bin base64_test ibd2sdi mysql_config_editor mysqlpump perror protoc basic-t innochecksum mysql_secure_installation mysqlrouter pfs-t protoc-3.11.4 bug25714 libmysql_api_test mysql_server_mock mysqlrouter_keyring pfs_account-oom-t range_check_err comp_client_err lz4_decompress mysql_ssl_rsa_setup mysqlrouter_passwd pfs_connect_attr-t rest_cli comp_err mf_iocache_test mysql_tzinfo_to_sql mysqlrouter_plugin_info pfs_host-oom-t simple-t comp_sql my_print_defaults mysql_upgrade mysqlshow pfs_instr-oom-t skip-t conf_to_src myisam_ftdump mysqladmin mysqlslap pfs_instr-t skip_all-t gen_keyword_list myisamchk mysqlbinlog mysqltest pfs_instr_class-oom-t thr_lock gen_lex_hash myisamlog mysqlcheck mysqltest_safe_process pfs_instr_class-t todo-t gen_lex_token myisampack mysqld mysqlxtest pfs_misc-t uca9dump hp_test1 mysql mysqldump mytime_client-t pfs_noop-t xprotocol_plugin hp_test2 mysql_client_test mysqlimport no_plan-t pfs_user-oom-t zlib_decompress
MySQLサーバーを動かす
データベースの初期化
MySQLサーバーを動かすためにはデータベースファイルの初期化が必要。
デバッグビルドされた mysqld
を使ってデータベースファイルの初期化を行う。
bin/mysqld --initialize --basedir=$(pwd) --datadir=$(pwd)/data
この時標準出力にMySQLの管理者パスワードが出力されるので記録しておく。
[Note] [MY-010454] [Server] A temporary password is generated for root@localhost: o*w5h=lh?F+E
--basedir
--datadir
を指定しない場合はビルドディレクトリがデフォルトのbasedirになるようだ。
なので、上記の場合は指定があってもなくても結果は同じになった。
サーバーの起動
MySQLサーバーを起動するには mysqld
を実行する。
bin/mysqld
でMySQLサーバー起動できる。一般的にはMySQLのオプションを指定するために my.cnf
を使うことが多い。
以下のように my.cnf
を用意する。ディレクトリはどこでも良いが今回は bld/
に設置する。
[mysqld] basedir=/Users/masayuki14/workspace/mysql-server/bld datadir=/Users/masayuki14/workspace/mysql-server/bld/data
--defaults-file
オプションを使って my.cnf
を指定してMySQLサーバーを起動する。
bin/mysqld --defaults-file=./my.cnf
mysqlクライアントから接続
サーバーを起動したら別ターミナルを開いてMySQLクライアントからサーバーに接続する。
bin/mysql -u root -p Enter password:
データベースの初期化時に出力された初期パスワードを使ってログインする。 このパスワードは失効状態なので、パスワードを再設定する必要がある。 ALTER USER で変更する。
ALTER USER root@localhost IDENTIFIED BY 'MySQL8.0';
この時、デフォルトのポリシーでは英大文字小文字数字記号を含む8文字以上のパスワードにしないといけない。
サーバーの停止
mysqladmin コマンドを使うかMySQLサーバーに接続してSHUTDOWN コマンドを入力する。
bin/mysqladmin -u root shutdown -p Enter password:
/bin/mysql -u root -p Enter password: mysql> SHUTDOWN;
VSCodeのDebuggerを動かす
C/C++拡張をインストール
ソースコードがある mysql-server/
ディレクトリでVSCodeを開くとソースコードが読める。C/C++拡張のインストールをお勧めされるのでインストールする。これによってコードジャンプとかデバッガーとかが動くんだと思う。拡張機能で何が追加されるとかそのへんはよくわかってない。
デバッグビルドをする前後で型情報とかの表示も変わるようだ。
.gitignore を編集したほうがいい
ビルド用のディレクトリがGitの差分として認識されてしまうので、 .gitignore
を編集したほうがVSCodeに余計な負荷がかからなさそう。
bld/ boost/
を追加する。
デバッグ構成の追加
VSCodeの左サイドメニューからデバッガを選ぶ。三角と虫のアイコンのやつ。デフォルトではNode.jsのみが利用可能だが、C/C++拡張によりlldbが追加されている。 [構成の追加]からlldbを選んで追加すると launch.json
が作成されエディタに表示される。
launch.json
の一部を以下のように変えてMySQLサーバーが起動するようにする。
"program": "${workspaceFolder}/bld/bin/mysqld", "args": ["--defaults-file=${workspaceFolder}/bld/my.cnf"],
${workspaceFolder}
はソースコードを開いた mysql-server/
ディレクトリになるので、デバッグビルドしたmysqld
と引数の--defaults-file
を指定する。
デバッガを動かしてブレークポイントを設定
デバッガは三角の起動ボタンをクリックすると動き出す。起動するとデバッグコンソールにメッセージが表示されMySQLサーバーが立ち上がる。
試しに sql_parse.cc:1178
の do_command()
関数あたりにブレークポイントを設定する。
その後MySQLクライアントをつないで SELECT 1;
などを実行してみるとブレークポイントで処理が止まって変数の中身などが確認できる。
bin/mysql -u root -p Enter password: mysql> select 1; +---+ | 1 | +---+ | 1 | +---+ 1 row in set (0.00 sec)
こんな感じで確認できる。マウスポインターを変数に当てれば中身が見えるし、コールスタックなども確認できる。
正直なところさっぱりわからない。
これでデバッグビルドしてデバッガを動かす、の一連の作業はおわり。
デバッグビルドは何が嬉しいの?
mysqld
や mysql
のデバッグ関連のオプションはデバッグビルドされた場合に使えるようになります。mysqld
では --debug-sync-timeout=N
が使えるようになったり、
mysql
クライアントコマンドでは --debug
--debug-check
--debug-info
のオプションが使えるようにります。スタックトレースなども出力できますが見方がわからないので、どう役立てていいか良くわかりません。だれか教えて。
以前なにかのスライドでMySQLクライアントでトレース情報みたいなものを出しているのを見たことがあるけど、どうやってやるんだろう。勘違いかな。
ということで普通にMySQLを使う上では何も嬉しいことはないと思います。ソースコード読んでみたいとか、デバッガ動かしたい、みたいなマニアックな欲求がない場合はデバッグビルドに手を出すことはないでしょう。一部の情報によるとmysqldump
のソースコードは読みやすいらしいです。
きっかけ
デバッグビルドやってみようと思ったのは2年前でこのブログがきっかけでした。
当時これを見ながらやってみたところ、うまくいかず原因もわからずで放置していましたが、MySQL熱が最近すこし上がってきたのと時間の余裕ができたのでやってみました。 作業ログをGitHub Issue に残してあり速攻で諦めているのがよく分かります。
MySQL8.0 source build · Issue #15 · masayuki14/worklog · GitHub
今回はじっくりリファレンスマニュアルを読みながら進めたので時間がかかりましたが、いろんな情報が自分の中でつながっていく感覚というのは良いものです。 MySQLのデバッグビルドに興味がある方は試してみてください。
最後に、最近発売された MySQL徹底入門 第4版はいいぞ!