MySQL5.7でmysql-utilitiesにハマった話


MySQL5.7 + GTID + Loss-less Semi-sync + mysqlfailover、夢の構成です。
これを検証していてハマった話の顛末を書いておきます。

「先によく調べておけよ」ってことなのかもしれないですが・・・

## 検証環境

最初はこんな感じで検証してました。

* CentOS7
* mysql-community-server-5.7.10-1.el7.x86_64
* mysql-utilities-1.5.6-1.el7.noarch
* mysql-connector-python-2.1.3-1.el7.x86_64


## 問題の現象

手動フェイルオーバーを試そうとすると、失敗するわけです。

```bash
$ mysqlrpladmin failover --slaves=mysqladmin:password@192.168.200.106,mysqladmin:password@192.168.200.107 --rpl-user=repl:password

WARNING: Using a password on the command line interface can be insecure.
# Checking privileges.
# Performing failover.
ERROR: The server 192.168.200.106:3306 does not comply to the latest GTID feature support. Errors:
    Missing gtid_executed system variable.
```

気になるのは最後のメッセージ

```
Missing gtid_executed system variable.
```

いやいや、ちゃんと`gtid_executed`変数はありますよ。

```mysql
mysql> show global variables like 'gtid_executed'\G;
*************************** 1. row ***************************
Variable_name: gtid_executed
        Value: 023ec6ed-9ef5-11e5-85c9-0800276b5788:1-2,
```


## 解決

で、気付いたわけです。
**ちゃんと`gtid_executed`変数を取得できてないだけじゃないか** と。
たぶん、mysql-connector-pythonがMySQL5.7に対応していないんですね。

### 修正

直します。

```bash
$ cp -p /usr/lib/python2.7/site-packages/mysql/utilities/common/server.py /tmp/
$ vi /usr/lib/python2.7/site-packages/mysql/utilities/common/server.py
[変更前]
### この行を探して
        res = self.exec_query("SHOW VARIABLES LIKE 'gtid_executed'")

[変更後]
### GLOBALという文字列を加えます。
        res = self.exec_query("SHOW GLOBAL VARIABLES LIKE 'gtid_executed'")
```

差分はこんな感じ。

```bash
$ diff -u /tmp/server.py /usr/lib/python2.7/site-packages/mysql/utilities/common/server.py
--- /tmp/server.py	2015-09-15 15:50:33.000000000 +0000
+++ /usr/lib/python2.7/site-packages/mysql/utilities/common/server.py	2015-12-10 05:28:40.799389254 +0000
@@ -1425,7 +1425,7 @@
             errors.append("    GTID is not enabled.")
         if not self.check_version_compat(5, 6, 9):
             errors.append("    Server version must be 5.6.9 or greater.")
-        res = self.exec_query("SHOW VARIABLES LIKE 'gtid_executed'")
+        res = self.exec_query("SHOW GLOBAL VARIABLES LIKE 'gtid_executed'")
         if res == [] or not res[0][0] == "gtid_executed":
             errors.append("    Missing gtid_executed system variable.")
         if errors:
```

### 動作確認

改めて動作確認。

```bash
$ mysqlrpladmin failover --slaves=mysqladmin:password@192.168.200.106,mysqladmin:password@192.168.200.107 --rpl-user=repl:password
WARNING: Using a password on the command line interface can be insecure.
# Checking privileges.
# Performing failover.
# Candidate slave 192.168.200.106:3306 will become the new master.
# Checking slaves status (before failover).
# Preparing candidate for failover.
# Creating replication user if it does not exist.
# Stopping slaves.
# Performing STOP on all slaves.
# Switching slaves to new master.
# Disconnecting new master as slave.
# Starting slaves.
# Performing START on all slaves.
# Checking slaves for errors.
# Failover complete.
#
# Replication Topology Health:
+------------------+-------+---------+--------+------------+---------+
| host             | port  | role    | state  | gtid_mode  | health  |
+------------------+-------+---------+--------+------------+---------+
| 192.168.200.106  | 3306  | MASTER  | UP     | ON         | OK      |
| 192.168.200.107  | 3306  | SLAVE   | UP     | ON         | OK      |
+------------------+-------+---------+--------+------------+---------+
# ...done.
```

動いた！


## 最後に

全て確認したわけではないので、mysql-connector-python-2.1.3にはまだバグ(というかMySQL5.7未対応)がありそうな気がします。
そのうちに修正された正式版が出ると思うので、DB関連は慌てず待ったほうが良さそうですね。