1、InnoDB Cluster 集群介绍
InnoDB Cluster集群是MySQL官方推出的高可用方案。一个InnoDB Cluster至少由三个MySQL Server实例组成,它提供了高可用性和可扩展性。通过使用MySQL Shell包含的AdminAPI,你可以很容易地配置和管理一组至少三个MySQL服务器实例,作为一个InnoDB集群。
InnoDB集群中的每个MySQL服务器实例都运行MySQL组复制,它提供了在InnoDB集群内复制数据的机制,并具有内置的故障转移。AdminAPI消除了在InnoDB集群中直接使用组复制的需要,但要了解更多信息,请参阅组复制,其中解释了详细信息。从MySQL 8.0.27开始,你也可以设置InnoDB ClusterSet,通过连接一个主InnoDB集群和一个或多个自己在其他位置的副本,比如不同的数据中心,为InnoDB集群部署提供容灾能力。
MySQL Router 可以根据你部署的集群自动配置自己,透明地将客户端应用程序连接到服务器实例。如果服务器实例发生意外故障,集群将自动重新配置。在默认的单主模式下,一个InnoDB集群只有一个可读写的服务器实例——主实例。多个辅助服务器实例是主服务器实例的副本。如果主服务器出现故障,备用服务器将自动升级为主服务器。MySQL Router 检测到这一点,并将客户端应用程序转发到新的主服务器。高级用户还可以将集群配置为具有多个主节点。
MySQL Router 软件通常与业务应用部署在一起,业务应用通过MySQL Router对底层MySQL MGR 数据库进行数据请求操作。MySQL Router可动态感知底层MySQL MGR 集群各节点的健康状态并根据这些信息对业务请求进行路由转发,通过不同的端口实现读写分离功能。
InnoDB集群使用了下面的MySQL技术:
1、MySQL Shell,这是MySQL的高级客户端和代码编辑器。
2、MySQL服务器和组复制,这使得一组MySQL实例提供高可用性。InnoDB集群提供了另一种易于使用的编程方式来处理组复制。
3、MySQL Router,一个轻量级中间件,在你的应用程序和InnoDB集群之间提供透明路由。
2、官方 InnoDB Cluster 架构图
3、环境信息
主机名 | ip地址 | OS版本 | 内存、CPU | 安装软件 | 端口 |
---|---|---|---|---|---|
node1 | 192.168.100.10 | Centos7.9 | 4G 、 1个双核 | MySQL Server 8.0.36 MySQL Shell 8.0.36 MySQL Router 8.0.36 |
3306 / 6446(写)6447(读) |
node2 | 192.168.100.11 | Centos7.9 | 4G 、 1个双核 | MySQL Server 8.0.36 MySQL Shell 8.0.36 MySQL Router 8.0.36 |
3306 / 6446(写)6447(读) |
node3 | 192.168.100.12 | Centos7.9 | 4G 、 1个双核 | MySQL Server 8.0.36 MySQL Shell 8.0.36 MySQL Router 8.0.36 |
3306 / 6446(写)6447(读) |
4、InnoDB Cluster 安装过程
4.1下载软件
MySQL Shell 8.0.36
下载地址:https://downloads.mysql.com/archives/shell/
软件名称:mysql-shell-8.0.36-linux-glibc2.17-x86-64bit.tar.gz
MySQL Router 8.0.36
下载地址:https://downloads.mysql.com/archives/router/
软件名称:mysql-router-8.0.36-linux-glibc2.17-x86_64.tar.xz
MySQL Server 8.0.36
下载地址:https://downloads.mysql.com/archives/router/
软件名称:mysql-8.0.36-linux-glibc2.17-x86_64.tar.xz
4.2配置系统
4.2.1关闭防火墙
systemctl disable firewalld.service systemctl stop firewalld.service systemctl status firewalld
复制
4.2.2关闭SELINUX
vi /etc/selinux/config 修改SELINUX=disabled 或者 sed -i 's/^SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
复制
4.2.3配置/etc/hosts
vi /etc/hosts 192.168.100.10 node1 192.168.100.11 node2 192.168.100.12 node3
复制
4.2.4配置内核
4.2.5禁用透明大页
#检查THP开启情况 cat /sys/kernel/mm/transparent_hugepage/enabled always madvise [never] ### 4.2.6关闭THP echo never > /sys/kernel/mm/transparent_hugepage/enabled ## 设置重启后自动关闭 chmod +x /etc/rc.d/rc.local systemctl enable rc-local.service cat >> /etc/rc.d/rc.local <<EOF swapoff -a if test -f /sys/kernel/mm/transparent_hugepage/enabled; then echo never > /sys/kernel/mm/transparent_hugepage/enabled fi if test -f /sys/kernel/mm/transparent_hugepage/defrag; then echo never > /sys/kernel/mm/transparent_hugepage/defrag fi EOF
复制
4.2.7配置资源限制
cat >>/etc/security/limits.conf << EOF * soft nproc 65536 * hard nproc 65536 * soft nofile 65536 * hard nofile 65536 mysql soft nproc 65536 mysql hard nproc 65536 mysql soft nofile 65536 mysql hard nofile 65536 EOF
复制
4.2.8设置内核参数
cat>>/etc/sysctl.conf <<EOF vm.swappiness = 1 EOF sysctl -p 生效
复制
4.2.9删除mariadb
# rpm -qa|grep maria mariadb-5.5.68-1.el7.x86_64 mariadb-libs-5.5.68-1.el7.x86_64 mariadb-server-5.5.68-1.el7.x86_64 # rpm -e mariadb-libs-5.5.68-1.el7.x86_64 --nodeps # rpm -e mariadb-server-5.5.68-1.el7.x86_64 --nodeps # rpm -e mariadb-5.5.68-1.el7.x86_64
复制
4.3安装MySQL Shell(三台主机)
--node1节点安装MySQL Shell [root@node1 ~]# cd /soft [root@node1 soft]# tar -zxvf mysql-shell-8.0.36-linux-glibc2.17-x86-64bit.tar.gz -C /data [root@node1 soft]# cd /data [root@node1 data]# mv mysql-shell-8.0.36-linux-glibc2.17-x86-64bit/ mysqlsh [root@node1 data]# chown -R mysql:mysql /data --node2和node3节点安装方法同node1,此处略
复制
4.4安装MySQL 实例(三台主机)
4.4.1创建用户和组
groupadd mysql useradd -g mysql mysql ``` ### 4.4.2解压MySQL软件并授权 ```language tar -xvf /soft/mysql-8.0.36-linux-glibc2.17-x86_64.tar.gz -C /data/ cd /data mv mysql-8.0.36-linux-glibc2.17-x86_64 mysql chown -R mysql:mysql /data/mysql/
复制
4.4.3配置mysql用户环境变量
vi .bashrc export PATH=$PATH:/data/mysql/bin/:/data/mysqlsh/bin/data/mysqlrouter/bin --环境变量生效 source .bashrc
复制
4.4.4创建my.cnf文件
node1:
su - mysql vi /data/my.cnf [mysqld] port=3306 basedir=/data/mysql datadir=/data/data socket=/data/data/mysql.sock pid_file=/data/data/mysql.pid server_id=10 gtid_mode=ON enforce_gtid_consistency=ON binlog_checksum=NONE log_bin=binlog log_slave_updates=ON binlog_format=ROW master_info_repository=TABLE relay_log_info_repository=TABLE character_set_server = UTF8MB4 #log settings log_timestamps = SYSTEM log_error = /data/data/error.log slow_query_log = 1 slow_query_log_file = /data/data/slow.log transaction_write_set_extraction=XXHASH64 loose-group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" "/data/my.cnf" 33L, 884C written [mysql@node1 ~]$ cat /data/my.cnf [mysqld] port=3306 basedir=/data/mysql datadir=/data/data socket=/data/data/mysql.sock pid_file=/data/data/mysql.pid server_id=10 gtid_mode=ON enforce_gtid_consistency=ON binlog_checksum=NONE log_bin=binlog log_slave_updates=ON binlog_format=ROW master_info_repository=TABLE relay_log_info_repository=TABLE character_set_server = UTF8MB4 #log settings log_timestamps = SYSTEM log_error = /data/data/error.log slow_query_log = 1 slow_query_log_file = /data/data/slow.log transaction_write_set_extraction=XXHASH64 loose-group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" loose-group_replication_start_on_boot=OFF loose-group_replication_local_address= "192.168.100.10:33061" loose-group_replication_group_seeds= "192.168.100.10:33061,192.168.100.11:33061,192.168.100.12:33061" loose-group_replication_bootstrap_group=OFF report_host=192.168.100.10 report_port=3306
复制
node2和node3只有下面3个参数不同,按实际情况修改:
node2:
server_id=11 loose-group_replication_local_address= "192.168.100.11:33061" report_host=192.168.100.11
复制
node3:
server_id=12 loose-group_replication_local_address= "192.168.100.12:33061" report_host=192.168.100.12
复制
4.4.5初始化数据库
三个节点都进行初始化
--mysql用户 node1: [mysql@node1 ~]$ /data/mysql/bin/mysqld --defaults-file=/data/my.cnf --initialize --user=mysql [mysql@node1 ~]$ grep log_error /data/my.cnf log_error = /data/data/error.log [mysql@node1 ~]$ grep temporary /data/data/error.log 2024-05-22T21:56:26.997616+08:00 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: a9ltqgfywj&R node2和node3节点操作方法同node1,此处略
复制
4.4.6启动数据库
三个节点都启动数据库
node1: [mysql@node1 ~]$ /data/mysql/bin/mysqld --defaults-file=/data/my.cnf & [1] 13085 node2和node3节点启动方法同node1,此处略 --修改root账号密码,三个节点都执行 mysql> SET SQL_LOG_BIN=0; mysql> alter user root@'localhost' identified by 'Root'; mysql> flush privileges; mysql> SET SQL_LOG_BIN=1;
复制
4.5配置MySQL SERVER
--三个节点都执行 --使用mysql shell连接到mysql实例 \c root@localhost?socket=(/data/data/mysql.sock) --配置实例 dba.configureInstance() 这一步会创建可以远程连接的账号
复制
过程如下:
4.6创建InnoDB Cluster集群
var c = dba.createCluster('mycluster');
复制
过程如下:
4.7添加InnoDB Cluster集群其他节点
c.addInstance('192.168.100.11:3306') --选择clone的恢复方式 c.addInstance('192.168.100.12:3306') --选择clone的恢复方式
复制
过程如下:
4.8查看InnoDB Cluster集群状态
c.status()
复制
过程如下:
使用mysql客户端查询mgr成员信息
mysql> select * from performance_schema.replication_group_members; +---------------------------+--------------------------------------+----------------+-------------+--------------+-------------+----------------+----------------------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION | MEMBER_COMMUNICATION_STACK | +---------------------------+--------------------------------------+----------------+-------------+--------------+-------------+----------------+----------------------------+ | group_replication_applier | 05c27710-1843-11ef-80a9-00505621b833 | 192.168.100.12 | 3306 | ONLINE | SECONDARY | 8.0.36 | MySQL | | group_replication_applier | 122d7061-1843-11ef-8ddb-005056286a23 | 192.168.100.10 | 3306 | ONLINE | PRIMARY | 8.0.36 | MySQL | | group_replication_applier | 141bfb53-1843-11ef-b4e7-005056393b43 | 192.168.100.11 | 3306 | ONLINE | SECONDARY | 8.0.36 | MySQL | +---------------------------+--------------------------------------+----------------+-------------+--------------+-------------+----------------+----------------------------+ 3 rows in set (0.00 sec)
复制
4.9配置 MySQL Router
4.9.1安装 MySQL Router
生产环境中一般是在应用服务器上安装 MySQL Router,并且做Router的高可用。这里测试,在三个节点使用mysql用户安装MySQL Router
tar -xvf /soft/mysql-router-8.0.36-linux-glibc2.17-x86_64.tar.xz -C /data/ cd /data mv mysql-router-8.0.36-linux-glibc2.17-x86_64 mysqlrouter
复制
4.9.2初始化 MySQL Router
在三个节点做初始化
cd /data/mysqlrouter/bin --初始化,地址写primary的地址 mysqlrouter --bootstrap root@192.168.100.10:3306 --directory /data/mysqlrouter/router --conf-base-port 6446 --conf-use-sockets --force 初始化后,创建了配置文件:/data/mysqlrouter/router/mysqlrouter.conf
复制
过程如下:
[mysql@node1 mysqlrouter]$ mysqlrouter --bootstrap root@192.168.100.10:3306 --directory /data/mysqlrouter/router --conf-base-port 6446 --conf-use-sockets --force Please enter MySQL password for root: # Bootstrapping MySQL Router 8.0.36 (MySQL Community - GPL) instance at '/data/mysqlrouter/router'... - Creating account(s) (only those that are needed, if any) - Verifying account (using it to run SQL queries that would be run by Router) - Storing account in keyring - Adjusting permissions of generated files - Creating configuration /data/mysqlrouter/router/mysqlrouter.conf # MySQL Router configured for the InnoDB Cluster 'mycluster' After this MySQL Router has been started with the generated configuration $ mysqlrouter -c /data/mysqlrouter/router/mysqlrouter.conf InnoDB Cluster 'mycluster' can be reached by connecting to: ## MySQL Classic protocol - Read/Write Connections: localhost:6446, /data/mysqlrouter/router/mysql.sock - Read/Only Connections: localhost:6447, /data/mysqlrouter/router/mysqlro.sock ## MySQL X protocol - Read/Write Connections: localhost:6448, /data/mysqlrouter/router/mysqlx.sock - Read/Only Connections: localhost:6449, /data/mysqlrouter/router/mysqlxro.sock [mysql@node1 mysqlrouter]$
复制
查看生成的配置文件
[mysql@node1 router]$ cat mysqlrouter.conf # File automatically generated during MySQL Router bootstrap [DEFAULT] logging_folder=/data/mysqlrouter/router/log runtime_folder=/data/mysqlrouter/router/run data_folder=/data/mysqlrouter/router/data keyring_path=/data/mysqlrouter/router/data/keyring master_key_path=/data/mysqlrouter/router/mysqlrouter.key connect_timeout=5 read_timeout=30 dynamic_state=/data/mysqlrouter/router/data/state.json client_ssl_cert=/data/mysqlrouter/router/data/router-cert.pem client_ssl_key=/data/mysqlrouter/router/data/router-key.pem client_ssl_mode=PREFERRED server_ssl_mode=AS_CLIENT server_ssl_verify=DISABLED unknown_config_option=error [logger] level=INFO [metadata_cache:bootstrap] cluster_type=gr router_id=1 user=mysql_router1_5ru2e8qxks27 metadata_cluster=mycluster ttl=0.5 auth_cache_ttl=-1 auth_cache_refresh_interval=2 use_gr_notifications=0 [routing:bootstrap_rw] bind_address=0.0.0.0 bind_port=6446 socket=/data/mysqlrouter/router/mysql.sock destinations=metadata-cache://mycluster/?role=PRIMARY routing_strategy=first-available protocol=classic [routing:bootstrap_ro] bind_address=0.0.0.0 bind_port=6447 socket=/data/mysqlrouter/router/mysqlro.sock destinations=metadata-cache://mycluster/?role=SECONDARY routing_strategy=round-robin-with-fallback protocol=classic [routing:bootstrap_x_rw] bind_address=0.0.0.0 bind_port=6448 socket=/data/mysqlrouter/router/mysqlx.sock destinations=metadata-cache://mycluster/?role=PRIMARY routing_strategy=first-available protocol=x [routing:bootstrap_x_ro] bind_address=0.0.0.0 bind_port=6449 socket=/data/mysqlrouter/router/mysqlxro.sock destinations=metadata-cache://mycluster/?role=SECONDARY routing_strategy=round-robin-with-fallback protocol=x [http_server] port=8443 ssl=1 ssl_cert=/data/mysqlrouter/router/data/router-cert.pem ssl_key=/data/mysqlrouter/router/data/router-key.pem [http_auth_realm:default_auth_realm] backend=default_auth_backend method=basic name=default_realm [rest_router] require_realm=default_auth_realm [rest_api] [http_auth_backend:default_auth_backend] backend=metadata_cache [rest_routing] require_realm=default_auth_realm [rest_metadata_cache] require_realm=default_auth_realm
复制
4.9.3启动 MySQL Router
[mysql@node1 router]$ cd /data/mysqlrouter/router [mysql@node1 router]$ ls data log mysqlro.sock mysqlrouter.conf mysqlrouter.key mysqlrouter.pid mysql.sock mysqlxro.sock mysqlx.sock run start.sh stop.sh [mysql@node1 router]$ ./start.sh [mysql@node1 router]$ PID 16035 written to '/data/mysqlrouter/router/mysqlrouter.pid' stopping to log to the console. Continuing to log to filelog node2和node3操作方法和node1相同
复制
4.9.4查看MySQL Router信息
var c=dba.getCluster() c.listRouters()
复制
过程如下:
MySQL localhost:33060+ ssl JS > c.listRouters(); { "clusterName": "mycluster", "routers": { "node1::": { "hostname": "node1", "lastCheckIn": "2024-05-23 23:38:04", "roPort": "6447", "roXPort": "6449", "rwPort": "6446", "rwXPort": "6448", "version": "8.0.36" }, "node2::": { "hostname": "node2", "lastCheckIn": "2024-05-23 23:38:06", "roPort": "6447", "roXPort": "6449", "rwPort": "6446", "rwXPort": "6448", "version": "8.0.36" }, "node3::": { "hostname": "node3", "lastCheckIn": "2024-05-23 23:38:07", "roPort": "6447", "roXPort": "6449", "rwPort": "6446", "rwXPort": "6448", "version": "8.0.36" } } }
复制
4.9.5配置MySQL Router的启停服务
编写MySQL Router服务配置文件
vi /usr/lib/systemd/system/mysqlrouter.service [Unit] Description=MySQL Router After=syslog.target After=network.target [Service] Type=simple User=mysql Group=mysql ExecStart=/data/mysqlrouter/bin/mysqlrouter -c /data/mysqlrouter/router/mysqlrouter.conf Restart=on-failure PrivateTmp=true [Install] WantedBy=multi-user.target
复制
配置服务
systemctl daemon-reload systemctl enable mysqlrouter.service systemctl status mysqlrouter.service systemctl start mysqlrouter.service systemctl stop mysqlrouter.service
复制
4.9.6使用MySQL Router路由测试
读写测试
mysql -h192.168.100.10 -uroot -p'Root' -P6446 create database testdb; use testdb; create table testtab(id int);
复制
[mysql@node1 ~]$ mysql -h192.168.100.10 -uroot -p'Root%1234' -P6446 mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 68303 Server version: 8.0.36 MySQL Community Server - GPL Copyright (c) 2000, 2024, 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> create database testdb; Query OK, 1 row affected (0.01 sec) mysql> use testdb; Database changed mysql> create table testtab(id int); Query OK, 0 rows affected (0.05 sec) 结论:当使用6446 RW端口连接时,会连接到后端InnoDB Cluster集群中所有的PRIMARY节点,进行读写操作。
复制
只读测试
[mysql@node1 ~]$ mysql -h192.168.100.10 -uroot -p'Root' -P6447 -e"select @@hostname;" mysql: [Warning] Using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | node3 | +------------+ [mysql@node1 ~]$ mysql -h192.168.100.10 -uroot -p'Root' -P6447 -e"select @@hostname;" mysql: [Warning] Using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | node2 | +------------+ [mysql@node1 ~]$ mysql -h192.168.100.10 -uroot -p'Root' -P6447 -e"select @@hostname;" mysql: [Warning] Using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | node3 | +------------+ [mysql@node1 ~]$ mysql -h192.168.100.10 -uroot -p'Root' -P6447 -e"select @@hostname;" mysql: [Warning] Using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | node2 | +------------+ 结论: 当使用6447 RO端口连接时,会连接到后端InnoDB Cluster集群中所有的SECONDARY节点,并且以rr(round-robin)的策略调度。
复制
参考文档
https://dev.mysql.com/doc/mysql-shell/8.0/en/mysql-innodb-cluster.html