GA

2024/01/19

keyring_file_dataに相対パスを指定したらdatadirからの相対パスで作られてしまった


TL;DR

  • keyring_file_data に絶対パスを指定したら面倒なことになった
  • 相対パスを指定するとdatadirの真下に作りやがる

準備。 keyring_file_data を指定しない場合はコンパイル時デフォルト (rpmは /var/lib/mysql-keyring 、 Standaloneは basedir/keyring ) に作る。

$ sudo dnf install -y https://dev.mysql.com/get/mysql80-community-release-el8-9.noarch.rpm
$ sudo dnf module -y disable mysql
$ sudo dnf install -y mysql-community-server
$ sudo vim /etc/my.cnf
..
user=mysql
early_plugin_load=keyring_file.so

$ sudo mysqld --initialize-insecure
$ sudo systemctl start mysqld
$ sudo mysql -e "CREATE DATABASE d1; CREATE TABLE d1.t1 (num int) ENCRYPTION='Y'; INSERT INTO d1.t1 VALUES(1), (2), (3)"

$ sudo ls -l /var/lib/mysql-keyring/keyring
-rw-r-----. 1 mysql mysql 187 Jan 19 09:10 /var/lib/mysql-keyring/keyring

絶対パスに書き換えてみる。そのままだと自動生成に失敗するので先にディレクトリを作っておく。 ディレクトリには少なくとも700のパーミッションがないとkeyring_fileを掴むのに失敗して、MySQLは起動するけど ERROR 3185 (HY000) at line 1: Can't find master key from keyring, please check in the server log if a keyring is loaded and initialized successfully. のエラーを吐かれる

$ sudo systemctl stop mysqld
$ sudo dnf remove -y mysql-community-server
$ sudo rm -r /var/lib/mysql*

$ sudo dnf install -y mysql-community-server

$ sudo vim /etc/my.cnf
..
user=mysql
early_plugin_load=keyring_file.so
keyring_file_data=/mysql/mysql-secret

$ sudo mkdir -m 700 /mysql
$ sudo chown -R mysql. /mysql

$ sudo mysqld --initialize-insecure
$ sudo systemctl start mysqld
$ sudo mysql -e "CREATE DATABASE d1; CREATE TABLE d1.t1 (num int) ENCRYPTION='Y'; INSERT INTO d1.t1 VALUES(1), (2), (3)"

$ sudo ls -l /mysql/mysql-secret
-rw-r-----. 1 mysql mysql 187 Jan 19 09:23 /mysql/mysql-secret

相対パスに書き換えてみる。

$ sudo systemctl stop mysqld
$ sudo dnf remove -y mysql-community-server
$ sudo rm -r /var/lib/mysql* /mysql

$ sudo dnf install -y mysql-community-server

$ sudo vim /etc/my.cnf
..
user=mysql
early_plugin_load=keyring_file.so
keyring_file_data=./path_to_key

$ sudo mysqld --initialize-insecure
$ sudo systemctl start mysqld
$ sudo mysql -e "CREATE DATABASE d1; CREATE TABLE d1.t1 (num int) ENCRYPTION='Y'; INSERT INTO d1.t1 VALUES(1), (2), (3)"

$ sudo ls -l /var/lib/mysql/path_to_key
-rw-r-----. 1 mysql mysql 187 Jan 19 09:26 /var/lib/mysql/path_to_key

Σ(゚д゚lll) えっ、datadirからの相対パスだと解釈しちゃうの…?

2024/01/12

MySQL ShellのloadDumpが MySQL Error 1449 (HY000): The user specified as a definer ('xxx'@'%') does not exist で転けたり転けなかったりする

 

TL;DR

  • DEFINERが存在しないSQL SECURITY DEFINERなビューと、そのビューを使ったビューがある時にMySQL ShellのloadDumpが転けることも転けないこともある
    • mysqldumpからのリストアは100%転ける
  • 転けるのが正しい気がするけど何故か転けずに完了してしまうのが気になったのでこのエントリ

参考: 日々の覚書: MySQLの論理バックアップにおける2段階のViewのリストア

下準備。
ビューのDEFINERになっているアカウントをDROPして、「DEFINERが存在しないビュー」「そのビューを使ったビュー」を作る。
(先にアカウントを作ってからDROPしないと、「DEFINERが存在しないビュー」までは無理矢理作れるけれども「そのビューを使ったビュー」が作れない)

CREATE USER dummy;
CREATE DATABASE d1;
CREATE definer=dummy VIEW d1.v1 AS SELECT 1;
CREATE VIEW d1.v2 AS SELECT * FROM d1.v1;
DROP USER dummy;
SHOW WARNINGS;

DROP USERした時にちゃんとワーニングは出る。

mysql> SHOW WARNINGS;
+---------+------+----------------------------------------------------------------+
| Level   | Code | Message                                                        |
+---------+------+----------------------------------------------------------------+
| Warning | 4005 | User 'dummy'@'%' is referenced as a definer account in a view. |
+---------+------+----------------------------------------------------------------+
1 row in set (0.00 sec)

比較のためにmysqldumpも取っておく。ちなみに --single-transaction を省くと個別にLOCK TABLEしようとして転ける。

$ mysqldump -h172.17.0.2 -B d1 --single-transaction > /tmp/d1.sql

このダンプをリストアしようとすると必ず転ける。

$ mysql -h172.17.0.3 -vv < /tmp/d1.sql
..
--------------
/*!50001 CREATE ALGORITHM=UNDEFINED */
/*!50013 DEFINER=`root`@`%` SQL SECURITY DEFINER */
/*!50001 VIEW `v2` AS select `v1`.`1` AS `1` from `v1` */
--------------

ERROR 1449 (HY000) at line 85: The user specified as a definer ('dummy'@'%') does not exist
Bye

MySQL ShellでdumpInstanceする。

$ mysqlsh -h172.17.0.2 -- util dumpInstance '/tmp/dump'
Please provide the password for 'root@172.17.0.2':
Save password for 'root@172.17.0.2'? [Y]es/[N]o/Ne[v]er (default No):
Acquiring global read lock
Global read lock acquired
Initializing - done
1 out of 5 schemas will be dumped and within them 0 tables, 2 views.
3 out of 6 users will be dumped.
Gathering information - done
All transactions have been started
Locking instance for backup
Global read lock has been released
Writing global DDL files
Writing users DDL
Running data dump using 4 threads.
NOTE: Progress information uses estimated values and may not be accurate.
Writing schema metadata - done
Writing DDL - done
Writing table metadata - done
Starting data dump
?% (0 rows / ?), 0.00 rows/s, 0.00 B/s uncompressed, 0.00 B/s compressed
Dump duration: 00:00:00s
Total duration: 00:00:00s
Schemas dumped: 1
Tables dumped: 0
Uncompressed data size: 0 bytes
Compressed data size: 0 bytes
Compression ratio: 0.0
Rows written: 0
Bytes written: 0 bytes
Average uncompressed throughput: 0.00 B/s
Average compressed throughput: 0.00 B/s

この時、 /tmp/dump/d1.json に入っている views の順番も多少関係する。v1が先に来ていれば転ける確率の方が高くなり、v2が先に来ていれば転けない可能性の方が高かった。

$ cat /tmp/dump/d1.json
{
    "schema": "d1",
    "includesDdl": true,
    "includesViewsDdl": true,
    "includesData": true,
    "tables": [],
    "views": [
        "v2",
        "v1"
    ],
    "events": [],
    "functions": [],
    "procedures": [],
    "basenames": {
        "v2": "d1@v2",
        "v1": "d1@v1"
    }
}

--threads を大きめにすると転ける可能性が高くなる。

転けない時はこんな感じ。

$ mysqlsh -h172.17.0.4 -- util loadDump '/tmp/dump' --threads=10
Please provide the password for 'root@172.17.0.2':
Save password for 'root@172.17.0.2'? [Y]es/[N]o/Ne[v]er (default No):
Loading DDL and Data from '/tmp/dump' using 10 threads.
Opening dump...
Target is MySQL 8.0.35. Dump was produced from MySQL 8.0.35
Scanning metadata - done
Checking for pre-existing objects...
Executing common preamble SQL
Executing DDL - done
Executing view DDL - done
Executing common postamble SQL
Starting data load
?% (0 bytes / ?), 0.00 B/s, 0 / 0 tables done
Recreating indexes - done
No data loaded.
0 warnings were reported during the load.

転ける時はこんな感じ。

$ mysqlsh -h172.17.0.5 -- util loadDump '/tmp/dump' --threads=20
Please provide the password for 'root@172.17.0.2':
Save password for 'root@172.17.0.2'? [Y]es/[N]o/Ne[v]er (default No):
Loading DDL and Data from '/tmp/dump' using 20 threads.
Opening dump...
Target is MySQL 8.0.35. Dump was produced from MySQL 8.0.35
Scanning metadata - done
Checking for pre-existing objects...
Executing common preamble SQL
Executing DDL - done
ERROR: Error executing DDL script for view `d1`.`v2`: MySQL Error 1449 (HY000): The user specified as a definer ('dummy'@'%') does not exist: /*!50001 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`%` SQL SECURITY DEFINER VIEW `v2` AS select `v1`.`1` AS `1` from `v1` */
Executing view DDL - done
ERROR: The user specified as a definer ('dummy'@'%') does not exist

ビューを2段階リストアしているので、mysqldumpとかで直列にやった場合はこうなる。

CREATE VIEW v1 AS SELECT 1 AS 1;
CREATE VIEW v2 AS SELECT 1 AS 1;
DROP VIEW v1;
CREATE DEFINER=dummy VIEW v1 AS SELECT 1;
DROP VIEW v2;
CREATE VIEW v2 AS SELECT * FROM v1;    -- ここでER_NO_SUCH_USER(=1449)で転ける

しかしパラレルにリストアすると、まれに v2 と v1 のタイミングがひっくり返る。MySQL Shellはd1.jsonのviewsに順番に読もうとする(んだと思う)ので、v2が先に来ているとよくこの順番になるんではないか。

CREATE VIEW v1 AS SELECT 1 AS 1;
CREATE VIEW v2 AS SELECT 1 AS 1;
DROP VIEW v2;
CREATE VIEW v2 AS SELECT * FROM v1;    -- この時点ではv1は不正なビューではないので転けない

DROP VIEW v1;

CREATE DEFINER=dummy VIEW v1 AS SELECT 1;  -- 不正なビューだがワーニング止まりなので転けはしない

なので、転けたり転けなかったりするという違いが生まれている模様。
たぶん、動作としては常に転けるのが正しいとは思う。

2024/01/09

MySQLの論理バックアップにおける2段階のViewのリストア

TL;DR

  • mysqldump とかが CREATE VIEW v1 AS SELECT 1 AS num, 1 AS val とかいう一見VIEW定義となんの関係もない CREATE VIEW 文を吐く理由

mysqldumpは単にアルファベット順にテーブルやビューの定義を取得するので、シンプルに直接 CREATE VIEW を書いてしまうと順番によってはリストアに転ける。

mysql80 38> CREATE TABLE t1 (num serial, val varchar(32));
Query OK, 0 rows affected (0.04 sec)

mysql80 38> INSERT INTO t1 VALUES (1, 'one'), (2, 'two');
Query OK, 2 rows affected (0.01 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql80 38> CREATE VIEW v1 AS SELECT * FROM t1;
Query OK, 0 rows affected (0.01 sec)

mysql80 38> CREATE VIEW a_v1 AS SELECT val FROM v1 WHERE num = 1;
Query OK, 0 rows affected (0.02 sec)

mysql80 38> SHOW TABLES;
+--------------+
| Tables_in_d2 |
+--------------+
| a_v1         |              <-- ビューv1を参照しているのでアルファベット順にリストアすると転ける
| t1           |
| v1           |
+--------------+
3 rows in set (0.00 sec)

mysql80 38> use d3
Database changed

mysql80 38> CREATE VIEW a_v1 AS SELECT val FROM v1 WHERE num = 1;
ERROR 1146 (42S02): Table 'd3.v1' doesn't exist

なのでこれを避けるために、

  • Base Tableの CREATE TABLE と ダミーの CREATE VIEW を流す
  • ↑が流れ終わった後に本物の CREATE VIEW を流す
    という2ステップで実行している。
$ mysqldump80 d2
..
--
-- Temporary view structure for view `a_v1`
--

DROP TABLE IF EXISTS `a_v1`;
/*!50001 DROP VIEW IF EXISTS `a_v1`*/;
/*!50001 CREATE VIEW `a_v1` AS SELECT
 1 AS `val`*/;

--
-- Table structure for table `t1`
--

DROP TABLE IF EXISTS `t1`;
CREATE TABLE `t1` (
  `num` bigint unsigned NOT NULL AUTO_INCREMENT,
  `val` varchar(32) DEFAULT NULL,
  UNIQUE KEY `num` (`num`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

--
-- Temporary view structure for view `v1`
--

DROP TABLE IF EXISTS `v1`;
/*!50001 DROP VIEW IF EXISTS `v1`*/;
SET @saved_cs_client     = @@character_set_client;
/*!50001 CREATE VIEW `v1` AS SELECT
 1 AS `num`,
 1 AS `val`*/;

--
-- Final view structure for view `a_v1`
--

/*!50001 DROP VIEW IF EXISTS `a_v1`*/;
/*!50001 CREATE ALGORITHM=UNDEFINED */
/*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */
/*!50001 VIEW `a_v1` AS select `v1`.`val` AS `val` from `v1` where (`v1`.`num` = 1) */;

--
-- Final view structure for view `v1`
--

/*!50001 DROP VIEW IF EXISTS `v1`*/;
/*!50001 CREATE ALGORITHM=UNDEFINED */
/*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */
/*!50001 VIEW `v1` AS select `t1`.`num` AS `num`,`t1`.`val` AS `val` from `t1` */;

..
  1. 最初のTemporary view structureの時点では CREATE VIEW では固定値を列挙するだけなのでビューのビュー ( a_v1 )でも依存関係は問題はなくリストアできて
  2. Final view structureの時点でダミーを DROP VIEW して本来の定義を CREATE VIEW することで復元できる、たとえ順番が入れ違って a_v1 が先にリストアされても、カラムの定義まではダミーの方で作成済みなのでビューのビューでもリストアできる

という仕組み。

意外とよくできてる。

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でも上手くいくかも知れない。初回で見落として繰り返してしまったか…。

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