GA

2023/12/10

MySQL公式のDockerリポジトリがcontainer-registry.oracle.comに引っ越していた

この記事は MySQLのカレンダー | Advent Calendar 2023 の10日目の記事です。昨日は meijik さんの 最新のSQL標準(SQL:2023)とFirebird/MySQL/PostgreSQL | キムラデービーブログ でした。

TL;DR


Before

$ sudo docker pull mysql/mysql-server

After

$ sudo docker pull container-registry.oracle.com/mysql/community-server

これだけ。
イメージビルド用のDockerfileは変わっていないっぽいので、Oracle社ビルドのイメージを使っていたなら大した差はないはず(このDockerfileやentrypoint.shはDocker社ビルドのイメージとはそもそも盛大に違うので、もともとがDocker社ビルドのものだったりすると非互換がある)

ちなみにDocker社ビルドの方はこっち

Oracle社ビルド用のイメージとして俺はこんなエイリアスを用意していて(そもそもMySQLのDockerコンテナはバージョンごとのちょっとした動作確認をするのに便利、くらいにしか使わない)

dmysql ()
{
    sudo docker run -d -P -e MYSQL_ALLOW_EMPTY_PASSWORD=1 -e MYSQL_ROOT_PASSWORD="""" -e MYSQL_ROOT_HOST=""%"" --restart=on-failure mysql/mysql-server:$1
}

このお引越しを経てこうなりました (バージョン番号の判定にまさに 日々の覚書: 明日使えない地味なシェルスクリプト用ワンライナー集 のやつを使っている…)

dmysql ()
{
    version_str="$1";
    [[ -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 -P -e MYSQL_ALLOW_EMPTY_PASSWORD=1 -e MYSQL_ROOT_PASSWORD="""" -e MYSQL_ROOT_HOST=""%"" $repo:$1
}

直近の5.7(5.7.44とか)はサポートしてない (そもそも引越し前にも引越し先にもないのでそうならざるを得ない)けどまあ仕方なし…

明日は yyamasaki1 さんです!

2023/12/07

明日使えない地味なシェルスクリプト用ワンライナー集

この記事は MySQLのカレンダー | Advent Calendar 2023 の7日目の記事です。
6日目は けんつ さんの MySQL いい感じにコントリビュートする方法(非公式) - それが僕には楽しかったんです。 でした。


TL;DR

  • なんの変哲もないよく使うワンライナーです。SQLだけでできたり使ったりするものは入っていない気がする

バージョンxxx移行yyy未満、みたいなのをやりたい

  • MySQLは内部的にも メジャーバージョン番号 * 10000 + マイナーバージョン番号 * 100 + リリース番号 みたいな計算式をよく使っているのでそれに倣う
$ mysql -sse "SELECT @@version" | awk -F"[.-]" '{printf("%d%02d%02d\n", $1, $2, $3)}'
$ mysql -sse "SELECT sys.version_major() * 10000 + sys.version_minor() * 100 + sys.version_patch()"

バイナリログだけのサイズを合計したい

$ mysql -sse "SHOW BYNARY LOGS" | awk '{i += $2}END{print i}' | numfmt --to=iec

(番外)リレーログだけのサイズを合計したい

  • SHOW BINARY LOGS みたいなのが無いので、厳密にやろうとすると大変 ( relay_log_basename をたどったりとか)。おとなしく *relay* で引いちゃうのが良いんではないか。
$ ls -l /path/to/datadir/*relay* | awk '{i += $5}END{print i}' | numfmt --to=iec

master_info_repositoryからCHANGE REPLICATION SOURCE TOステートメントを作る

  • 急に perl が出てくるのは awk だとシングルクォートが面倒だったから
$ mysql -sse "SELECT host, port, user_name, user_password, enabled_auto_position FROM mysql.slave_master_info WHERE channel_name = ''" |  perl -nlaE 'printf(qq{CHANGE REPLICATION SOURCE TO source_host = "%s", source_port = %d, source_user = "%s", source_password = "%s", source_auto_position = %d;\n}, @F)'

(番外) master.infoファイルからCHANGE REPLICATION SOURCE TOステートメントを作る

  • cat で取った内容を一度変数に詰めるとspace seperatedな1行に出来ることを利用している

    • ワンライナーじゃない(∩゚д゚)アーアーきこえなーい
  • master.info の並び順は一応ドキュメントに解説されているけれど、将来変わるかも知れないしそもそも master_info_repository=FILE 自体が非推奨になったので微妙。

$ line=$(cat master.info)
$ echo $line | while read dummy dummy dummy master_host master_user master_password master_port dummy ; do
  printf "CHANGE MASTER TO master_host = '%s', master_port = %d, master_user = '%s', master_password= '%s';\n" $master_host $master_port $master_user $master_password
done

ダメなクエリが延々流れてきてCPUが詰まっているのでとにかく来た順番にKILLしたい

  • grep次第で特定のクエリに絞ったり絞らなかったりができるあたりがよく使う所以か
$ mysql -sse "SHOW PROCESSLIST" | grep -v 'system user' | grep -v 'Binlog Dump' | awk -F"\t" -v timelimit=10 '$6 > timelimit && $5 != "Sleep"{print $1}' | while read id ; do
  mysql -e "KILL $id"
done

MySQL 8.0とそれ以降でも mysql_native_passwordのハッシュを知りたい

$ mysql -sse "SELECT CONCAT('*', UPPER(SHA1(UNHEX(SHA1('$raw_password')))));"

read用のVIPでちゃんと分散してるかどうか確かめる

  • forの外側で sort | uniq -cでちゃんと分散してるか数える
$ for n in {1..100}; do
  mysql -h $read_vip -sse "SELECT @@hostname"
done | sort | uniq -c

auto_incrementなカラムで梳きながらDELETEなりUPDATEなりする

$ for ((i=$min; i<=$max; i+=$limit)); do 
  mysql -ve "DELETE FROM t1 WHERE id BETWEEN $i AND $i+$limit AND $original_where_clause"
 sleep $sleep
done

圧縮しながらxtrabackupを取る

  • ファイルリダイレクトでなく ssh "cat - > .." とかにパイプすればリモートにも転送できる
$ xtrabackup -uroot --stream=xbstream --backup | pzstd -c > xtrabackup.xb.zst

圧縮済のxbstreamを展開する

  • ↑の逆パターン
    • カレントディレクトリに色々ぶちまけるのでワーキングディレクトリを作った方が良いと思う
$ pzstd -dc xtrabackup.xb.zst | xbstream -xv

トランザクションがなかなか途切れないテーブルにどうしてもALTER TABLEしたくて1秒までなら何とか我慢しながら成功するまでひたすらリトライする

  • 1秒までの他のクエリのブロッキングは許す(でないといつまでも終わらない)
  • オンラインALTER TABLEは「2回」メタデータロックを取るので、開始前と終了直前どちらでタイムアウトする可能性もある
    • 30分かかるALTER TABLEが終了処理のメタデータロックでタイムアウトしても泣かない
$ while true ; do
  mysql -sse "SET SESSION lock_wait_timeout= 1; ALTER TABLE t1 ADD KEY idx_something(some_column)" || break
  sleep 1
done

バックアップしたりリストアしたりKILLしたりALTER TABLE無限リトライなんてことをしょっちゅうやってるんですねわかります!()

明日は taka_yuki_04 さんです!

2023/12/05

ConoHaの上でひたすらMySQLをビルドする in 2023

この記事は ConoHaのカレンダー | Advent Calendar 2023 と MySQLのカレンダー | Advent Calendar 2023 の5日目の記事です。

去年は CentOS 9 Stream でビルドしたらしい。

今年は Rocky Linux 8, 9 が正式にMySQLのSupported PlatformになったのでRocky Linux 9でやってみる。

(cppを足しておけば Rocky Linux 9でもビルドできた可能性がある)



$ cat /etc/os-release

NAME="Rocky Linux"

VERSION="9.2 (Blue Onyx)"

ID="rocky"

ID_LIKE="rhel centos fedora"

VERSION_ID="9.2"

PLATFORM_ID="platform:el9"

PRETTY_NAME="Rocky Linux 9.2 (Blue Onyx)"

ANSI_COLOR="0;32"

LOGO="fedora-logo-icon"

CPE_NAME="cpe:/o:rocky:rocky:9::baseos"

HOME_URL="https://rockylinux.org/"

BUG_REPORT_URL="https://bugs.rockylinux.org/"

SUPPORT_END="2032-05-31"

ROCKY_SUPPORT_PRODUCT="Rocky-Linux-9"

ROCKY_SUPPORT_PRODUCT_VERSION="9.2"

REDHAT_SUPPORT_PRODUCT="Rocky Linux"

REDHAT_SUPPORT_PRODUCT_VERSION="9.2"

MySQLは折角だから8.2.0を選ぶぜ!

$ wget https://dev.mysql.com/get/Downloads/MySQL-8.2/mysql-boost-8.2.0.tar.gz
$ tar xf mysql-boost-8.2.0.tar.gz
$ mkdir build
$ cd build
$ cmake -DWITH_BOOST=../mysql-8.2.0/boost ../mysql-8.2.0
-bash: cmake: command not found

まずはcmake

$ sudo dnf install -y cmake
$ cmake -DWITH_BOOST=../mysql-8.2.0/boost ../mysql-8.2.0
..
CMake Warning at CMakeLists.txt:397 (MESSAGE):
  Could not find devtoolset compiler/linker in /opt/rh/gcc-toolset-12

CMake Warning at CMakeLists.txt:399 (MESSAGE):
  You need to install the required packages:

   yum install gcc-toolset-12-gcc gcc-toolset-12-gcc-c++ gcc-toolset-12-binutils gcc-toolset-12-annobin-annocheck gcc-toolset-12-annobin-plugin-gcc

CMake Error at CMakeLists.txt:401 (MESSAGE):
  Or you can set CMAKE_C_COMPILER and CMAKE_CXX_COMPILER explicitly.

-- Configuring incomplete, errors occurred!

メッセージの通りgcc, gcc-c++, binutilsとかを突っ込む

$ sudo dnf install -y gcc-toolset-12-gcc gcc-toolset-12-gcc-c++ gcc-toolset-12-binutils gcc-toolset-12-annobin-annocheck gcc-toolset-12-annobin-plugin-gcc

$ cmake -DWITH_BOOST=../mysql-8.2.0/boost ../mysql-8.2.0

..
-- Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the system variable OPENSSL_ROOT_DIR (missing: OPENSSL_CRYPTO_LIBRARY OPENSSL_INCLUDE_DIR)
--
Could not find system OpenSSL
Make sure you have specified a supported SSL version.
Valid options are :
openssl[0-9]+ (use alternative system library)
yes (synonym for system)
</path/to/custom/openssl/installation>

CMake Error at cmake/ssl.cmake:84 (MESSAGE):
  Please install the appropriate openssl developer package.

Call Stack (most recent call first):
  cmake/ssl.cmake:346 (FATAL_SSL_NOT_FOUND_ERROR)
  cmake/ssl.cmake:518 (FIND_SYSTEM_OPENSSL)
  CMakeLists.txt:1831 (MYSQL_CHECK_SSL)

次はopenssl-devel

$ sudo dnf install -y openssl-devel
$ cmake -DWITH_BOOST=../mysql-8.2.0/boost ../mysql-8.2.0
..
CMake Error at cmake/readline.cmake:92 (MESSAGE):
  Curses library not found.  Please install appropriate package,

      remove CMakeCache.txt and rerun cmake.On Debian/Ubuntu, package name is libncurses5-dev, on Redhat and derivates it is ncurses-devel.
Call Stack (most recent call first):
  cmake/readline.cmake:126 (FIND_CURSES)
  cmake/readline.cmake:220 (MYSQL_USE_BUNDLED_EDITLINE)
  CMakeLists.txt:1934 (MYSQL_CHECK_EDITLINE)

ncurses-devel. これはCMaKeCache.txt消してあげないといけないやつ。

$ sudo dnf install -y ncurses-devel
$ rm CMakeCache.txt
$ cmake -DWITH_BOOST=../mysql-8.2.0/boost ../mysql-8.2.0
..
CMake Warning at cmake/rpc.cmake:40 (MESSAGE):
  Cannot find RPC development libraries.  You need to install the required
  packages:

    Debian/Ubuntu:              apt install libtirpc-dev
    RedHat/Fedora/Oracle Linux: yum install libtirpc-devel
    SuSE:                       zypper install glibc-devel

Call Stack (most recent call first):
  cmake/rpc.cmake:96 (WARN_MISSING_SYSTEM_TIRPC)
  plugin/group_replication/libmysqlgcs/cmake/configure.cmake:34 (MYSQL_CHECK_RPC)
  plugin/group_replication/libmysqlgcs/CMakeLists.txt:31 (INCLUDE)

CMake Error at cmake/rpc.cmake:97 (MESSAGE):
  Could not find rpc/rpc.h in /usr/include or /usr/include/tirpc
Call Stack (most recent call first):
  plugin/group_replication/libmysqlgcs/cmake/configure.cmake:34 (MYSQL_CHECK_RPC)
  plugin/group_replication/libmysqlgcs/CMakeLists.txt:31 (INCLUDE)

毎年引っかかるrpc.h

$ sudo dnf install -y libtirpc-devel
Last metadata expiration check: 0:10:10 ago on Mon Dec  4 15:11:45 2023.
No match for argument: libtirpc-devel
Error: Unable to find a match: libtirpc-devel

エラーメッセージの通りにやるとそんなものないと言われる… 去年の自分に助けられ て、crbなるリポジトリにあることが判明。

$ sudo dnf install -y --enablerepo=crb libtirpc-devel
$ cmake -DWITH_BOOST=../mysql-8.2.0/boost ../mysql-8.2.0

..
CMake Warning at cmake/rpc.cmake:29 (MESSAGE):
  Cannot find rpcgen executable.  You need to install the required packages:

    Debian/Ubuntu:              apt install rpcsvc-proto
    RedHat/Fedora/Oracle Linux: yum install rpcgen
    SuSE:                       zypper install glibc-devel

Call Stack (most recent call first):
  plugin/group_replication/libmysqlgcs/cmake/rpcgen.cmake:122 (WARN_MISSING_RPCGEN_EXECUTABLE)
  plugin/group_replication/libmysqlgcs/CMakeLists.txt:50 (INCLUDE)

CMake Error at plugin/group_replication/libmysqlgcs/cmake/rpcgen.cmake:123 (MESSAGE):
  Could not find rpcgen
Call Stack (most recent call first):
  plugin/group_replication/libmysqlgcs/CMakeLists.txt:50 (INCLUDE)

rpcgenと同じものなのかと思ったらrpcgenはrpcgenでいるらしい。

$ sudo dnf install -y --enablerepo=crb rpcgen
$ cmake -DWITH_BOOST=../mysql-8.2.0/boost ../mysql-8.2.0
..
-- Build files have been written to: /home/yoku0825/build

cmake完了。 今年は ~さっさと終わらせたくて~ 奮発して4コア4GBのインスタンスを使ってるので少しは快適か

$ time make -j$(nproc)
..
[ 52%] Building CXX object plugin/group_replication/libmysqlgcs/CMakeFiles/mysqlgcs.dir/src/bindings/xcom/xcom/pax_msg.cc.o
In file included from /home/yoku0825/mysql-8.2.0/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/pax_msg.cc:30:
/home/yoku0825/mysql-8.2.0/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/app_data.h:43:1: error: ‘app_data_ptr’ does not name a type
   43 | app_data_ptr clone_app_data(app_data_ptr a);
      | ^~~~~~~~~~~~
/home/yoku0825/mysql-8.2.0/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/app_data.h:44:1: error: ‘app_data_ptr’ does not name a type
   44 | app_data_ptr clone_app_data_single(app_data_ptr a);
      | ^~~~~~~~~~~~
/home/yoku0825/mysql-8.2.0/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/app_data.h:45:1: error: ‘app_data_ptr’ does not name a type
   45 | app_data_ptr new_app_data();
      | ^~~~~~~~~~~~

..
/home/yoku0825/mysql-8.2.0/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/site_def.h:67:22: warning: ‘node_no_exists’ defined but not used [-Wunused-variable]
   67 | static inline bool_t node_no_exists(node_no n, site_def const *site) {
      |                      ^~~~~~~~~~~~~~
/home/yoku0825/mysql-8.2.0/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/synode_no.h:44:19: warning: ‘group_mismatch’ defined but not used [-Wunused-variable]
   44 | static inline int group_mismatch(synode_no x, synode_no y) {
      |                   ^~~~~~~~~~~~~~
make[2]: *** [plugin/group_replication/libmysqlgcs/CMakeFiles/mysqlgcs.dir/build.make:99: plugin/group_replication/libmysqlgcs/CMakeFiles/mysqlgcs.dir/src/bindings/xcom/xcom/pax_msg.cc.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:9709: plugin/group_replication/libmysqlgcs/CMakeFiles/mysqlgcs.dir/all] Error 2
make: *** [Makefile:166: all] Error 2

real    2m5.571s
user    7m22.443s
sys     0m50.147s

あれ、転けた。。

なんかどうもこれと同じような気がするけど解決方法が全く分からない…。

諦めてRocky Linux 8にすることにする!

改めて。

$ cat /etc/os-release
NAME="Rocky Linux"
VERSION="8.7 (Green Obsidian)"
ID="rocky"
ID_LIKE="rhel centos fedora"
VERSION_ID="8.7"
PLATFORM_ID="platform:el8"
PRETTY_NAME="Rocky Linux 8.7 (Green Obsidian)"
ANSI_COLOR="0;32"
LOGO="fedora-logo-icon"
CPE_NAME="cpe:/o:rocky:rocky:8:GA"
HOME_URL="https://rockylinux.org/"
BUG_REPORT_URL="https://bugs.rockylinux.org/"
ROCKY_SUPPORT_PRODUCT="Rocky-Linux-8"
ROCKY_SUPPORT_PRODUCT_VERSION="8.7"
REDHAT_SUPPORT_PRODUCT="Rocky Linux"
REDHAT_SUPPORT_PRODUCT_VERSION="8.7"

$ sudo dnf install -y cmake gcc-toolset-12-gcc gcc-toolset-12-gcc-c++ gcc-toolset-12-binutils gcc-toolset-12-annobin-annocheck gcc-toolset-12-annobin-plugin-gcc openssl-devel ncurses-devel --enablerepo=powertools libtirpc-devel rpcgen

$ wget https://dev.mysql.com/get/Downloads/MySQL-8.2/mysql-boost-8.2.0.tar.gz
$ tar xf mysql-boost-8.2.0.tar.gz
$ mkdir build
$ cd build

$ cmake -DWITH_BOOST=../mysql-8.2.0/boost ../mysql-8.2.0

$ time make -j$(nproc)

..
[ 13%] Generating xdr_gen/xcom_vp.h, xdr_gen/xcom_vp_xdr.c
cannot find C preprocessor: cpp
/usr/bin/rpcgen: C preprocessor failed with exit code 1
[ 13%] Building CXX object extra/icu/CMakeFiles/icuuc.dir/icu-release-73-1/source/common/ucnv_lmb.cpp.o
cannot find C preprocessor: cpp
/usr/bin/rpcgen: C preprocessor failed with exit code 1
cannot find C preprocessor: cpp
/usr/bin/rpcgen: C preprocessor failed with exit code 1
cannot find C preprocessor: cpp
/usr/bin/rpcgen: C preprocessor failed with exit code 1
cannot find C preprocessor: cpp
/usr/bin/rpcgen: C preprocessor failed with exit code 1
[ 13%] Building CXX object mysys/CMakeFiles/mysys_objlib.dir/my_kdf.cc.o
cannot find C preprocessor: cpp
/usr/bin/rpcgen: C preprocessor failed with exit code 1
cannot find C preprocessor: cpp
/usr/bin/rpcgen: C preprocessor failed with exit code 1
cannot find C preprocessor: cpp
/usr/bin/rpcgen: C preprocessor failed with exit code 1
cannot find C preprocessor: cpp
/usr/bin/rpcgen: C preprocessor failed with exit code 1
cannot find C preprocessor: cpp
/usr/bin/rpcgen: C preprocessor failed with exit code 1
[ 13%] Building CXX object extra/icu/CMakeFiles/icui18n.dir/icu-release-73-1/source/i18n/nortrans.cpp.o
cannot find C preprocessor: cpp
/usr/bin/rpcgen: C preprocessor failed with exit code 1
cannot find C preprocessor: cpp
/usr/bin/rpcgen: C preprocessor failed with exit code 1
[ 13%] Building CXX object plugin/group_replication/libmysqlgcs/CMakeFiles/mysqlgcs.dir/src/bindings/xcom/xcom/pax_msg.cc.o
In file included from /home/yoku0825/mysql-8.2.0/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/pax_msg.cc:30:
/home/yoku0825/mysql-8.2.0/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/app_data.h:43:1: error: 'app_data_ptr' does not name a type
   43 | app_data_ptr clone_app_data(app_data_ptr a);
      | ^~~~~~~~~~~~

..

もしかして cannot find C preprocessor: cpp を見落としてた?

$ sudo dnf install cpp
$ time make -j$(nproc)
..

違った。 なんかrpcgenをもう一度やってない気がしたのでビルドディレクトリを綺麗にしてもう一度makeしてみる。

$ rm -r *
$ cmake -DWITH_BOOST=../mysql-8.2.0/boost ../mysql-8.2.0
$ make -j$(nproc)
..
[100%] Building CXX object unittest/gunit/CMakeFiles/merge_large_tests-t.dir/__/__/storage/example/ha_example.cc.o
[100%] Linking CXX executable ../../runtime_output_directory/merge_large_tests-t
[100%] Built target merge_large_tests-t

上手くいったじゃん…。

ということはcppを足してからやり直せばRocky Linux 9でも上手くいくかも知れない。初回で見落として繰り返してしまったか…。

けど、それは来年にでもやるとして今年もお疲れさまでした。