2014年11月4日火曜日

Percona Server 5.6.21にsuper_read_onlyが来ました

【2015/07/10 10:06】
MySQL 5.7.8にもsuper_read_onlyが来るらしいですよ!

MySQL 5.7.8 – Now featuring super_read_only and disabled_storage_engines | Master MySQL


super_read_onlyって何?
  => Facebook MySQL 5.6が最初に突っ込んだ(と思う)機能 で、
      Super_privがあってもread_only状態を無視できなくする機能(フツーのread_onlyはSuper_privがあると更新できちゃう)
    => これがFacebook MySQLから WebScaleSQL にポートされて、それが更に Percona Server にポートされたかたち。
      => Percona Server 5.6.21-70.0 is now available

これによってアプリのユーザーが何故かSuper_privを持ってる不思議な環境でもスレーブを勝手に更新されるとかなくなるわけですね!

…や、そのために全部Percona Server 5.6にするくらいなら、がんばってSuper_priv撲滅したい。


取り敢えず試してみる。


$ bin/mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.6.21-70.0-log Source distribution

Copyright (c) 2009-2014 Percona LLC and/or its affiliates
Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> SHOW GLOBAL VARIABLES LIKE '%read_only';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| innodb_read_only | OFF   |
| read_only        | OFF   |
| super_read_only  | OFF   |
| tx_read_only     | OFF   |
+------------------+-------+
4 rows in set (0.05 sec)

mysql> SET GLOBAL read_only= 1;
Query OK, 0 rows affected (0.14 sec)

mysql> SHOW GLOBAL VARIABLES LIKE '%read_only';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| innodb_read_only | OFF   |
| read_only        | ON    |
| super_read_only  | OFF   |
| tx_read_only     | OFF   |
+------------------+-------+
4 rows in set (0.11 sec)

mysql> CREATE TABLE read_only_without_super_read_only (num int);
Query OK, 0 rows affected (0.37 sec)

ここまではただのread_onlyなので、Super_priv持ち(rootでログインしておる)のユーザーの場合はCREATE TABLEできてしまう。


mysql> SET GLOBAL super_read_only= 1;
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW GLOBAL VARIABLES LIKE '%read_only';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| innodb_read_only | OFF   |
| read_only        | ON    |
| super_read_only  | ON    |
| tx_read_only     | OFF   |
+------------------+-------+
4 rows in set (0.00 sec)

mysql> CREATE TABLE super_read_only (num int);
ERROR 1290 (HY000): The MySQL server is running with the --read-only (super) option so it cannot execute this statement

super_read_onlyにしたら作れなくなったよ! \(^o^)/

…地味ですね。まあ地味な機能ですものね。
しかし、Percona ServerがWebScaleSQLの機能を取り込んだのは大きいようなそうでもないような。
(Perconaのイメージ的に、本家のは漏れなく取り込むし、HandlerSocketやMariaDB由来のパッチも「そろそろ枯れてきたんじゃね?」ってPerconaが判断したタイミングで取り込んでいるイメージ)

MariaDBも追随するかなぁ?
TokuDBはどっちが先だったか忘れたけど、GaleraもPercona先行でMariaDBも追随した感じだから、動き始めるかもしれない。


ちなみにこのsuper_read_only、飽くまでread_onlyの拡張なので

mysql> SHOW GLOBAL VARIABLES LIKE '%read_only';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| innodb_read_only | OFF   |
| read_only        | ON    |
| super_read_only  | ON    |
| tx_read_only     | OFF   |
+------------------+-------+
4 rows in set (0.00 sec)

mysql> SET GLOBAL read_only= 0;
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW GLOBAL VARIABLES LIKE '%read_only';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| innodb_read_only | OFF   |
| read_only        | OFF   |
| super_read_only  | OFF   |
| tx_read_only     | OFF   |
+------------------+-------+
4 rows in set (0.00 sec)

mysql> SET GLOBAL super_read_only= 1;
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW GLOBAL VARIABLES LIKE '%read_only';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| innodb_read_only | OFF   |
| read_only        | ON    |
| super_read_only  | ON    |
| tx_read_only     | OFF   |
+------------------+-------+
4 rows in set (0.00 sec)

read_onlyを無効にしてsuper_read_onlyだけONにするとか不思議なマネは出来ないようにちゃんとなっている。

エラーメッセージに"(super)"を書き足してるのは随所に見られるけど、sql/sql_parse.ccのdeny_updates_if_read_only_option()をゴニョゴニョしているところが本体だと思う。


$ diff -c <(sed -n '/deny_updates_if_read_only_option/,/}/p' percona-server-5.6.21-70.0/sql/sql_parse.cc) <(sed -n '/deny_updates_if_read_only_option/,/}/p' mysql-5.6.21/sql/sql_parse.cc)
*** /dev/fd/63  2014-11-04 11:04:07.437501780 +0900
--- /dev/fd/62  2014-11-04 11:04:07.437501780 +0900
***************
*** 12,18 ****
      ((ulong)(thd->security_ctx->master_access & SUPER_ACL) ==
       (ulong)SUPER_ACL);

!   if (user_is_super && (!opt_super_readonly))
      DBUG_RETURN(FALSE);

    if (!(sql_command_flags[lex->sql_command] & CF_CHANGES_DATA))
--- 12,18 ----
      ((ulong)(thd->security_ctx->master_access & SUPER_ACL) ==
       (ulong)SUPER_ACL);

!   if (user_is_super)
      DBUG_RETURN(FALSE);

    if (!(sql_command_flags[lex->sql_command] & CF_CHANGES_DATA))
***************
*** 48,54 ****
    }
      if (deny_updates_if_read_only_option(thd, all_tables))
      {
!       my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0),
!                opt_super_readonly ? "--read-only (super)" : "--read-only");
        DBUG_RETURN(-1);
      }
--- 48,53 ----
    }
      if (deny_updates_if_read_only_option(thd, all_tables))
      {
!       my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
        DBUG_RETURN(-1);
      }

0 件のコメント :

コメントを投稿