GA

2014/11/17

topライクにperformance_schemaを眺めるらしいpstopとやら

pstop – a top-like program for MySQL (based on performance_schema) を見て試してみたメモ。

$ git clone https://github.com/sjmudd/pstop.git
$ cd pstop
$ ll
total 52
-rw-rw-r-- 1 ec2-user ec2-user  710 Nov 17 10:03 BUGS
-rw-rw-r-- 1 ec2-user ec2-user  738 Nov 17 10:03 keys.txt
drwxrwxr-x 2 ec2-user ec2-user 4096 Nov 17 10:03 lib
-rw-rw-r-- 1 ec2-user ec2-user 1315 Nov 17 10:03 LICENSE
-rw-rw-r-- 1 ec2-user ec2-user 3905 Nov 17 10:03 main.go
-rw-rw-r-- 1 ec2-user ec2-user 1986 Nov 17 10:03 NEW_FEATURES
drwxrwxr-x 6 ec2-user ec2-user 4096 Nov 17 10:03 performance_schema
-rw-rw-r-- 1 ec2-user ec2-user 1041 Nov 17 10:03 README.md
drwxrwxr-x 2 ec2-user ec2-user 4096 Nov 17 10:03 screen
-rw-rw-r-- 1 ec2-user ec2-user 5551 Nov 17 10:03 screen_samples.txt
drwxrwxr-x 2 ec2-user ec2-user 4096 Nov 17 10:03 state
drwxrwxr-x 2 ec2-user ec2-user 4096 Nov 17 10:03 version

おい、こいつgoだぞ…:(;゙゚'ω゚'): go弱な俺には起動の仕方すらわからない。。


$ go build
main.go:15:2: cannot find package "github.com/go-sql-driver/mysql" in any of:
        /usr/lib/golang/src/pkg/github.com/go-sql-driver/mysql (from $GOROOT)
        ($GOPATH not set)
main.go:16:2: cannot find package "github.com/nsf/termbox-go" in any of:
        /usr/lib/golang/src/pkg/github.com/nsf/termbox-go (from $GOROOT)
        ($GOPATH not set)
main.go:18:2: cannot find package "github.com/sjmudd/mysql_defaults_file" in any of:
        /usr/lib/golang/src/pkg/github.com/sjmudd/mysql_defaults_file (from $GOROOT)
        ($GOPATH not set)
main.go:19:2: cannot find package "github.com/sjmudd/pstop/lib" in any of:
        /usr/lib/golang/src/pkg/github.com/sjmudd/pstop/lib (from $GOROOT)
        ($GOPATH not set)
main.go:20:2: cannot find package "github.com/sjmudd/pstop/state" in any of:
        /usr/lib/golang/src/pkg/github.com/sjmudd/pstop/state (from $GOROOT)
        ($GOPATH not set)
main.go:21:2: cannot find package "github.com/sjmudd/pstop/version" in any of:
        /usr/lib/golang/src/pkg/github.com/sjmudd/pstop/version (from $GOROOT)
        ($GOPATH not set)

むーん。


$ export GOPATH=~/gopath
$ go get
go install: no install location for directory /home/ec2-user/pstop outside GOPATH
$ go build

よくわかってないけどこれでビルドできた。


$ ./pstop
2014/11/17 10:06:11 Could not load ini fileopen /home/ec2-user/.my.cnf: no such file or directory

どうも~/.my.cnfを読み込んで接続情報を取るらしい。


$ cat ~/.my.cnf
[client]
user= msandbox
password= msandbox
port= 5621
host= 127.0.0.1

$ ./pstop

起動できた。
TABキーを叩くとtable_io_waits_summary_by_table, table_io_waits_summary_by_table, file_summary_by_instance, table_lock_waits_summary_by_tableのタブを順繰りに表示してくれる。
"t"でp_sが収集し始めてからの累計と、最後に統計情報をリセット(たぶん、pstopの中で。いちども"z"を叩いてなければ、pstopが起動したときから)の累計切り替え。
"+", "-"で表示間隔の調整。"h"でヘルプだけど、ヘルプから戻るのはもう一度"h"。罠い。

今のところは荒削りにこれで機能が全てっぽい。innotopばりに発展していってくれるととてもうれしい。

Mroonga + MySQL 5.6とMariaDB 10.0だとスピードが結構違う?

あんま真面目に調べてないんですがメモ。


mysql> SELECT COUNT(*) FROM t1 WHERE MATCH(text_column) AGAINST('*D+ xxx' IN BOOLEAN MODE);
+----------+
| COUNT(*) |
+----------+
|    45402 |
+----------+
1 row in set (0.03 sec)

MariaDB [d1]> SELECT COUNT(*) FROM t1 WHERE MATCH(text_column) AGAINST('*D+ xxx' IN BOOLEAN MODE);
+----------+
| COUNT(*) |
+----------+
|    45402 |
+----------+
1 row in set (0.06 sec)

なんか倍くらい違う。


MariaDB [d1]> SHOW PROFILE cpu for query 1;
+-------------------------+----------+----------+------------+
| Status                  | Duration | CPU_user | CPU_system |
+-------------------------+----------+----------+------------+
| starting                | 0.000109 | 0.000000 |   0.000000 |
| checking permissions    | 0.000009 | 0.000000 |   0.000000 |
| Opening tables          | 0.000032 | 0.000000 |   0.000000 |
| After opening tables    | 0.000010 | 0.000000 |   0.000000 |
| System lock             | 0.000008 | 0.000000 |   0.000000 |
| Table lock              | 0.000008 | 0.000000 |   0.001000 |
| After table lock        | 0.000019 | 0.000000 |   0.000000 |
| init                    | 0.000045 | 0.000000 |   0.000000 |
| optimizing              | 0.000347 | 0.000000 |   0.000000 |
| statistics              | 0.000200 | 0.000000 |   0.000000 |
| preparing               | 0.000028 | 0.000000 |   0.000000 |
| FULLTEXT initialization | 0.040459 | 0.027995 |   0.014998 |
| executing               | 0.000024 | 0.000000 |   0.000000 |
| Sending data            | 0.020768 | 0.019997 |   0.000000 |
| end                     | 0.000011 | 0.000000 |   0.000000 |
| query end               | 0.000006 | 0.000000 |   0.000000 |
| closing tables          | 0.000839 | 0.000000 |   0.001000 |
| freeing items           | 0.000012 | 0.000000 |   0.000000 |
| updating status         | 0.000025 | 0.000000 |   0.000000 |
| cleaning up             | 0.000008 | 0.000000 |   0.000000 |
+-------------------------+----------+----------+------------+
20 rows in set (0.00 sec)

mysql> SHOW PROFILE cpu for query 2;
+----------------------+----------+----------+------------+
| Status               | Duration | CPU_user | CPU_system |
+----------------------+----------+----------+------------+
| starting             | 0.000057 | 0.000000 |   0.000000 |
| checking permissions | 0.000009 | 0.000000 |   0.000000 |
| Opening tables       | 0.000016 | 0.000000 |   0.000000 |
| init                 | 0.000018 | 0.000000 |   0.000000 |
| System lock          | 0.000007 | 0.000000 |   0.000000 |
| optimizing           | 0.031675 | 0.094985 |   0.011998 |
| executing            | 0.000027 | 0.000000 |   0.000000 |
| end                  | 0.000007 | 0.000000 |   0.000000 |
| query end            | 0.000005 | 0.000000 |   0.000000 |
| closing tables       | 0.000255 | 0.000000 |   0.000000 |
| freeing items        | 0.000344 | 0.002000 |   0.001000 |
| cleaning up          | 0.000005 | 0.000000 |   0.000000 |
+----------------------+----------+----------+------------+
12 rows in set, 1 warning (0.00 sec)

MariaDB 10.0はMySQL 5.5の時と同じような感じで、FULLTEXT initializationとSending Dataがほとんどの時間を占めてる。MySQL 5.6はoptimizingだけに集中している。これは、計上するステージが変わったからなのかなで済むけど、CPU_userを見るとMariaDBでは全て実時間以下のCPU使用時間に対し、MySQL 5.6のoptimizingステージは実時間の3倍くらいのCPU使用時間になっている。

MySQL 5.6、このへんなんかチューニングしてる? それともPROFILINGでやってるから取れてない(MySQL 5.6ではPROFILING非推奨でp_s使えってことになってるから)だけ?


【2014/11/17 16:10】
お客様の中に詳しい方がいらっしゃいました :)




mysql> SET SESSION mroonga_enable_optimization= OFF;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT COUNT(*) FROM t1 WHERE MATCH(text_column) AGAINST('*D+ xxx' IN BOOLEAN MODE);
+----------+
| COUNT(*) |
+----------+
|    45402 |
+----------+
1 row in set (0.04 sec)

確かにMySQL 5.6ではenable_optimization切ってもそんなに変わらない(= Mroongaのoptimizationでなく、MySQLのFTのレイヤーでごにょごにょしてMroongaのAPIを叩いてる?)


MariaDB [d1]> SET SESSION mroonga_enable_optimization= OFF;
Query OK, 0 rows affected (0.00 sec)

MariaDB [d1]> SELECT COUNT(*) FROM t1 WHERE MATCH(search_text) AGAINST('*D+ xxx' IN BOOLEAN MODE);
+----------+
| COUNT(*) |
+----------+
|    45402 |
+----------+
1 row in set (0.22 sec)

MariaDB 10.0はごりっと落ちる。


【2015/05/27 17:25】
全く別の本番データでPercona Server 5.6 + Mroonga (本当はスレッドプールの影響を計りたかったのでスレッドプール有/無) vs. MariaDB 10.0.19 + Mroonga (面倒なのでスレッドプールなしだけ)を計ってみたけど、やっぱりMariaDBの方が結構遅い。

なんなんだろう。。



MySQL Fabricつらい(FABRIC_OPT_MODE = roはスレーブだけを見に行くわけじゃない)

mysqlコマンドラインクライアントにHA切り替え機能を実装する編 でいじったコマンドラインクライアントでちょこちょこいじってたらなんか不思議な挙動に辿り着く。


mysql> \F ro
Current FABRIC_OPT_DEFAULT_MODE is ro

mysql> SELECT @@port, @@read_only;
+--------+-------------+
| @@port | @@read_only |
+--------+-------------+
|  20886 |           0 |
+--------+-------------+
1 row in set (0.00 sec)

mysql> SELECT @@port, @@read_only;
+--------+-------------+
| @@port | @@read_only |
+--------+-------------+
|  20886 |           0 |
+--------+-------------+
1 row in set (0.00 sec)

mysql> SELECT @@port, @@read_only;
+--------+-------------+
| @@port | @@read_only |
+--------+-------------+
|  20887 |           1 |
+--------+-------------+
1 row in set (0.00 sec)

mysql> SELECT @@port, @@read_only;
+--------+-------------+
| @@port | @@read_only |
+--------+-------------+
|  20887 |           1 |
+--------+-------------+
1 row in set (0.00 sec)

mysql> SELECT @@port, @@read_only;
+--------+-------------+
| @@port | @@read_only |
+--------+-------------+
|  20886 |           0 |
+--------+-------------+
1 row in set (0.00 sec)


マスターとスレーブの間で分散してる。

mysql_options(&mysql, FABRIC_OPT_DEFAULT_MODE, "ro")を設定して10回mysql_queryを叩くプログラムで試してみると

$ ./a.out
Using Fabric for MYSQL connection
port: 20887, read_only: 1
port: 20886, read_only: 0
port: 20887, read_only: 1
port: 20887, read_only: 1
port: 20887, read_only: 1
port: 20887, read_only: 1
port: 20886, read_only: 0
port: 20887, read_only: 1
port: 20887, read_only: 1
port: 20887, read_only: 1


やっぱり分散してる。

$ mysqlfabric group lookup_servers my_first_fabric
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




Fabric内部のweightとやらは1:1になっているのでそうなのか(にしては、スレーブに偏りすぎてる気がするんだけど 母数が足りなかっただけで、1000回に増やしたらまあこんなもんだろうって感じだった)

$ ./a.out | sort | uniq -c
    528 port: 20886, read_only: 0
    472 port: 20887, read_only: 1
      1 Using Fabric for MYSQL connection

$ ./a.out | sort | uniq -c
    505 port: 20886, read_only: 0
    495 port: 20887, read_only: 1
      1 Using Fabric for MYSQL connection

$ ./a.out | sort | uniq -c
    499 port: 20886, read_only: 0
    501 port: 20887, read_only: 1
      1 Using Fabric for MYSQL connection


スレーブ側のweightを10000まで上げてみる。

$ mysqlfabric group lookup_servers my_first_fabric
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 server set_weight 4b7036a9-63fc-11e4-942e-fa163e020fd0 10000
Fabric UUID:  5ca1ab1e-a007-feed-f00d-cab3fe13249e
Time-To-Live: 1

                                uuid finished success result
------------------------------------ -------- ------- ------
4ca2ef7d-3770-4beb-b557-55ea025b18bf        1       1      1

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


$ mysqlfabric group lookup_servers my_first_fabric
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 10000.0


$ ./a.out | sort | uniq -c
   1000 port: 20887, read_only: 1
      1 Using Fabric for MYSQL connection

$ ./a.out | sort | uniq -c
   1000 port: 20887, read_only: 1
      1 Using Fabric for MYSQL connection

$ ./a.out | sort | uniq -c
      1 port: 20886, read_only: 0
    999 port: 20887, read_only: 1
      1 Using Fabric for MYSQL connection


うん、よさげ。スレーブのweightを1のままでマスターのweight 0の方がいいのかしらんと思ったけど、weightを0にするのはダメみたい。

$ mysqlfabric server set_weight 47cf54df-63fc-11e4-942e-fa163e020fd0 0
Fabric UUID:  5ca1ab1e-a007-feed-f00d-cab3fe13249e
Time-To-Live: 1

ServerError: Cannot set the server's weight (0.0) to a value lower than or equal to 0.0


当たり前ながら、どれだけスレーブ側にweightを寄せてもFABRIC_OPT_MODE = rwなら必ずマスターを見に行く。

$ ./a.out | sort | uniq -c
   1000 port: 20886, read_only: 0
      1 Using Fabric for MYSQL connection


まだまだ検証要りそうだねぇ。。

2014/11/14

MySQL Fabricつらい(mysqlコマンドラインクライアントにHA切り替え機能を実装する編)

Connector/CでマスタースレーブHA打ち分け編 の応用で、mysqlコマンドラインクライアントにHA打ち分け機能を追加してみました。

パッチはこんな感じ。MySQL 5.7.5-m15のmysqlコマンドラインクライアントベースだけど、labs版のConnector/Cが5.6をベースにしてるっぽい気配がして、おとなしく5.6のコマンドラインクライアントベースにすればよかったかも。。


*** client/mysql.cc.orig 2014-09-18 22:36:41.000000000 +0900
--- client/mysql.cc 2014-11-14 16:28:49.499593984 +0900
***************
*** 76,82 ****
  using std::min;
  using std::max;
  
! const char *VER= "14.14";
  
  /* Don't try to make a nice table if the data is too big */
  #define MAX_COLUMN_LENGTH      1024
--- 76,82 ----
  using std::min;
  using std::max;
  
! const char *VER= "14.14-fabric";
  
  /* Don't try to make a nice table if the data is too big */
  #define MAX_COLUMN_LENGTH      1024
***************
*** 188,193 ****
--- 188,195 ----
  static char delimiter[16]= DEFAULT_DELIMITER;
  static size_t delimiter_length= 1;
  unsigned short terminal_width= 80;
+ static char *opt_fabric_group= 0, *opt_fabric_user= 0;
+ static char *opt_fabric_password= 0;
  
  #if defined (_WIN32) && !defined (EMBEDDED_LIBRARY)
  static char *shared_memory_base_name=0;
***************
*** 255,261 ****
             com_notee(String *str, char*), com_charset(String *str,char*),
             com_prompt(String *str, char*), com_delimiter(String *str, char*),
       com_warnings(String *str, char*), com_nowarnings(String *str, char*),
!      com_resetconnection(String *str, char*);
  
  #ifdef USE_POPEN
  static int com_nopager(String *str, char*), com_pager(String *str, char*),
--- 257,264 ----
             com_notee(String *str, char*), com_charset(String *str,char*),
             com_prompt(String *str, char*), com_delimiter(String *str, char*),
       com_warnings(String *str, char*), com_nowarnings(String *str, char*),
!      com_resetconnection(String *str, char*),
!      com_fabric(String *str, char*);
  
  #ifdef USE_POPEN
  static int com_nopager(String *str, char*), com_pager(String *str, char*),
***************
*** 322,327 ****
--- 325,332 ----
  #ifdef USE_POPEN
    { "edit",   'e', com_edit,   0, "Edit command with $EDITOR."},
  #endif
+   // Added by yoku0825.
+   { "fabric", 'F', com_fabric, 1, "Choose fabric opt group." },
    { "ego",    'G', com_ego,    0,
      "Send command to mysql server, display result vertically."},
    { "exit",   'q', com_quit,   0, "Exit mysql. Same as quit."},
***************
*** 1833,1838 ****
--- 1838,1855 ----
     "password sandbox mode.",
     &opt_connect_expired_password, &opt_connect_expired_password, 0, GET_BOOL,
     NO_ARG, 0, 0, 0, 0, 0, 0},
+   // Added by yoku0825.
+   {"fabric-group", 0,
+    "fabric group", &opt_fabric_group, &opt_fabric_group, 0,
+    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+   {"fabric-user", 0,
+    "Real user name which is used to connect through MySQL Fabric",
+    &opt_fabric_user, &opt_fabric_user, 0,
+    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+   {"fabric-password", 0,
+    "Real password which is used to connect through MySQL Fabric",
+    &opt_fabric_password, &opt_fabric_password, 0,
+    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
    { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
  };
  
***************
*** 4883,4888 ****
--- 4900,4909 ----
    }
  #endif
  
+   // Added by yoku0825.
+   if (opt_fabric_group)
+     mysql_options(&mysql, MYSQL_OPT_USE_FABRIC, NULL);
+ 
    if (!mysql_real_connect(&mysql, host, user, password,
                            database, opt_mysql_port, opt_mysql_unix_port,
                            connect_flag | CLIENT_MULTI_STATEMENTS))
***************
*** 4898,4903 ****
--- 4919,4932 ----
      return -1;     // Retryable
    }
  
+   // Added by yoku0825.
+   if (opt_fabric_group)
+   {
+     mysql_options(&mysql, FABRIC_OPT_GROUP, opt_fabric_group);
+     mysql_options4(&mysql, FABRIC_OPT_GROUP_CREDENTIALS, opt_fabric_user, opt_fabric_password);
+     mysql_options(&mysql, FABRIC_OPT_DEFAULT_MODE, "rw");
+   }
+ 
  #ifdef _WIN32
    /* Convert --execute buffer from UTF8MB4 to connection character set */
    if (!execute_buffer_conversion_done++ &&
***************
*** 5763,5765 ****
--- 5792,5812 ----
    }
    return error;
  }
+ 
+ // Added by yoku0825.
+ static int com_fabric(String *buffer __attribute__((unused)),
+                       char *line __attribute__((unused)))
+ {
+   char *ptr=strchr(line, ' ');
+   char *new_fabric_opt_mode= my_strdup(PSI_NOT_INSTRUMENTED,
+                                         ptr ? ptr + 1 : 0, MYF(MY_WME));
+ 
+   if (strcmp(new_fabric_opt_mode, "ro") || strcmp(new_fabric_opt_mode, "rw"))
+   {
+     mysql_options(&mysql, FABRIC_OPT_DEFAULT_MODE, new_fabric_opt_mode);
+     tee_fprintf(stdout, "Current FABRIC_OPT_DEFAULT_MODE is %s\n", new_fabric_opt_mode);
+   }
+   else
+     tee_fprintf(stdout, "Failed to change FABRIC_OPT_DEFAULT_MODE. Only 'ro' and 'rw' are permitted.\n", new_fabric_opt_mode);
+   return 0;
+ }

取り敢えずConnector/CからMySQL Fabricでマスタースレーブの打ち分けをするのに必要なパラメーターはグループ名, 本物のノードに接続するユーザー名とパスワードくらいなので、オプション(--fabric-group, --fabric-user, --fabric-password)で受け取るようにする。

あとはmysql_real_connectを読んでいるsql_real_connectの中で、--fabric-groupが渡されてたらMYSQL_OPT_USE_FABRICを押し込んで、接続後にFABRIC_OPT_GROUP, FABRIC_OPT_GROUP_CREDENTIALS, FABRIC_OPT_DEFAULT_MODEを押し込むという感じ。コンソールの中でrwとroを切り替えるためにcom_fabricも追加。

実際こんな感じ。


$ client/mysql -P32275 -h127.0.0.1 -uadmin -pxxxx --protocol=tcp ## FabricサーバーのMySQLプロトコルの口に、FABRICモードでなく接続
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 53
Server version: 1.5.3-fabric -- Fabricサーバーのバージョンが出てくる

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> SELECT @@port; -- Fabricサーバーにつながってるだけなので何も出てこない
Query OK, 0 rows affected (0.00 sec)


$ client/mysql -P32275 -h127.0.0.1 -uadmin -pxxxx --protocol=tcp --fabric-group=my_first_fabric --fabric-user=msandbox --fabric-password=msandbox
mysql: [Warning] Using a password on the command line interface can be insecure.
Using Fabric for MYSQL connection -- FABRIC経由でつながると(今のところ必ず)これが出る。
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 167034
Server version: 5.6.21-log Source distribution -- MySQLサーバーのバージョン

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> SELECT @@port; -- デフォルトはrw側
+--------+
| @@port |
+--------+
|  20886 |
+--------+
1 row in set (0.00 sec)

mysql> fabric ro -- "fabric {ro|rw}"で切り替えられるようにした
Current FABRIC_OPT_DEFAULT_MODE is ro

mysql> SELECT @@port; -- こっちがro側
+--------+
| @@port |
+--------+
|  20887 |
+--------+
1 row in set (0.00 sec)

mysql> \F rw -- "\Fはfabricのシノニム"
Current FABRIC_OPT_DEFAULT_MODE is rw

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

前回 使ってたFABRIC_OPT_MODEの方は、mysql_optionsしたすぐ次のクエリー(ただし、トランザクションの途中であれば考慮してくれる)でしか有効でないらしいので、FABRIC_OPT_DEFAULT_modeを使うようにしてみた。

ちなみに、Fabricサーバー(mysqlfabric)のMySQLプロトコルの口にログインしただけの状態でstatusとか叩くとコマンドラインクライアントが落ちる。

MySQL Bugs: #74340: Crash on status query when connected to fabric

--fabric-groupや--fabric-user, --fabric-passwordが間違ってて上手くバックエンドにつなぎにいけない場合も(クライアントがコア吐いて)これまた落ちるんだけど、取り敢えず仕様ということで。。

こんな感じで誰か DBD::mysql にMySQL Fabricをポートしてくだしあ。


【2014/11/17 11:33】
FABRIC_OPT_MODEの動きについてこっちに追記。
http://yoku0825.blogspot.jp/2014/11/mysql-fabricfabricoptmode-ro.html


【2014/12/02 18:56】
Githubに上げたのを忘れてたので一応張っておく。
https://github.com/yoku0825/fabric_mysql_client

2014/11/10

MySQL Fabricつらい(Connector/CでマスタースレーブHA打ち分け編)

わたしのC力は低いので、サンプルプログラムはへちょいです。

MySQL Fabric対応のコネクターというともろもろありますが、俺が使えるコネクター(つまりDBD::mysqlのことだ!)がないので、Connector/Cにしました。labsです。

参考にしたサイトはこちら。
Using Connector/C with Fabric (MySQL Connectors C)
Oracle公式のConnector/C(チーム)のブログなんてあったんだね! というかこの1記事しかn<censored>

まずは labs からConnector/C 6.2.0 を取ってきてmake。なんかlabsからダウンロードする時にちょくちょく接続がリセットされるんだけどこれ俺だけ?


$ wget http://downloads.mysql.com/snapshots/pb/mysql-connector-c-6.2.0-labs/mysql-connector-c-6.2.0-labs-src.tar.gz
$ tar xzf mysql-connector-c-6.2.0-labs-src.tar.gz
$ cd mysql-connector-c-6.2.0-labs-src
$ cmake -DCMAKE_INSTALL_PREFIX=/home/mysql/connector .
$ make
$ make install

インストール場所だけ他とぶつからないように変えました。


$ vim test.cc
  1 #include <iostream>
  2 #include "mysql.h"
  3
  4
  5 int main()
  6 {
  7   MYSQL mysql;
  8
  9   mysql_init(&mysql);
 10   mysql_options(&mysql, MYSQL_OPT_USE_FABRIC, NULL);
 11
 12   if (!(mysql_real_connect(&mysql, "127.0.0.1", "admin", "xxxx", NULL,
 13                            32275, NULL, 0)))
 14     std::cout << mysql_error(&mysql) << std::endl;
 15   else
 16   {
 17     mysql_options(&mysql, FABRIC_OPT_GROUP, "my_first_fabric");
 18     mysql_options4(&mysql, FABRIC_OPT_GROUP_CREDENTIALS, "msandbox", "msandbox");
 19     mysql_options(&mysql, FABRIC_OPT_MODE, "ro");
 20     mysql_query(&mysql, "SELECT @@port");
 21     MYSQL_RES *res_from_ro= mysql_store_result(&mysql);
 22     MYSQL_ROW row_from_ro = mysql_fetch_row(res_from_ro);
 23     std::cout << "Fabric ro port: " << row_from_ro[0] << std::endl;
 24
 25     mysql_options(&mysql, FABRIC_OPT_MODE, "rw");
 26     mysql_query(&mysql, "SELECT @@port");
 27     MYSQL_RES *res_from_rw= mysql_store_result(&mysql);
 28     MYSQL_ROW row_from_rw = mysql_fetch_row(res_from_rw);
 29     std::cout << "Fabric rw port: " << row_from_rw[0] << std::endl;
 30   }
 31
 32 }


Fabricサーバーに接続して、roプロパティとrwプロパティでそれぞれポート番号を調べるだけのヤーツ(mysql_free_resultすらしない手抜きっぷり)

$ export LD_LIBRARY_PATH=/home/mysql/connector/lib
$ gcc -I/home/mysql/connector/include -L/home/mysql/connector/lib -lmysqlclient -g test.cc
/usr/bin/ld: cannot find -lmysqlclient
collect2: ld returned 1 exit status

$ ll /home/mysql/connector/lib
total 28256
-rw-r--r-- 1 mysql mysql 19390738 Nov 10 19:27 libmysqlconc62.a
lrwxrwxrwx 1 mysql mysql       24 Nov 10 19:27 libmysqlconc62.so -> libmysqlconc62.so.19.0.0
-rw-r--r-- 1 mysql mysql  9537551 Nov 10 19:27 libmysqlconc62.so.19.0.0
lrwxrwxrwx 1 mysql mysql       16 Nov 10 19:27 libmysqlconc.a -> libmysqlconc62.a
lrwxrwxrwx 1 mysql mysql       17 Nov 10 19:27 libmysqlconc.so -> libmysqlconc62.so
lrwxrwxrwx 1 mysql mysql       24 Nov 10 19:27 libmysqlconc.so.19 -> libmysqlconc62.so.19.0.0

$ gcc -I/home/mysql/connector/include -L/home/mysql/connector/lib -lmysqlconc -g test.cc

$ ldd a.out
        linux-vdso.so.1 =>  (0x00007fff415ff000)
        libmysqlconc.so.19 => /home/mysql/connector/lib/libmysqlconc.so.19 (0x00007f05dcc37000)
        libc.so.6 => /lib64/libc.so.6 (0x00000039a8000000)
        libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x000000321aa00000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00000039a8400000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00000039a7c00000)
        librt.so.1 => /lib64/librt.so.1 (0x00000039a9000000)
        libm.so.6 => /lib64/libm.so.6 (0x00000039a8c00000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x000000321a600000)
        /lib64/ld-linux-x86-64.so.2 (0x00000039a7800000)


むむ、なんかlibmysqlclientからlibmysqlconcに名前が変わってた。

$ mysqlfabric group lookup_servers my_first_fabric
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


$ ./a.out
Using Fabric for MYSQL connection
Fabric ro port: 20887
Fabric rw port: 20886
ちゃんとmysql_optionsで"ro"を指定したのはSECONDARYに、"rw"を指定したのはPRIMARYに行ってる。
$ ./sandboxes/rsandbox_5_6_21/master/stop

$ mysqlfabric group lookup_servers my_first_fabric
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  FAULTY READ_WRITE    1.0
4b7036a9-63fc-11e4-942e-fa163e020fd0 127.0.0.1:20887 PRIMARY READ_WRITE    1.0


$ ./a.out
Using Fabric for MYSQL connection
Fabric ro port: 20887
Fabric rw port: 20887


マスターを停止して(MySQL Fabric上での)切り替わりが起こると、roもrwも両方新しいPRIMARYの方に向いた。
$ ./sandboxes/rsandbox_5_6_21/master/start
. sandbox server started

$ mysqlfabric server set_status 47cf54df-63fc-11e4-942e-fa163e020fd0 SPARE
Fabric UUID:  5ca1ab1e-a007-feed-f00d-cab3fe13249e
Time-To-Live: 1

                                uuid finished success result
------------------------------------ -------- ------- ------
79142ce2-bc61-4be9-8837-3b6d782344c0        1       1      1

state success          when                                                   description
----- ------- ------------- -------------------------------------------------------------
    3       2   1.41562e+09 Triggered by <mysql .fabric.events.event="" 0x22ae450="" at="" object="">.
    4       2   1.41562e+09                        Executing action (_set_server_status).
    5       2   1.41562e+09                         Executed action (_set_server_status).

$ mysqlfabric group lookup_servers my_first_fabric
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   SPARE    OFFLINE    1.0
4b7036a9-63fc-11e4-942e-fa163e020fd0 127.0.0.1:20887 PRIMARY READ_WRITE    1.0


$ ./a.out
Using Fabric for MYSQL connection
Fabric ro port: 20887
Fabric rw port: 20887


起動してSPARE状態に戻してやると、mode: OFFLINEになってた。相変わらずConnector/Cからは両方PRIMARYを向いている。
$ mysqlfabric server set_status 47cf54df-63fc-11e4-942e-fa163e020fd0 SECONDARY
Fabric UUID:  5ca1ab1e-a007-feed-f00d-cab3fe13249e
Time-To-Live: 1

                                uuid finished success result
------------------------------------ -------- ------- ------
b946e459-f80e-4a9f-8f99-a43174de4832        1       1      1

state success          when                                                   description
----- ------- ------------- -------------------------------------------------------------
    3       2   1.41562e+09 Triggered by <mysql .fabric.events.event="" 0x22ae450="" at="" object="">.
    4       2   1.41562e+09                        Executing action (_set_server_status).
    5       2   1.41562e+09                         Executed action (_set_server_status).


$ mysqlfabric group lookup_servers my_first_fabric
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


$ ./a.out
Using Fabric for MYSQL connection
Fabric ro port: 20887
Fabric rw port: 20887

んん、status: SECONDARYに戻してもConnector/Cは戻ってない。コネクター側でキャッシュを持つとか聞いてるやつだろうか。
とはいえ、3分くらい待ってみても、Fabricサーバーを再起動しても、test.ccをコンパイルしなおしてもずっと20887に寄ったままだった。なんじゃこれ。

ちなみに、DBD::mysqlなんかはlibmysqlclientをそのまま使ってるのでDBI->connectのところでFabricのオプションを突っ込むことになるだろうし(それがmysql_optionsにマッピングされているはず), Connector/JやConnector/PythonはそもそもMySQLプロトコルじゃなくてXML-RPCでしゃべっているのでこれとは違ったアレになるはず。ちょっと微妙かな。。

MySQL Fabricつらい(XML-RPCでつついてみる編)

MySQL Fabricの基本概念としては、
* Fabricサーバーはファームに関する情報だけを提供して、
* 実際の接続のハンドルはFabric対応コネクターが提供する

Fabricサーバーがしゃべるプロトコルは2種類。XML-RPCとMySQLプロトコルで、問い合わせ結果はコネクター側にキャッシュされて、TTLによって破棄される(実際にはコネクターの実装に依存するんだろうけど)

現在MySQL Fabricに対応しているコネクターは
* Connector/Python (○racleさん謹製)
* Connector/J (○racleさん謹製)
* mysqlnd (PHPによるクライアント実装で、シャード機能のみ実験的にサポート(HA機能は(まだ?)サポートしない))
* Connector/C (○racleさん謹製だけどlabsリリース)

そして、Connector/Cが現在唯一FabricサーバーとMySQLプロトコルでしゃべる。
…ってか、

MYSQL mysql;
mysql_init(&mysql);
mysql_option(&mysql, MYSQL_OPT_USE_FABRIC, NULL);
mysql_real_connect(&mysql, "127.0.0.1", "user", "password",
NULL, 32275, NULL, 0);
https://blogs.oracle.com/mysqlconnectors-C/entry/using_fabric_with_connector_c

( д ) ゚ ゚ え、mysql_real_connectで直接叩くの!? プロキシも直接兼ねる感じになるの!? (調べてない)

DBD::mysqlはlibmysqlclientを使ってるので、方式的にはこっちになるはず。他にlibmysqlclient使ってるのってなんかあったっけ。Rubyにも何かあった気がする(RubyのMySQLライブラリは名前がややこしすぎて憶えられない。。)


まあいいや。取り敢えず、コネクターのつもりになってXML-RPCでつついてみようという企画。

$ 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


$ perl -MRPC::XML::Client -MData::Dumper -e '$client= RPC::XML::Client->new("http://localhost:32274/RPC2"); $request= RPC::XML::request->new("group.lookup_servers", RPC::XML::string->new("my_first_fabric")); print Dumper $client->send_request($request);'
$VAR1 = 'RPC::XML::Client::send_request: HTTP server error: Unauthorized';

ありゃ、怒られた。そりゃそうか。認証があった。


$ perl -MRPC::XML::Client -MData::Dumper -e '$client= RPC::XML::Client->new("http://localhost:32274/RPC2"); $client->credentials("MySQL Fabric", "admin", "xxxx"); $request= RPC::XML::request->new("group.lookup_servers", RPC::XML::string->new("my_first_fabric")); print Dumper $client->send_request($request);'
$VAR1 = 'RPC::XML::Client::send_request: HTTP server error: Bad Request';

Bad Request言われた(´・ω・`)
あんまり時間もかけたくないし、取り敢えずXML-RPC経由では認証要らない設定にして再起動。


$ mysqlfabric manage stop

$ vim /etc/mysql/fabric.cfg
..
[protocol.xmlrpc]
disable_authentication = yes
..

$ mysqlfabric manage start --daemonize

止める前に設定を変えてしまうと、クライアントとしてのmysqlfabric manage stopがそれを読んで認証をかっ飛ばそうとするので、まだ認証が有効なFabricサーバーがそれを蹴る。ので間にはさむ。
これでどうかというと


$ perl -MRPC::XML::Client -MData::Dumper -e '$client= RPC::XML::Client->new("http://localhost:32274/RP
C2"); $client->credentials("MySQL Fabric", "admin", "xml"); $request= RPC::XML::request->new("group.lookup_servers", RPC::XML:
:string->new("my_first_fabric")); print Dumper $client->send_request($request);'
$VAR1 = bless( [
                 bless( do{\(my $o = '1')}, 'RPC::XML::int' ),
                 bless( do{\(my $o = '5ca1ab1e-a007-feed-f00d-cab3fe13249e')}, 'RPC::XML::string' ),
                 bless( do{\(my $o = '1')}, 'RPC::XML::int' ),
                 bless( do{\(my $o = '')}, 'RPC::XML::string' ),
                 bless( [
                          bless( {
                                   'info' => bless( {
                                                    'names' => bless( [
                                                                      bless( do{\(my $o = 'server_uuid')}, 'RPC::XML::string'
),
                                                                      bless( do{\(my $o = 'address')}, 'RPC::XML::string' ),
                                                                      bless( do{\(my $o = 'status')}, 'RPC::XML::string' ),
                                                                      bless( do{\(my $o = 'mode')}, 'RPC::XML::string' ),
                                                                      bless( do{\(my $o = 'weight')}, 'RPC::XML::string' )
                                                                    ], 'RPC::XML::array' )
                                                  }, 'RPC::XML::struct' ),
                                   'rows' => bless( [
                                                    bless( [
                                                             bless( do{\(my $o = '47cf54df-63fc-11e4-942e-fa163e020fd0')}, 'RPC::XML::string' ),
                                                             bless( do{\(my $o = '127.0.0.1:20886')}, 'RPC::XML::string' ),
                                                             bless( do{\(my $o = 'PRIMARY')}, 'RPC::XML::string' ),
                                                             bless( do{\(my $o = 'READ_WRITE')}, 'RPC::XML::string' ),
                                                             bless( do{\(my $o = '1.0')}, 'RPC::XML::double' )
                                                           ], 'RPC::XML::array' ),
                                                    bless( [
                                                             bless( do{\(my $o = '4b7036a9-63fc-11e4-942e-fa163e020fd0')}, 'RPC::XML::string' ),
                                                             bless( do{\(my $o = '127.0.0.1:20887')}, 'RPC::XML::string' ),
                                                             bless( do{\(my $o = 'SECONDARY')}, 'RPC::XML::string' ),
                                                             bless( do{\(my $o = 'READ_ONLY')}, 'RPC::XML::string' ),
                                                             bless( do{\(my $o = '1.0')}, 'RPC::XML::double' )
                                                           ], 'RPC::XML::array' )
                                                  ], 'RPC::XML::array' )
                                 }, 'RPC::XML::struct' )
                        ], 'RPC::XML::array' )
               ], 'RPC::XML::array' );

よっしゃよっしゃ。
これでFabric非対応のコネクターからでもほげほげふがふができそう(認証さえ何とかすれば)

…やー、Fabricサーバー以外の追加コンポーネントがなしでできるからMySQL Fabricいいなーと思ってるのに、ゴニョゴニョするとか正直やりたくないけど。。

2014/11/06

MySQL Fabricつらい(障害ノードの戻しとか)

マスター昇格編 でマスターをkillしても、スレーブがちゃんとマスターに昇格してくれるところまでは良かったんですが、


$ mysqlfabric group lookup_servers my_first_fabric
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  FAULTY READ_WRITE    1.0
4b7036a9-63fc-11e4-942e-fa163e020fd0 127.0.0.1:20887 PRIMARY READ_WRITE    1.0



(旧)マスターを起動したあとでも、待てど暮らせどファームには勝手に戻ってこない。


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

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.

master [localhost] {msandbox} ((none)) > show slave status\G
Empty set (0.00 sec)


$ mysqlfabric group promote my_first_fabric
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 manual
ly.

killしてもう一度起動したマスターには、当然今のマスターの情報はない。生きてる間にpromoteならFabricサーバーがログインしてゴニョゴニョしてくれるんだろうけど、そもそも接続できなかったんだから当たり前。スレーブがいないんだからもちろんpromoteもできない。


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

                                uuid finished success result
------------------------------------ -------- ------- ------
dec31088-00b1-4a33-bf36-622a9e1f302a        1       1      1

state success          when                                                   description
----- ------- ------------- -------------------------------------------------------------
    3       2   1.41526e+09 Triggered by <mysql .fabric.events.event="" 0x26c38d0="" at="" object="">.
    4       2   1.41526e+09                       Executing action (_block_write_demote).
    5       2   1.41526e+09                        Executed action (_block_write_demote).
    3       2   1.41526e+09 Triggered by <mysql .fabric.events.event="" 0x26c39d0="" at="" object="">.
    4       2   1.41526e+09                       Executing action (_wait_slaves_demote).
    5       2   1.41526e+09                        Executed action (_wait_slaves_demote).


$ mysqlfabric group health my_first_fabric
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_err
or sql_error
------------------------------------ -------- --------- -------------- ----------------- -------------- --------------- ------
-- ---------
47cf54df-63fc-11e4-942e-fa163e020fd0        1    FAULTY              0                 1              0               0    Fal
se     False
4b7036a9-63fc-11e4-942e-fa163e020fd0        1 SECONDARY              0                 1              0               0    Fal
se     False

issue
-----


$ mysqlfabric group lookup_servers my_first_fabric
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    FAULTY READ_WRITE    1.0
4b7036a9-63fc-11e4-942e-fa163e020fd0 127.0.0.1:20887 SECONDARY  READ_ONLY    1.0


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

                                uuid finished success result
------------------------------------ -------- ------- ------
01a40c48-347d-4fa8-887c-2cde33a353ad        1       1      1

state success          when                                                   description
----- ------- ------------- -------------------------------------------------------------
    3       2   1.41526e+09 Triggered by <mysql .fabric.events.event="" 0x2552e50="" at="" object="">.
    4       2   1.41526e+09                      Executing action (_define_ha_operation).
    5       2   1.41526e+09                       Executed action (_define_ha_operation).
    3       2   1.41526e+09 Triggered by <mysql .fabric.events.event="" 0x26bc7d0="" at="" object="">.
    4       2   1.41526e+09                      Executing action (_find_candidate_fail).
    5       2   1.41526e+09                       Executed action (_find_candidate_fail).
    3       2   1.41526e+09 Triggered by <mysql .fabric.events.event="" 0x26bc710="" at="" object="">.
    4       2   1.41526e+09                     Executing action (_check_candidate_fail).
    5       2   1.41526e+09                      Executed action (_check_candidate_fail).
    3       2   1.41526e+09 Triggered by <mysql .fabric.events.event="" 0x26bc750="" at="" object="">.
    4       2   1.41526e+09                          Executing action (_wait_slave_fail).
    5       2   1.41526e+09                           Executed action (_wait_slave_fail).
    3       2   1.41526e+09 Triggered by <mysql .fabric.events.event="" 0x26c3890="" at="" object="">.
    4       2   1.41526e+09                      Executing action (_change_to_candidate).
    5       2   1.41526e+09                       Executed action (_change_to_candidate).


$ mysqlfabric group health my_first_fabric
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        1  FAULTY              0                 1              0               0    False
     False
4b7036a9-63fc-11e4-942e-fa163e020fd0        1 PRIMARY              0                 0              0               0    False
     False

issue
-----



demote/promoteしてみたけどコレジャナイ
じゃあ、remove/addで登録しなおすか。


$ mysqlfabric group remove my_first_fabric 47cf54df-63fc-11e4-942e-fa163e020fd0
Fabric UUID:  5ca1ab1e-a007-feed-f00d-cab3fe13249e
Time-To-Live: 1

                                uuid finished success result
------------------------------------ -------- ------- ------
51509e3b-d1a7-4876-a52d-e25364c46d8d        1       1      1

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


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

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


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

                                uuid finished success result
------------------------------------ -------- ------- ------
f50a682b-dab6-4094-9f54-72c72569e71a        1       1      1

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


$ mysqlfabric group lookup_servers my_first_fabric                            [896/2897]
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


$ ./check_slaves.a
master
              Master_Log_File: mysql-bin.000003
          Read_Master_Log_Pos: 1548
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
          Exec_Master_Log_Pos: 1548
slave # 1
             File: mysql-bin.000003
         Position: 1548

あ、ちゃんとスレーブとしてファームに組み込まれた。


$ make_multiple_sandbox 5.6.21
installing node 1
installing node 2
installing node 3
group directory installed in $HOME/sandboxes/multi_msb_5_6_21

$ ./use_all "select @@port"
# server: 1:
@@port
14722
# server: 2:
@@port
14723
# server: 3:
@@port
14724

$ vim node?/my.sandbox.cnf
..
log-slave-updates
gtid-mode= ON
enforce-gtid-consistency

$ export MYCLIENT_OPTIONS="-uroot"
$ ./use_all "grant all on *.* to fabric@localhost identified by 'fabric_password'"
$ ./restart_all

$ mysqlfabric group add my_first_fabric 127.0.0.1:14722
$ mysqlfabric group add my_first_fabric 127.0.0.1:14723
$ mysqlfabric group add my_first_fabric 127.0.0.1:14724

$ mysqlfabric group health my_first_fabric
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_err
or sql_error
------------------------------------ -------- --------- -------------- ----------------- -------------- --------------- ------
-- ---------
01250ed8-6584-11e4-9e28-fa163e020fd0        1 SECONDARY              0                 0              0               0    Fal
se     False
47cf54df-63fc-11e4-942e-fa163e020fd0        1 SECONDARY              0                 0              0               0    Fal
se     False
4b7036a9-63fc-11e4-942e-fa163e020fd0        1   PRIMARY              0                 0              0               0    Fal
se     False
f9fe3cee-6583-11e4-9e28-fa163e020fd0        1 SECONDARY              0                 0              0               0    Fal
se     False
fd8c1c45-6583-11e4-9e28-fa163e020fd0        1 SECONDARY              0                 0              0               0    Fal
se     False

issue
-----


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

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.

node1 [localhost] {root} ((none)) > show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| d1                 |
| mysql              |
| performance_schema |
| test               |
+--------------------+
5 rows in set (0.01 sec)

おおー。GTIDだから、マスターにバイナリーログさえ残ってればmysqlfabric group addするより前のバイナリーログもちゃんと適用される。
ジェネラルログを覗くと、


76 Connect   fabric@localhost on
                   76 Query     SET NAMES 'utf8' COLLATE 'utf8_general_ci'
                   76 Query     SET @@session.autocommit = ON
                   76 Query     SELECT @@GLOBAL.SERVER_UUID as SERVER_UUID
                   76 Query     SELECT @@GLOBAL.SERVER_ID as SERVER_ID
                   76 Query     SELECT @@GLOBAL.VERSION as VERSION
                   76 Query     SELECT @@GLOBAL.GTID_MODE as GTID_MODE
                   76 Query     SELECT @@GLOBAL.LOG_BIN as LOG_BIN
                   76 Query     SELECT @@GLOBAL.READ_ONLY as READ_ONLY
                   76 Query     SHOW GRANTS
                   76 Query     STOP SLAVE
                   76 Query     SHOW SLAVE STATUS
                   76 Query     SHOW SLAVE STATUS
                   76 Query     CHANGE MASTER TO MASTER_HOST = '127.0.0.1' MASTER_USER = 'fabric' MASTER_PASSWORD =  MASTER_PORT = 20887
                   76 Query     SET @@GLOBAL.READ_ONLY = ON
                   76 Query     SELECT @@GLOBAL.READ_ONLY as READ_ONLY
                   76 Query     START SLAVE
                   76 Query     SHOW SLAVE STATUS
                   76 Query     SHOW SLAVE STATUS

うむ。シャードをゴニョゴニョするときはmysqldumpを使う(/etc/mysql/fabric.cfgにmysqldumpのパスを書くパラメーターがある)けど、単に追加するだけの時はFabricサーバーは特に面倒を見ないと。とはいえGTID前提だから、XtraBackupでサクッと作ってサクッとmysqlfabric group addでおしまいと。

( ´-`).oO(や、便利なんだけどその前提条件がな。。


【2014/11/06 18:16】
途中からだいぶ脱線していた気がするけれど、もともとの目的だった"status: FAULTYからstatus: SECONDARYに戻す"は、




$ mysqlfabric server set_status 4b7036a9-63fc-11e4-942e-fa163e020fd0 SPARE
Fabric UUID:  5ca1ab1e-a007-feed-f00d-cab3fe13249e
Time-To-Live: 1

                                uuid finished success result
------------------------------------ -------- ------- ------
aa09ecf8-2f55-4c11-bc25-53b0ae19b3b0        1       1      1

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


$ mysqlfabric group health my_first_fabric
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        1 PRIMARY              0                 0              0               0    False     False
4b7036a9-63fc-11e4-942e-fa163e020fd0        1   SPARE              0                 0              0               0    False     False

issue
-----


$ mysqlfabric server set_status 4b7036a9-63fc-11e4-942e-fa163e020fd0 SECONDARY
Fabric UUID:  5ca1ab1e-a007-feed-f00d-cab3fe13249e
Time-To-Live: 1

                                uuid finished success result
------------------------------------ -------- ------- ------
1e8eb7c0-2233-4087-86cb-bedc9e331f1e        1       1      1

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


$ mysqlfabric group health my_first_fabric
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        1   PRIMARY              0                 0              0               0    False     False
4b7036a9-63fc-11e4-942e-fa163e020fd0        1 SECONDARY              0                 0              0               0    False     False

issue
-----



Σ(゚д゚lll) できたーっ!