MySQL Utilitiesの導入とmysqlfailoverの動作確認

準同期レプリケーションの環境向けにMySQL Utilitiesを導入し、mysqlfailoverの動作を確認します。最後に実運用へのmysqlfailover導入に向けての課題出しもしてみたいと思います。

mysqlfailoverとは

MySQLの準同期レプリケーションはスレーブの台数はいくらでも増やすことができますが、マスターとしては、1台しか動作できず、そのマスターでしかINSERTやUPDATEなどの更新(DML文)を実行できない仕組み上の制約があります。
そのマスターの生死を監視し、障害が発生した時にスレーブの1台をマスターに昇格するフェールオーバーを自動で実行してくれるのが今回導入するmysqlfailoverです。mysqlfailoverはOracleが開発・配布しているMySQL Utilitiesの一つの機能です。
従来、この様なマスターの可用性の確保はMaster-HA for MySQL(以下MHA)で実現するのが一般的でしたが、残念ながらMHAの開発やrpmパッケージの配布が終了してしまっているそうです。

環境・構成

今回MySQLとは別に監視用のサーバを立てています。監視専用のサーバを確保できない場合などは、スレーブの1台にmysqlfailoverを導入する事も可能です。
MySQLの導入や準同期レプリケーションの設定は過去の記事で紹介した手順で導入しています。

CentOS7&MySQL5.7でクラッシュセーフな準同期レプリケーションを構築する - tkn4416 Tech Blog

f:id:tkn4416:20180410074330p:plain

監視用のサーバの構成

MySQL Utilities1.6.5
CentOS Linux release 7.4.1708 (Core)
・ESXi6.5仮想サーバー(RAM:2GB、HDD:16GB(シンプロビジョニング))
NIC:1枚(192.168.1.0/24に接続)

監視対象のMySQLサーバの仕様・パラメータ

以下の過去記事の手順で、マスター1台、スレーブ2台の準同期レプリケーションを設定しています。明記しない限り、システム変数(パラメータ)も以下の記事の設定です。

サーバ構成も記事の通りで、全サーバ(3台)とも以下の通りです。
・MySQL5.7.21
CentOS Linux release 7.4.1708 (Core)
・ESXi6.5仮想サーバー(RAM:2GB、HDD:16GB(シンプロビジョニング))
NIC:1枚(192.168.1.0/24に接続)

手順

パスワードやGTID等は*(アスタリスク)で伏字にしています。

1. レプリケーション設定の変更

前回の記事ではSTART SLAVE構文でレプリケーション用のユーザとパスワードを設定していましたが、CHANGE MASTER TOでユーザとパスワードを設定し、master info repositoryにマスター接続情報が登録されないとmysqlfailoverが動作しなかった為、スレーブ全台で設定をし直します。
セキュリティについてNoteレベルのメッセージ(Code 1759/1760)がでていますが、1760については後ほど実運用に向けての課題1で触れています。

[MySQLスレーブ全台(192.168.1.1213)]
mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)

mysql> reset slave all;
Query OK, 0 rows affected (0.00 sec)

mysql> CHANGE MASTER TO
    ->     MASTER_HOST = '192.168.1.11',
    ->     MASTER_PORT = 3306,
    ->     MASTER_USER= 'repl',
    ->     MASTER_PASSWORD= '******',
    ->     MASTER_AUTO_POSITION = 1;
Query OK, 0 rows affected, 2 warnings (0.01 sec)

Note (Code 1759): Sending passwords in plain text without SSL/TLS is extremely insecure.
Note (Code 1760): Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
mysql> START SLAVE;
Query OK, 0 rows affected (0.00 sec)

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.1.11
                  Master_User: repl
                  Master_Port: 3306
(中略)
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
(以下略)

2. MySQL Utilitiesのインストール

監視用サーバにMySQL UtilitiesとMySQL Clientを導入します。

初めに、MySQL公式Yumリポジトリ情報をインストールします。インストールするRPMパッケージは、下記のURLから最新版のファイル名を確認してコマンドを置き換えてください。
https://dev.mysql.com/downloads/repo/yum/

[監視用サーバ]
shell> yum localinstall https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm

MySQL UtilitiesとMySQL Clientをインストールします。

[監視用サーバ]
shell> yum install mysql-utilities mysql-community-client

以下のパッケージがインストールまたは置換されました。

インストール:
  mysql-community-client.x86_64 0:5.7.21-1.el7
  mysql-community-libs.x86_64 0:5.7.21-1.el7
  mysql-community-libs-compat.x86_64 0:5.7.21-1.el7
  mysql-utilities.noarch 0:1.6.5-1.el7

依存性関連をインストールしました:
  mysql-community-common.x86_64 0:5.7.21-1.el7
  mysql-connector-python.x86_64 0:2.1.7-1.el7

置換:
  mariadb-libs.x86_64 1:5.5.56-2.el7

3. 監視用ユーザを作成と接続確認

監視用サーバ(Linuxユーザ)

監視用のサーバに監視用のLinuxユーザを追加します。

[監視用サーバ]
shell> useradd dbmon
shell> passwd dbmon

監視対象MySQLサーバ(MySQLユーザ)

MySQLのマスター(192.168.1.11)のみで実行します。(スレーブにも反映されます。)

[MySQLマスター]
CREATE USER 'utilities'@'192.168.1.%' identified by '******';

GRANT ALL PRIVILEGES ON *.* TO 'utilities'@'192.168.1.%' WITH GRANT OPTION;

接続確認

監視用サーバに作成したユーザ(dbmon)でログインし直し、監視対象MySQLサーバへの接続を確認します。

[監視用サーバ]
shell> mysql -u utilities -h 192.168.1.11 -p

4. MySQL Utilitiesの動作確認

MySQL Utilitiesの動作確認として、mysqlfailoverの前にmysqlrpladminというツールでレプリケーションのヘルスチェックをしてみます。

[監視用サーバ]
[dbmon@**** ~]$ mysqlrpladmin --master=utilities:******@192.168.1.11:3306 \
> --slaves=utilities:******@192.168.1.12:3306,utilities:******@192.168.1.13:3306 \
> health
WARNING: Using a password on the command line interface can be insecure.
# Checking privileges.
#
# Replication Topology Health:
+------------------+-------+---------+--------+------------+---------+
| host             | port  | role    | state  | gtid_mode  | health  |
+------------------+-------+---------+--------+------------+---------+
| 192.168.1.11     | 3306  | MASTER  | UP     | ON         | OK      |
| 192.168.1.12     | 3306  | SLAVE   | UP     | ON         | OK      |
| 192.168.1.13     | 3306  | SLAVE   | UP     | ON         | OK      |
+------------------+-------+---------+--------+------------+---------+
# ...done.

5. mysqlfailoverの監視用デーモン起動

mysqlfailoverのデーモンを起動します。

[dbmon@**** ~]$ mysqlfailover \
> --master=utilities:******@192.168.1.11:3306 \
> --slaves=utilities:******@192.168.1.12:3306,utilities:******@192.168.1.13:3306 \
> --log=/home/dbmon/mysqlfailover.log \
> --pidfile=/home/dbmon/failover_daemon.pid \
> --rpl-user=repl:****** \
> --failover-mode=auto \
> --daemo=start \
> -v
WARNING: Using a password on the command line interface can be insecure.
NOTE: Log file '/home/dbmon/mysqlfailover.log' does not exist. Will be created.
Starting failover daemon...

[dbmon@**** ~]$ ps aux | grep mysqlfailover
dbmon    22176  0.5  0.6 242532 13080 ?        S    07:18   0:00 /usr/bin/python /usr/bin/mysqlfailover --master=utilities:******@192.168.1.11:3306 --slaves=utilities:******@192.168.1.12:3306,utilities:******@192.168.1.13:3306 --log=/home/dbmon/mysqlfailover.log --pidfile=/home/dbmon/failover_daemon.pid --rpl-user=repl:****** --failover-mode=auto --daemo=start -v
dbmon    22188  0.0  0.0 112676   992 pts/0    R+   07:19   0:00 grep --color=auto mysqlfailover

起動しました。
psコマンドでパスワードが丸見えですが、実運用に向けての課題2で簡単に対処方法を紹介しています。

パラメータで指定したログファイルには以下の様に起動時のログと定期的なヘルスチェック結果が出力されます。

[dbmon@**** ~]$ cat /home/dbmon/mysqlfailover.log
2018-04-04 07:18:56 AM INFO MySQL Utilities mysqlfailover version 1.6.5.
2018-04-04 07:18:57 AM INFO Server '192.168.1.11:3306' is using MySQL version 5.7.21-log.
2018-04-04 07:18:57 AM INFO Server '192.168.1.12:3306' is using MySQL version 5.7.21-log.
2018-04-04 07:18:57 AM INFO Server '192.168.1.13:3306' is using MySQL version 5.7.21-log.
2018-04-04 07:18:57 AM INFO Checking privileges.
2018-04-04 07:18:57 AM INFO Unregistering existing instances from slaves.
2018-04-04 07:18:57 AM INFO Registering instance on master.
2018-04-04 07:18:57 AM INFO Failover daemon started.
2018-04-04 07:18:57 AM INFO Failover mode = auto.
2018-04-04 07:19:00 AM INFO Master Information
2018-04-04 07:19:00 AM INFO Binary Log File: mysql-bin.000003, Position: 403, Binlog_Do_DB: N/A, Binlog_Ignore_DB: N/A
2018-04-04 07:19:00 AM INFO GTID Executed Set: ********-****-****-****-************:1-4
2018-04-04 07:19:00 AM INFO Getting health for master: 192.168.1.11:3306.
2018-04-04 07:19:00 AM INFO Health Status:
2018-04-04 07:19:00 AM INFO host: 192.168.1.11, port: 3306, role: MASTER, state: UP, gtid_mode: ON, health: OK, version: 5.7.21-log, master_log_file: mysql-bin.000003, master_log_pos: 403, IO_Thread: , SQL_Thread: , Secs_Behind: , Remaining_Delay: , IO_Error_Num: , IO_Error: , SQL_Error_Num: , SQL_Error: , Trans_Behind:
2018-04-04 07:19:00 AM INFO host: 192.168.1.12, port: 3306, role: SLAVE, state: UP, gtid_mode: ON, health: OK, version: 5.7.21-log, master_log_file: mysql-bin.000003, master_log_pos: 403, IO_Thread: Yes, SQL_Thread: Yes, Secs_Behind: 0, Remaining_Delay: No, IO_Error_Num: 0, IO_Error: , SQL_Error_Num: 0, SQL_Error: , Trans_Behind: 0
2018-04-04 07:19:00 AM INFO host: 192.168.1.13, port: 3306, role: SLAVE, state: UP, gtid_mode: ON, health: OK, version: 5.7.21-log, master_log_file: mysql-bin.000003, master_log_pos: 403, IO_Thread: Yes, SQL_Thread: Yes, Secs_Behind: 0, Remaining_Delay: No, IO_Error_Num: 0, IO_Error: , SQL_Error_Num: 0, SQL_Error: , Trans_Behind: 0
(以下、Master Informationt部分とHealth Status部分の繰り返し)

6. マスターを停止してフェールオーバーを発動させる

フェールオーバーを発動させて動作を確認する為、マスター(192.168.1.11)のMySQLサーバを停止します。

[マスター]
# systemctl stop mysqld.service

しばらくするとフェールオーバーが発動しました。 mysqlfailoverのログファイルにフェールオーバーの状況の詳細が出力されます。

正常にフェールオーバーすると残りの2台構成で監視を継続しています。MHAは1回しかフェールオーバーできず二重障害に対応できなかったので、この点はMHAより優れています。

[監視用サーバ]
(/home/dbmon/mysqlfailover.logから抜粋)
2018-04-04 07:27:46 AM INFO host: 192.168.1.12, port: 3306, role: SLAVE, state: UP, gtid_mode: ON, health: OK, version: 5.7.21-log, master_log_file: mysql-bin.000003, master_log_pos: 403, IO_Thread: Yes, SQL_Thread: Yes, Secs_Behind: 0, Remaining_Delay: No, IO_Error_Num: 0, IO_Error: , SQL_Error_Num: 0, SQL_Error: , Trans_Behind: 0
2018-04-04 07:27:46 AM INFO host: 192.168.1.13, port: 3306, role: SLAVE, state: UP, gtid_mode: ON, health: OK, version: 5.7.21-log, master_log_file: mysql-bin.000003, master_log_pos: 403, IO_Thread: Yes, SQL_Thread: Yes, Secs_Behind: 0, Remaining_Delay: No, IO_Error_Num: 0, IO_Error: , SQL_Error_Num: 0, SQL_Error: , Trans_Behind: 0
2018-04-04 07:28:10 AM INFO Master may be down. Waiting for 3 seconds.
2018-04-04 07:28:25 AM INFO Failed to reconnect to the master after 3 attempts.
2018-04-04 07:28:25 AM CRITICAL Master is confirmed to be down or unreachable.
2018-04-04 07:28:25 AM INFO Failover starting in 'auto' mode...
2018-04-04 07:28:25 AM INFO Checking eligibility of slave 192.168.1.12:3306 for candidate.
2018-04-04 07:28:25 AM INFO GTID_MODE=ON ... Ok
2018-04-04 07:28:25 AM INFO Replication user exists ... Ok
2018-04-04 07:28:25 AM INFO Candidate slave 192.168.1.12:3306 will become the new master.
2018-04-04 07:28:25 AM INFO Checking slaves status (before failover).
2018-04-04 07:28:25 AM INFO Preparing candidate for failover.
2018-04-04 07:28:25 AM INFO Reading events in relay log for slave 192.168.1.12:3306
2018-04-04 07:28:25 AM INFO Reading events in relay log for slave 192.168.1.13:3306
2018-04-04 07:28:25 AM INFO No missing transactions found on 192.168.1.13:3306. Skipping connection of candidate as slave.
2018-04-04 07:28:25 AM INFO Creating replication user if it does not exist.
2018-04-04 07:28:25 AM INFO Stopping slaves.
2018-04-04 07:28:25 AM INFO Performing STOP on all slaves.
2018-04-04 07:28:26 AM WARNING Executing stop on slave 192.168.1.12:3306 WARN - slave is not configured with this master
2018-04-04 07:28:26 AM INFO Executing stop on slave 192.168.1.12:3306 Ok
2018-04-04 07:28:26 AM WARNING Executing stop on slave 192.168.1.13:3306 WARN - slave is not configured with this master
2018-04-04 07:28:26 AM INFO Executing stop on slave 192.168.1.13:3306 Ok
2018-04-04 07:28:26 AM INFO Switching slaves to new master.
2018-04-04 07:28:26 AM INFO Disconnecting new master as slave.
2018-04-04 07:28:26 AM INFO Execute on 192.168.1.12:3306: RESET SLAVE ALL
2018-04-04 07:28:26 AM INFO Starting slaves.
2018-04-04 07:28:26 AM INFO Performing START on all slaves.
2018-04-04 07:28:26 AM INFO Executing start on slave 192.168.1.13:3306 Ok
2018-04-04 07:28:26 AM INFO Checking slaves for errors.
2018-04-04 07:28:27 AM INFO 192.168.1.13:3306 status: Ok
2018-04-04 07:28:27 AM INFO Failover complete.
2018-04-04 07:28:32 AM INFO Unregistering existing instances from slaves.
2018-04-04 07:28:32 AM INFO Registering instance on new master 192.168.1.12:3306.
2018-04-04 07:28:32 AM INFO Master Information
2018-04-04 07:28:32 AM INFO Binary Log File: mysql-bin.000002, Position: 968, Binlog_Do_DB: N/A, Binlog_Ignore_DB: N/A
2018-04-04 07:28:32 AM INFO GTID Executed Set: ********-****-****-****-************:1-4[...]
2018-04-04 07:28:32 AM INFO Getting health for master: 192.168.1.12:3306.
2018-04-04 07:28:32 AM INFO Health Status:
2018-04-04 07:28:32 AM INFO host: 192.168.1.12, port: 3306, role: MASTER, state: UP, gtid_mode: ON, health: OK, version: 5.7.21-log, master_log_file: mysql-bin.000002, master_log_pos: 968, IO_Thread: , SQL_Thread: , Secs_Behind: , Remaining_Delay: , IO_Error_Num: , IO_Error: , SQL_Error_Num: , SQL_Error: , Trans_Behind:
2018-04-04 07:28:32 AM INFO host: 192.168.1.13, port: 3306, role: SLAVE, state: UP, gtid_mode: ON, health: OK, version: 5.7.21-log, master_log_file: mysql-bin.000002, master_log_pos: 968, IO_Thread: Yes, SQL_Thread: Yes, Secs_Behind: 0, Remaining_Delay: No, IO_Error_Num: 0, IO_Error: , SQL_Error_Num: 0, SQL_Error: , Trans_Behind: 0
(以下、Master Informationt部分とHealth Status部分の繰り返し)

7. 監視デーモンの停止

デーモンを停止するだけですが、ちょっと注意が必要です。
MySQL Utilities1.6.5のバグ(※BUG#85254)の回避の為、デーモン停止の前に追加手順が必要です。

MySQL Bugs: #85254: mysqlfailover 1.6.5 stop breaks replication
監視用テーブル(mysql.failover_console)のCREATE時、マスターでバイナリログの出力をOFFにしている(スレーブにレプリケーションしない)が、DROP時にバイナリログの出力を停止していないので、スレーブで存在しないテーブルを削除しようとしてエラーが発生し、レプリケーションが停止してしまう事象。

回避策はデーモンの停止の前に、MySQLのマスターで以下のDROP文を流すだけです。

[新マスター]
DROP TABLE IF EXISTS mysql.failover_console;

監視デーモンの停止は監視用サーバーで以下のコマンドを実行します。

[監視用サーバ]
[dbmon@**** ~]$ mysqlfailover --daemo=stop --pidfile=/home/dbmon/failover_daemon.pid

8. 旧マスターの後処理

動作確認の後片付けとして、フェールオーバーを発動させる為に停止した旧マスターを新マスターのスレーブとして設定します。

MySQLサーバを起動します。

[旧マスター]
# systemctl start mysqld.service

旧マスターを新マスターのスレーブに設定します。

[旧マスター]
mysql> reset slave all;
Query OK, 0 rows affected (0.01 sec)

mysql> CHANGE MASTER TO
    ->     MASTER_HOST = '192.168.1.12',
    ->     MASTER_PORT = 3306,
    ->     MASTER_USER= 'repl',
    ->     MASTER_PASSWORD= '******',
    ->     MASTER_AUTO_POSITION = 1;
Query OK, 0 rows affected, 2 warnings (0.01 sec)

Note (Code 1759): Sending passwords in plain text without SSL/TLS is extremely insecure.
Note (Code 1760): Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
mysql> start slave;
Query OK, 0 rows affected (0.01 sec)

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.1.12
                  Master_User: repl
                  Master_Port: 3306
(中略)
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
(以下略)

実運用へのmysqlfailover導入に向けての課題

ここまでの動作確認で分かった対処の検討が必要な課題や、実現できていないことをまとめます。

(課題1) slave_master_infoでレプリケーション用ユーザのパスワードが見えてしまう

mysql.slave_master_infoにレプリケーション用ユーザのパスワードが平文で載ってしまいます(★の部分)。これは、手順1でSTART SLAVE文でパスワードを指定する方法だとmysqlfailoverが動作しない問題の対処として、CHANGE MASTER TO構文でパスワードを指定した為です。
これについては、権限設定でmysqlスキーマかこのテーブル単体で管理者以外に見せない設定にしてしまえば良いだけですね。

mysql> select * from mysql.slave_master_info\G
*************************** 1. row ***************************
       Number_of_lines: 25
       Master_log_name: mysql-bin.000003
        Master_log_pos: 194
                  Host: 192.168.1.11
             User_name: repl
         User_password: ******(★)
                  Port: 3306
         Connect_retry: 60
           Enabled_ssl: 0
                Ssl_ca:
            Ssl_capath:
              Ssl_cert:
            Ssl_cipher:
               Ssl_key:
Ssl_verify_server_cert: 0
             Heartbeat: 30
                  Bind:
    Ignored_server_ids: 0
                  Uuid: 1d1d635c-257d-11e8-a4e9-000c2969ff50
           Retry_count: 86400
               Ssl_crl:
           Ssl_crlpath:
 Enabled_auto_position: 1
          Channel_name:
           Tls_version:
1 row in set (0.00 sec)

(課題2) psコマンドでmysqlfailover用のパスワードが見えてしまう

手順5で前述の通り、監視用サーバでpsコマンドを叩くとmysqlfailover監視デーモンの起動時に指定したパスワードが見えてしまいます。(以下の*伏字部分)
これはlogin-path(.mylogin.cnf)を使って認証することで対処可能です。login-pathなら他のユーザから見えてしまっても.mylogin.cnfを設定したLinuxユーザでログインしないとMySQLに接続できないからです。

[dbmon@**** ~]$ ps aux | grep mysqlfailover
dbmon    22176  0.5  0.6 242532 13080 ?        S    07:18   0:00 /usr/bin/python /usr/bin/mysqlfailover --master=utilities:******@192.168.1.11:3306 --slaves=utilities:******@192.168.1.12:3306,utilities:******@192.168.1.13:3306 --log=/home/dbmon/mysqlfailover.log --pidfile=/home/dbmon/failover_daemon.pid --rpl-user=repl:****** --failover-mode=auto --daemo=start -v
dbmon    22188  0.0  0.0 112676   992 pts/0    R+   07:19   0:00 grep --color=auto mysqlfailover

(課題3) 監視デーモン停止でレプリケーションが停止してしまう(BUG#85254)

手順7で回避手順を実施したMySQL Utilities1.6.5のバグです。MySQL Utilitiesのアップデートで根本解決するまでは、以下のDROP文をデーモン停止の前に流しましょう。 ※MySQL Bugs: #85254: mysqlfailover 1.6.5 stop breaks replication

なお、このバグは、MySQL Utilities1.6.4のバグの対処として変更された箇所に起因していて、MySQL Utilities 1.6.4以前は別の問題を抱えています。運用で回避しながら1.6.5を使うのがベストでしょう。

DROP TABLE IF EXISTS mysql.failover_console;

(課題4) クライアントからマスターへの接続の切り替え

mysqlfailoverやMySQL Utilitiesのその他のコマンドではアプリなどのクライアントからの接続の切り替えはしてくれません。MySQLがフェールオーバーしてもクライアントからの接続を新しいマスターに切り替えないと意味がありません。
mysqlfailoverのデーモン起動の際、フェールオーバー前後で呼び出す外部スクリプトを指定できます。そのスクリプトにフェールオーバー前後のサーバのIPアドレスを引数で渡してくれるので、vip(仮想IPアドレス)を付け替えるスクリプトを(シェルスクリプトなどで)書くのが良いと思います。MHAでも同様にvip(仮想IPアドレス)を付け替える方法が一般的でしたので、MHAからの乗り換えの方ならスクリプトをある程度流用できそうですね。

CentOS7&MySQL5.7でクラッシュセーフな準同期レプリケーションを構築する

レプリケーションや高可用性構成の検証の為、MySQL5.7に準同期レプリケーションを構築した手順をまとめます。
MySQL5.7でデフォルトでONになっているロスレスレプリケーションの他、GTIDやクラッシュセーフスレーブもONにした手堅い設定になっています。いずれもMySQL5.7ではパフォーマンスを維持しながら可用性を高められるオプションなので、新規導入ならONにするのがお勧めです。

はじめに手順をまとめます。主要なオプション(パラメータ)については手順の後にまとめています。

前提

サーバーの用意

・マスター用:1台
・スレーブ用:1台以上
マスター・スレーブとも以下の記事の手順で新規インストールしています。
CentOS7にyumでMySQL5.7最新版をインストールする - tkn4416 Tech Blog

運用中のサーバをもとにスレーブを追加しレプリケーション構成にする場合、スレーブへのデータのコピーなどの作業も必要です。

サーバーの構成

全台とも以下の構成で確認しています。
・MySQL5.7.21
CentOS Linux release 7.4.1708 (Core)
・ESXi6.5仮想サーバー(RAM:2GB、HDD:16GB(シンプロビジョニング))
NIC:1枚(192.168.1.0/24に接続)

手順

rootで作業しています。必要に応じてsudoを付けて実行してください。
IPアドレスは第4オクテットを伏字(**)にしていますので、環境にあわせて変更してください。

1. ファイアウォールの設定

CentOS7のデフォルト設定ではMySQLレプリケーションの通信がブロックされてしまう為、publicゾーンにmysqlを追加します。

#publicゾーンにmysqlを追加
firewall-cmd --permanent --add-service=mysql --zone=public
#設定確認
firewall-cmd --permanent --list-services --zone=public
#設定反映
firewall-cmd --reload

2. 準同期レプリケーションプラグインのインストール

mysqlfailoverなどでスレーブのマスター昇格がある環境の場合、マスター用、スレーブ用双方導入してください。

マスター

mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';

スレーブ

mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';

3. レプリケーション用ユーザの作成

マスター昇格がある場合、スレーブにも設定が必要です。IPアドレスやパスワードなどは適宜変更してください。

マスター

mysql> create user repl@'192.168.1.%' identified by '*******';
mysql> grant replication slave on *.* to repl@'192.168.1.%';

4. オプションファイル(/etc/my.cnf)の編集

オプションファイル(/etc/my.cnf)の最後尾に以下を追加します。
関連する主要なオプション(パラメータ)については、手順の後で説明します。

マスター

1行目と23行目はレプリケーションの動作と関係ありませんが確認しやすい様に設定しています。

log_timestamps = SYSTEM                 # ログ出力のタイムゾーンをOS設定準拠

log_bin=mysql-bin
log_slave_updates = TRUE

## Replication
server_id = 1                           # Server毎に一意
report-host = DB01                      # Server毎に一意
report-port = 3306
gtid_mode = ON
enforce_gtid_consistency = ON

## Master
rpl_semi_sync_master_enabled = 1        # 準同期レプリケーションを有効にする(Masterのみ)
master-info-repository = TABLE

## Slave
#rpl_semi_sync_slave_enabled = 1        # 準同期レプリケーションを有効にする(Slaveのみ)
relay_log_recovery = TRUE
relay_log_info_repository = TABLE

[mysql]
show-warnings                           # Warningを即時表示

スレーブ

サーバー毎に一意にするオプションは適宜設定値を変更してください。
1行目と23行目はレプリケーションの動作と関係ありませんが確認しやすい様に設定しています。

log_timestamps = SYSTEM                 # ログ出力のタイムゾーンをOS設定準拠

log_bin=mysql-bin
log_slave_updates = TRUE

## Replication
server_id = 2                           # Server毎に一意
report-host = DB02                      # Server毎に一意
report-port = 3306
gtid_mode = ON
enforce_gtid_consistency = ON

## Master
#rpl_semi_sync_master_enabled = 1       # 準同期レプリケーションを有効にする(Masterのみ)
master-info-repository = TABLE

## Slave
rpl_semi_sync_slave_enabled = 1         # 準同期レプリケーションを有効にする(Slaveのみ)
relay_log_recovery = TRUE
relay_log_info_repository = TABLE

[mysql]
show-warnings                           # Warningを即時表示

5. MySQLサーバーの再起動

全サーバーでMySQLサーバーを再起動します。

systemctl restart mysqld.service

6. レプリケーションの開始

スレーブ

スレーブの全サーバで以下を実行します。

mysql> CHANGE MASTER TO
 MASTER_HOST = '192.168.1.**',
 MASTER_PORT = 3306,
 MASTER_AUTO_POSITION = 1;

mysql>START SLAVE USER='repl' PASSWORD='*********';

7. レプリケーションの確認

スレーブ

-- スレーブステータスの確認
mysql> SHOW SLAVE STATUS\G

以下の2項目がYesとなることを確認します。

mysql> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
(中略)
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
(中略)
1 row in set (0.00 sec)

マスター

mysql> SHOW MASTER STATUS\G

設定したスレーブが表示されることを確認します。

mysql> SHOW SLAVE HOSTS;
+-----------+------+------+-----------+--------------------------------------+
| Server_id | Host | Port | Master_id | Slave_UUID                           |
+-----------+------+------+-----------+--------------------------------------+
|         2 | DB02 | 3306 |         1 | ********-****-****-****-************ |
+-----------+------+------+-----------+--------------------------------------+
1 row in set (0.00 sec)

レプリケーション、バイナリログ関連のオプション(サーバーシステム変数)

上の手順では暗黙のデフォルトで問題ないオプションは特に設定していませんが、大事なものは下表にまとめます。

サーバーシステム変数の詳細は以下のリンク先(公式マニュアル)をご覧ください。
https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html

オプション(システム変数)名 暗黙のデフォルト値 本手順設定値 説明
sync_binlog 1 1 クラッシュセーフなバイナリログ同期
expire_logs_days 0(無期限) 0 バイナリログの保持期間[単位:日]
log_slave_updates FALSE TRUE スレーブでレプリケーション起因の更新もバイナリログ出力する。マスター昇格の可能性のあるスレーブはTRUE必須。
server_id 0 サーバー毎 サーバー毎に一意な整数を設定
report-host サーバー毎 サーバー毎に一意な文字列。SHOWコマンドやMySQL Utilitiesで表示に使うホスト名、mysqlfailover使用時は設定必須。
report-port 3306 mysqlfailover使用時は設定必須
gtid_mode OFF ON GTIDの有効/無効、mysqlfailover使用時はON必須
enforce_gtid_consistency OFF ON GTIDの一貫性を担保できないSQLの発行を禁止
rpl_semi_sync_master_enabled 0(OFF) 1(ON) 準同期レプリケーションのマスターとしての動作を有効化
rpl_semi_sync_master_timeout 10000(10秒) 10000 スレーブからの応答のタイムアウト値[単位:ミリ秒]、超過した場合非同期レプリケーションでの動作に切り替える。
rpl_semi_sync_master_wait_for_slave_count 1 1 マスターのコミット時に応答を待つスレーブの台数
rpl_semi_sync_master_wait_point AFTER_SYNC AFTER_SYNC AFTER_SYNCにすることでロスレス準同期レプリケーションとして動作
master-info-repository FILE TABLE マスター情報リポジトリの格納先。mysqlfailover使用時はTABLEが必須。
rpl_semi_sync_slave_enabled 0(OFF) 1(ON) 準同期レプリケーションのスレーブとしての動作の有効化
relay_log_recovery FALSE TRUE MySQLサーバ起動時にリレーログとリレーログリポジトリを比較し、未適用のリレーログがあれば破棄する。クラッシュセーフスレーブはTRUE必須。
relay_log_purge TRUE TRUE 不要なリレーログを破棄する。クラッシュセーフスレーブではTRUE必須。
relay_log_info_repository FILE TABLE リレーログ情報リポジトリの格納先。TABLEの場合、トランザクションでデータの整合性が保証される。クラッシュセーフスレーブではTABLEが必須。

CentOS7にyumでMySQL5.7最新版をインストールする

MySQL5.7でレプリケーションや高可用性構成などを検証する機会に恵まれました。
備忘録として手順や検証結果を残していこうと思いますが、はじめに検証に使った環境のMySQLのインストール手順をまとめます。

環境

サーバー

・ESXi6.5仮想サーバー
・RAM:2GB、HDD:16GB(シンプロビジョニング)、NIC:1枚

OS

CentOS Linux release 7.4.1708 (Core)
 → minimalでインストールし、最低限のネットワーク設定のみ実施済

手順

rootで作業しています。必要に応じてsudoを付けて実行してください。

1. MySQL公式Yumリポジトリの情報のインストール

インストールするRPMパッケージは、下記のURLから最新版のファイル名を確認してコマンドを置き換えてください。
https://dev.mysql.com/downloads/repo/yum/

yum localinstall https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm

真っ先にyum remove mariadb-libsしている手順をよく見かけますが、上記パッケージをインストールするとMySQLインストール時にmysql-libsと置換してくれるので削除不要です。削除した場合、依存性の関係でpostfixが削除されますのでご注意を。

2018/5/10補記 MySQL8.0GA以降の追加手順

2018/4/19にMySQL8.0がGAになり、上記リンクの最新のMySQL公式YumリポジトリからはデフォルトでMySQL8.0が導入されるようになりました。
引き続き、MySQL5.7をインストールしたい場合、下記の手順でMySQL8.0リポジトリの無効化とMySQL5.7リポジトリの有効化を行います。

# 公式リポジトリ情報ファイルのインストール(上記手順と同じ)
yum localinstall https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm

# yum-utilsのインストール
yum install yum-utils
# MySQL8.0リポジトリの無効化
yum-config-manager --disable mysql80-community
# MySQL5.7リポジトリの有効化
yum-config-manager --enable mysql57-community
# mysql-communityの定義ファイルの確認
cat /etc/yum.repos.d/mysql-community.repo

2. MySQL のインストール

yum install mysql-community-server

以下のパッケージがインストールまたは置換されました。

インストール:
  mysql-community-libs.x86_64 0:5.7.21-1.el7
  mysql-community-libs-compat.x86_64 0:5.7.21-1.el7
  mysql-community-server.x86_64 0:5.7.21-1.el7

依存性関連をインストールしました:
  mysql-community-client.x86_64 0:5.7.21-1.el7
  mysql-community-common.x86_64 0:5.7.21-1.el7
  net-tools.x86_64 0:2.0-0.22.20131004git.el7
  perl.x86_64 4:5.16.3-292.el7
  perl-Carp.noarch 0:1.26-244.el7
  perl-Encode.x86_64 0:2.51-7.el7
  perl-Exporter.noarch 0:5.68-3.el7
  perl-File-Path.noarch 0:2.09-2.el7
  perl-File-Temp.noarch 0:0.23.01-3.el7
  perl-Filter.x86_64 0:1.49-3.el7
  perl-Getopt-Long.noarch 0:2.40-2.el7
  perl-HTTP-Tiny.noarch 0:0.033-3.el7
  perl-PathTools.x86_64 0:3.40-5.el7
  perl-Pod-Escapes.noarch 1:1.04-292.el7
  perl-Pod-Perldoc.noarch 0:3.20-4.el7
  perl-Pod-Simple.noarch 1:3.28-4.el7
  perl-Pod-Usage.noarch 0:1.63-3.el7
  perl-Scalar-List-Utils.x86_64 0:1.27-248.el7
  perl-Socket.x86_64 0:2.010-4.el7
  perl-Storable.x86_64 0:2.45-3.el7
  perl-Text-ParseWords.noarch 0:3.29-4.el7
  perl-Time-HiRes.x86_64 4:1.9725-3.el7
  perl-Time-Local.noarch 0:1.2300-2.el7
  perl-constant.noarch 0:1.27-2.el7
  perl-libs.x86_64 4:5.16.3-292.el7
  perl-macros.x86_64 4:5.16.3-292.el7
  perl-parent.noarch 1:0.225-244.el7
  perl-podlators.noarch 0:2.5.1-3.el7
  perl-threads.x86_64 0:1.87-4.el7
  perl-threads-shared.x86_64 0:1.43-6.el7

置換:
  mariadb-libs.x86_64 1:5.5.56-2.el7

3. 必要に応じて/etc/my.cnfの編集

ここでは特に編集していません。
データディレクトリやエラーログ(mysqld.log)の出力先をカスタマイズしたい場合、このタイミングで編集します。レプリケーション構成にしたい場合でも、このタイミングではバイナリログやGTIDの設定はデフォルトのまま無効とします。

4. MySQL Serverの初回起動

systemctl start mysqld.service

問題がなければ特にメッセージは返りません。

5. temporary passwordの確認とパスワード変更

初期パスワードと必要に応じてUUIDを確認します。

grep 'A temporary password' /var/log/mysqld.log
grep UUID /var/log/mysqld.log

上で確認したパスワードでmysqlにログインします。

mysql -u root -p

MySQLのrootユーザのパスワードを設定します。

mysql> SET PASSWORD='********';

インストールされた環境の構成

以下のような構成になりました。その他の詳細は以下のリンク先をご覧ください。 https://dev.mysql.com/doc/refman/5.7/en/linux-installation-rpm.html#mysql-installation-layout-linuxrpm

パス
オプションファイル /etc/my.cnf
データディレクト /var/lib/mysql/
エラーログ /var/log/mysqld.log
Pidファイル /var/run/mysql/mysqld.pid
Socket /var/lib/mysql/mysql.sock

CentOS6へのMySQL5.6インストール方法3選

MySQL5.6環境が必要になった為、インストール手順をあれこれ試してみました。
備忘録も兼ね、実際に使えそうな手順を3つ残します。

導入先の環境

CentOS6.8(x86_64)をminimalでインストールし、事前に環境に応じたネットワーク設定とwgetを導入(※)しています。 ※yum install wget

全てrootで作業しています。適宜sudoを付けるなどしてください。

[方法1] Yumリポジトリから5.6最新版を導入(お勧め)

MySQL公式のYumリポジトリからMySQL5.6の最新版をインストールする手順です。
特に理由がない限り、この方法がお勧めです。

1.MySQL公式Yumリポジトリの情報のインストール&設定

以下のURLから、Red Hat Enterprise Linux 6用のRPMパッケージを入手します。
mysql57~.rpmしかありませんが、5.6の情報も含まれているので大丈夫です。

Download MySQL Yum Repository
https://dev.mysql.com/downloads/repo/yum/

以下の例は、調査時点(2017/4/5)のパッケージの最新版です。作業時点で確認してください。

shell> wget https://dev.mysql.com/get/mysql57-community-release-el6-9.noarch.rpm

続けてインストール

shell> yum localinstall ./mysql57-community-release-el6-9.noarch.rpm

以下の設定ファイルを編集して、MySQL5.7を無効、MySQL5.6を有効に変更します。

shell> vi /etc/yum.repos.d/mysql-community.repo

編集内容

[mysql56-community]
enabled=0 ⇒ enabled=1

[mysql57-community]
enabled=1 ⇒ enabled=0

2.MySQLのインストール

Yumコマンドでインストールします。

shell> yum install mysql-community-server

以下のパッケージがインストールまたは置換されました。

インストール:
  mysql-community-libs.x86_64 0:5.6.35-2.el6
  mysql-community-libs-compat.x86_64 0:5.6.35-2.el6
  mysql-community-server.x86_64 0:5.6.35-2.el6

依存性関連をインストールしました:
  mysql-community-client.x86_64 0:5.6.35-2.el6
  mysql-community-common.x86_64 0:5.6.35-2.el6
  numactl.x86_64 0:2.0.9-2.el6
  perl.x86_64 4:5.10.1-141.el6_7.1
  perl-DBI.x86_64 0:1.609-4.el6
  perl-Module-Pluggable.x86_64 1:3.90-141.el6_7.1
  perl-Pod-Escapes.x86_64 1:1.04-141.el6_7.1
  perl-Pod-Simple.x86_64 1:3.13-141.el6_7.1
  perl-libs.x86_64 4:5.10.1-141.el6_7.1
  perl-version.x86_64 3:0.77-141.el6_7.1

置換:
  mysql-libs.x86_64 0:5.1.73-7.el6

3.MySQLの起動とパスワードの変更

MySQLのサービスを起動します。

shell> service mysqld start

MySQLにrootでログインし、パスワードを設定します。
この方法の場合のみ、初期状態ではパスワードは設定されていません。

shell> mysql -u root   
mysql> SET PASSWORD = PASSWORD('hogehoge'); 

必要に応じてmysql_secure_installationで設定を変更します。

shell> /usr/bin/mysql_secure_installation

[方法2] 過去のバージョンのRPMパッケージをYumで導入する

指定のバージョンをインストールする必要がある場合におすすめの手順です。

1.RPMパッケージの入手

以下のURLからRPMパッケージを入手します。

MySQL Community Server (Archived Versions)
https://downloads.mysql.com/archives/community/

以下の3パッケージは必須、他は必要に応じて選んでください。

以下の例では、MySQL5.6.11のパッケージのパスを確認して、wgetコマンドでダウンロードしています。

wget https://downloads.mysql.com/archives/get/file/MySQL-server-5.6.11-2.el6.x86_64.rpm
wget https://downloads.mysql.com/archives/get/file/MySQL-client-5.6.11-2.el6.x86_64.rpm
wget https://downloads.mysql.com/archives/get/file/MySQL-devel-5.6.11-2.el6.x86_64.rpm
wget https://downloads.mysql.com/archives/get/file/MySQL-shared-compat-5.6.11-2.el6.x86_64.rpm
wget https://downloads.mysql.com/archives/get/file/MySQL-shared-5.6.11-2.el6.x86_64.rpm

2.ダウンロードしたパッケージのインストール

入手したRPMパッケージの置いてある場所で実行します。

yum install ./*.rpm

以下のパッケージがインストールまたは置換されました。

インストール:
  MySQL-client.x86_64 0:5.6.11-2.el6         MySQL-devel.x86_64 0:5.6.11-2.el6
  MySQL-server.x86_64 0:5.6.11-2.el6         MySQL-shared.x86_64 0:5.6.11-2.el6
  MySQL-shared-compat.x86_64 0:5.6.11-2.el6

依存性関連をインストールしました:
  perl.x86_64 4:5.10.1-141.el6_7.1
  perl-Module-Pluggable.x86_64 1:3.90-141.el6_7.1
  perl-Pod-Escapes.x86_64 1:1.04-141.el6_7.1
  perl-Pod-Simple.x86_64 1:3.13-141.el6_7.1
  perl-libs.x86_64 4:5.10.1-141.el6_7.1
  perl-version.x86_64 3:0.77-141.el6_7.1

置換:
  mysql-libs.x86_64 0:5.1.73-7.el6

3.MySQLの起動とパスワードの変更

MySQLのサービスを起動します。

shell> service mysqld start

rootの初期パスワードを確認します。

shell> cat /root/.mysql_secret

rootでログインし、パスワードを変更します。

shell> mysql -u root -p
    
mysql> SET PASSWORD = PASSWORD('hogehoge');

必要に応じてmysql_secure_installationで設定を変更します。

shell> /usr/bin/mysql_secure_installation

[方法3] PRMパッケージを個別にインストールする

インターネット接続できない環境でのインストールなどに応用できます。今回の確認環境はインターネット接続がある環境で、一部Yumも使っています。 この方法の場合、RPMパッケージの導入順序を意識したり、/etc/my.cnfの設置・設定も必要になります。

この手順は、以下の公式ドキュメントを参考にしています。

2.5.5 RPM パッケージを使用して MySQLLinux にインストールする
https://dev.mysql.com/doc/refman/5.6/ja/linux-installation-rpm.html

1.RPMパッケージの入手

以下のURLからRPMパッケージを入手します。

MySQL Community Server (Archived Versions)
https://downloads.mysql.com/archives/community/

以下の3パッケージは必須、他は必要に応じて選んでください。

以下の例では、MySQL5.6.11のパッケージのパスを確認して、wgetコマンドでダウンロードしています。

wget https://downloads.mysql.com/archives/get/file/MySQL-server-5.6.11-2.el6.x86_64.rpm
wget https://downloads.mysql.com/archives/get/file/MySQL-client-5.6.11-2.el6.x86_64.rpm
wget https://downloads.mysql.com/archives/get/file/MySQL-devel-5.6.11-2.el6.x86_64.rpm
wget https://downloads.mysql.com/archives/get/file/MySQL-shared-compat-5.6.11-2.el6.x86_64.rpm
wget https://downloads.mysql.com/archives/get/file/MySQL-shared-5.6.11-2.el6.x86_64.rpm

2.MySQL-shared-compatのインストール

CentOS6標準のmysql-libs(クライアントライブラリ)の互換ライブラリです。これを先にインストールする点が重要です。

rpm -ivh MySQL-shared-compat-5.6.11-2.el6.x86_64.rpm

3.mysql-libsの削除

MySQL公式ドキュメントによると、MySQL-shared-compatがmysql-libsは無効にするので、削除しなくても共存できるそうです。 今回は、Yumを使って、削除しています。

yum remove mysql-libs

4.依存性の解決

入手したRPMパッケージの置いてある場所で実行します。

rpm -ivh --test ./*.rpm

以下の様に前提パッケージが表示されるので全てインストールします。
今回の環境では、perlを導入(※)しています。
yum install perl

エラー: 依存性の欠如:
        /usr/bin/perl は MySQL-client-5.6.11-2.el6.x86_64 に必要とされています
        /usr/bin/perl は MySQL-server-5.6.11-2.el6.x86_64 に必要とされています
        perl は MySQL-test-5.6.11-2.el6.x86_64 に必要とされています

5.残りのMySQLのパッケージの導入

最低限必要なのは、MySQL-serverとMySQL-clientです。その他は要件に合わせて導入します。

rpm -ivh MySQL-server-5.6.11-2.el6.x86_64.rpm
rpm -ivh MySQL-client-5.6.11-2.el6.x86_64.rpm
rpm -ivh MySQL-devel-5.6.11-2.el6.x86_64.rpm
rpm -ivh MySQL-shared-5.6.11-2.el6.x86_64.rpm

6./etc/my.cnfの作成

テンプレートをコピーして、最低限必要な箇所を設定します。

cp -p /usr/share/mysql/my-default.cnf /etc/my.cnf
vi /etc/my.cnf

編集箇所は、5.6.11の場合、18行目からの部分です。

編集前

 # basedir = .....
 # datadir = .....
 # port = .....
 # server_id = .....
 # socket = .....

編集後

 basedir = /usr
 datadir = /var/lib/mysql
 port = 3306
 server_id = 2
 socket = /var/lib/mysql/mysql.sock

7.MySQLの起動とパスワードの変更

MySQLのサービスを起動します。

shell> service mysqld start

rootの初期パスワードを確認します。

shell> cat /root/.mysql_secret

rootでログインし、パスワードを変更します。

shell> mysql -u root -p
mysql> SET PASSWORD = PASSWORD('hogehoge');

必要に応じてmysql_secure_installationで設定を変更します。

shell> /usr/bin/mysql_secure_installation