以前、MySQL8.0 で MySQL InnoDB Cluster を構築する の記事で MySQL 8.0.4 RC版を使った構築方法をご紹介しましたが、あれからバージョンも進み、新機能がいくつも追加され、 MySQL InnoDB Cluster の構築方法も5.7、8.0RC版を経て以前よりも簡単に自由度も高くなりました。
今回の記事では改めて MySQL 8.0.13 を使ったセットアップ方法をご紹介したいと思います。
MySQL InnoDB Cluster とは?
MySQL InnoDB Cluster は下記のコンポーネントをまとめた名称で、それ自体が1つの製品ではありません。
コンポーネント同士が強く結びついて動作させることが前提のため、サードパーティ製品を導入する際に組み合わせにより発生するトラブルに悩まされることもなく、汎用的なツールにありがちな複雑な設定やセットアップから解放されます。
- MySQL Group Replication (MySQLデータベースサーバー)
- MySQL Router (接続ルーティング)
- MySQL Shell (mysqlコマンド拡張)
環境設定
- Python
MySQL Shell を使用するサーバーでは Python 2.7 が必要です。下記のコマンドでPythonが実行されるので、複数のバージョンがインストールされているような環境では2.7が実行されるように変更してください。
1 |
$ /usr/bin/env python |
- IPv4 ネットワーク
MySQL Group Replication で使用するグループコミュニケーションは IPv4 のみがサポートされています。
構成
AWSのEC2上に構築しました。OSは CentOS 7.5 です
マシン | IP | ホスト名 |
---|---|---|
MySQL Server (Node1) | 172.26.46.105 | node1 |
MySQL Server (Node2) | 172.26.46.234 | node2 |
MySQL Server (Node3) | 172.26.46.67 | node3 |
MySQL Router | 172.26.46.134 | mysql_router |
MySQL Shell | 172.26.46.87 | mysql_shell |
8.0 RC版では、すべてのノードに MySQL Shell のインストールが必要でしたが、今回からはMySQL Serverに接続できればどこにインストールしてもよくなりました。
共通のセットアップ
このセクションのSELinuxの無効化とMySQLの公式レポジトリの追加は、MySQL InnoDB Cluster を動かす全てのマシンで実行します。
SELinuxを無効にします
1 2 |
[all_server] $ sudo setenforce 0 [all_server] $ sudo sed -i -e 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config |
MySQLの公式レポジトリを追加します
1 |
[all_server] $ sudo yum install -y https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm |
MySQL Shell のセットアップ
MySQL Shell は yum コマンドでパッケージをインストールするだけです
1 |
[mysql_shell] $ sudo yum install -y mysql-shell |
MySQL Group Replication のセットアップ
このセクションのMySQLのインストールからrootユーザーの設定まではMySQLサーバーを動かすNode1、Node2、Node3で実行します
パッケージをインストールします
1 |
[node1,node2,node3] $ sudo yum install -y mysql-community-server |
MySQL Server を起動します
1 |
[node1,node2,node3] $ sudo systemctl start mysqld |
rootの一時パスワードを変更します
1 2 |
[node1,node2,node3] $ mysql -u root -p<code>grep 'temporary password' /var/log/mysqld.log | awk -e '{print $13}' mysql> ALTER USER root@localhost IDENTIFIED BY 'Password1!'; |
リモートアクセス可能なrootを作成します
1 2 3 4 5 |
mysql> create user 'root'@'172.26.46.%' identified by 'Password1!'; Query OK, 0 rows affected (0.08 sec) mysql> grant all on *.* to 'root'@'172.26.46.%' with grant option; Query OK, 0 rows affected (0.07 sec) |
MySQL Group Replication の各インスタンスの設定
ここからは MySQL Shell がインストールされている環境であればどこからでも構いません。
MySQL Group Replication の設定をチェックします
1 2 3 4 |
[mysql_shell] $ mysqlsh MySQL JS> dba.checkInstanceConfiguration('root@172.26.46.105') Please provide the password for 'root@172.26.46.105': # パスワードを入力 |
設定が足りないため、エラーになります
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
Some configuration options need to be fixed: +--------------------------+---------------+----------------+--------------------------------------------------+ | Variable | Current Value | Required Value | Note | +--------------------------+---------------+----------------+--------------------------------------------------+ | binlog_checksum | CRC32 | NONE | Update the server variable | | enforce_gtid_consistency | OFF | ON | Update read-only variable and restart the server | | gtid_mode | OFF | ON | Update read-only variable and restart the server | | server_id | 1 | <unique ID> | Update read-only variable and restart the server | +--------------------------+---------------+----------------+--------------------------------------------------+ Please use the dba.configureInstance() command to repair these issues. { "config_errors": [ { "action": "server_update", "current": "CRC32", "option": "binlog_checksum", "required": "NONE" }, { "action": "restart", "current": "OFF", "option": "enforce_gtid_consistency", "required": "ON" }, { "action": "restart", "current": "OFF", "option": "gtid_mode", "required": "ON" }, { "action": "restart", "current": "1", "option": "server_id", "required": "<unique ID>" } ], "errors": [], "status": "error" } |
8.0 RC版では、これらの設定を my.cnf に書き出す必要があったため、MySQL Server が動いているサーバーのローカルで MySQL Shell を sudo 実行する必要がありました。
しかし、8.0.13 からは MySQL 8.0 で新しく追加された「SET PERSIST」を使って、リモートからでも設定を永続化させることができ、また、再起動が必要な設定についても、「RESTART」コマンドを使って外部からMySQLの再起動が可能になったため、必ずしもローカルのMySQL Shellから実行する必要がなくなりました。
リモートから MySQL Group Replication に必要な設定を追加する
1 2 |
MySQL JS > dba.configureInstance('root@172.26.46.105') Please provide the password for 'root@172.26.46.105': # パスワードの入力 |
設定変更箇所の確認と
1 2 3 4 5 6 7 8 9 |
Some configuration options need to be fixed: +--------------------------+---------------+----------------+--------------------------------------------------+ | Variable | Current Value | Required Value | Note | +--------------------------+---------------+----------------+--------------------------------------------------+ | binlog_checksum | CRC32 | NONE | Update the server variable | | enforce_gtid_consistency | OFF | ON | Update read-only variable and restart the server | | gtid_mode | OFF | ON | Update read-only variable and restart the server | | server_id | 1 | <unique ID> | Update read-only variable and restart the server | +--------------------------+---------------+----------------+--------------------------------------------------+ |
これらの設定を変更するかの確認。「y」を選択します。
1 |
Do you want to perform the required configuration changes? [y/n]: y |
MySQLサーバーの再起動をするかの確認。「y」を選択します。
1 |
Do you want to restart the instance after configuring it? [y/n]: y |
同様の設定変更を他の2ノードでも行います
1 2 |
MySQL JS> dba.configureInstance('root@172.26.46.234') MySQL JS> dba.configureInstance('root@172.26.46.67') |
MySQL Group Replication のクラスターを組む
このセクションも同様に、MySQL Shell がインストールしている環境であれば、どこからでも構いません。
クラスタを作成します
1 2 3 4 5 6 7 8 |
[mysql_shell] $ mysqlsh MySQL JS> c root@172.26.46.105 Creating a session to 'root@172.26.46.105' Please provide the password for 'root@172.26.46.105': # パスワードを入力 MySQL JS> cluster = dba.createCluster('mycluster') A new InnoDB cluster will be created on instance 'root@172.26.46.105:3306'. |
クラスターにノードを追加
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
MySQL JS> cluster.addInstance('root@172.26.46.234') MySQL JS> cluster.addInstance('root@172.26.46.67') MySQL JS> cluster.status() { "clusterName": "mycluster", "defaultReplicaSet": { "name": "default", "primary": "172.26.46.105:3306", "ssl": "REQUIRED", "status": "OK", "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.", "topology": { "172.26.46.105:3306": { "address": "172.26.46.105:3306", "mode": "R/W", "readReplicas": {}, "role": "HA", "status": "ONLINE" }, "172.26.46.234:3306": { "address": "172.26.46.234:3306", "mode": "R/O", "readReplicas": {}, "role": "HA", "status": "ONLINE" }, "172.26.46.67:3306": { "address": "172.26.46.67:3306", "mode": "R/O", "readReplicas": {}, "role": "HA", "status": "ONLINE" } } }, "groupInformationSourceMember": "mysql://root@172.26.46.105:3306" } |
MySQL Group Replication の初期設定では 更新処理はプライマリノードと呼ばれるノードにのみ許可され、その他のノードは読み込み処理のみになります(read_only=ONの状態)
クラスターを構築後、MySQLのユーザーを見ると mysql_innodbcluster%
というユーザーが自動で作成されています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
mysql> select user, host from mysql.user; +----------------------------------+--------------+ | user | host | +----------------------------------+--------------+ | mysql_innodb_cluster_r0429842674 | % | | mysql_innodb_cluster_r0429850502 | % | | mysql_innodb_cluster_r0429853749 | % | | root | 172.26.46.% | | mysql.infoschema | localhost | | mysql.session | localhost | | mysql.sys | localhost | | mysql_innodb_cluster_r0429842674 | localhost | | mysql_innodb_cluster_r0429850502 | localhost | | mysql_innodb_cluster_r0429853749 | localhost | | root | localhost | +----------------------------------+--------------+ 11 rows in set (0.00 sec) |
データベースも mysql_innodb_cluster_metadata
が作成されています。
1 2 3 4 5 6 7 8 9 10 11 |
mysql> show databases; +-------------------------------+ | Database | +-------------------------------+ | information_schema | | mysql | | mysql_innodb_cluster_metadata | | performance_schema | | sys | +-------------------------------+ 5 rows in set (0.00 sec) |
設定値も、my.cnf には変更がありませんが、mysqld-auto.cnf
がデータディレクトリ以下に作られて、Group Replication に必要な設定が反映されています。
1 2 |
[node1] $ sudo cat /var/lib/mysql/mysqld-auto.cnf { "Version" : 1 ...省略... , "gtid_mode" : { "Value" : "ON" , "Metadata" : { "Timestamp" : 1541387935827216 , "User" : "root" , "Host" : "ip-172-26-46-87.ap-northeast-1.compute.internal" } } } } } |
MySQL Router のセットアップ
MySQL Router のパッケージをインストールします
1 |
[mysql_router] $ sudo yum install -y mysql-router |
MySQL Router の初期設定
MySQL Router は MySQL Group Replication のステータスを元にルーティング先を決めています。
bootstrap パラメーターで指定するノードはプライマリノードになります。
MySQL Shellでcluster.status()
コマンドの実行結果に表示される"primary": "172.26.46.105:3306"
がプライマリノードです
1 |
[mysql_router] $ sudo mysqlrouter --bootstrap root@172.26.46.105 --user=mysqlrouter |
接続情報が表示されます。
1 2 3 4 5 6 7 8 |
The following connection information can be used to connect to the cluster after MySQL Router has been started with generated configuration.. Classic MySQL protocol connections to cluster 'mycluster': - Read/Write Connections: localhost:6446 - Read/Only Connections: localhost:6447 X protocol connections to cluster 'mycluster': - Read/Write Connections: localhost:64460 - Read/Only Connections: localhost:64470 |
通常のSQLによる読み込みと書き込みは 6446 ポートを使用、読み込みのみは 6447 ポートを使用することになります。
MySQL Group Replicationでは更新処理はプライマリノードのみのため、6446ポートの接続はプライマリノードにルーティングされ、6447ポートは読み込み処理のためラウンドロビンで残りのノードにルーティングされます。
まとめ
MySQL 8.0.13 の MySQL InnoDB Cluster の構築では、MySQL 8.0 の新機能を使うことで、MySQLさえ起動していれば、Group Replication を構築するためにSSHでログインする必要がなくなりました。この仕組みを使えば、Dockerなどを使ってコンテナ化するのも容易になるため、コンテナ型仮想化が進むインフラにおいても使い勝手のよいデータベースとなると考えられます。
MySQL InnoDB Clusterの構築に不安を感じていませんか?
高可用性やフェイルオーバーの設定に不安がある方、構築にかかる時間やリソースが心配な方へ。スマートスタイルのMySQL専門エンジニアが、あなたのシステム環境に最適なInnoDB Cluster構築を全面サポートします。ご検討中の方は下記リンクよりお問い合わせください。