TL;DR
- 手を出さない方がいいのはSET PERSIST_ONLYの話で、SET PERSISTは手を出してもいいと思う
SET GLOBAL
,SET PERSIST
には値をセットするためのバリデーター(各サーバー変数ごとにある)が用意されているが、SET PERSIST_ONLY
はそのバリデーターを通らないため、不正な値を突っ込んでもエラーになってくれないmysqld
を再起動しようとした時に、mysqld-auto.cnf
(SET 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
..
良い子のみんな、 `SET PERSIST_ONLY` を使って良いのはニンジャだけだ。良い子は `SET PERSIST` を使うんだ。— yoku0825 (@yoku0825) 2019年4月23日
0 件のコメント :
コメントを投稿