主夫ときどきプログラマ

データベース、Webエンジニアリング、コミュニティ、etc

MySQL8.0のデバッグビルドをわりと詳しく書いてみる

MySQLデバッグビルドをやってみたので、その方法をまとめました。
参考になるブログなどは少なく、書いてある内容も暗黙知の部分が多く自分にはわからなかったので公式のドキュメントを読みながら進めました。
英語のドキュメントではありますが、わりと読めます。そしてGoogle翻訳つよい。ありがとう。 デバッグビルドしてVSCodeでデバッガーを動かすところまでの手順を紹介します。

環境

UbuntumacOSの両方で検証した。 基本的に同じ手順でできる。
Xcodeを使う場合はオプションで指定することでできる。

macOSはCatalina 10.15.6、Ubuntuは 18.04 20.04 でビルドが成功した。

事前準備

macHomebrewXcodeをインストールする。brewで必要なライブラリはインストールできる。 Linuxはaptを使ってインストールできる。

ビルドに必要なライブラリなど

ビルドに必要なライブラリはリファレンスマニュアルに記載がある。
MySQL :: MySQL 8.0 Reference Manual :: 2.9.2 Source Installation Prerequisites

これらのライブラリが必要になるので事前にインストールする。

  • g++
  • pkg-config

これらも特に記載がないが必要だった。

ncurses はそういう名前のライブラリをインストールするのではなく、コマンド群(ツール群)のようだ。以下のコマンドが使えればOK。UbuntuにもmacOSにも標準で入っているようだ。

  • captoinfo, a termcap conversion tool
  • clear, utility for clearing the screen
  • infocmp, the terminfo decompiler
  • tabs, set tabs on a terminal
  • tic, the terminfo compiler
  • toe, list (table of) terminfo entries
  • tput, utility for retrieving terminal capabilities in shell scripts
  • tset, to initialize the terminal

インストールする

Ubuntuではaptを使ってインストールする。

apt update 
apt upgrade

apt install cmake make gcc g++ openssl bison pkg-config

macOSの場合はXcodeをインストールすればCコンパイラはインストールされる。  gcc --versiong++ --version を実行すればXcodeのものが使われているのが確認できる。 他はbrewでインストールできる。

brew install cmake make openssl bison pkg-config

ソースコードを取得する

ソースコードGitHubで公開されている

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:1178do_command() 関数あたりにブレークポイントを設定する。 その後MySQLクライアントをつないで SELECT 1; などを実行してみるとブレークポイントで処理が止まって変数の中身などが確認できる。

bin/mysql -u root -p
Enter password:

mysql> select 1;
+---+
| 1 |
+---+
| 1 |
+---+
1 row in set (0.00 sec)

f:id:masayuki14:20200730164524p:plain
VSCodeによるDebug

こんな感じで確認できる。マウスポインターを変数に当てれば中身が見えるし、コールスタックなども確認できる。
正直なところさっぱりわからない。

これでデバッグビルドしてデバッガを動かす、の一連の作業はおわり。

デバッグビルドは何が嬉しいの?

mysqldmysqlデバッグ関連のオプションはデバッグビルドされた場合に使えるようになります。mysqld では --debug-sync-timeout=N が使えるようになったり、 mysql クライアントコマンドでは --debug --debug-check --debug-info のオプションが使えるようにります。スタックトレースなども出力できますが見方がわからないので、どう役立てていいか良くわかりません。だれか教えて。

以前なにかのスライドでMySQLクライアントでトレース情報みたいなものを出しているのを見たことがあるけど、どうやってやるんだろう。勘違いかな。

ということで普通にMySQLを使う上では何も嬉しいことはないと思います。ソースコード読んでみたいとか、デバッガ動かしたい、みたいなマニアックな欲求がない場合はデバッグビルドに手を出すことはないでしょう。一部の情報によるとmysqldumpソースコードは読みやすいらしいです。

きっかけ

デバッグビルドやってみようと思ったのは2年前でこのブログがきっかけでした。

labs.gree.jp

当時これを見ながらやってみたところ、うまくいかず原因もわからずで放置していましたが、MySQL熱が最近すこし上がってきたのと時間の余裕ができたのでやってみました。 作業ログをGitHub Issue に残してあり速攻で諦めているのがよく分かります。

MySQL8.0 source build · Issue #15 · masayuki14/worklog · GitHub

今回はじっくりリファレンスマニュアルを読みながら進めたので時間がかかりましたが、いろんな情報が自分の中でつながっていく感覚というのは良いものです。 MySQLデバッグビルドに興味がある方は試してみてください。

最後に、最近発売された MySQL徹底入門 第4版はいいぞ!

じぶん Release Notes (ver 0.38.1)

じ# masayuki14 (ver 0.38.1)がリリースされました。更新内容は下記のとおりです。

今回はちゃんと月末にリリースできました。頑張りました。今月は仕事量が比較的少なめで、他のことをする時間があっていろいろ試せてよかったな、という1ヶ月でした。先月までの危機感からか、アウトプットの量が増えてよかった。これはやる気の問題ではなく、時間の有無の問題で、如何に時間を確保するのかが重要ということを改めて実感した。ドラッカーもたしかどっかで言ってたはず。7月は仕事時間が増える予定なので、ここをしっかりやりくりしないと何もできなくなる。来月はさらに気を引き締めないといけませんよ。

お仕事

  • Rails + Vue.js の案件
    • ドメイン知識も増えてきたのでできることも増えてきた
    • ややこしい実装もちゃんと仕様に落とし込んで議論したりできて満足
      • IssueやPRで実装や仕様を詰めてたのでSlackではそういう話が殆どなかった
      • 込み入った内容はSpreadsheetで状態遷移とか話す内容まとめて「あとは決めるだけ」にしてあげるとみんな幸せになる

GitHubのissue検索で is:issue updated:>=2020-06-01 assignee:masayuki14 ってやってやると6月のやつが出るので、やったことを確認しながら振り返れてよい。 関係者がリモートで全員離れてるので、議論するには事前の準備が大切だし、準備しておけばスムーズに話がまとまる。やはり準備に時間かけるの大事。

  • アンバサダーレポート
    • ちょっと遅れている
    • ネタの仕込みと検証に時間かかるのでいろんなことを少しずつ並行で進めていったほうがいいかな

Tech

  • GCP
    • サーバーレスでスクリプト動かして結果をslackに投げる、的なやつやった
    • 簡単にだがはんなりPythonでもLTもできた
    • もうちょっと肉付けしてアンバサダーレポートにもする
  • MySQL
    • ソースからデバッグビルドをやった
    • CloudやDockerでシュッと使える現代にどれだけ意味があるかわからんが、やりたいからやる、ってのを大事にしていくスタイル
    • 結構じっくり公式ドキュメント読んだので理解は深まった。使う予定も役に立つ気配もはまったくない。
    • 次はデバッガと連携してソースコード読めるようになりたい
  • Atcoder
    • ABC170に参加してレーティングが下がった。早く茶帯になりたい
    • DPを少しずつやってる。ほんとに少しずつ。DPコンテストのLCSが時間制限でクリアできないよ!

読書

  • かくしごと
    • アニメが面白かったので原作がほしくなった。久米田康治作品は結構好きだけど、もっていない。
  • 蟻本
    • LCSやりました。回答例のコードに微妙に納得がいかない。
  • 達人に学ぶSQL徹底指南書第2版
    • いろんなSQLの使い方を知れてたいへん面白い
    • ORMやアプリケーション側でこねくり回す中でしか仕事したことないので、一度こういうSQLをぶっこんでレビューで弾かれてみたい。

読了はない。

そして来週、MySQL徹底入門 第4版 MySQL 8.0対応 が出るので読みたいなぁと思いつつ、読み切れる気がしないのでどうしよう。

tmtms.hatenablog.com

KPT

Keep

Problem

お酒飲んで寝ると朝起きれないので、お酒は減らさないといけない。ストレッチ(Yoga?)をちゃんとしないと肩腰の不具合が強まるので、ちゃんと体をいたわる必要がある。でもゲームしたり漫画、アニメをみちゃうんだよなぁ。

Try

  • MySQL
    • MySQLのデバッガとVSCode(or XCode)を連携させてうごかすぞ。そしてブログもちゃんと書く。
    • MySQL Diversなる取り組みがあるので参加したいなぁ。
  • GCP
    • GitHubに乗せて自動ビルドとデプロイまでしあげたい
    • Techpit教材の方に自動化の章を追加したいので構成とか考えてちょっとでもすすめたい

じぶん Release Notes (ver 0.38.0)

masayuki14 (ver 0.38.0)がリリースされました。更新内容は下記のとおりです。

今回マイナーバージョンが更新されました。年に1度の誕生日ぴったしリリースの機を逃し、我が人生なんてこんなものか、という感じです。38歳になりました。今後とも宜しくお願いします。

お仕事

  • Rails + Vue.js のお仕事をはじめました。

ものすごく久しぶりにちゃんとRailsのコードを書いています。いろいろと大変に便利になっています。あのgemとかこのgemとか。 こういうのリストアップして紹介する感じの情報って需要あるんだろうか。

休校が解除となり3ヶ月ぶりに自宅で一人で仕事をする機会が戻ってきました。仕事に対する姿勢を正さねば。

Tech

  • Ruby関連で便利だなと思ったものいろいろ

    • VCR: 外部のAPIへ接続するようなテストを書く時に便利に使えた。
      • 1年ほど前に別プロジェクトで外部APIを扱ったコードを書いたときこれ知ってたらテスト書けたなー、というやつ。
    • pry-byebug: Rubyデバッグツール
      • binding.pry を書いておけばRubyの実行を止めて様子を伺えてとても便利。
    • RSpec: テストフレームワーク
      • ほとんど test/unit しか使ったことなかったので、ちゃんと勉強して書けるようになった。特に難しいところがないので、乗り換えるのが容易だった。
    • VSCodeのいろいろな設定が簡単になっててうれしい
      • Rubocopの自動実行と反映がよい
      • ESLintの自動実行と反映もよい
      • Solargraph の補完は多分効いていると思うので便利認定
  • AtCoder

    • 5月はABCコンテストが少なかったので1回だけ
    • DPの理解に兆しが見えたので続けたい。
      • はんなりPythonの勉強会くらいしか時間とれてないので6月はもうちょっとふやす。

読書

またしても技術書全然読めてない。蟻本を少しやったくらいか。

漫画

  • 新刊をいくつか
  • アオアシ
    • 既刊20巻を読んだ。連載中で一番おもしろいサッカー漫画じゃなかろうか。
    • とはいえほかはGiantKillingしかしらない。
  • 犬夜叉
    • サンデーうぇぶりきっかけで読み直し中
    • 10年以上ぶりで内容全然覚えてない。
    • 30巻くらいで「まだ終わらんのか」という感想を当時も抱いてたのを思い出した。

KPT

Keep

Problem

わるかったこと、なんだけど「〇〇できてない」 っていうのは悪いことなので、そもそもやるつもりがないから、やるつもりないんならもうその考えは消してしまえばいいじゃん、っていうことなのか。ちゃんとできること、やることを見つめ直せ、ということか。

Try

今月挑戦すること。そもそもできることだけを宣言しないとだめだ。

  • 朝型シフト
    • 早起きしてしごとするのだ
  • GCP 止まってるやつ、今月こそやる。仕事に余裕ができたのでできるはず。
  • DP学習すすめる。
  • AtCoderのABCコンテスト2回はやるぞ。

すべてのチャレンジの根幹は 朝型シフト なので、これはちゃんとやろう。これができればほかは自動的にできるはず。

じぶん Release Notes (ver 0.37.11)

masayuki14 (ver 0.37.11)がリリースされました。更新内容は下記のとおりです。

遅くなってしまった。日付を遡ろうかと思ったけど、そんなことは重要じゃないと気づいた。

仕事

  • 引き続きでWordpressのお手伝いを少し
  • PHPの保守で少しコードを書いた
  • Techpit教材は5章をリリース

休校や自宅保育ということで、集中して仕事をできる時間が短かった。

Tech

  • GCP を試してみる
    • CloudRun, CloudBuild をやる。
    • CloudRunで実行して、SlackHookにメッセージ送る、ってやつが途中でとまっちゃってる。
    • 5月中に一連の流れをせいりしたい
  • AtCoder
    • ABCに2回参加
    • 茶色まであともうすこし
    • はんなりPythonの勉強会もやった
    • DP 動的計画法の壁にぶつかっている5月はこれを越えたい

勉強会・イベント

  • はんなりPython
    • AtCoderの回を月1でやるようになった
    • LTと発表とかそろそろやらんと

読書

技術書ぜんぜん読めてない。 キングダムはGW中に全57巻を読んだ

WIP

その他

  • 自粛はひま
  • どうせ子供に邪魔されて集中できない、と思うと調べ物とか勉強とか手に使ない
    • ただの言い訳思考でかっこ悪いので、やることはやろう
  • 万年筆のインクがもれてキーボードが赤くなった
  • はやく学校始まってほしい

KPT

最近は自堕落になっているので同しようもない

Try

  • Techpit6章GCPのやつは整理してまとめるひつようあり
  • 5月から Vue.js + Rails のしごとにJoinするのでがんばる
  • Railsってやること多くてめんどくさいけどちゃんとやろう

2020年の目標

もう4月だ。いや、すぐにでも5月だ。どうしようか。でもちゃんと書いておこう。 ということで今年の目標です。すでにいろいろ動き出していますが明示することもやはり大事なのだ。

継続すること

  • コミュニティ活動
  • ブログなどのアウトプット
  • Docker/k8s 深める
  • 仕事しすぎない

昨年続けられたことは今年もそのまま続ける感じです。あえて1つだけ

データベース深める

これもちょっとずつ進めていきたい。あまり運用とか使い込むような機会はないのだけど、MySQLについてはもっとやっていきたいよね。

新しいチャレンジ

AtCoder

2月くらいからAtCoderを始めて楽しくなってきた。コンテストにも参加していてあと3回で認められたプレイヤーになれるのでもう一息だ。 成績はこんな感じ。 atcoder.jp

色とか級とかまだどんなもんかわかってないけど、年末には水色のところには行きたい。

Rust

これはAtCoderと一緒にやろうと思ってたけど、ちょっとムズすぎて序盤で詰まってる。すでに困ってる。

個人活動

教材の販売と個人メンターを始めた。まだこれで何をやっていきたいか、みたいなものははっきりしてないんだけれど1年かけていろいろ試したりして育てていきたいと思っておる。どうなることか。

体が資本

毎年筋トレやるといってやらないので、これどうにかしない。運動ちゃんとしよう。最近YoutubeでYoga動画みながらやってるのでこれを続けるのが良さそう。