GA

2024/12/05

とあるDBAのMySQL サンドボックス

この記事は 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をインストールしたのもこのインスタンスです :D

明日は takaidohigashiさん です!

0 件のコメント :

コメントを投稿