How to build MySQL 8.0.11 on Windows
こんにちわ。せじまです。今回はゆるふわです。
はじめに
皆さんはMySQLのソースコードを読むとき、何を使って読まれているでしょうか。私は以前からOpenGrokを愛用しているのですが、ここ2-3年はVisual Studioを使うことが増えました。OpenGrokでさっくり読み始めて「これけっこう大変だな」と思ったら Visual Studio に切り替えるなど、使い分けています。
MySQLは5.5からCMakeに対応し、以来、Visual StudioでビルドするときもCMake叩くようになったのですが、Windowsでビルドするときはちょっとクセがあります。MySQL8.0.4からCommunity Editionもビルド時にOpenSSLが求められるようになったのですが、MySQL8の公式ドキュメント読んだだけでMySQL8.0.11をWindowsでビルドするのはちょっとハードル高いかも思ったので、備忘録を兼ねて今日はそのへんを書いてみようと思います。
今回のお題は、「Visual StudioでMySQL8.0.11をデバッグビルドしてソースコード読んでみよう」というところです。
実際にWindows上でmysqldをビルドして動かそうとすると、はるか昔に坂井さんのblogやキムラさんのblogで指摘されていたように、ビルド時にロケールを日本以外にしないといけないんですが、最近は、ビルド通してコード読むだけなら、ロケール変更しなくてもできるようになりました。なので、今回はお手軽にロケール変更しないでコード読めるようにするところまでやってみることにします。
そして、MySQL8.0とOpenSSLに関する話にも、少し触れておくことにします。
How to build MySQL 8.0.11 on Windows10
先ずはVisual Studio 2015以降を準備してください。MySQL8.0からC++11準拠になっているため、Visual Studio 2015以降じゃないと、MySQL8.0はWindowsでビルドできなくなりました。個人用途であれば、Visual Studio Community Edition でも良いのではないでしょうか。
余談ですが、MySQL8.0はGoogle C++ Style Guide に準拠したものになるなど、Coding Standardなどもいろいろ見直されたそうです。興味のある方は次の記事を参照してください。
MySQL 8.0 GA のソースコードをダウンロード
https://dev.mysql.com/downloads/mysql/
からMySQL Community Server 8.0 GAの最新版の zip をダウンロードします。現時点で最新は8.0.11です。今回は
C:\work\mysqlbuild\mysql-8.0.11
を作業フォルダにしてみました。
BOMつける
VC++にUTF-8のソースコードをコンパイルしてもらうにはBOMつけるのが確実だと思うんですが、いい時代になりました。Windows力低いおっさんにも、 Windows Subsystem for Linuxという強い味方があります。WSLでUbuntuいれて apt-get install nkf すれば、次のようなワンライナーでBOMつけられます。
1 2 |
$ find /mnt/c/work/mysqlbuild/mysql-8.0.11/ -type f | egrep '\.(c|cc|cpp|h|hpp)$' | xargs -n 1 file | grep UTF | grep -v BOM | cut -d':' -f 1 | xargs -n 1 nkf --overwrite --oc=UTF-8-BOM |
CMake & bison のインストール
CMake はもちろんのこと、 sql_yacc.yy などをコンパイルするために bison for Windows が必須なので、2.8 Installing MySQL from Source を参考にしつつそれぞれインストールします。
※余談ですが、 INSERT や SELECT などの SQL が飛んできたとき、 mysqld がどういう関数を呼んでいるか調べたいなら、 sql/sql_yacc.yy や sql/sql_yacc.cc から読み始めるのが良いのではないかと思います。
OpenSSL1.0.2 のインストール
MySQL8.0.4からCommunity EditionもOpenSSLを使うようになったのですが、 MySQL 8.0 Reference Manual はまだそのあたり追いついてない部分があるのかもしれません。そのあたり補足していきます。
まず、Reference Manual のExample 3: Creating SSL Files on Windowsには、http://www.slproweb.com/products/Win32OpenSSL.html からOpenSSL for Windowsをダウンロードするように書いてあるので、今回はここからlightじゃないパッケージを持ってきてインストールします。
(いろいろ試して気づいたんですが) MySQL8.0.11ってOpenSSL 1.1.0だとWindowsではCMake通らないようです。(最初はドキュメントに書かれてないオプション試すなどいろいろやってたのですが、 OpenSSL 1.0.2 と 1.1.0 どちらもダウンロードし試して気づきました。)現時点ではOpenSSLのlatest stable versionは1.1.0らしいですが、Windows では、Long Term Supportの1.0.2使うと良いでしょう。
Windowsで64bit版のOpenSSLをインストールする際、 インストール先はデフォルトの
C:\OpenSSL-Win64
になるとします。
ドキュメントのWITH_SSLオプションの説明にある通り、Windowsだとそのパスは勝手にチェックしてもらえるので楽ちんです。あとはインストール時にきかれる
Copy OpenSSL DLL files to
は
The OpenSSL binaries (/bin) directory
にします。なぜかといいますと${WITH_SSL_PATH}/bin 配下にある DLL をコピーしていますので
CMake
OpenSSLインストールしたら、CLIからCMake叩きます。コマンドプロンプトでもいいんですが、Ctrl+Rでbck-i-search(reverse incrememtal search)できるので、私はpowershellをよく使ってます。powershellひらいて
1 2 3 |
> cd C:\work\mysqlbuild\mysql-8.0.11 > mkdir bld > cd bld |
して、 Visual Studio 2015 がインストールされている環境では
1 |
PS C:\work\mysqlbuild\mysql-8.0.11\bld> cmake .. -DWITH_DEBUG=1 -G "Visual Studio 14 2015 Win64" -DDOWNLOAD_BOOST=1 -DWITH_BOOST=C:\work\mysqlbuild\boost |
とすればOKです。
あとは、\work\mysqlbuild\mysql-8.0.11\bld 配下に生成されたMySQL.slnを、VisualStudioで開いてビルドしましょう。
※当初は OpenSSL1.1.0で試してて「あれこれ普通にやったらビルド通らなくね?」と思ってその手順をまとめてblogに書こうと思ったんですが、MySQL8.0.11はWindowsだとOpenSSL1.1に対応していないっていうだけの話でした。
補足1:MySQLとOpenSSL1.1
OpenSSL1.1.0について調べててけっこう気になったのですが、 OpenSSLのRelease Strategyを見てみますと
Version 1.1.0 will be supported until one year after the release of 1.1.1
Version 1.0.2 will be supported until 2019-12-31 (LTS).
となってます。じゃ 1.1.1 がいつリリースされるかというと、
We have defined the following release criteria for 1.1.1:
の中に
TLSv1.3 RFC published (with at least one beta release after the publicaction)
という記載があります。
となると、現状、MySQL8.0.11をOpenSSL1.0.2にリンクして使ってると、2019年12月31日に OpenSSL 1.0.2 がEnd Of Lifeになって、(おそらくそのころにはリリースされているであろう)OpenSSL1.1.1に対応したMySQL8.0.xに、マイナーバージョンアップする必要があるってことになるんでしょうか?
少なくとも、Linux上でMySQL8.0使うほとんどの人にとって、そうはならないと思います。
Changes in MySQL 8.0.4 (2018-01-23, Release Candidate) には次のように書いてあります。MySQL8.0.4の時点で、*nixではOpenSSL 1.1.0に対応済みです。
MySQL can now be linked against OpenSSL 1.1 on Unix and Unix-like systems. (Bug #25094892, Bug #83814)
とりあえず、OpenSSL1.1.0に対応できているかどうか確認するべく、Ubuntu 18.04 LTS上でMySQL8.0.11をビルドしてみましたが、libssl.so.1.1にリンクして起動するところまで確認できました。
また、https://dev.mysql.com/downloads/mysql/ から、 mysql-server_8.0.11-1ubuntu18.04_amd64.deb-bundle.tar と mysql-server_8.0.11-1ubuntu16.04_amd64.deb-bundle.tar をダウンロードして ldd mysqld してみましたが、Ubuntu 18.04 LTS 向けの mysqld は18.04にバンドルされている libssl.so.1.1 に、Ubuntu 16.04 LTS向けの mysqld は16.04にバンドルされている libssl.so.1.0.0 にリンクされてました。
自分で OpenSSL ビルドして mysqld 使いたいという人にとっては(例えば、OpenSSL1.1.1がリリースされたらmysqldとTLS1.3で通信したいと考えている人にとっては)、 OpenSSLのリリーススケジュール等気になるところかもしれません。ただ、Linux上でMySQL8.0使うほとんどの人は、ディストリビューションに付属しているlibssl.soやlibcrypto.so使っていけばいいというだけではないかと思います。Ubuntu 18.04 LTSなど、一部のLinuxのディストリビューションでは、付属されているOpenSSLがすでに 1.1.0 になっているため、それらのディストリビューションでも使いやすくするべく、MySQL8.0.4の時点で対応されたのでしょう。
ただ、WindowsでMySQL8.0使う人にとっては、 2019年12月31日にOpenSSL1.0.2がEOLになるということは、実は重要な問題なのかもしれません。OpenSSL1.1.1がリリースされた暁には、Windows版のMySQL8.0もOpenSSL1.1.1に対応すると思いますが、現時点でWindowsが1.1.0に対応できていないというのは、不具合かというとビミョウな気もしますね。MySQL 8.0 Reference Manual のC.10.5 Windows Platform Limitations に書いといてくれても良いかなぁ、と感じるところではあります。
というわけで、制限事項に追記してはいかがでしょうか?と、バグレポートに上げておきました。
補足2: comp_err
mysqld_error.h などは comp_err というプログラムによって生成されます。よって、先ずは comp_err がビルドできないことには、 mysqld をビルドすることは
できません。
MySQL8.0.11では、comp_err もOpenSSLのライブラリにリンクするようになりました。よって、OpenSSLへのリンクにコケてると、そもそもmysqld_error.hなどが生成できません。
Visual Studio でMySQLビルドするのってかなり時間かかるので、もし何かうまくいかないようであれば、先ずは comp_err だけでビルドが通るか試してみるのが、切り分け方として良いんではないかなぁと個人的には思うなどします。
補足3:私が主に使ってる Source Code Viewer
ごくごく稀にMySQL界隈の人に「MySQLのソースコード読むときに何使ってますか?」的なことを聞かれることがあるんで、わたしがOSSのソースコード読むときに使っているソフトウェアを列挙してみます。
MySQLでデバッガ使う段階になったら Emacs と gdb 使ってるんですが、それまではIDE使うことが多いです。
OpenGrok
むかし同僚に教えてもらってから使い始めました。仕事柄、LinuxのTCPプロトコルスタック周りやMySQLのソースコードを読んで解析することがあるのですが、社内向け資料をまとめるときなどに、OpenGrockは非常に便利で使い出があります。OpenGrokはUniversal ctags使ってるのですが、ctagsに対応した諸々のテキストエディタと違って、URLでソースコードを引用できるのです。私はよほど手強いものでない限り、いきなりOpenGrokでソースコード読み始めて、URLまとめて資料書いたり、チャットに書いて説明したりしています。
Visual Studio 2015 or 2017
数年前、当時InnoDBの開発をしていた方が「コードを書くのには使ってないけど、読むのにはEclipse使ってる」とおっしゃられてました。当時、私はそれを聞いて「なるほどコード書くのと読むのに使うものは別々で良いかぁ」「へんにこだわらなくても、C++読むならIDE使った方が楽かぁ」と感じてました。
で、私物のノートPCでMySQLのソースコード読んだり、自宅でいろいろ試してみたりするとき、どうしようかなぁ思って知人らに話を聞いたら、なんか、ノートPCにLinux入れてそこでMySQLのデバッグしてる人がそこそこいたんですね(私の観測範囲だと)。私物のノートPCならともかく、職場のPCにUbuntu入れるのはちとアレかなぁと感じることもあり。最終的に仕事でInnoDBの解析できた方が良いこともあるので「職場で用意しやすいIDE(for MySQL)ほしいなぁ」というのが、私にとってしばらく課題でありました。
そうこうしていると、MySQL5.5以降、ビルドするときは(Windows上でも)CMake叩けば良いようになりました。また、Visual Studio 2013 のときに Community Edition でたので、自宅でMySQLのコード読むときは、Visual Studio Community 2013 使って読めるようになりました。自宅でいろいろ試してるうちに「これなら、Windowsマシンと Visual Studio のライセンスあれば、 MySQL のコード読むのが ctags 使うより捗るんじゃないかな?」と感じるようになってきて、最近はMySQLのソースコード読むとき、Visual Studio使うことが多くなりました。
ちなみに、次のスライド書くときは、 EmacsとOpenGrokでソースコード読んでました。
ただ、次のスライドに関するあたりのInnoDBのソースコード読んでたらだいぶしんどいなと思ったので、このあたりからInnoDBのコード読むときにVisualStudio使い始めました。
また、このあたりもけっこうヘビーな内容だったので、ソースコード読むときにVisualStudioも使ってます。
Visual Studio Code
じつに今更感ありますが、さいきん使い始めました。 Visual Studio 使ってるのになんで Visual Studio Code も使うかと言いますと
- さいきんのMySQLに入った新しい機能をガッツリ読むときは Visual Studio でデバッグビルドして読む
- 特定のマイナーバージョンのMySQLをさっくり読みたいときは Visual Studio Code
くらいの使い分けをしています。最新のメジャーバージョンのMySQLはVisual Studioで、以前のMySQLは Visual Studio Codeでも良いかなぁと思ったりしてます。
https://github.com/mysql/mysql-server はマイナーバージョンごとにタグついてるので、 git clone して特定のタグに切り替えて Visual Studio Code でソースコード読むという使い方が便利です。例えば MySQL のバグレポート上げるとき、Bug #86356みたいに see the code って言って特定のマイナーバージョンで github.com から引用したいことがあるんですが、 Visual Studio Code で予め対象のソースコードと行数を調べておくと、github.com から引用するのがだいぶ楽になります。
また、そろそろ Ubuntu で kernel 4.15 使いたいなぁと思っているので、 kernel 4.15 のソースコード読むときは git://kernel.ubuntu.com/ubuntu/ubuntu-bionic.git を git clone して、 Visual Studio Code で読もうかなと、さいきん思うなどしています。
今回のお題にはそぐわないですけど、 git clone して Visual Studio Code でOSS読むっていうの、けっこう悪くないと思いますね。お手軽ですし。
おわりに
Visual Studio で MySQL8.0.11のソースコード読む準備をしてたら、MySQLでもTLS1.3について意識することもあるんだなぁ、と意外な気付きが得られました。このへんの動向は今後も見守っていきたいなと思います。
ソースコード読む準備も整ったことですし、次回以降はMySQL8.0について何か書けたら良いなと思うなどしてます。