GA

2020/07/30

MySQL 8.0.17とそれ以前では、CREATE USER .. DEFAULT ROLE ..構文を使うと、ロールの情報が正しくレプリケーションされない

TL;DR

  • mysql.role_edges テーブルと mysql.default_roles テーブルがマスターとスレーブでズレる
    • マスターでは登録されるけどスレーブでは登録されない
    • つまりスレーブでは「そのロールを使う権限もそのロールがデフォルトロールである情報も失われる」
  • See MySQL Bugs: #93252: Default role is not logged into the binary log
    • Fixed in 8.0.18

8.0.15を使ってレプリケーションを組んでいたらハマった。
バイナリログへの記録がそもそもおかしいことになる。

mysql> SELECT @@version;
+-----------+
| @@version |
+-----------+
| 8.0.17    |
+-----------+
1 row in set (0.00 sec)

mysql> CREATE ROLE myrole;
Query OK, 0 rows affected (0.01 sec)

mysql> CREATE USER yoku0825 DEFAULT ROLE myrole;
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW BINLOG EVENTS IN 'binlog.000002';
+---------------+-----+----------------+-----------+-------------+--------------------------------------------------------------------------------+
| Log_name      | Pos | Event_type     | Server_id | End_log_pos | Info                                                                           |
+---------------+-----+----------------+-----------+-------------+--------------------------------------------------------------------------------+
| binlog.000002 |   4 | Format_desc    |         1 |         124 | Server ver: 8.0.17, Binlog ver: 4                                              |
| binlog.000002 | 124 | Previous_gtids |         1 |         155 |                                                                                |
| binlog.000002 | 155 | Anonymous_Gtid |         1 |         232 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                                           |
| binlog.000002 | 232 | Query          |         1 |         333 | CREATE ROLE myrole /* xid=7 */                                                 |
| binlog.000002 | 333 | Anonymous_Gtid |         1 |         410 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                                           |
| binlog.000002 | 410 | Query          |         1 |         559 | CREATE USER 'yoku0825'@'%' IDENTIFIED WITH 'caching_sha2_password' /* xid=8 */ |
+---------------+-----+----------------+-----------+-------------+--------------------------------------------------------------------------------+
6 rows in set (0.00 sec)

そもそも、 binlog_format によらずSQLがそのまま転記されるタイプの CREATE USER ステートメントだが「俺が打ったものと若干違う(そしてそこには DEFAULT ROLE 句はない)」ことがお分かりいただけるだろうか。

この CREATE USER ステートメントの書き換え自体は ずっと昔からやっていてIDENTIFIED BY で平文パスワードを指定しても「平文はバイナリログに載せず、ハッシュ後の値でバイナリログに載せる」ために構文を書き換えたりしていた。あとは認証プラグインの情報とかも追記している(これはいつからだったか…)

で、その書き換え部分にバグがあったっぽい。
修正コミットはこれ。

Bug#28948915 DEFAULT ROLE IS NOT LOGGED INTO THE BINARY LOG · mysql/mysql-server@d278a87

CREATE USER .. DEFAULT ROLE .. は「ユーザー作成」「ロールの許可」「デフォルトロールの指定」がいっぺんに指定できて便利なんだけど、MySQL 8.0.17とそれ以前を使っている場合は注意。

日々の覚書: CREATE USER .. DEFAULT ROLE .. で指定すると一発でROLEも許可される

( ´-`).oO(↑の時点では気が付いてなくて、最近スレーブをスイッチオーバーさせようとして初めて気が付いた…つらい…

pt-table-checksum で mysql.role_edges とmysql.default_roles だけがズレてたらこれかも知れないので気を付けて!

0 件のコメント :

コメントを投稿