2019年4月23日火曜日

MySQL 8.0.15現在、 SET PERSIST_ONLY にはあんまり手を出さない方が良いと思う

TL;DR

  • 手を出さない方がいいのはSET PERSIST_ONLYの話で、SET PERSISTは手を出してもいいと思う
  • SET GLOBAL, SET PERSIST には値をセットするためのバリデーター(各サーバー変数ごとにある)が用意されているが、 SET PERSIST_ONLY はそのバリデーターを通らないため、不正な値を突っ込んでもエラーになってくれない
  • mysqld を再起動しようとした時に、 mysqld-auto.cnfSET PERSIST, SET PERSIST_ONLY の保管先)に不正な値が突っ込んであるとそれを適用できなくて mysqld が起動してくれない

最初に見つけた時は innodb_ft_aux_table で見つけたのでそんなにアレじゃないかなと思ってたんだけれども、 SET GLOBAL, SET PERSIST には値をセットするためのバリデーター(各サーバー変数ごとにある)が用意されているが、 SET PERSIST_ONLY はそのバリデーターを通らないため、不正な値を突っ込んでもエラーになってくれない、という不具合を3月にレポートしていた。
数値型のやつに文字列型、みたいなやつはちゃんと弾いてくれる。

mysql80 8> SET PERSIST_ONLY max_connections= 'abc';

ERROR 1232 (42000): Incorrect argument type to variable 'max_connections'
問題になるのは、「文字列型を受け取るけどそれにもちゃんとルールがある」やつだ。
ばぐれぽ で使っている innodb_ft_aux_table は「フルテキストインデックスが存在するテーブル」を指定しなければならない。それ以外のテーブルを指定した場合はエラーになる。
mysql80 8> SHOW CREATE TABLE d1.t1\G -- フルテキストインデックスがない
*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE `t1` (
  `num` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `val` varchar(32) DEFAULT NULL,
  UNIQUE KEY `num` (`num`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)

mysql80 8> SET GLOBAL innodb_ft_aux_table = 'd1/t1';
ERROR 1231 (42000): Variable 'innodb_ft_aux_table' can't be set to the value of 'd1/t1'
SET PERSIST_ONLY はこれをすり抜けるので、次に mysqld を起動しようとした時にこの不正な値がキマって起動しなくなる。
mysql80 8> SET PERSIST_ONLY innodb_ft_aux_table = 'd1/t1';
Query OK, 0 rows affected (0.00 sec)

mysql80 8> SELECT * FROM performance_schema.persisted_variables;
+---------------------+----------------+
| VARIABLE_NAME       | VARIABLE_VALUE |
+---------------------+----------------+
| innodb_ft_aux_table | d1/t1          |
+---------------------+----------------+
1 row in set (0.01 sec)
ちなみに「間違った!」というのがわかるのであれば、 RESET PERSIST ステートメントでクリアできる。 mysqld を落とす前なら。
mysql80 8> RESET PERSIST innodb_ft_aux_table;
Query OK, 0 rows affected (0.00 sec)

mysql80 8> SELECT * FROM performance_schema.persisted_variables;
Empty set (0.00 sec)
話が厄介なのは、「ENUMなサーバー変数」で、コイツは「文字列でも数値でもセットできる」「本来正しい(?)値は文字列型」「数値を渡された時に文字列に変換しているのはどうやら変数セット時のバリデーター」というアレがあり、
mysql80 8> SELECT @@binlog_error_action;
+-----------------------+
| @@binlog_error_action |
+-----------------------+
| ABORT_SERVER          |
+-----------------------+
1 row in set (0.00 sec)

mysql80 8> SET GLOBAL binlog_error_action = 0; -- SET GLOBALで数値をセットするじゃろ?
Query OK, 0 rows affected (0.00 sec)

mysql80 8> SELECT @@binlog_error_action; -- ちゃんと文字列で表示されるじゃろ?
+-----------------------+
| @@binlog_error_action |
+-----------------------+
| IGNORE_ERROR          |
+-----------------------+
1 row in set (0.00 sec)
mysql80 8> SET PERSIST_ONLY binlog_error_action = 0; -- PERSIST_ONLYで数値をセットするじゃろ?
Query OK, 0 rows affected (0.00 sec)

mysql80 8> SELECT * FROM performance_schema.persisted_variables; -- 0のままじゃろ?
+---------------------+----------------+
| VARIABLE_NAME       | VARIABLE_VALUE |
+---------------------+----------------+
| binlog_error_action | 0              |
+---------------------+----------------+
1 row in set (0.00 sec)

mysql80 8> RESTART; -- キマるんじゃ
Query OK, 0 rows affected (0.01 sec)
エラーログはこんなんなりました。
無限にプロセスの起動失敗と再起動を繰り返しております(たぶん RESTART ステートメントじゃなくて systemctl restart mysqld とかだと綺麗に死んでくれるかな…わからん)
2019-04-23T08:29:56.321633Z 8 [System] [MY-011086] [Server] Received RESTART from user root.  Restarting mysqld (Version: 8.0.15).
..
2019-04-23T08:30:00.242090Z 0 [System] [MY-010910] [Server] /usr/mysql/8.0.15/bin/mysqld: Shutdown complete (mysqld 8.0.15)  Source di
stribution.
2019-04-23T08:30:00.388768Z mysqld_safe Number of processes running now: 0
2019-04-23T08:30:00.393888Z mysqld_safe mysqld restarted

..
2019-04-23T08:30:12.326063Z 5 [ERROR] [MY-011268] [Server] Configuring persisted options failed: "Variable 'binlog_error_action' can't
 be set to the value of '0'".
2019-04-23T08:30:12.326121Z 0 [ERROR] [MY-010175] [Server] Setting persistent options failed.
2019-04-23T08:30:12.440194Z mysqld_safe Number of processes running now: 0
2019-04-23T08:30:12.444490Z mysqld_safe mysqld restarted

..
2019-04-23T08:30:13.507286Z 5 [ERROR] [MY-011268] [Server] Configuring persisted options failed: "Variable 'binlog_error_action' can't
 be set to the value of '0'".
2019-04-23T08:30:13.507327Z 0 [ERROR] [MY-010175] [Server] Setting persistent options failed.
2019-04-23T08:30:13.633597Z mysqld_safe Number of processes running now: 0
2019-04-23T08:30:13.638389Z mysqld_safe mysqld restarted

..
2019-04-23T08:30:15.253603Z 5 [ERROR] [MY-011268] [Server] Configuring persisted options failed: "Variable 'binlog_error_action' can't
 be set to the value of '0'".
2019-04-23T08:30:15.253652Z 0 [ERROR] [MY-010175] [Server] Setting persistent options failed.
2019-04-23T08:30:15.364141Z mysqld_safe Number of processes running now: 0
2019-04-23T08:30:15.368649Z mysqld_safe mysqld restarted

..





0 件のコメント :

コメントを投稿