MySQL 8.0.13 で MySQL InnoDB Cluster を構築する
MySQL InnoDB Cluster はアプリケーションからのルーティングも含めたフルスタックなHAソリューションです。
こちらの記事でも構築方法をご紹介しましたが、MySQL Shellもバージョンアップされてmy.cnfの自動設定や対話形式によるセットアップなど以前よりも簡単に構築できるようになりました。
今回の記事では、MySQL8.0.4 Release Candidate版を使ったセットアップ方法を紹介します。
MySQL InnoDB Cluster とは?
MySQL InnoDB Cluster は下記のコンポーネントをまとめた名称で、それ自体が1つの製品ではありません。
- MySQL Group Replication (MySQLデータベースサーバー)
- MySQL Router (接続ルーティング)
- MySQL Shell (mysqlコマンド拡張)
環境設定
- Python
Python 2.7 が必要です。MySQL Shell では下記のコマンドでPythonが実行されるので、複数のバージョンがインストールされているような環境では2.7が実行されるように変更してください。
1 |
$ /usr/bin/env python |
- 名前解決
MySQL Group Replicationで各MySQLサーバー間はホスト名を使って接続するため、名前解決できるようにhostsやDNSの設定が必要です。
参考:InnoDB Cluster Requirements
構成
AWSのEC2上に構築しました。
マシン | IP | host | 詳細 |
---|---|---|---|
クライアント | 172.26.45.168 | client | MySQL Router |
node1 | 172.26.45.54 | node1 | MySQL Server |
node2 | 172.26.45.225 | node2 | MySQL Server |
node3 | 172.26.45.84 | node3 | MySQL Server |
全てのノードでMySQL Shellもインストールします
Group Replication のセットアップ
このセクションの内容は Group Replication をインストールするすべてのマシンで実行します。
パッケージのインストール
SELinux を無効にします
1 2 |
$ sudo setenforce 0 $ sudo sed -i -e 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config |
レポジトリを追加します
1 |
$ sudo yum install -y https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm |
インストールするMySQLを8.0にします
1 2 |
$ sudo yum-config-manager --disable mysql57-community $ sudo yum-config-manager --enable mysql80-community |
MySQL Server と MySQL Shellをインストールします
1 |
$ sudo yum install -y mysql-community-server mysql-shell |
MySQL Shell は my.cnf の自動設定で必要になります
MySQLのrootユーザー設定
MySQL 8.0.4以前のクライアントライブラリを使用した接続を行う場合、MySQL 8.0.4以降のデフォルトの認証方式が解釈できないため、 以前の認証方式をデフォルトとする設定を行います。
1 |
echo "default_authentication_plugin=mysql_native_password" | sudo tee -a /etc/my.cnf |
参考:日々の覚書: MySQL 8.0.4におけるデフォルト認証形式の変更
MySQL Server を起動します
1 |
$ sudo systemctl start mysqld |
rootの一時パスワードを変更します
1 2 3 |
$ mysql -u root -p`grep 'temporary password' /var/log/mysqld.log | awk -e '{print $12}'` mysql> ALTER USER root@localhost IDENTIFIED WITH mysql_native_password BY 'Password1!'; |
Group Replication の各インスタンスの設定
ユニークな server_id になるように my.cnf に追記します
1 |
$ echo "server_id = <サーバーID>" | sudo tee -a /etc/my.cnf |
mysqlsh をroot権限で実行します。( /etc/my.cnf の書き換えを行うため)
1 |
$ sudo mysqlsh |
InnoDB Cluster の設定チェック
1 2 |
mysql-js> dba.checkInstanceConfiguration('root@localhost:3306') Please provide the password for 'root@localhost: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 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
Validating instance... The instance 'localhost:3306' is not valid for Cluster usage. The following issues were encountered: - Some configuration options need to be fixed. +----------------------------------+---------------+----------------+--------------------------------------------------+ | Variable | Current Value | Required Value | Note | +----------------------------------+---------------+----------------+--------------------------------------------------+ | binlog_checksum | CRC32 | NONE | Update the server variable or restart the server | | enforce_gtid_consistency | OFF | ON | Restart the server | | gtid_mode | OFF | ON | Restart the server | | log_bin | 0 | 1 | Restart the server | | log_slave_updates | 0 | ON | Restart the server | | master_info_repository | FILE | TABLE | Restart the server | | relay_log_info_repository | FILE | TABLE | Restart the server | | transaction_write_set_extraction | OFF | XXHASH64 | Restart the server | +----------------------------------+---------------+----------------+--------------------------------------------------+ Please fix these issues, restart the server and try again. { "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": "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" } |
以前はこの結果を元にmy.cnfの設定を行う必要がありましたが、MySQL Shellを使うと自動で設定してくれるようになりました。
Group Replication が動くように対話形式で設定を変更します。
1 2 |
mysql-js> dba.configureLocalInstance() Please provide the password for 'root@localhost:3306': # パスワードを入力 |
/etc/my.cnf を変更するかの確認(ここでは y を入力)
1 2 3 |
Detecting the configuration file... Found configuration file at standard location: /etc/my.cnf Do you want to modify this file? [Y|n]: [Y|n]: |
root ユーザーが他のホストからアクセスできない設定になっているため、
1) root ユーザーを他のホストからアクセスできるようにする
2) 別のユーザーを作成する
3) ユーザーを作らない
ここでは 2 を選択します
1 2 3 4 5 6 7 |
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]: |
以下の設定で作成します
1 2 |
Account Name: icroot Password: Password1! |
設定が終了したので MySQL Shell を抜けます
1 2 |
mysql-js> \q Bye! |
設定された /etc/my.cnf は以下のように追記されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$ cat /etc/my.cnf ...(省略)... log_slave_updates = ON 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 |
MySQL Server を再起動します
1 |
$ sudo systemctl restart mysqld |
Group Replication のクラスターを組む
MySQL Shell を使ってGroup Replicationのクラスタを組みます。
このセクションは MySQL Shell がインストールされている環境であればどこからでも構いません。
クラスタを作成する
1 2 3 |
$ mysqlsh mysql-js> shell.connect('icroot@172.26.45.54') mysql-js> cluster = dba.createCluster('mycluster') |
クラスタにノードを追加する
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 |
mysql-js> cluster.addInstance('icroot@172.26.45.225') mysql-js> cluster.addInstance('icroot@172.26.45.84') mysql-js> cluster.status() { "clusterName": "mycluster", "defaultReplicaSet": { "name": "default", "primary": "172.26.45.54:3306", "status": "OK", "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.", "topology": { "172.26.45.225:3306": { "address": "172.26.45.225:3306", "mode": "R/O", "readReplicas": {}, "role": "HA", "status": "ONLINE" }, "172.26.45.54:3306": { "address": "172.26.45.54:3306", "mode": "R/W", "readReplicas": {}, "role": "HA", "status": "ONLINE" }, "172.26.45.84:3306": { "address": "172.26.45.84:3306", "mode": "R/O", "readReplicas": {}, "role": "HA", "status": "ONLINE" } } } } |
Group Replication の初期設定では 更新処理はプライマリノードと呼ばれるノードにのみ許可され、その他のノードは読み込み処理のみになります(read_only=ONの状態)
参考:Production Deployment of InnoDB Cluster
MySQL Router のセットアップ
MySQL Router をインストールしたいインスタンスで実行します。
パッケージのインストール
レポジトリを追加します
1 |
$ sudo yum install -y https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm |
インストールするMySQLを8.0にします
1 2 |
$ sudo yum-config-manager --disable mysql57-community $ sudo yum-config-manager --enable mysql80-community |
MySQL Router をインストールします
1 |
$ sudo yum install -y mysql-router |
MySQL Router の初期設定
MySQL Router は Group Replication のステータスを元にルーティング先を決めています。
bootstrap パラメーターで指定するノードはプライマリノードになります
1 |
$ sudo mysqlrouter --bootstrap icroot@172.26.45.54:3306 --user=mysqlrouter |
接続設定が表示されます。
1 2 3 4 5 6 7 8 9 10 11 12 |
Bootstrapping system MySQL Router instance... MySQL Router has now been configured for the InnoDB cluster 'mycluster'. The following connection information can be used to connect to the cluster. 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 ポートを使用することになります。
Group Replicationでは更新処理はプライマリノードのみのため、6446ポートの接続はプライマリノードにルーティングされ、6447ポートは読み込み処理のためラウンドロビンで残りのノードにルーティングされます。
MySQL Router の起動
MySQL Router を起動します。
1 |
$ sudo systemctl start mysqlrouter |
動作確認
MySQL Router 経由でアクセスしてみます
1 2 3 4 5 6 7 8 9 10 11 |
$ mysqlsh --uri icroot@127.0.0.1:6446 --sql mysql-sql> show databases; +-------------------------------+ | Database | +-------------------------------+ | information_schema | | mysql | | mysql_innodb_cluster_metadata | | performance_schema | +-------------------------------+ 4 rows in set (0.00 sec) |
別ユーザーを作成してRead Onlyポート(6447)から接続して更新クエリーを流した場合、read_only=ON となっていたのでエラーとなります。
1 2 3 |
$ mysqlsh --uri sbtest@127.0.0.1:6447 --sql mysql-sql> CREATE DATABASE sbtest; ERROR: 1290 (HY000): The MySQL server is running with the --super-read-only option so it cannot execute this statement |
また更新はプライマリノード固定、参照についてはラウンドロビンで分散されます。
1 2 3 4 5 6 7 8 9 10 11 12 |
$ mysqlsh --uri sbtest@127.0.0.1:6447 --sql -e "select @@hostname" +--------------+ | @@hostname | +--------------+ | node2 | +--------------+ $ mysqlsh --uri sbtest@127.0.0.1:6447 --sql -e "select @@hostname" +--------------+ | @@hostname | +--------------+ | node3 | +--------------+ |
参考: Using MySQL Router with InnoDB Cluster
まとめ
これまではアプリケーションのルーティングも含めた高可用性構成はサードパーティのツールを組み合わせて構築することが多かったのですが、MySQL Shell もバージョンアップが進み、my.cnf の自動書き換えや対話型セットアップによってMySQL InnoDB Clusterの構築が以前よりも簡単になりました。