GA

2014/11/05

MySQL Fabricつらい(HA/登録編)

昨日インストールしたMySQL Fabric にファーム(MySQL Fabric管理下のmysqld群をこう呼ぶぽい)を追加していく。

まずはグループを作成。これが「同じデータセットを持っているマスターとスレーブの組」扱いになるはず。


$ mysqlfabric group create my_first_fabric --description="MySQL Fabric is too hard to me"
Password for admin:
Fabric UUID:  5ca1ab1e-a007-feed-f00d-cab3fe13249e
Time-To-Live: 1

                                uuid finished success result
------------------------------------ -------- ------- ------
8fb1a6df-0be9-4395-8240-8082c50a88e6        1       1      1

state success          when                                                   description
----- ------- ------------- -------------------------------------------------------------
    3       2   1.41515e+09 Triggered by <mysql.fabric.events.Event object at 0x24e2cd0>.
    4       2   1.41515e+09                             Executing action (_create_group).
    5       2   1.41515e+09                              Executed action (_create_group).


$ mysqlfabric group lookup_groups
Password for admin:
Fabric UUID:  5ca1ab1e-a007-feed-f00d-cab3fe13249e
Time-To-Live: 1

       group_id                    description failure_detector master_uuid
--------------- ------------------------------ ---------------- -----------
my_first_fabric MySQL Fabric is too hard to me                0        None

最初はdescriptionを"MySQL Fabricつらい"にしたんだけど、非ASCII文字だとlookup_groupsした時に表示されなかった(´・ω・`)
そしてグループにサーバーを追加する。


$ mysqlfabric group add my_first_fabric 127.0.0.1:20886
Password for admin:
Fabric UUID:  5ca1ab1e-a007-feed-f00d-cab3fe13249e
Time-To-Live: 1

ServerError: Error accessing server (127.0.0.1:20886): 1045 (28000): Access denied for user 'fabric'@'localhost' (using password: NO).

ありゃ、こっちにもfabricユーザー必要なの。


master> GRANT ALL ON fabric.* TO fabric@localhost IDENTIFIED BY 'fabric_password';

$ mysqlfabric group add my_first_fabric 127.0.0.1:20886
Password for admin:
Fabric UUID:  5ca1ab1e-a007-feed-f00d-cab3fe13249e
Time-To-Live: 1

ServerError: Error accessing server (127.0.0.1:20886): 1045 (28000): Access denied for user 'fabric'@'localhost' (using password: NO).

まだ転ける。ってか、using password: NOになってるじゃん。


$ vim /etc/mysql/fabric.cfg
..
[servers]
password = 
user = fabric
unreachable_timeout = 5
..

ここかな。password = fabric_passwordとして


$ mysqlfabric group add my_first_fabric 127.0.0.1:20886
Password for admin:
Fabric UUID:  5ca1ab1e-a007-feed-f00d-cab3fe13249e
Time-To-Live: 1

ServerError: Error accessing server (127.0.0.1:20886): 1045 (28000): Access denied for user 'fabric'@'localhost' (using password: NO).

( ゚д゚) ポルァ

マニュアル読むと、[servers]セクションで良さそうなもんなのに。。
http://dev.mysql.com/doc/mysql-utilities/1.5/en/fabric-cfgref-servers.html


==試行錯誤すること2時間あまり==


記載する先は[servers]セクションで合ってるけど、コンフィグ書き換えたあとに再起動が必要だった_| ̄|○ mysqlfabric groupで起動したmysqlfabricコマンドは飽くまでmysqlfabric manage startしたFabricサーバーのRPCを叩くだけで、実際にファームのMySQLにコマンドを投げたりしているのはmysqlfabric manage start側だった、という仕組みぽい。

これで今度こそ上手くいくのだー(フラグ)


$ mysqlfabric group add my_first_fabric 127.0.0.1:20886
Password for admin:
Fabric UUID:  5ca1ab1e-a007-feed-f00d-cab3fe13249e
Time-To-Live: 1

ServerError: User (fabric) does not have appropriate privileges (ALL PRIVILEGES) on server (127.0.0.1:20886, 47cf54df-63fc-11e4-942e-fa163e020fd0).

あ、グローバルALLが必要ですか。。


master> GRANT ALL ON *.* TO fabric@localhost;

$ mysqlfabric group add my_first_fabric 127.0.0.1:20886
Password for admin:
Fabric UUID:  5ca1ab1e-a007-feed-f00d-cab3fe13249e
Time-To-Live: 1

                                uuid finished success result
------------------------------------ -------- ------- ------
795e8cbc-5878-409a-9c7b-35c353081f8a        1       1      1

state success          when                                                   description
----- ------- ------------- -------------------------------------------------------------
    3       2   1.41516e+09 Triggered by .
    4       2   1.41516e+09                               Executing action (_add_server).
    5       2   1.41516e+09                                Executed action (_add_server).

$ mysqlfabric group lookup_servers my_first_fabric
Password for admin:
Fabric UUID:  5ca1ab1e-a007-feed-f00d-cab3fe13249e
Time-To-Live: 1

                         server_uuid         address    status      mode weight
------------------------------------ --------------- --------- --------- ------
47cf54df-63fc-11e4-942e-fa163e020fd0 127.0.0.1:20886 SECONDARY READ_ONLY    1.0

やっとキタ━━━━(゚∀゚)━━━━!!
この調子でスレーブも登録。


$ mysqlfabric group add my_first_fabric 127.0.0.1:20887
Password for admin:
Fabric UUID:  5ca1ab1e-a007-feed-f00d-cab3fe13249e
Time-To-Live: 1

                                uuid finished success result
------------------------------------ -------- ------- ------
59db0454-22cf-4a79-bd6a-9d576003be4a        1       1      1

state success          when                                                   description
----- ------- ------------- -------------------------------------------------------------
    3       2   1.41516e+09 Triggered by .
    4       2   1.41516e+09                               Executing action (_add_server).
    5       2   1.41516e+09                                Executed action (_add_server).


$ mysqlfabric group lookup_servers my_first_fabric
Password for admin:
Fabric UUID:  5ca1ab1e-a007-feed-f00d-cab3fe13249e
Time-To-Live: 1

                         server_uuid         address    status      mode weight
------------------------------------ --------------- --------- --------- ------
47cf54df-63fc-11e4-942e-fa163e020fd0 127.0.0.1:20886 SECONDARY READ_ONLY    1.0
4b7036a9-63fc-11e4-942e-fa163e020fd0 127.0.0.1:20887 SECONDARY READ_ONLY    1.0

チュートリアルでは「正しくレプリケーションが構成されていればpromoteしなくてもいいよ」とか言ってたけど、両方ともstatus: SECONDARYになっちゃってるしmode: READ_ONLYと認識されているのでpromoteしておく。


$ mysqlfabric group promote my_first_fabric
Password for admin:
Fabric UUID:  5ca1ab1e-a007-feed-f00d-cab3fe13249e
Time-To-Live: 1

                                uuid finished success result
------------------------------------ -------- ------- ------
1879f58e-f3a6-47b3-b70a-83d7756ea275        1       1      1

state success          when                                                   description
----- ------- ------------- -------------------------------------------------------------
    3       2   1.41516e+09 Triggered by .
    4       2   1.41516e+09                      Executing action (_define_ha_operation).
    5       2   1.41516e+09                       Executed action (_define_ha_operation).
    3       2   1.41516e+09 Triggered by .
    4       2   1.41516e+09                      Executing action (_find_candidate_fail).
    5       2   1.41516e+09                       Executed action (_find_candidate_fail).
    3       2   1.41516e+09 Triggered by .
    4       2   1.41516e+09                     Executing action (_check_candidate_fail).
    5       2   1.41516e+09                      Executed action (_check_candidate_fail).
    3       2   1.41516e+09 Triggered by .
    4       2   1.41516e+09                          Executing action (_wait_slave_fail).
    5       2   1.41516e+09                           Executed action (_wait_slave_fail).
    3       2   1.41516e+09 Triggered by .
    4       2   1.41516e+09                      Executing action (_change_to_candidate).
    5       2   1.41516e+09                       Executed action (_change_to_candidate).

$ mysqlfabric group lookup_servers my_first_fabric
Password for admin:
Fabric UUID:  5ca1ab1e-a007-feed-f00d-cab3fe13249e
Time-To-Live: 1

                         server_uuid         address    status       mode weight
------------------------------------ --------------- --------- ---------- ------
47cf54df-63fc-11e4-942e-fa163e020fd0 127.0.0.1:20886 SECONDARY  READ_ONLY    1.0
4b7036a9-63fc-11e4-942e-fa163e020fd0 127.0.0.1:20887   PRIMARY READ_WRITE    1.0

Σ(゚д゚lll) 引数なしで行ったらスレーブをPRIMARYって認識した!!
どうしてそうなった。。server_uuidが若いからか。SHOW SLAVE STATUSとか見ないのかそうなのか。

promoteしなおしてみる。


$ mysqlfabric group promote my_first_fabric
Password for admin:
Fabric UUID:  5ca1ab1e-a007-feed-f00d-cab3fe13249e
Time-To-Live: 1

GroupError: There is no valid candidate that can be automatically chosen in group (my_first_fabric). Please, choose one manually.

あ、あー、FabricがPRIMARYだと思っているスレーブ(127.0.0.1:20087)にはスレーブが存在しないからダメと。手動で選択しろと。


$ mysqlfabric group promote my_first_fabric --slave_id=47cf54df-63fc-11e4-942e-fa163e020fd0
Password for admin:
Fabric UUID:  5ca1ab1e-a007-feed-f00d-cab3fe13249e
Time-To-Live: 1

DatabaseError: Command (SHOW SLAVE STATUS, ()) failed accessing (127.0.0.1:20886). 1227 (42000): Access denied; you need (at least one of) the SUPER, REPLICATION CLIENT privilege(s) for this operation.

( ゚д゚) ファッ!? と思ったら、さっきと同じで、mysqlfabric manage startの時点でコネクションが張りっぱなしになっててchange_db()が走るタイミングがないので、権限がリロードされてないぽい。


$ mysqlfabric manage stop
Password for admin:
Fabric UUID:  5ca1ab1e-a007-feed-f00d-cab3fe13249e
Time-To-Live: 1

Success (empty result set)

$ mysqlfabric manage start --daemonize

$ mysqlfabric group promote my_first_fabric --slave_id=47cf54df-63fc-11e4-942e-fa163e020
fd0
Password for admin:
Fabric UUID:  5ca1ab1e-a007-feed-f00d-cab3fe13249e
Time-To-Live: 1

ServerError: Server (47cf54df-63fc-11e4-942e-fa163e020fd0) is not a valid candidate slave due to the following reason: ({'sql_error': False, 'io_error': False, 'io_not_running': False, 'sql_not_running': False, 'is_not_configured': True, 'is_not_running': False}).

うむ。
SECONDARYだと思ってるけどマスターだもんね。SHOW SLAVE STATUSの結果からっぽだよね。うん。


$ mysqlfabric group demote my_first_fabric
Password for admin:
Fabric UUID:  5ca1ab1e-a007-feed-f00d-cab3fe13249e
Time-To-Live: 1

                                uuid finished success result
------------------------------------ -------- ------- ------
beb3d5e5-6753-40fc-b5ef-1297e48e49b9        1       1      1

state success          when                                                   description
----- ------- ------------- -------------------------------------------------------------
    3       2   1.41516e+09 Triggered by .
    4       2   1.41516e+09                       Executing action (_block_write_demote).
    5       2   1.41516e+09                        Executed action (_block_write_demote).
    3       2   1.41516e+09 Triggered by .
    4       2   1.41516e+09                       Executing action (_wait_slaves_demote).
    5       2   1.41516e+09                        Executed action (_wait_slaves_demote).

$ mysqlfabric group lookup_servers my_first_fabric
Password for admin:
Fabric UUID:  5ca1ab1e-a007-feed-f00d-cab3fe13249e
Time-To-Live: 1

                         server_uuid         address    status      mode weight
------------------------------------ --------------- --------- --------- ------
47cf54df-63fc-11e4-942e-fa163e020fd0 127.0.0.1:20886 SECONDARY READ_ONLY    1.0
4b7036a9-63fc-11e4-942e-fa163e020fd0 127.0.0.1:20887 SECONDARY READ_ONLY    1.0

$ mysqlfabric group promote my_first_fabric --slave_id=47cf54df-63fc-11e4-942e-fa163e020fd0
Password for admin:
Fabric UUID:  5ca1ab1e-a007-feed-f00d-cab3fe13249e
Time-To-Live: 1

                                uuid finished success result
------------------------------------ -------- ------- ------
06b7ea19-1202-4b03-962d-1f36b4d50768        1       1      1

state success          when                                                   description
----- ------- ------------- -------------------------------------------------------------
    3       2   1.41516e+09 Triggered by .
    4       2   1.41516e+09                      Executing action (_define_ha_operation).
    5       2   1.41516e+09                       Executed action (_define_ha_operation).
    3       2   1.41516e+09 Triggered by .
    4       2   1.41516e+09                     Executing action (_check_candidate_fail).
    5       2   1.41516e+09                      Executed action (_check_candidate_fail).
    3       2   1.41516e+09 Triggered by .
    4       2   1.41516e+09                          Executing action (_wait_slave_fail).
    5       2   1.41516e+09                           Executed action (_wait_slave_fail).
    3       2   1.41516e+09 Triggered by .
    4       2   1.41516e+09                      Executing action (_change_to_candidate).
    5       2   1.41516e+09                       Executed action (_change_to_candidate).

$ mysqlfabric group lookup_servers my_first_fabric
Password for admin:
Fabric UUID:  5ca1ab1e-a007-feed-f00d-cab3fe13249e
Time-To-Live: 1

                         server_uuid         address    status       mode weight
------------------------------------ --------------- --------- ---------- ------
47cf54df-63fc-11e4-942e-fa163e020fd0 127.0.0.1:20886   PRIMARY READ_WRITE    1.0
4b7036a9-63fc-11e4-942e-fa163e020fd0 127.0.0.1:20887 SECONDARY  READ_ONLY    1.0

demoteで一度SECONDARYに戻してやってから、正しい方を指定してpromote。
この状態でMasterを落としてやると(MySQL::Sandbox使ってます)


$ master/stop

$ mysqlfabric group lookup_servers my_first_fabric
Password for admin:
Fabric UUID:  5ca1ab1e-a007-feed-f00d-cab3fe13249e
Time-To-Live: 1

                         server_uuid         address    status       mode weight
------------------------------------ --------------- --------- ---------- ------
47cf54df-63fc-11e4-942e-fa163e020fd0 127.0.0.1:20886   PRIMARY READ_WRITE    1.0
4b7036a9-63fc-11e4-942e-fa163e020fd0 127.0.0.1:20887 SECONDARY  READ_ONLY    1.0

$ mysqlfabric group health my_first_fabric
Password for admin:
Fabric UUID:  5ca1ab1e-a007-feed-f00d-cab3fe13249e
Time-To-Live: 1

                                uuid is_alive    status is_not_running is_not_configured io_not_running sql_not_running                                                                           io_error sql_error
------------------------------------ -------- --------- -------------- ----------------- -------------- --------------- ---------------------------------------------------------------------------------- ---------
47cf54df-63fc-11e4-942e-fa163e020fd0        0    FAULTY              0                 0              0               0                                                                              False     False
4b7036a9-63fc-11e4-942e-fa163e020fd0        1 SECONDARY              0                 0              1               0 error reconnecting to master 'fabric@127.0.0.1:20886' - retry-time: 60  retries: 2     False

issue
-----

$ mysqlfabric group lookup_servers my_first_fabric
Password for admin:
Fabric UUID:  5ca1ab1e-a007-feed-f00d-cab3fe13249e
Time-To-Live: 1

                         server_uuid         address    status       mode weight
------------------------------------ --------------- --------- ---------- ------
47cf54df-63fc-11e4-942e-fa163e020fd0 127.0.0.1:20886   PRIMARY READ_WRITE    1.0
4b7036a9-63fc-11e4-942e-fa163e020fd0 127.0.0.1:20887 SECONDARY  READ_ONLY    1.0

(少なくとも)すぐには切り替わらなかった(´・ω・`)


$ vim /etc/mysql/fabric.cnf
..
[failure_tracking]
notification_interval = 60
notification_clients = 50
detection_timeout = 1
detection_interval = 6
notifications = 300
detections = 3
failover_interval = 0
prune_time = 3600
..

この辺の設定なんだろうけど、そのあたりはまたこんど。。

2014/11/04

MySQL Fabricつらい(インストール編)

取り敢えずインストールだけしたメモ。インストール編といいながら続編があるかどうかは定かではない。


$ sudo rpm -i http://dev.mysql.com/get/mysql-community-release-el6-5.noarch.rpm
$ sudo yum install mysql-community-server mysql-utilities
$ sudo service mysqld start

MySQL Fabric用のMySQL(Fabric的にはバッキングストアとかストレージって呼んでる)なので、取り敢えずOracle公式のyumリポジトリーで突っ込む。
そのほうがMySQL Utilities(mysqlfabricはコレに入ってる)のインストール(Connector/Pythonを要求してくる)が簡単なので。


$ mysql -uroot
mysql> GRANT ALL ON fabric.* TO fabric@localhost IDENTIFIED BY 'fabric_password';

バッキングストアにはfabricスキーマを作っておく。


$ sudo vim /etc/mysql/fabric.cfg

$ diff -c /etc/mysql/fabric.cfg{.orig,}
*** /etc/mysql/fabric.cfg.orig  2014-09-24 19:08:45.000000000 +0000
--- /etc/mysql/fabric.cfg       2014-11-04 10:14:29.123248604 +0000
***************
*** 17,23 ****
  address = localhost:3306
  connection_delay = 1
  connection_timeout = 6
! password =
  connection_attempts = 6

  [failure_tracking]
--- 17,23 ----
  address = localhost:3306
  connection_delay = 1
  connection_timeout = 6
! password = fabric_password
  connection_attempts = 6

  [failure_tracking]

取り敢えずバッキングストア用のパスワードだけ埋める。


$ sudo touch /var/log/fabric.log
$ sudo chown mysql. /var/log/fabric.log

--daemonizeする場合には/var/log/fabric.log(初期設定)に書き込めないと起動できなかった。
--daemonizeなしで標準出力に書かせてるぶんにはログに書かないぽく、パーミッションなしでも起動できる。


$ mysqlfabric manage setup
[INFO] 1415096154.828998 - MainThread - Initializing persister: user (fabric), server (localhost:3306), database (fabric).
Finishing initial setup
=======================
Password for admin user is not yet set.
Password for admin/xmlrpc:
Repeat Password:
Password set.
Password set.
No result returned

fabricスキーマの初期設定。
気を利かせてGRANTしたときついでに`CREATE DATABASE fabric`したらむしろ怒られた。空っぽの状態でやるのが吉。
adminユーザーのパスワードはFabricサーバーの管理用パスワードで、バッキングストアのパスワードとは何の関係もない。
空パスワードにしようとしたら、ドラクエ3やMother2みたいな感じでひたすら入力しろと迫ってくる。


$ mysqlfabric manage start
[INFO] 1415096186.341115 - MainThread - Initializing persister: user (fabric), server (localhost:3306), database (fabric).
[INFO] 1415096186.347491 - MainThread - Loading Services.
[INFO] 1415096186.356114 - MainThread - MySQL-RPC protocol server started, listening on localhost:32275
[INFO] 1415096186.363849 - MainThread - Fabric node starting.
[INFO] 1415096186.367503 - MainThread - Starting Executor.
[INFO] 1415096186.367640 - MainThread - Setting 5 executor(s).
[INFO] 1415096186.368038 - Executor-0 - Started.
[INFO] 1415096186.369436 - Executor-1 - Started.
[INFO] 1415096186.371009 - Executor-2 - Started.
[INFO] 1415096186.372460 - Executor-3 - Started.
[INFO] 1415096186.373751 - MainThread - Executor started.
[INFO] 1415096186.374267 - Executor-4 - Started.
[INFO] 1415096186.378326 - MainThread - Starting failure detector.
[INFO] 1415096186.379138 - XML-RPC-Server - XML-RPC protocol server ('127.0.0.1', 32274) started.
[INFO] 1415096186.379361 - XML-RPC-Server - Setting 1 XML-RPC session(s).
[INFO] 1415096186.379623 - XML-RPC-Session-0 - Started XML-RPC-Session.

--daemonizeする場合はすぐに制御が返ってきて、出力は全て[logging]セクションで指定したファイルに行く。
しかし、daemonizeしようがするまいがタイムスタンプはUNIXTIMEなのか。。

MySQL Fabricは他の(MHA for MySQL, mysqlfailover, PXC(Galera Cluster), MySQL Cluster)と違ってIPの管理を自分でしない(Fabricノード(とコネクター)に任せる)あたりがちょっと素敵そうなところかと思って手を出してみたい。
バッキングストアの冗長化はkeepalivedでMySQL Cluster全部載せにしちゃうのがいいかな。。
あとは対応コネクターを選ぶのがちょっとアレな感じはするけれど。

次があるかどうかは定かではない。


【2014/11/06 14:51】
次があった。 => MySQL Fabricつらい(HA/登録編)

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);
      }

2014/10/29

innodb_file_format= AntelopeとBarracudaが混じっても特に問題がない

というか混じりようがない。

innodb_file_format はそもそも.ibdファイルだけに利くパラメーターであり、innodb_file_per_table が無効の場合は勝手にAntelope相当の状態にフォールバックされる。

mysql56> SET GLOBAL innodb_file_per_table= 0;
Query OK, 0 rows affected (0.05 sec)

mysql56> SET GLOBAL innodb_file_format= Barracuda;
Query OK, 0 rows affected (0.03 sec)

mysql56> CREATE TABLE t1 (num int) ROW_FORMAT= Dynamic;
Query OK, 0 rows affected, 2 warnings (0.59 sec)

mysql56> SHOW WARNINGS;
+---------+------+------------------------------------------------------------+
| Level   | Code | Message                                                    |
+---------+------+------------------------------------------------------------+
| Warning | 1478 | InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table. |
| Warning | 1478 | InnoDB: assuming ROW_FORMAT=COMPACT.                       |
+---------+------+------------------------------------------------------------+
2 rows in set (0.00 sec)

というわけで、
  • 1つのテーブルはAntelopeとBarracudaの両方の状態を持つことはできない(ROW_FORMATはテーブル属性で1つしかもてない)
  • 1つのBarracudaなテーブルは必ず.ibdファイルに格納される
  • Antelopeなテーブルはそのテーブルの.ibdファイルまたはibdata1に格納される
ので、運用中に混ぜても(それ自体は)全然問題ないです。
知らずにAntelopeのまま何年か運用してきたものを途中からSET GLOBALで乗り換えてALTER TABLE t1 ROW_FORMAT= Compressedとかも大丈夫(もちろんpt-online-schema-changeしますが)

もちろん逆も大丈夫、何らかの理由でBarracudaなテーブルをいくつか作ってからAntelopeに戻しても何の問題もない(やるとは思えないけど聞かれたのはそういうことだったんだ。。)

2014/10/27

innodb_rubyでfast index creationとそうでないのを比べてみる

や、MyNA会でデモした時にむしろこれをやれよって話なんですが。

InnoDB Plugin以降で加わったInnoDBのfast index creationと、それまでのインデックス作成について、innodb_rubyを使って比べてみました。

まずは最初にロードを済ませてから、後からfast index creationでインデックスを作るパターン。


master [localhost] {msandbox} (d1) > CREATE TABLE t1 (num int unsigned primary key, val varchar(32) not null);   
Query OK, 0 rows affected (0.02 sec)

master [localhost] {msandbox} (d1) > LOAD DATA INFILE '/tmp/md5_10000' INTO TABLE t1;                            
Query OK, 10000 rows affected (0.17 sec)
Records: 10000  Deleted: 0  Skipped: 0  Warnings: 0

$ innodb_space -f d1/t1.ibd space-extents-illustrate

  Start Page ╭────────────────────────────────────────────────────────────────╮
           0 │███▁▄███████████████████████████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
          64 │█████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
             ╰────────────────────────────────────────────────────────────────╯

Legend (█ = 1 page):
  Page Type                                                         Pages    Ratio
  █ System                                                              3    0.52%
  █ Index 31                                                           38    6.60%
  ░ Free space                                                         87   15.10%



ウインドーズだと文字化けしそうな予感がたっぷりなので、xtermでやったスクリーンショットもぺたり。


コイツにインデックスを足します。


master [localhost] {msandbox} (d1) > ALTER TABLE t1 ADD KEY (val);
Query OK, 0 rows affected (0.05 sec)
Records: 0  Duplicates: 0  Warnings: 0

$ innodb_space -f d1/t1.ibd space-extents-illustrate                        [66/19159]

  Start Page ╭────────────────────────────────────────────────────────────────╮
           0 │███▁▄███████████████████████████████▁▅█████████████████████████▆│
          64 │█████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
             ╰────────────────────────────────────────────────────────────────╯

Legend (█ = 1 page):
  Page Type                                                         Pages    Ratio
  █ System                                                              3    0.52%
  █ Index 31                                                           38    6.60%
  █ Index 32                                                           28    4.86%
  ░ Free space                                                         59   10.24%


やっぱり白黒になりやがったか。。
スクリーンショットでぺたり。



もともとあったデータ領域の後ろに、新しく作られたインデックスが追加されています。

じゃあインデックスを追加してからロードするパターン。


master [localhost] {msandbox} (d1) > CREATE TABLE t2 (num int unsigned primary key, val varchar(32) not null, key
Query OK, 0 rows affected (0.01 sec)

master [localhost] {msandbox} (d1) > LOAD DATA INFILE '/tmp/md5_10000' INTO TABLE t2;
Query OK, 10000 rows affected (0.30 sec)
Records: 10000  Deleted: 0  Skipped: 0  Warnings: 0

[mysql@v157-7-154-209 data]$ innodb_space -f d1/t2.ibd space-extents-illustrate                                  

  Start Page ╭────────────────────────────────────────────────────────────────╮
           0 │███▁▁▄█▆▇██▇███▇██▇▇████▇██▇▇▇▆█▆▆████████████▇▇▇▇██▆▇█▇▇█▇▇█▆▆█│
          64 │█████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
         128 │█████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
         192 │░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
         256 │░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
             ╰────────────────────────────────────────────────────────────────╯

Legend (█ = 1 page):
  Page Type                                                         Pages    Ratio
  █ System                                                              3    0.47%
  █ Index 33                                                           38    5.94%
  █ Index 34                                                           33    5.16%
  ░ Free space                                                        246   38.44%



データ本体(Index 33)とvalインデックス(Index 34)が交じり合って並ぶような感じ。


最後に、ALGORITHM= COPYでインデックスを追加した場合。

master [localhost] {msandbox} (d1) > CREATE TABLE t3 (num int unsigned primary key, val varchar(32) not null);   
Query OK, 0 rows affected (0.05 sec)

master [localhost] {msandbox} (d1) > LOAD DATA INFILE '/tmp/md5_10000' INTO TABLE t3;
Query OK, 10000 rows affected (0.17 sec)
Records: 10000  Deleted: 0  Skipped: 0  Warnings: 0

master [localhost] {msandbox} (d1) > ALTER TABLE t3 ADD KEY (val), ALGORITHM= COPY;
Query OK, 10000 rows affected (0.20 sec)
Records: 10000  Duplicates: 0  Warnings: 0

$ innodb_space -f d1/t3.ibd space-extents-illustrate                        [16/19155]

  Start Page ╭────────────────────────────────────────────────────────────────╮
           0 │███▁▄███████████████████████████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
          64 │█████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
             ╰────────────────────────────────────────────────────────────────╯

Legend (█ = 1 page):
  Page Type                                                         Pages    Ratio
  █ System                                                              3    0.52%
  █ Index 35                                                           38    6.60%
  ░ Free space                                                         87   15.10%

$ innodb_space -f d1/t3.ibd space-extents-illustrate                         [2/19155]

  Start Page ╭────────────────────────────────────────────────────────────────╮
           0 │███▁▁▄█▆▇██▇███▇██▇▇████▇██▇▇▇▆█▆▆████████████▇▇▇▇██▆▇█▇▇█▇▇█▆▆█│
          64 │█████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
         128 │█████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
         192 │░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
         256 │░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
             ╰────────────────────────────────────────────────────────────────╯

Legend (█ = 1 page):
  Page Type                                                         Pages    Ratio
  █ System                                                              3    0.47%
  █ Index 36                                                           38    5.94%
  █ Index 37                                                           33    5.16%
  ░ Free space                                                        246   38.44%


おお、やっぱりこうなるよね。


なお、t1テーブル(ロードしてからADD INDEX)をOPTIMIZEしても特に変わらなかった。
ALTER TABLE t1 Engine= InnoDB相当で、暗黙にALGORITHM= COPYだからだと思われる。ALTER TABLE t1 Engine= InnoDBは変わらなかったけれど、ALTER TABLE t1 Engine= InnoDB, ALGORITHM= COPYだと2つのインデックスが並ぶ感じに整列された。

innodb_ruby楽しいよ!

2014/10/22

MySQL 5.6.21, 5.7.5以降では、server_idかぶりやserver_uuidかぶりでマシなエラーを吐くようになったらしい

準同期レプリケーションでStop/Startのログが大量に出力される・・・。 : しがないエンジニアのつぶやき を拝見して、そういえばこんなBugがクローズされてなかったっけ? と思い出したので試してみた。

MySQL Bugs: #72578: Duplicate slave server_uuid in replication forum gives no specific error message

シンプルにカブらせてSTART SLAVEしてみる。


Master - Slaveでserver_uuidカブり。

2014-10-22T02:15:32.090514Z 4 [Note] Slave I/O thread: connected to master 'root@127.0.0.1:64056',replication started in log 'FIRST' at position 4
2014-10-22T02:15:32.275705Z 4 [ERROR] Slave I/O: Fatal error: The slave I/O thread stops because master and slave have equal MySQL server UUIDs; these UUIDs must be different for replication to work. Error_code: 1593


Master - Slaveでserver_idカブり。

2014-10-22T10:10:23.047895Z 2 [Note] Slave I/O thread: connected to master 'root@127.0.0.1:64056',replication started in log 'bin.000006' at position 147
2014-10-22T10:10:23.049217Z 2 [ERROR] Slave I/O: Fatal error: The slave I/O thread stops because master and slave have equal MySQL server ids; these ids must be different for replication to work (or the --replicate-same-server-id option must be used on slave but this does not always make sense; please check the manual before using it). Error_code: 1593
2014-10-22T10:10:23.049264Z 2 [Note] Slave I/O thread exiting, read up to log 'bin.000006', position 147


Slave同士のserver_uuidカブり。

2014-10-22T10:16:52.643392Z 2 [Note] Slave: received end packet from server due to dump thread being killed on master. Dump threads are killed for example during master shutdown, explicitly by a user, or when the master receives a binlog send request from a duplicate server UUID <940d4a6d-59d3-11e4-91ef-001a4aa000e2> : Error
2014-10-22T10:16:52.643440Z 2 [Note] Slave I/O thread: Failed reading log event, reconnecting to retry, log 'bin.000006' at position 147


わかりやすくなってるー :)

ところで、Slave同士のserver_idカブりはエラーにならず再接続も発生せずフツーに2台に更新が伝播されたんだけど、server_uuid使ってるとこうなるようになったんだっけ…? (わからん)

2014/10/21

OSC 2014 Tokyo/Fall でブース番していた感想

去る 2014/10/18(土), 19(日)に OSC 2014 Tokyo/Fall がありました。
日本MySQLユーザ会の セミナー は 須藤さん が、ブース番は同じく須藤さんとわたしでした。
MyNAは土曜日だけの出展でした。そして俺得。

今回のOSCは Oracle MySQL Community Team(土曜日は やまさきさん, 日曜日は かじやまさん)が協賛企業として出展していたので、MyNAもその隣に配置してもらえました。鉄板ネタも生まれました。

「この机! この机のこっち側は日本MySQLユーザ会で、こっち側はOracle MySQLチームです!」

笑ってくれる人多くて助かりました :) 他の開場でOracle MySQLと相乗りする機会があったら使ってもらっていいですよ :)





向かって左側がMyNAの机、いつもどおりの平常運転。。
向かって右側がOracle MySQLの机で、机のデコレーションもちょっとだけやる気があったりチラシがいっぱい置いてあったり nippondanjiさん がOSC広島で披露された「アタッシュケースを開けば、直ぐにMySQL Clusterの動作デモ環境が出来上がるというスグレモノ」 も展示してありました。

nippondanjiさん は土曜日の14時までの滞在でしたが、少なくとも土曜日いっぱい(結局日曜日はどうなったんだろう?)はこのデモ環境が置いてありました。


札束の入っていそうなアタッシュケースを開くスーツ姿の漢(ブレてる。。)




持ち主が帰ったあと、必死でMySQL Clusterの説明をする須藤さん。
夕方頃にはすっかり詳しくなっていました。すげぇ。

nippondanjiさんとお昼を食べながら、第一正規形の定義についてだとかrelay-log-repository= TABLEについてだとか語りました。楽しかったです :)