MySQL 8.0.13 で MySQL InnoDB Cluster を構築する | スマートスタイル TECH BLOG|データベース&クラウドの最新技術情報を配信
の写経
所感
- 従来のようなレプリケーション設定ではファイル変更必須だったが、コマンド実行だけで構築簡単
- nodeがダウンすると良い感じにプライマリが切り替わる
- 復帰すると良い感じにセカンダリへ
- 如何せんまだまだWebにノウハウが多いとは言えない
- routerがいればnodeがダウンしても自動的に接続先を切り替えてくれるが、router自体の冗長化はどうするのかとなるが、各アプリケーション・サーバーにrouterを入れるのが正解?
構成
- docker-composeでOSはAlmaLinux8。(あえて公式mysqlコンテナを使わず)
- mysqlのバージョンはmysql-server-8.0.21(現在最新)
マシン | IP | ホスト名 |
---|---|---|
MySQL Shell | 172.30.0.2 | shell |
MySQL Router | 172.30.0.3 | router |
MySQL Server (node1) | 172.30.0.11 | node1 |
MySQL Server (node2) | 172.30.0.12 | node2 |
docker-composeファイル
# vim: set ts=2 et:
version: '3.5'
services:
shell:
image: almalinux/almalinux:8
hostname: shell
privileged: true
command: /sbin/init
networks:
app_net:
ipv4_address: 172.30.0.2
router:
image: almalinux/almalinux:8
hostname: router
privileged: true
command: /sbin/init
networks:
app_net:
ipv4_address: 172.30.0.3
node1:
image: almalinux/almalinux:8
hostname: node1
privileged: true
command: /sbin/init
networks:
app_net:
ipv4_address: 172.30.0.11
node2:
image: almalinux/almalinux:8
hostname: node2
privileged: true
command: /sbin/init
networks:
app_net:
ipv4_address: 172.30.0.12
networks:
app_net:
name: app_net
driver: bridge
ipam:
driver: default
config:
- subnet: 172.30.0.0/24
※ポート3306を公開していないのでアクセスできないのはとりあえず気にしない
各サーバーへのログインは
docker-compose exec node1 /bin/bash
構築
// node1~2で実行
# dnf install -y https://dev.mysql.com/get/mysql80-community-release-el8-1.noarch.rpm
# dnf install -y mysql-server
# systemctl start mysqld
# mysql
mysql> create user 'root'@'172.30.0.%' identified by 'Password1!';
mysql> grant all on *.* to 'root'@'172.30.0.%' with grant option;
// shellで実行
# dnf install -y https://dev.mysql.com/get/mysql80-community-release-el8-1.noarch.rpm
# dnf install -y mysql-shell
// MySQL Group Replication の各インスタンスの設定
# mysqlsh
MySQL JS> dba.configureInstance('root@node1')
Do you want to perform the required configuration changes? [y/n]: y
Do you want to restart the instance after configuring it? [y/n]: y
MySQL JS> dba.configureInstance('root@node2')
Do you want to perform the required configuration changes? [y/n]: y
Do you want to restart the instance after configuring it? [y/n]: y
MySQL JS> dba.checkInstanceConfiguration('root@node1')
MySQL JS> dba.checkInstanceConfiguration('root@node2')
// MySQL Group Replication のクラスターを組む
MySQL JS> \c root@node1
MySQL JS> cluster = dba.createCluster('mycluster')
MySQL JS> cluster.addInstance('root@node2')
MySQL JS> cluster.status()
// 二回目接続時
# mysqlsh
MySQL JS> \c root@node1
MySQL JS> cluster = dba.getCluster()
MySQL JS> cluster.status()
// routerで実行
# dnf install -y https://dev.mysql.com/get/mysql80-community-release-el8-1.noarch.rpm
# dnf install -y mysql-router-community
# mysqlrouter --bootstrap root@node1 --user=mysqlrouter
## MySQL Classic protocol
- Read/Write Connections: localhost:6446
- Read/Only Connections: localhost:6447
## MySQL X protocol
- Read/Write Connections: localhost:6448
- Read/Only Connections: localhost:6449
# systemctl start mysqlrouter
// (mysqlコマンドが入っていればどこからでもよいので)routerに接続
# mysql -u root -p -h router -P 6446 --prompt="mysql-\p> "
mysql-6446>
確認
// mode1で実行
# mysql
mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| group_replication_applier | 607e2f00-ab3e-11eb-9608-0242ac1e000b | node1 | 3306 | ONLINE | PRIMARY | 8.0.21 |
| group_replication_applier | 6167af21-ab3e-11eb-853a-0242ac1e000c | node2 | 3306 | ONLINE | SECONDARY | 8.0.21 |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
2 rows in set (0.00 sec)
// shellで実行
# mysqlsh
MySQL JS> \c root@node1
MySQL JS> cluster = dba.getCluster()
MySQL JS> cluster.status()
{
"clusterName": "mycluster",
"defaultReplicaSet": {
"name": "default",
"primary": "node1:3306",
"ssl": "REQUIRED",
"status": "OK_NO_TOLERANCE",
"statusText": "Cluster is NOT tolerant to any failures.",
"topology": {
"node1:3306": {
"address": "node1:3306",
"memberRole": "PRIMARY",
"mode": "R/W",
"readReplicas": {},
"replicationLag": null,
"role": "HA",
"status": "ONLINE",
"version": "8.0.21"
},
"node2:3306": {
"address": "node2:3306",
"memberRole": "SECONDARY",
"mode": "R/O",
"readReplicas": {},
"replicationLag": null,
"role": "HA",
"status": "ONLINE",
"version": "8.0.21"
}
},
"topologyMode": "Single-Primary"
},
"groupInformationSourceMember": "node1:3306"
}
MySQL JS> cluster.listRouters()
{
"clusterName": "mycluster",
"routers": {
"router::system": {
"hostname": "router",
"lastCheckIn": null,
"roPort": 6447,
"roXPort": 6449,
"rwPort": 6446,
"rwXPort": 6448,
"version": "8.0.24"
}
}
}
CentOSにMySQLのインストール/アンインストール - Qiita
MySQL 8.0.13 で MySQL InnoDB Cluster を構築する | スマートスタイル TECH BLOG|データベース&クラウドの最新技術情報を配信
docker-composeで作成されるものの名前を明示的に指定する方法 - Qiita
docker-composeでコンテナの内部IPアドレスを固定化してWebサイトを作る - sagantaf
MySQL InnoDB Cluster を使って運用を手抜きしよう - Speaker Deck
MySQL Routerの冗長化について - 2000秒後の私へ
オンラインで MySQL InnoDB Cluster の構成を変更する | スマートスタイル TECH BLOG|データベース&クラウドの最新技術情報を配信