InnoDB Clusterが、2017/4/12にGAになりました。
lab版ではこちらの記事で既に試してましたが、GAになって結構変わったところもあるみたいなので改めて書き直してみました。
InnoDB Clusterがどういうものかは、こちらを見てみて下さい。
簡単に言えば、Group Replication + MySQL Router + MySQL Shellで、
Group Replicationで作ったレプリケーションクラスタに、MySQL RouterがR/WやR/Oの透過的ルーティングをしてくれる、
というもので、その操作にMySQL Shellを使う、
という感じです。
今回の記事では、InnoDB Clusterのセットアップまでをやっていこうと思います。
今回使った環境の情報を参考までに書いておきます。
MySQLサーバ innodb-cluster1 192.168.2.224 innodb-cluster2 192.168.2.225 innodb-cluster3 192.168.2.226 APサーバ cent7-mysql57-1 192.168.2.221 cent7-mysql57-2 192.168.2.222
※「APサーバのくせにホスト名にmysqlって書いてある!」というツッコミは禁止です!(MySQLは止めてあります)
MySQLの開発チームが公開しているブログにCentOS用のセットアップ手順があったので、
こちらを参照していきましょう。
公式マニュアルはこちらにあるので、
ちょくちょくこちらも見て間違いがないかチェック。
https://dev.mysql.com/doc/refman/5.7/en/mysql-innodb-cluster-working-with-production-deployment.html
なお、以下の手順では3つのインスタンス(別ホスト上)をクラスタに参加させます。
MySQLのインストールなどなどは、特に記載してない限りは3つのインスタンスで同様に実行します。
GR・SHELLのパッケージインストール
InnoDB Clusterは、「InnoDB Cluster」というパッケージがあるわけではなく、
MySQL ServerのGroup Replication機能、MySQL Router、MySQL Shellの3つを組み合わせてできるものです。
必要となるパッケージは以下の3つです。
mysql-community-server-5.7.18-1.el7.x86_64.rpm mysql-router-2.1.3-1.el7.x86_64.rpm mysql-shell-1.0.9-1.el7.x86_64.rpm
早速インストールしていきましょう。
なお、以降も同じですが、一般的なコマンドについては結果出力は省きます。
くどいので。
MySQLのインストールと初期設定まではまとめて書いてしまいます。
# rpm -Uvh mysql-community-libs-compat-5.7.18-1.el7.x86_64.rpm mysql-community-libs-5.7.18-1.el7.x86_64.rpm mysql-community-common-5.7.18-1.el7.x86_64.rpm # rpm -ivh mysql-community-client-5.7.18-1.el7.x86_64.rpm # rpm -ivh mysql-community-server-5.7.18-1.el7.x86_64.rpm # systemctl start mysqld.service # cat /var/log/mysqld.log | grep -i password # mysql -uroot -p Enter password:(先ほどのパスワード) mysql> set password for root@localhost='MySQL5.7'; mysql> uninstall plugin validate_password; mysql> set password for root@localhost='root'; mysql> exit
もちろん、validate_passwordプラグインは抜かなくても良いです。
そして、ホスト名の名前解決が必要とのことなので、
それを追記しました。
# vi /etc/hosts # cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 # added for InnoDB Cluster 192.168.2.224 innodb-cluster1 192.168.2.225 innodb-cluster2 192.168.2.226 innodb-cluster3
次はMySQL Shellのインストールです。
# rpm -ivh mysql-shell-1.0.9-1.el7.x86_64.rpm
簡単ですね。
InnoDB Cluster加入準備
lab版の頃と違うのはここから。
GA版ではなんと、my.cnfに設定を入れてくれる関数、dba.configureLocalInstance()があります。
MySQL Shellから利用できます。
# mysqlsh Welcome to MySQL Shell 1.0.9 Copyright (c) 2016, 2017, 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', '\h' or '\?' for help, type '\quit' or '\q' to exit. Currently in JavaScript mode. Use \sql to switch to SQL mode and execute queries. mysql-js>
MySQL Shellは、JavaScriptモード、Pythonモード、SQLモードの3種類のモードがあります。
ここではデフォルトのJavaScriptモードで進めます。
mysql-js> dba.configureLocalInstance(); Please provide the password for 'root@localhost:3306': Detecting the configuration file... Found configuration file at standard location: /etc/my.cnf Do you want to modify this file? [Y|n]: Y MySQL user 'root' cannot be verified to have access to other hosts in the network. 1) Create root@% with necessary grants 2) Create account with different name 3) Continue without creating account 4) Cancel Please select an option [1]: 2 Please provide an account name (e.g: icroot@%) to have it created with the necessary privileges or leave empty and press Enter to cancel. Account Name: icroot@% Password for new account: Confirm password: Validating instance... The configuration has been updated but it is required to restart the server. { "config_errors": [ { "action": "restart", "current": "OFF", "option": "enforce_gtid_consistency", "required": "ON" }, { "action": "restart", "current": "OFF", "option": "gtid_mode", "required": "ON" }, { "action": "restart", "current": "0", "option": "log_bin", "required": "1" }, { "action": "restart", "current": "0", "option": "log_slave_updates", "required": "ON" }, { "action": "restart", "current": "FILE", "option": "master_info_repository", "required": "TABLE" }, { "action": "restart", "current": "FILE", "option": "relay_log_info_repository", "required": "TABLE" }, { "action": "restart", "current": "OFF", "option": "transaction_write_set_extraction", "required": "XXHASH64" } ], "errors": [], "restart_required": true, "status": "error" } mysql-js>
ここまで見た感じ、何に使うかわからないですが、
他ホストからの接続用ユーザの作成、
/etc/my.cnfへの設定の追記をやってくれたようです。
確認してみましょう。
mysql-js> \sql Switching to SQL mode... Commands end with ; mysql-sql> \connect localhost Creating a Session to 'root@localhost' Enter password: Classic Session successfully established. No default schema selected. mysql-sql> select user, host from mysql.user; +-----------+-----------+ | user | host | +-----------+-----------+ | icroot | % | | mysql.sys | localhost | | root | localhost | +-----------+-----------+ 3 rows in set (0.00 sec) mysql-sql>
確かに先ほど指定したicroot@%ユーザが作られていますね。
次は/etc/my.cnf。
ちなみに、MySQL Shellは、抜けるときには\quitか\q、です。
exitやquitでは抜けられないので注意!
(Ctrl+Cでも抜けられましたが)
あと、デフォルトで書かれているコメントアウトされている行はうっとうしいので消しました。
# cat /etc/my.cnf [mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock symbolic-links=0 log-error=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid log_slave_updates = ON server_id = 2512783239 relay_log_info_repository = TABLE master_info_repository = TABLE transaction_write_set_extraction = XXHASH64 binlog_format = ROW disabled_storage_engines = MyISAM,BLACKHOLE,FEDERATED,CSV,ARCHIVE report_port = 3306 binlog_checksum = NONE enforce_gtid_consistency = ON log_bin gtid_mode = ON
なんかすごいいっぱい書かれました。
今まで勝手にmy.cnfに書く、という挙動はなかっただけに、
カルチャーショック。
pid-fileまでは元々書かれていたので、
log_slave_updates以下がdba.configureLocalInstance()によって書かれた行ですね。
disabled_storage_enginesにMyISAMと書かれているのが涙を誘います。
さて、dba.configureLocalInstance()実行後にも書かれていた通り、
これらは再起動が必要なパラメータなので、
MySQLを再起動しておきましょう。
# systemctl restart mysqld.service
そして設定が正しく反映されているかどうか確認する関数があるそうなので、
試してみましょう。
# mysqlsh mysql-js> dba.checkInstanceConfiguration('root@localhost:3306'); Please provide the password for 'root@localhost:3306': Validating instance... The instance 'localhost:3306' is valid for Cluster usage { "status": "ok" } mysql-js>
“status”: “ok”と言ってくれているので、問題なさそうですね。
これでInnoDB Clusterへ加入する準備は整ったわけです。
InnoDB Cluster作成
さて、それではクラスターを作成しましょう。
既に各インスタンスは加入準備OKの設定になっていますので、
MySQL Shellでクラスタを作って加入させるだけです。
※ここは1つのインスタンスのみで実行
[root@innodb-cluster1 ~]# mysqlsh mysql-js> shell.connect('icroot@192.168.2.224:3306'); Please provide the password for 'icroot@192.168.2.224:3306': Creating a Session to 'icroot@192.168.2.224:3306' Classic Session successfully established. No default schema selected. mysql-js> var cluster = dba.createCluster('UCO_Cluster'); A new InnoDB cluster will be created on instance 'icroot@192.168.2.224:3306'. Creating InnoDB cluster 'UCO_Cluster' on 'icroot@192.168.2.224:3306'... Adding Seed Instance... Cluster successfully created. Use Cluster.addInstance() to add MySQL instances. At least 3 instances are needed for the cluster to be able to withstand up to one server failure. mysql-js>
ちなみにここ、connectのところで、
shell.connect(‘icroot@localhost:3306’);
と書いても接続はできるのですが、次のcreateClusterするところで、
Dba.createCluster: To add an instance to the cluster, please use a valid, non-local hostname or IP. localhost can only be used with sandbox MySQL instances. (RuntimeError)
と言われます。
状態を確認しましょう。
mysql-js> cluster.status(); { "clusterName": "UCO_Cluster", "defaultReplicaSet": { "name": "default", "primary": "192.168.2.224:3306", "status": "OK_NO_TOLERANCE", "statusText": "Cluster is NOT tolerant to any failures.", "topology": { "192.168.2.224:3306": { "address": "192.168.2.224:3306", "mode": "R/W", "readReplicas": {}, "role": "HA", "status": "ONLINE" } } } } mysql-js>
1つのインスタンスがONLINEで参加しているのが確認できます。
残りの2台を追加しましょう。
これは、今まで作業していたホストからでもリモートで実行できます。
mysql-js> cluster.addInstance('icroot@192.168.2.225:3306'); A new instance will be added to the InnoDB cluster. Depending on the amount of data on the cluster this might take from a few seconds to several hours. Please provide the password for 'icroot@192.168.2.225:3306': Adding instance to the cluster ... The instance 'icroot@192.168.2.225:3306' was successfully added to the cluster. mysql-js> cluster.addInstance('icroot@192.168.2.226:3306'); A new instance will be added to the InnoDB cluster. Depending on the amount of data on the cluster this might take from a few seconds to several hours. Please provide the password for 'icroot@192.168.2.226:3306': Adding instance to the cluster ... The instance 'icroot@192.168.2.226:3306' was successfully added to the cluster. mysql-js> cluster.status(); { "clusterName": "UCO_Cluster", "defaultReplicaSet": { "name": "default", "primary": "192.168.2.224:3306", "status": "OK", "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.", "topology": { "192.168.2.224:3306": { "address": "192.168.2.224:3306", "mode": "R/W", "readReplicas": {}, "role": "HA", "status": "ONLINE" }, "192.168.2.225:3306": { "address": "192.168.2.225:3306", "mode": "R/O", "readReplicas": {}, "role": "HA", "status": "ONLINE" }, "192.168.2.226:3306": { "address": "192.168.2.226:3306", "mode": "R/O", "readReplicas": {}, "role": "HA", "status": "ONLINE" } } } } mysql-js>
いいですね、最初のホストがR/W、残りがR/Oでクラスタに参加しました。
これでクラスタ側は準備完了です。
言い換えれば、Group Replication部分は完成です。
MySQL Routerインストール
次はMySQL Routerの準備をしましょう。
MySQL Routerは、マニュアルによればAPサーバと同居させるのが推奨らしいので、
別サーバにインストールしましょう。
今回はAPサーバを2台用意しました。
インストール自体は簡単です。
# rpm -ivh mysql-router-2.1.3-1.el7.x86_64.rpm
これでインストールは完了です。
MySQL Router設定
MySQL Routerは、bootstrapオプションを指定することで、
InnoDB Clusterの(Group Replicationの)構成情報を取得しに行くことができます。
# mysqlrouter --bootstrap icroot@192.168.2.224:3306 --directory /etc/UCO_Cluster --user=root Please enter MySQL password for icroot: Bootstrapping MySQL Router instance at /etc/UCO_Cluster... MySQL Router has now been configured for the InnoDB cluster 'UCO_Cluster'. The following connection information can be used to connect to the cluster. Classic MySQL protocol connections to cluster 'UCO_Cluster': - Read/Write Connections: localhost:6446 - Read/Only Connections: localhost:6447 X protocol connections to cluster 'UCO_Cluster': - Read/Write Connections: localhost:64460 - Read/Only Connections: localhost:64470
ここで、私はrootユーザで作業していたので、
–user=rootを付けないと、以下のようなエラーが出力されました。
Error: You are bootstraping as a superuser. This will make all the result files (config etc.) privately owned by the superuser. Please use --user=username option to specify the user that will be running the router. Use --user=root if this really should be the superuser.
セキュアでないからでしょうか。
とりあえずはrootユーザでやってしまいましたが、
もしかしたらセキュリティ上マズイ可能性もあるので、要確認ですね。
ともあれ、これで–directoryで指定したディレクトリに、
今回作ったクラスタ(UCO_Cluster)用の設定ファイル、起動スクリプト等が作成されました。
# ls -l /etc/UCO_Cluster 合計 16 drwx------ 2 root root 20 4月 14 07:35 data drwx------ 2 root root 28 4月 14 07:35 log -rw------- 1 root root 1184 4月 14 07:35 mysqlrouter.conf -rw------- 1 root root 87 4月 14 07:35 mysqlrouter.key drwx------ 2 root root 6 4月 14 07:35 run -rwx------ 1 root root 151 4月 14 07:35 start.sh -rwx------ 1 root root 144 4月 14 07:35 stop.sh
ではMySQL Routerを起動しましょう。
# /etc/UCO_Cluster/start.sh PID 1121 written to /etc/UCO_Cluster/mysqlrouter.pid
なんかすごい簡単ですね。
MySQL Fabricの頃に手動で/etc/mysqlrouter.iniを書いていたのがなつかしいです。
これでInnoDB Cluster完成です。
動作確認
簡単な動作確認をしてみましょう。
まずは書き込みです。
APサーバ#1から書き込みましょう。
・・・と思いましたが、まだそんなユーザ作ってないので無理ですね。
しかたないので、R/Wになっているサーバに直接ログインしてユーザを作って、
ついでにテスト用テーブルも作っちゃいましょう。
※R/WになっているMySQLサーバ1台のみで作業します。
[root@innodb-cluster1 ~]# mysqlsh mysql-js> \connect localhost Enter password: mysql-js> \sql mysql-sql> create user admin@'%' identified by 'admin'; mysql-sql> grant all on *.* to admin@'%'; mysql-sql> create database UCO; mysql-sql> create table UCO.t1 (id int primary key auto_increment, comment varchar(50));
気を取り直して、APサーバ#1から書き込み!
# mysql -uadmin -padmin -h192.168.2.221 -P6446 -e"insert into UCO.t1 values(null, 'from AP1')" # mysql -uadmin -padmin -h192.168.2.221 -P6446 -e"select * from UCO.t1" mysql: [Warning] Using a password on the command line interface can be insecure. +----+----------+ | id | comment | +----+----------+ | 6 | from AP1 | +----+----------+
よーしよしよし、ちゃんとINSERTできたな。
次はR/Oを試してみよう。
# mysql -uadmin -padmin -h192.168.2.221 -P6447 -e"select @@hostname, @@port" mysql: [Warning] Using a password on the command line interface can be insecure. +-----------------+--------+ | @@hostname | @@port | +-----------------+--------+ | innodb-cluster2 | 3306 | +-----------------+--------+ # mysql -uadmin -padmin -h192.168.2.221 -P6447 -e"select @@hostname, @@port" mysql: [Warning] Using a password on the command line interface can be insecure. +-----------------+--------+ | @@hostname | @@port | +-----------------+--------+ | innodb-cluster3 | 3306 | +-----------------+--------+
ちゃんとラウンドロビンで参照できてますね。
更新は拒否してくれるかな?
# mysql -uadmin -padmin -h192.168.2.221 -P6447 -e"insert into UCO.t1 values(null, 'from AP1')" mysql: [Warning] Using a password on the command line interface can be insecure. ERROR 1290 (HY000) at line 1: The MySQL server is running with the --super-read-only option so it cannot execute this statement
よしよし、予想通り。
これで簡単な挙動確認はおしまい。
障害時の挙動も確認したいですが、今日はここまで。
長文読んで頂いてありがとうございました!!!
2016/4/23 追記
障害時の挙動確認もやってみました。
記事はこちら。