MySQL高可用集群

https://dev.mysql.com/doc/mysql-shell/8.4/en/mysql-innodb-cluster.html

1 什么是MySQL高可用集群
  • MySQL高可用集群:MySQL InnoDB Cluster
  • InnoDB Cluster是MySQL官方实现高可用+读写分离的架构方案,包含以下组件
    • MySQL Group Replication:简称MGR,是MySQL的主从同步高可用方案,包括数据同步和角色选举
    • MySQL Shell是InnoDB Cluster的管理工具,用来创建和管理集群
    • MySQL Router是业务流量入口,支持对MGR的主从角色判断,可以配置不同的端口分别对外提供读写服务,实现读写分离
  • MySQL InnoDB Cluster架构图
  • InnoDB Cluster将三个MySQL数据库实例构成一个高可用集群
  • 其中一个实例是具有读写能力的主成员
  • 其他两个实例是具有只读能力的次成员
  • 组复制将数据从主成员复制到次成员
  • MySQL Router将连接读写端口的客户端请求转发到主成员,将连接到只读端口的客户端请求转发到次成员
2 搭建高可用集群示例
2.1 准备三个MySQL实例
2.2.1 准备MySQL实例 20 0 0 0
  • 创建目录
复制代码
mkdir -p /opt/mysql/20000/{data,log,tmp}`
`
  • 准备配置文件
复制代码
vi /opt/mysql/20000/my.cnf`

`[mysql]`
`#设置mysql客户端默认编码`
`default-character-set=utf8`
`[mysqld]`
`port=20000`
`pid-file= /opt/mysql/20000/mysqld.pid`
`socket= /opt/mysql/20000/mysqld.sock`
`datadir= /opt/mysql/20000/data`
`log-error=/opt/mysql/20000/log/mysqld.log`
`tmpdir=/opt/mysql/20000/tmp`
`mysqlx-port=20010`
`mysqlx-socket=/opt/mysql/20000/mysqldx.sock`
`secure-file-priv= NULL`
`# Disabling symbolic-links is recommended to prevent assorted security risks`
`symbolic-links=0`
`#服务器唯一ID,默认是1`
`server-id=20000`
`#启用二进制日志`
`log-bin=mysql-bin`
`#最大连接数`
`max_connections=1000`
`#设置默认时区`
`default-time_zone='+8:00'`
`# 0:区分大小写`
`# 1:不区分大小写`
`lower_case_table_names=1`
`user = mysql`
`#启用全局事务标识符(GTID)模式`
`gtid_mode=on`
`#强制GTID的一致性。这意味着在执行事务时,MySQL将确保所有涉及的服务器都使用相同的GTID集。`
`enforce_gtid_consistency=on`
`#启用并行复制`
`binlog_transaction_dependency_tracking=WRITESET`
`replica_preserve_commit_order=ON`
`replica_parallel_type=LOGICAL_CLOCK`
`transaction_write_set_extraction=XXHASH64`
`
  • 初始化库
复制代码
chown -R mysql:mysql /opt/mysql/20000`
`mysqld --defaults-file=/opt/mysql/20000/my.cnf --initialize`
`
  • 启库
复制代码
mysqld --defaults-file=/opt/mysql/20000/my.cnf &`
`
  • 初始化密码
复制代码
#查看临时密码`
`cat /opt/mysql/20000/log/mysqld.log|grep "A temporary password"`
`#登录`
`mysql -uroot -p'ji2m:aJ9K26y' --socket=/opt/mysql/20000/mysqld.sock`
`>ALTER USER 'root'@'localhost' identified by '123456';`
`  CREATE USER 'root'@'%' IDENTIFIED  BY '123456';`
`  GRANT ALL PRIVILEGES ON *.* TO 'root'@'%';`
`  flush privileges;`

`
  • 给root账号赋InnoDB Cluster 相关权限
复制代码
mysql -uroot -p'123456' --socket=/opt/mysql/20000/mysqld.sock`
`>GRANT CLONE_ADMIN, CONNECTION_ADMIN, CREATE USER, EXECUTE, FILE, GROUP_REPLICATION_ADMIN, PERSIST_RO_VARIABLES_ADMIN, PROCESS, RELOAD, REPLICATION CLIENT, REPLICATION SLAVE, REPLICATION_APPLIER, REPLICATION_SLAVE_ADMIN, ROLE_ADMIN, SELECT, SHUTDOWN, SYSTEM_VARIABLES_ADMIN ON *.* TO 'root'@'%' WITH GRANT OPTION;`
 `GRANT DELETE, INSERT, UPDATE ON mysql.* TO 'root'@'%' WITH GRANT OPTION;`
 `GRANT ALTER, ALTER ROUTINE, CREATE, CREATE ROUTINE, CREATE TEMPORARY TABLES, CREATE VIEW, DELETE, DROP, EVENT, EXECUTE, INDEX, INSERT, LOCK TABLES, REFERENCES, SHOW VIEW, TRIGGER, UPDATE ON mysql_innodb_cluster_metadata.* TO 'root'@'%' WITH GRANT OPTION;`
 `GRANT ALTER, ALTER ROUTINE, CREATE, CREATE ROUTINE, CREATE TEMPORARY TABLES, CREATE VIEW, DELETE, DROP, EVENT, EXECUTE, INDEX, INSERT, LOCK TABLES, REFERENCES, SHOW VIEW, TRIGGER, UPDATE ON mysql_innodb_cluster_metadata_bkp.* TO 'root'@'%' WITH GRANT OPTION;`
 `GRANT ALTER, ALTER ROUTINE, CREATE, CREATE ROUTINE, CREATE TEMPORARY TABLES, CREATE VIEW, DELETE, DROP, EVENT, EXECUTE, INDEX, INSERT, LOCK TABLES, REFERENCES, SHOW VIEW, TRIGGER, UPDATE ON mysql_innodb_cluster_metadata_previous.* TO 'root'@'%' WITH GRANT OPTION;`
`
2.2.2 复制实例 20001
复制代码
cp -rf /opt/mysql/20000 /opt/mysql/20001`
`sed -i "s#20000#20001#g" /opt/mysql/20001/my.cnf`
`sed -i "s#20010#20011#g" /opt/mysql/20001/my.cnf`
`rm -f /opt/mysql/20001/data/auto.cnf`
`chown -R mysql:mysql /opt/mysql/20001`
`mysqld --defaults-file=/opt/mysql/20001/my.cnf &`
`
2.2.3 复制实例20002
复制代码
cp -rf /opt/mysql/20000 /opt/mysql/20002`
`sed -i "s#20000#20002#g" /opt/mysql/20002/my.cnf`
`sed -i "s#20010#20012#g" /opt/mysql/20001/my.cnf`
`rm -f /opt/mysql/20002/data/auto.cnf`
`chown -R mysql:mysql /opt/mysql/20002`
`mysqld --defaults-file=/opt/mysql/20002/my.cnf &`
`
2.2 MySQL Shell 部署 集群
2.2.1 安装MySQL Shell

MySQL :: Download MySQL Shell

2.2.2 MySQL Shell 集群相关常用命令
复制代码
mysqlsh root@192.168.221.100:20000 --js`
`>` `dba.help();` `--查看帮助文档`
  `? dba.deploySandboxInstance --查看具体操作的帮助文档`
`
2. 2 . 3 检测实例是否满足要求
复制代码
mysqlsh root@192.168.221.100:20000 --js`
`> dba.checkInstanceConfiguration('root@192.168.221.100:20000');`
  `dba.checkInstanceConfiguration('root@192.168.221.100:20001');`
  `dba.checkInstanceConfiguration('root@192.168.221.100:20002');`
`

返回ok表示验证通过

2. 2 . 4 初始化InnoDB Cluster配置
复制代码
mysqlsh root@192.168.221.100:20000 --js`
`> dba.configureInstance('root@192.168.221.100:20000');`
  `dba.configureInstance('root@192.168.221.100:20001');`
  `dba.configureInstance('root@192.168.221.100:20002');`
`
2. 2 . 5 使用主实例创建集群
  • 创建集群
复制代码
mysqlsh root@192.168.221.100:20000 --js`
`> var cluster = dba.createCluster('myCluster');`
`
  • 创建集群后默认会将当前节点添加进集群,并作为主节点

  • 默认创建单主模式集群

  • 查看集群状态

复制代码
mysqlsh root@192.168.221.100:20000 --js`
`> var cluster = dba.getCluster('myCluster');`
  `cluster.status();`
`
2. 2 . 6 添加副本实例
复制代码
mysqlsh root@192.168.221.100:20000 --js`
`> var cluster = dba.getCluster('myCluster');`
  `cluster.addInstance('root@192.168.221.100:20001');`
  `cluster.addInstance('root@192.168.221.100:20002');`
  `cluster.status();`
`

新添加进来的实例默认作为副本节点

2.3 InnoDB Cluster数据 同步 测试
  • 主库20000添加数据
复制代码
mysql -uroot -p'123456' --socket=/opt/mysql/20000/mysqld.sock`
`> create database test;`
   `use test;`
   `create table test (id int,name varchar(10));`
   `ALTER TABLE test ADD PRIMARY KEY id(id);`
   `insert into test values(1,'a'),(2,'b'),(3,'c');`

`
  • 从库20001查询数据
复制代码
mysql -uroot -p'123456' --socket=/opt/mysql/20001/mysqld.sock`
`>  use test;`
   `select * from test;`
`
  • 从库20002查询数据
复制代码
mysql -uroot -p'123456' --socket=/opt/mysql/20002/mysqld.sock`
`>  use test;`
   `select * from test;`
`
2.4 InnoDB Cluster主从切换测试
  • kill主库实例20000
  • 查看组成员
复制代码
mysql -uroot -p'123456' --socket=/opt/mysql/20001/mysqld.sock`
`>  SELECT CHANNEL_NAME,MEMBER_ID,MEMBER_HOST,MEMBER_PORT, MEMBER_ROLE FROM performance_schema.replication_group_members;`
`
  • 查看集群状态
复制代码
mysqlsh root@192.168.221.100:20001 --js`
`> var cluster = dba.getCluster('myCluster');`
  `cluster.status();`
`
2. 5 MySQL Shell集群 常见 操作
2.5.1 参数配置
  • 使用cluster.options()查看当前集群的配置属性
  • 集群参数配置分为两种方式
    • cluster.setOption()设置集群属性,所有节点的
    • cluster.setInstanceOption()设置指定节点属性
复制代码
mysqlsh root@192.168.221.100:20000 --js`
`> var cluster = dba.getCluster('myCluster');`
  `cluster.setOption("memberWeight",50);`
  `#重新加入集群重试次数改为5次`
  `cluster.setOption("autoRejoinTries",5);`
  
  `#将其中一个节点的权重改为75`
`  cluster.setInstanceOption("192.168.221.100:20001","memberWeight",75);`
  `#重新加入集群重试次数改为10次`
`  cluster.setInstanceOption("192.168.221.100:20001","autoRejoinTries",10)`
`
2.5.2 配置节点权重
  • memberWeight选项的值域为0~100之间的整数,缺省值为50;
  • 该值是故障转移时自动选举主节点的百分比权重
  • 具有较高memberWeight值的实例更有可能在单主集群被选为主节点
复制代码
mysqlsh root@192.168.221.100:20000 --js`
`> var cluster = dba.getCluster('myCluster');`
  `#查看集群的参数配置`
  `cluster.options();`
  
  `#创建集群配置`
  `dba.createCluster('myCluster',` `{memberWeight:75});`
  `#添加实例时配置`
  `var cluster = dba.getCluster();`
  `cluster.addInstance('root@192.168.221.100:20001',{memberWeight:50});`
  `#集群创建完后修改配置`
`  cluster.setInstanceOption('192.168.221.100:20000','memberWeight',100)`
`
2.5.3 将节点重新加入集群
  • 状态为missing的节点是组复制关闭或者中断
  • 可使用cluster.rejionInstance()重新加入集群
  • 会重新对该节点设置MGR相关参数
2.5.4 集群多数节点异常恢复
  • 当集群多个节点异常,则失去了仲裁机制,无法选举出主节点
  • 使用cluster.forceQuorumUsingPartitionOf将集群剥离为单节点运行
2.5.5 集群节点角色切换
  • 单主模式指定主节点切换
复制代码
mysqlsh root@192.168.221.100:20000 --js`
`> var cluster = dba.getCluster('myCluster');`
   `cluster.setPrimaryInstance('192.168.221.100:20001');`
`
  • 单主模式切换为多主模式
复制代码
mysqlsh root@192.168.221.100:20000 --js`
`> var cluster = dba.getCluster('myCluster');`
   `cluster.switchToMultiPrimaryMode();`
`
  • 多主模式切换为单主模式
复制代码
mysqlsh root@192.168.221.100:20000 --js`
`> var cluster = dba.getCluster('myCluster');`
`   cluster.switchToSinglePrimaryMode("192.168.221.100:20000")`
`
2.5. 6 销毁集群
复制代码
mysqlsh root@192.168.221.100:20000 --js`
`> var cluster = dba.getCluster('myCluster');`
  `cluster.dissolve();`
`
2.5. 7 创建集群管理用户
复制代码
mysqlsh root@192.168.221.100:20000 --js`
`> var cluster = dba.getCluster('myCluster');`
   `cluster.setupAdminAccount('test');
  • 该操作会创建MySQL系统账号
  • mysqlsh连接集群时也可使用该账号登录
2. 6 MySQL Router连接集群
2.6.1 安装MySQL Router

MySQL :: Download MySQL Router

2.6.2 配置路由
复制代码
mysqlrouter --bootstrap root@192.168.221.100:20000 --force --user=root`
`
2.6.3 查看集群路由信息
复制代码
mysqlsh root@192.168.221.100:20000 --js`
`> var cluster = dba.getCluster('myCluster');`
   `cluster.listRouters();`
`
2.6.4 启动路由
复制代码
mysqlrouter &`
`
2.6.5 通过路由连接MySQL
  • mysql client连接路由
复制代码
mysql -uroot -p123456 -P6446  -h192.168.221.100`
`
  • mysqlsh连接路由
复制代码
mysqlsh root@192.168.221.100:6446  --sql`
`
2.7 MySQL Router连接测试
  • R/W端口测试读写
  • R/O端口测试读写
  • R/W Split端口测试读写
相关推荐
钢铁男儿16 分钟前
C# 接口(什么是接口)
java·数据库·c#
__风__1 小时前
PostgreSQL kv(jsonb)存储
数据库·postgresql
Databend1 小时前
Databend 产品月报(2025年6月)
数据库
Little-Hu2 小时前
QML TextEdit组件
java·服务器·数据库
保持学习ing4 小时前
day1--项目搭建and内容管理模块
java·数据库·后端·docker·虚拟机
发仔1235 小时前
Oracle与MySQL核心差异对比
mysql·oracle
宇钶宇夕5 小时前
EPLAN 电气制图:建立自己的部件库,添加部件-加SQL Server安装教程(三)上
运维·服务器·数据库·程序人生·自动化
爱可生开源社区5 小时前
SQLShift 重磅更新:支持 SQL Server 存储过程转换至 GaussDB!
数据库
贾修行5 小时前
SQL Server 空间函数从入门到精通:原理、实战与多数据库性能对比
数据库·sqlserver
傲祥Ax6 小时前
Redis总结
数据库·redis·redis重点总结