MySQL 5.7.23 で Group Replicationを構築しただけ
MySQL InnoDB Cluster 使いたいなー使いたいよね?ということで動作確認しようとしてハマりまくった際のメモ。
MySQL Shellで簡単に設定できませんでした。悲しい。
今回はMySQL Routerの設定はしません。
表記がわかりやすかったので、おおよその表記は「MySQL 8.0.13 で MySQL InnoDB Cluster を構築する」こちらのページを参考にさせていただいています。
環境
今回使用する環境は以下の通りです。
OS | アプリ | IP | ホスト名 |
---|---|---|---|
CentOS7 | MySQL 5.7.23, MySQL Shell 8.0.16 | 192.168.10.101 | node01 |
CentOS7 | MySQL 5.7.23, MySQL Shell 8.0.16 | 192.168.10.102 | node02 |
CentOS7 | MySQL 5.7.23, MySQL Shell 8.0.16 | 192.168.10.103 | node03 |
host名が[all_server] となっているコマンドはMySQLが動作しているすべてのnodeで実行します。 MySQLが5.7系列だとMySQL Shellはlocal環境で実行しないと設定の永続化が出来ないため、すべてのサーバにMySQL Shellをインストールする必要があります。
手元のPCにMySQL Shellのダウンロード
手元でMySQL Shellを実行したい場合はこの項を参考にしてください。
残念ながらMySQL 5.7系を使っていると手元で実行しても設定の永続化ができないので悲しくなります。
こちらのページ MySQL :: Download MySQL Shell からMySQL Shellをダウンロードして実行可能パスに配置してください。 今回はmacOSでダウンロードしました。
[mysqlsh] $ cd ~/Downloads [mysqlsh] $ tar -zxvf mysql-shell-8.0.16-macos10.14-x86-64bit.tar.gz [mysqlsh] $ mv mysql-shell-8.0.16-macos10.14-x86-64bit /usr/local/share/mysql-shell [mysqlsh] $ ln -s /usr/local/share/mysql-shell/bin/* /usr/local/bin/* [mysqlsh] $ mysqlsh --version mysqlsh Ver 8.0.16 for Darwin on x86_64 - for MySQL 8.0.16 (MySQL Community Server (GPL))
共通の設定
すべてのサーバで実行してください。
SELinuxを無効にします。無効にせずに利用する場合はこちらの記事「Group Replication 環境での SELinux / firewalld | スマートスタイル TECH BLOG|データベース&クラウドの最新技術情報を配信」を参考にしてください。
[all_server] $ sudo setenforce 0 [all_server] $ sudo sed -i -e 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
MySQL 5.7.23をインストールします。
[all_server] $ sudo rpm -ivh http://dev.mysql.com/get/mysql57-community-release-el7-7.noarch.rpm [all_server] $ cd /usr/local/src [all_server] $ sudo wget https://downloads.mysql.com/archives/get/file/mysql-5.7.23-1.el7.x86_64.rpm-bundle.tar [all_server] $ sudo tar -xvf mysql-5.7.23-1.el7.x86_64.rpm-bundle.tar [all_server] $ sudo yum list installed | grep mysql [all_server] $ sudo yum localinstall mysql-community-server-5.7.23-1.el7.x86_64.rpm \ mysql-community-client-5.7.23-1.el7.x86_64.rpm \ mysql-community-common-5.7.23-1.el7.x86_64.rpm \ mysql-community-devel-5.7.23-1.el7.x86_64.rpm \ mysql-community-libs-5.7.23-1.el7.x86_64.rpm \ mysql-community-libs-compat-5.7.23-1.el7.x86_64.rpm [all_server] $ sudo yum list installed | grep mysql
バージョンが5.7.23になっていれば成功です。
MySQL Shell をインストールします。
[all_server] $ cd /usr/local/src [all_server] $ sudo wget https://dev.mysql.com/get/Downloads/MySQL-Shell/mysql-shell-8.0.16-1.el7.x86_64.rpm [all_server] $ sudo yum localinstall mysql-shell-8.0.16-1.el7.x86_64.rpm [all_server] $ mysqlsh --version mysqlsh Ver 8.0.16 for Linux on x86_64 - for MySQL 8.0.16 (MySQL Community Server (GPL))
ユーザ権限を設定
Group Replicationに使うユーザの権限を設定します。ここではrepl
ユーザを設定します。
すべてのサーバで設定してください。
[all_server] $ sudo systemctl start mysqld mysql > SET SQL_LOG_BIN=0; mysql > CREATE USER repl@'%' IDENTIFIED BY 'mysqlrepl'; mysql > SET SQL_LOG_BIN=1; mysql > CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='mysqlrepl' FOR CHANNEL 'group_replication_recovery'; mysql > GRANT SELECT ON mysql_innodb_cluster_metadata.* TO 'repl'@'%'; mysql > GRANT SELECT ON performance_schema.global_status TO 'repl'@'%'; mysql > GRANT SELECT ON performance_schema.replication_applier_configuration TO 'repl'@'%'; mysql > GRANT SELECT ON performance_schema.replication_applier_status TO 'repl'@'%'; mysql > GRANT SELECT ON performance_schema.replication_applier_status_by_coordinator TO 'repl'@'%'; mysql > GRANT SELECT ON performance_schema.replication_applier_status_by_worker TO 'repl'@'%'; mysql > GRANT SELECT ON performance_schema.replication_connection_configuration TO 'repl'@'%'; mysql > GRANT SELECT ON performance_schema.replication_connection_status TO 'repl'@'%'; mysql > GRANT SELECT ON performance_schema.replication_group_member_stats TO 'repl'@'%'; mysql > GRANT SELECT ON performance_schema.replication_group_members TO 'repl'@'%'; mysql > GRANT SELECT ON performance_schema.threads TO 'repl'@'%' WITH GRANT OPTION; mysql > FLUSH PRIVILEGES;
Group Replicationの設定
後はGroup ReplicationをStartして、Nodeを追加していくだけです。
1台目(Primary Node)
mysqlshでGroup Replicationの設定をしていきましょう。
[node1] $ mysqlsh --log-level=DEBUG3 --uri repl@node1:3306 MySQL node1:3306 JS > var cluster = dba.createCluster('myCluster') A new InnoDB cluster will be created on instance 'repl@node1:3306'. Validating instance at node1:3306... This instance reports its own address as node1 Instance configuration is suitable. Creating InnoDB cluster 'prodCluster' on 'repl@node1:3306'... Adding Seed Instance... WARNING: On instance 'node1:3306' membership change cannot be persisted since MySQL version 5.7.23 does not support the SET PERSIST command (MySQL version >= 8.0.11 required). Please use the <Dba>.configureLocalInstance() command locally to persist the changes. 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 node1:3306 JS > dba.configureLocalInstance()
ここまでで、Group Replicationのclusterを作成し、Primary NodeとなるNode1を登録、設定の永続化ができました。
続いて、2台目と3台目(ともにSecondary Node)を追加していきます。
とここでエラーが。
[node1] $ mysqlsh --log-level=DEBUG3 --uri repl@node1:3306 MySQL node1:3306 JS > cluster = dba.getCluster() MySQL node1:3306 JS > cluster.addInstance('repl@node2: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. Adding instance to the cluster ... Validating instance at node2:3306... This instance reports its own address as node2 Instance configuration is suitable. Cluster.addInstance: WARNING: Not running locally on the server and can not access its error log. ERROR: Group Replication join failed. ERROR: Error joining instance to cluster: 'node2:3306' - Query failed. MySQL Error (3092): ClassicSession.query: The server is not configured properly to be an active member of the group. Please see more details on error log.. Query: START group_replication: MySQL Error (3092): ClassicSession.query: The server is not configured properly to be an active member of the group. Please see more details on error log. (RuntimeError)
node2のmysqlにloginしてreplication状況を確認してみましょう。
START GROUP REPLICATION;
していないとここではなんのレコードも出てきません。レコードがあるということはGroup Replicationの設定はできているはずです。
mysql> SELECT * FROM performance_schema.replication_group_members; +---------------------------+--------------------------------------+------------+-------------+--------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST| MEMBER_PORT | MEMBER_STATE | +---------------------------+--------------------------------------+------------+-------------+--------------+ | group_replication_applier | 34ce3aed-a249-11e9-b3e8-fa163e4531c6 | node2 | 3306 | OFFLINE | +---------------------------+--------------------------------------+------------+-------------+--------------+
次にnode2でjournalctl -xe
でエラーログを見てみましょう。
[node2] $ sudo journalctl -xe ... ... [ERROR] Plugin group_replication reported: 'This member has more executed transactions than those present in the group. Local transactions: 34ce3aed-a249-11e9-b3e8-fa163e4531c6:1-105 > Group transactions: 440dd2c5-a22b-11e9-b851-fa163e47fb1b:1-26, ... [ERROR] Plugin group_replication reported: 'The member contains transactions not present in the group. The member will now exit the group.' ...
なんかtrancastionがあるらしいですね。
ここでnode2でおもむろにRESET MASTER;
してみましょう。
[node2] $ sudo mysql -u root mysql > RESET MASTER;
そして、node1でもう一度node2をaddしてみます。
[node1] $ mysqlsh --log-level=DEBUG3 --uri repl@node1:3306 MySQL node1:3306 JS > var cluster = dba.getCluster(); MySQL node1:3306 JS > cluster.addInstance('repl@node2: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. Adding instance to the cluster ... Validating instance at node2:3306... This instance reports its own address as node2 Instance configuration is suitable. WARNING: On instance 'node2:3306' membership change cannot be persisted since MySQL version 5.7.23 does not support the SET PERSIST command (MySQL version >= 8.0.11 required). Please use the <Dba>.configureLocalInstance() command locally to persist the changes. WARNING: On instance 'node2:3306' membership change cannot be persisted since MySQL version 5.7.23 does not support the SET PERSIST command (MySQL version >= 8.0.11 required). Please use the <Dba>.configureLocalInstance() command locally to persist the changes. The instance 'repl@node2:3306' was successfully added to the cluster.
追加できたっぽいですね。念の為確認しましょう。
追加できているようです。
MySQL node1:3306 JS > cluster.status() { "clusterName": "myCluster", "defaultReplicaSet": { "name": "default", "primary": "node1:3306", "ssl": "DISABLED", "status": "OK_NO_TOLERANCE", "statusText": "Cluster is NOT tolerant to any failures.", "topology": { "node1:3306": { "address": "node1:3306", "mode": "R/W", "readReplicas": {}, "role": "HA", "status": "ONLINE" }, "node2:3306": { "address": "node2:3306", "mode": "R/O", "readReplicas": {}, "role": "HA", "status": "ONLINE" } }, "topologyMode": "Single-Primary" }, "groupInformationSourceMember": "node1:3306" }
このままだとnode2の設定の永続化ができていないのでやっていきます。
[node2] $ mysqlsh --log-level=DEBUG3 --uri repl@node2:3306 MySQL node2:3306 JS > dba.configureLocalInstance() The instance 'node2:3306' belongs to an InnoDB cluster. Detecting the configuration file... Found configuration file at standard location: /etc/my.cnf Do you want to modify this file? [y/N]: y Persisting the cluster settings... The instance 'node2:3306' was configured for use in an InnoDB cluster. The instance cluster settings were successfully persisted.
同様にnode3も設定していきましょう。同じようなエラーに遭遇しても慌てずにいきましょう。
[node1] $ mysqlsh --log-level=DEBUG3 --uri repl@node1:3306 MySQL node1:3306 JS > cluster = dba.getCluster() MySQL node1:3306 JS > cluster.addInstance('repl@node3:3306'); [node3] $ sudo mysql -u root mysql > RESET MASTER; [node1] $ mysqlsh --log-level=DEBUG3 --uri repl@node1:3306 MySQL node1:3306 JS > cluster = dba.getCluster(); MySQL node1:3306 JS > cluster.addInstance('repl@node3:3306'); [node3] $ mysqlsh --log-level=DEBUG3 --uri repl@node3:3306 MySQL node3:3306 JS > dba.configureLocalInstance() The instance 'node3:3306' belongs to an InnoDB cluster. Detecting the configuration file... Found configuration file at standard location: /etc/my.cnf Do you want to modify this file? [y/N]: y Persisting the cluster settings... The instance 'node3:3306' was configured for use in an InnoDB cluster. The instance cluster settings were successfully persisted. [node1] $ mysqlsh --log-level=DEBUG3 --uri repl@node1:3306 MySQL node1:3306 JS > cluster = dba.getCluster() MySQL node1:3306 JS > cluster.status() { "clusterName": "myCluster", "defaultReplicaSet": { "name": "default", "primary": "node1:3306", "ssl": "DISABLED", "status": "OK_NO_TOLERANCE", "statusText": "Cluster is NOT tolerant to any failures.", "topology": { "node1:3306": { "address": "node1:3306", "mode": "R/W", "readReplicas": {}, "role": "HA", "status": "ONLINE" }, "node2:3306": { "address": "node2:3306", "mode": "R/O", "readReplicas": {}, "role": "HA", "status": "ONLINE" }, "node3:3306": { "address": "node3:3306", "mode": "R/O", "readReplicas": {}, "role": "HA", "status": "ONLINE" } }, "topologyMode": "Single-Primary" }, "groupInformationSourceMember": "node1:3306" }
無事3台でGroup Replicationが構築できました。
次回は、Primary Nodeを止めてちゃんと切り替わるのか?、Primaryが死んだときやSecondaryが死んだときはどう復旧すればいいのかを確認していきます。