この記事は MySQL Advent Calendar 2024 の5日目の記事です。
昨日は yoku0825さん の ConoHa VPSでMySQLをビルドする 2024年 でした
昨日の記事では新しくRocky Linux 9でMySQLをビルドするために新調したインスタンスでやっていましたが、普段使いのインスタンスはEOLを迎えたCentOS7です
[ConoHa VPS](https://www.conoha.jp/vps/) の1GB(メモリ1GB, CPU2コア, SSD100GB)のやつです。これで3か月に1回くらいMySQLの新しいのがリリースされるたびにのんびりビルドしています。
バージョン間の動作確認やパッとコードを読むための環境として使っているので、MySQLはこんな風になっています。
$ ll /usr/mysql/* -d
drwxr-xr-x 10 yoku0825 yoku0825 4096 Jun 18 2021 /usr/mysql/5.0.96
drwxr-xr-x 11 yoku0825 yoku0825 4096 May 2 2021 /usr/mysql/5.1.73
drwxr-xr-x 13 yoku0825 yoku0825 4096 May 1 2024 /usr/mysql/5.5.62
drwxr-xr-x 13 yoku0825 yoku0825 4096 Sep 15 2021 /usr/mysql/5.6.51
drwxr-xr-x 11 yoku0825 yoku0825 4096 Jun 4 2024 /usr/mysql/5.7.44
drwxrwxr-x 13 yoku0825 yoku0825 4096 Dec 4 18:27 /usr/mysql/8.0.40
drwxrwxr-x 13 yoku0825 yoku0825 4096 Oct 17 09:45 /usr/mysql/8.4.3
drwxrwxr-x 13 yoku0825 yoku0825 4096 Oct 17 17:47 /usr/mysql/9.1.0
あと、MySQL Shellの dba.deploySandboxInstance が素直にPATH環境変数でmysqldを探してくれないので、それ用にrpmパッケージもインストールしてあります。
$ rpm -qa | grep mysql-community
mysql-community-icu-data-files-8.4.3-1.el7.x86_64
mysql-community-client-plugins-8.4.2-1.el7.x86_64
mysql-community-common-8.4.3-1.el7.x86_64
mysql-community-client-8.4.2-1.el7.x86_64
mysql-community-devel-8.4.2-1.el7.x86_64
mysql-community-libs-8.4.2-1.el7.x86_64
mysql-community-libs-compat-8.4.2-1.el7.x86_64
mysql-community-server-8.4.3-1.el7.x86_64
散らかっていて恐縮ですが、ソースコードはホームディレクトリに置いてあります。
ホームディレクトリで展開してインソースビルドしてmake installしているので、今 /usr/mysql にあるやつだけがディレクトリになっています。
容量の問題で、make installしたあとはmake cleanしてます。
$ ll -d mysql*
-rw-r--r-- 1 yoku0825 yoku0825 11478592 Feb 6 2012 mysql-4.0.30.tar.gz
-rw-r--r-- 1 yoku0825 yoku0825 22686667 Mar 2 2012 mysql-5.0.96.tar.gz
-rw-r--r-- 1 yoku0825 yoku0825 24023347 Nov 5 2013 mysql-5.1.73.tar.gz
-rw-r--r-- 1 yoku0825 yoku0825 21111902 Aug 29 2018 mysql-5.5.62.tar.gz
-rw-r--r-- 1 yoku0825 yoku0825 32411131 Jan 5 2021 mysql-5.6.51.tar.gz
drwxr-xr-x 34 yoku0825 yoku0825 4096 Jul 31 17:54 mysql-5.7.44
drwxr-xr-x 36 yoku0825 yoku0825 4096 Dec 4 18:42 mysql-8.0.40
-rw-r--r-- 1 yoku0825 yoku0825 425791134 Jul 13 02:50 mysql-8.4.2.tar.gz
drwxr-xr-x 35 yoku0825 yoku0825 4096 Dec 3 18:01 mysql-8.4.3
-rw-r--r-- 1 yoku0825 yoku0825 465097732 Sep 17 18:12 mysql-8.4.3.tar.gz
-rw-r--r-- 1 yoku0825 yoku0825 428335150 Jul 13 02:56 mysql-9.0.1.tar.gz
drwxr-xr-x 36 yoku0825 yoku0825 4096 Nov 11 13:16 mysql-9.1.0
-rw-r--r-- 1 yoku0825 yoku0825 480032080 Sep 24 19:09 mysql-9.1.0.tar.gz
-rw-r--r-- 1 yoku0825 yoku0825 53298645 Oct 11 2023 mysql-boost-5.7.44.tar.gz
-rw-r--r-- 1 yoku0825 yoku0825 490502884 Sep 18 17:38 mysql-boost-8.0.40.tar.gz
drwxr-xr-x 3 yoku0825 yoku0825 4096 Dec 5 14:32 mysql-sandboxes
drwxr-xr-x 17 yoku0825 yoku0825 4096 Dec 5 14:35 mysql-shell-8.4.3-src
-rw-r--r-- 1 yoku0825 yoku0825 152976386 Sep 18 13:36 mysql-shell-8.4.3-src.tar.gz
-rw-r--r-- 1 yoku0825 yoku0825 3330656 Dec 7 2021 mysql_random_data_load_0.1.12_Linux_x86_64.tar.gz
-rw-r--r-- 1 yoku0825 yoku0825 25554 Mar 29 2022 mysqlbench-0.1.tgz
ビルドはパス以外デフォルトで、INSTALL_LAYOUTもSTANDALONEなので /usr/mysql/x.y.z
の下に data
ができてそこがdatadirになります。tmpdirは全部 /tmp
ですね。
CMAKE_BUILD_TYPEはデフォルトでRelWithDebInfo, MINIMAL_RELWITHDEBINFOだけ明示的にOFFにしてあります。
容量の問題だったり、軽く100万件突っ込むだけで時間がかかってしまうので デバッグビルドではない です(一時期やってたけどやめた)
多少データが入ってるかも知れませんがこんな感じ。
]$ du -sh /usr/mysql/*
86M /usr/mysql/5.0.96
248M /usr/mysql/5.1.73
371M /usr/mysql/5.5.62
1.1G /usr/mysql/5.6.51
3.7G /usr/mysql/5.7.44
3.5G /usr/mysql/8.0.40
3.3G /usr/mysql/8.4.3
3.4G /usr/mysql/9.1.0
MySQL Shell以外ではもうとっくにメンテナンスされてない MySQL::Sandbox を使っています (後継の dbdeployer には移らないままdbdeployerもメンテナンスが終わってしまった)
バージョンを打ち分けられるように SANDBOX_BINARY=/usr/mysql
を設定しています。
$ make_replication_sandbox --how_many_slaves=1 8.0.40
..
MySQL 8.4とそれ以降は動きません。 ここ だけ修正してもダメです。CHANGE REPLICATION SOURCE TO
に対応していないからです。
本格的に8.4でやるようになったら自分のぶんだけ直すかもしれない。
(今はMySQL Shellのサンドボックスか↓のDockerコンテナと InnoDB ReplicaSet でなんとなくやりたいことはやれている)
自分でビルドしたバイナリは容量の問題で1つ新しいのが出たらすぐ前の世代は消しちゃいますが、たまに試したくなるのでそういう時に便利なのがDockerですね。
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 24.04 fec8bfd95b54 7 weeks ago 78.1MB
container-registry.oracle.com/mysql/community-server 8.4.3 4e4fdc4a92c8 7 weeks ago 579MB
container-registry.oracle.com/mysql/community-server 8.0.40 cbe43d82e50c 7 weeks ago 576MB
implem/pleasanter codedefiner 4255febbda1b 8 weeks ago 416MB
implem/pleasanter latest 5b7646c9bded 8 weeks ago 460MB
container-registry.oracle.com/mysql/community-server 8.0.39 15df6905a022 4 months ago 551MB
container-registry.oracle.com/mysql/community-server 8.4.2 a50438f82562 4 months ago 562MB
container-registry.oracle.com/mysql/community-server 8.0.38 d37c2d1560e3 5 months ago 551MB
quay.io/centos/centos stream8 197af1ac4595 6 months ago 218MB
container-registry.oracle.com/mysql/community-server 8.4.0 8d0dfbc1b8b6 7 months ago 564MB
container-registry.oracle.com/mysql/community-server 8.3.0 c0db6c8ff4af 10 months ago 691MB
rockylinux 9 9cc24f05f309 12 months ago 176MB
container-registry.oracle.com/mysql/community-server 8.2.0 39654aa412c0 13 months ago 596MB
container-registry.oracle.com/mysql/community-server 8.1.0 902aecd50aa8 16 months ago 566MB
mysql/mysql-server 5.7.41 a4ad24fe52cd 22 months ago 432MB
container-registry.oracle.com/mysql/community-server 8.0.28 12a2858989df 2 years ago 417MB
centos 7 eeb6ee3f44bd 3 years ago 204MB
私は dmysql x.y.z
でそのインスタンスが1つ浮かせられるように dmysql
というbash functionを作っています。
dmysql ()
{
version_str="$1";
shift;
[[ -z $version_str ]] && version_str="latest";
version_int=$(echo $version_str | awk -F"[.-]" '{printf("%d%02d%02d\n", $1, $2, $3)}');
if [[ $version_str = "latest" || $version_int -ge 80022 ]]; then
repo="container-registry.oracle.com/mysql/community-server";
else
repo="mysql/mysql-server";
fi;
docker run -d --restart=on-failure -P -e MYSQL_ALLOW_EMPTY_PASSWORD=1 -e MYSQL_ROOT_PASSWORD="""" -e MYSQL_ROOT_HOST=""%"" $repo:$version_str $@
}
ifが噛ませてあるのは 日々の覚書: MySQL公式のDockerリポジトリがcontainer-registry.oracle.comに引っ越していた からです。
これでだいたいの5.6から9.1(5.7の一部だけどっちのdockerリポジトリにもない…)は一発で起動できるので便利ですね。
変わり種としては、一番多く使う /usr/mysql
の下は mysqld_multi で起動していることです。
$ mysqld_multi start 80
$ mysqld_multi start 56,57
こんなコマンドになります。 /etc/my.cnf
がこんな感じになっていて
[mysqld50]
server-id = 1050
basedir = /usr/mysql/5.0.96
mysqld = /usr/mysql/5.0.96/libexec/mysqld
socket = /usr/mysql/5.0.96/var/mysql.sock
port = 64050
pid-file = /usr/mysql/5.0.96/var/mysql.pid
datadir = /usr/mysql/5.0.96/var
[mysqld51]
..
[mysqld84]
server-id = 1084
basedir = /usr/mysql/8.4.3
mysqld = /usr/mysql/8.4.3/bin/mysqld_safe
socket = /usr/mysql/8.4.3/data/mysql.sock
port = 64084
pid-file = /usr/mysql/8.4.3/data/mysql.pid
datadir = /usr/mysql/8.4.3/data
mysqlx= off
#mysql_native_password = ON
admin_address= 127.0.0.1
admin_port= 63084
[mysqld91]
server-id = 1091
basedir = /usr/mysql/9.1.0
mysqld = /usr/mysql/9.1.0/bin/mysqld_safe
socket = /usr/mysql/9.1.0/data/mysql.sock
port = 64091
pid-file = /usr/mysql/9.1.0/data/mysql.pid
datadir = /usr/mysql/9.1.0/data
mysqlx= off
admin_address= 127.0.0.1
admin_port= 63091
[mysqldXX]
の部分が mysqld_multi
の引数になるとこです。
もともとは別にバージョンじゃなくてdatadirとか分けてサンドボックスを起動/終了するためのものだと思うんですが、バージョン分けて起動するのに具合が良かったので長らく使っています。
実は mysqladmin
( mysqld_multi
が内部的に使う ) には非互換があって、一応こんな風に分岐しています。
multi ()
{
if [[ "$2" -lt "80" ]]; then
multi=/usr/mysql/5.6.51/bin/mysqld_multi;
else
multi=/usr/mysql/8.0.40/bin/mysqld_multi;
fi;
case "$1" in
"restart")
shift;
$multi stop $*;
sleep 10;
$multi start $*
;;
*)
$multi $*
;;
esac
}
人と変わってるところはこれくらいかなあ…?
あとは普通です、たぶん(perlのDBD::mysqlを8.4のlibmysqlclientでビルドしてるくらい?)
MySQL 3.23 系を力技でインストールする @yoku0825 さんwwww
— あわっち (@_awache) August 29, 2024
めっちゃ楽しいw
#mysql_jp pic.twitter.com/a5yJTlbQeg
明日は takaidohigashiさん です!