概要
前回 MySQL8.4.5 で InnoDBCluster を構築し FailOver 可能な MySQL 環境を構築してみました
今回は FailOver 後に PRIMARY が変わってしまうのに自動で対応するために MySQL Router を導入しバランシングしてみました
なお MySQL Router は Arm 環境には対応していないので注意しましょう
環境
- macOS 15.5
M1 mac 上の docker では動きません
環境
- Ubuntu 24.04
- docker 28.2.2
- MySQL 8.4.5
compose.yaml
過去のやつに mysqlrouter のサービスを追加しています
次回起動時に bootstrap の設定を使うようにボリュームを使っています
services:
mysqlrouter:
image: container-registry.oracle.com/mysql/community-router:8.4
depends_on:
- mysql1
- mysql2
- mysql3
environment:
- MYSQL_HOST=mysql1
- MYSQL_PORT=3306
- MYSQL_USER=root
- MYSQL_PASSWORD=rootpass
- MYSQL_INNODB_CLUSTER_MEMBERS=3
- MYSQL_ROUTER_BOOTSTRAP_EXTRA_OPTIONS=--conf-use-sockets --conf-use-gr-notifications
ports:
- "6446:6446" # Read-write port (Primary)
- "6447:6447" # Read-only port (all members)
networks:
- mysqlnet
restart: always
mysql1:
image: mysql:8.4.5
environment:
- MYSQL_ROOT_PASSWORD=rootpass
ports:
- "33061:3306"
command: >
--mysql-native-password=ON
--server-id=1
--gtid-mode=ON
--enforce-gtid-consistency=ON
--binlog-format=ROW
--log-bin=mysql-bin
--relay-log=relay-bin
--log-replica-updates=ON
--read-only=OFF
volumes:
- mysql1_data:/var/lib/mysql
restart: always
networks:
- mysqlnet
mysql2:
image: mysql:8.4.5
environment:
- MYSQL_ROOT_PASSWORD=rootpass
ports:
- "33062:3306"
command: >
--mysql-native-password=ON
--server-id=2
--gtid-mode=ON
--enforce-gtid-consistency=ON
--binlog-format=ROW
--log-bin=mysql-bin
--relay-log=relay-bin
--log-replica-updates=ON
--read-only=OFF
volumes:
- mysql2_data:/var/lib/mysql
restart: always
networks:
- mysqlnet
mysql3:
image: mysql:8.4.5
environment:
- MYSQL_ROOT_PASSWORD=rootpass
ports:
- "33063:3306"
command: >
--mysql-native-password=ON
--server-id=3
--gtid-mode=ON
--enforce-gtid-consistency=ON
--binlog-format=ROW
--log-bin=mysql-bin
--relay-log=relay-bin
--log-replica-updates=ON
--read-only=OFF
volumes:
- mysql3_data:/var/lib/mysql
restart: always
networks:
- mysqlnet
mysqlshell:
image: mysql:8.4.5
depends_on:
- mysql1
- mysql2
- mysql3
networks:
- mysqlnet
volumes:
- ./scripts:/scripts
command: >
bash -c "
echo 'Waiting for MySQL to be ready...' &&
sleep 15 &&
mysqlsh --host=mysql1 --port=3306 --user=root --password=rootpass --py < /scripts/setup_cluster.py
"
networks:
mysqlnet:
volumes:
mysql1_data:
mysql2_data:
mysql3_data:
MYSQL_ROUTER_BOOTSTRAP_EXTRA_OPTIONS の --conf-use-sockets は最後に s が付くのが正しいようです (参考)
--conf-use-gr-notifications も同様に s が付くのが正しいです
動作確認
まずは起動します
-
docker compose up -d
そして router に対して mysql コマンドが使えるか確認します
書き込みができるポートと読み込みのみのポートがあるのでそれぞれで挙動を確認しましょう
今回であれば 6446 が書き込み可能なポートで 6447 が読み込み専用ポートです
-
mysql -u root -h 192.168.1.100 --port 6446 -p
ちなみに InnoDBCluster では PRIMARY_KEY がないテーブルに対する書き込みはエラーになるので必ず PRIMARY_KEY を各テーブルに設定するようにしましょう
mysql> create database test;
Query OK, 1 row affected (0.01 sec)
mysql> use test;
Database changed
mysql> create table test (`id` int, `name` varchar(50));
Query OK, 0 rows affected (0.02 sec)
mysql> insert into test values (1, "hoge");
ERROR 3098 (HY000): The table does not comply with the requirements by an external plugin.
mysql> drop table test;
Query OK, 0 rows affected (0.01 sec)
mysql> create table test (`id` int primary key, `name` varchar(50));
Query OK, 0 rows affected (0.02 sec)
mysql> insert into test values (1, "hoge");
Query OK, 1 row affected (0.00 sec)
読み込み専用では上記のテーブルに書き込みできないことが確認できます
-
mysql -u root -h 192.168.1.100 --port 6447 -p
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> select * from test;
+----+------+
| id | name |
+----+------+
| 1 | hoge |
+----+------+
1 row in set (0.00 sec)
mysql> insert into test values (2, "fuga");
ERROR 1290 (HY000): The MySQL server is running with the --super-read-only option so it cannot execute this statement
耐障害テスト
PRIMARY なノードを停止し他に移動した上で書き込みが継続できるか試してみます
-
docker compose stop mysql1
-
docker compose start mysql1
-
docker compose exec -it mysql1 mysqlsh --py
dba.get_cluster().status()
クラスタの状態を確認し PRIMARY なノードが移動していることを確認します
このあとで 6446 ポートに接続し問題なくデータが登録できることを確認しましょう
mysql -u root -h 10.104.37.79 --port 6446 -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 0
Server version: 8.4.5-router MySQL Community Server - GPL
Copyright (c) 2000, 2025, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> select * from test;
+----+------+
| id | name |
+----+------+
| 1 | hoge |
+----+------+
1 row in set (0.00 sec)
mysql> insert into test values (2,"fuga");
Query OK, 1 row affected (0.01 sec)
最後に
MySQL8.4.5 で InnoDB Cluster に MySQL Router を設定し自動的に PRIMARY にバランシングしてくれる仕組みを試しました
確かに便利ですが PRIMARY_KEY の制約などは注意が必要かもしれません
0 件のコメント:
コメントを投稿