MySQL 5.7 のビルドにトライ ~ 5.6とは大違い

 ひとつ前の日記までで、MySQL 5.6 のビルドが快調にできたことに気をよくして、MySQL 5.7 のビルドにも挑戦してみました。5.6.35 と 5.6.34 の差(ビルド環境や方法に違いはない)と同じように バージョン番号関係の部分を 5.7.17 に変えれば良いのだろうと考えていたら、大違い。

MySQL5.6をビルドして動作させるのと違うところ

  • boost の 1.59 が要求される。Red Hat 7.3 のyumでは boost 1.53 しか入らないので一工夫必要
  • make するのにメモリが多く要求される。
  • データベースの初期化方法と、初期パスワード設定が違う


 以下それぞれについて説明したあと、全体の手順を紹介したいと思います。

boost 1.59 が必要

 yumでワンタッチで入らないので、一手間かかるなぁと思っていたら、MySQL開発チームは boost 1.59 入りのソースコードを提供してくれていました!*1
 mysql-5.7.17.tar.gz ではなく、mysql-boost-5.7.17.tar.gz をダウンロードして使用します。

f:id:sakaik:20170105160147j:plain:w350


メモリがいっぱい必要

 AWS Red Hat 7.3 の、t2.micro(1 CPU, 1GBメモリ)では、make の途中で落ちてしまいました。t2.medium (2 CPU, 4GBメモリ)では無事、処理を完了できました。

======
追記:
swapの設定をすることで、t2.micro でもビルドできました。ただし大変に時間がかかります。
MySQL 5.7 を t2.micro でもビルドできた! - sakaikの日々雑感~(T)編

======


 メモリが不足している環境で落ちるパターンは2つあるようで、

  • OOMキラーに殺されるケース (/var/log/messages にログが記録される)*2
  • 行儀良くメモリ不足になって落ちるケース


OOMキラーに殺されたときの出力:

 :
[ 43%] Building CXX object sql/CMakeFiles/sql.dir/item_func.cc.o
[ 43%] Building CXX object sql/CMakeFiles/sql.dir/item_geofunc.cc.o
c++: internal compiler error: Killed (program cc1plus)
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://bugzilla.redhat.com/bugzilla> for instructions.
make[2]: *** [sql/CMakeFiles/sql.dir/item_geofunc.cc.o] Error 4
make[1]: *** [sql/CMakeFiles/sql.dir/all] Error 2
make: *** [all] Error 2

行儀よく(?)メモリ不足で落ちたときの出力:

[ 41%] Building CXX object sql/CMakeFiles/sql.dir/item_geofunc.cc.o
virtual memory exhausted: Cannot allocate memory
make[2]: *** [sql/CMakeFiles/sql.dir/item_geofunc.cc.o] Error 1
make[1]: *** [sql/CMakeFiles/sql.dir/all] Error 2
make: *** [all] Error 2


OOMキラーに殺されたときの/var/log/messages への記録:

Jan 4 21:55:39 ip-172-31-16-117 kernel: Out of memory: Kill process 28375 (cc1plus) score 812 or sacrifice child Jan 4 21:55:39 ip-172-31-16-117 kernel: Killed process 28375 (cc1plus) total-vm:990440kB, anon-rss:821020kB, file-rss:1828kB, shmem-rss:0kB

MySQL 5.7 のビルド

 ということで、MySQL 5.7.17 をビルドする方法です。前述したように AWSの t2.micro ではメモリが不足していたので、4GBメモリの t2.medium のインスタンスを立ち上げて試しました。

f:id:sakaik:20170105160246j:plain:w350


今回は新しいマシン環境にしたので、各種モジュールを入れる:

# yum -y install wget gcc gcc-c++ cmake libaio-devel bison ncurses-devel perl-Data-Dumper
# yum -y remove mariadb-libs


MySQL 5.7.17(boost入り)を取得して展開:

$ mkdir mysql/
$ cd !$
$ wget http://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-boost-5.7.17.tar.gz
$ tar xvf mysql-boost-5.7.17.tar.gz
$ cd mysql-5.7.17

cmakeの実行。boostライブラリの位置を WITH_BOOST で指定するのがポイント。
その後 make*3

$ cmake -DWITH_BOOST=./boost -DCMAKE_INSTALL_PREFIX=/home/ec2-user/mysql/mysql5717 -DBUILD_CONFIG=mysql_release

$ make

$ make install

make には、t2.mediumの環境で40分かかりました。やっぱり MySQL 5.7、でかいですね。



インストール後の作業

 インストールが済んだら、

  • データベースファイルの作成
  • MySQLサーバの起動
  • クライアントからの接続確認

をします。

 MySQL 5.7.6 からは、初期データベースの作成方法が変更となっています*4

$ ./bin/mysqld --initialize
 :
2017-01-05T05:00:32.599615Z 1 [Note] A temporary password is generated for root@localhost: 4gV=;%jYin6v

作成すると、初期パスワードが画面に表示されていますので、覚えておきます*5


my.cnf を作成します。MySQL 5.6 と異なり、ベースとなるフォルダには my.cnf のひな形はありません。
新規に作成するか、あるいはテンプレートを使いたい人は support-files の中のmy-default.cnf ファイルをコピー/リネームして使います*6

$ vi my.cnf
------
[mysqld]
character-set-server=utf8mb4
log-error=/home/ec2-user/mysql/mysql5717/my.err
port=15717
socket=/tmp/mysql5717.sock

[mysqladmin]
socket=/tmp/mysql5717.sock

[mysql]
default-character-set=utf8mb4
socket=/tmp/mysql5717.sock
port=15717
------

 今回は ポートは 15717、キャラクタセットは utf8mb4 にしてみました。



MySQLサーバの起動:

$ ./bin/mysqld_safe &

クライアントからの接続:

$ ./bin/mysql --defaults-file=./my.cnf -uroot -p

 先ほど記憶した初期パスワードを入力します。

 MySQL 5.7 では、初期パスワードを変更するまで、なんにもできないようになっています。
ALTER USER 構文を使ってパスワードを変更します*7

mysql> ALTER USER root@localhost IDENTIFIED BY 'mynEwP455wD';

statusを見てみると、期待したバージョンが、期待したキャラクタセットの設定で起動していることがわかります。
f:id:sakaik:20170105160348j:plain:w350



 ということで、無事 MySQL 5.7 もビルドできました。
MySQL 5.7 は驚くほど大きな進化」とよく言いますが、1GBメモリの環境でビルドできないことや、ビルド時間が倍かかる(20分→40分)ことなどから、その進化のサイズが並ならぬものであることが実感できました。
 特に、今回メモリ不足で落ちたのが geo 関係のところということで、たまたまその位置で不足しただけという可能性は勿論ありますが、個人の印象としては「geo関係、でっかいなぁ」と感じました。


 ということで、年始の時間を利用した「MySQLビルドあそび」終了です。 yokuさんの記事に始まり、エラーの解決方法をtwitterでyokuさんに教えていただくなど、yokuさんにyokuお世話になりました。特に、メモリ不足の可能性には恐らく自力でたどり着かなかったと思います。ありがとうございました!

----------

*1:yoku0825さんに教えていただきました

*2:yoku0825さんに教えていただきました

*3:cmake したら make

*4:以前は、mysql_install_db スクリプトを使用しました

*5:ほとんどの人は自分の脳で覚えられないでしょうから、コピペなどの技術を用います

*6:MySQL 5.7.18からは、このファイルも同梱されなくなるとアナウンスされているので、基本的に my.cnf は自分で作るものだと思っておくと良いでしょう

*7:MySQL 5.7.6より前は SET PASSWORD FOR 構文を使いました