Skip to content

Mysql innodb cluster部署

InnoDB Cluster 组件介绍

InnoDB Cluster 组件

  1. MySQL Shell:是 MySQL 的高级客户端和代码编辑器。
  2. MySQL server 和 Group Replication:使一组 MySQL 实例能够提供高可用性。
  3. MySQL Router:一种轻量级中间件,可在应用程序和 InnoDB Cluster 之间提供透明路由。

功能

提供自动成员管理、容错、自动故障转移等功能。 InnoDB Cluster 通常以单主模式运行,具有一个主实例(读写)和多个辅助实例(只读)。高级用户还可以利用多主模式,其中所有实例都是主实例。您甚至可以在 InnoDB Cluster 在线时更改集群的拓扑,以确保尽可能高的可用性。

部署节点规划

示例部署

本示例使用 7 台虚拟机进行部署,部署架构如下:

  1. Host IP:192.168.72.50,操作系统:Ubuntu 22.04,角色:mysql innodb/mysql shell。
  2. Host IP:192.168.72.51,操作系统:Ubuntu 22.04,角色:mysql innodb/mysql shell。
  3. Host IP:192.168.72.52,操作系统:Ubuntu 22.04,角色:mysql innodb/mysql shell。
  4. Host IP:192.168.72.41,操作系统:Ubuntu 22.04,角色:mysql router/mysql client。
  5. Host IP:192.168.72.42,操作系统:Ubuntu 22.04,角色:mysql router/mysql client。
  6. Host IP:192.168.72.33,操作系统:Ubuntu 22.04,角色:haproxy/keepalived。
  7. Host IP:192.168.72.34,操作系统:Ubuntu 22.04,角色:haproxy/keepalived。

通用要求

  1. 至少三台 MySQL 服务器用于 mysql innodb 节点。
  2. 至少一台 MySQL Router 服务器。
  3. 可以用 ELB/SLB 替换 haproxy+keepalived。

部署步骤

1. 在所有 mysql-router 节点及 mysql-innodb 节点执行以下操作

  1. 配置主机名
Terminal window
hostnamectl set-hostname mysql-innodb01
hostnamectl set-hostname mysql-innodb02
hostnamectl set-hostname mysql-innodb03
hostnamectl set-hostname mysql-router01
hostnamectl set-hostname mysql-router02

分别在每个节点配置主机名。 2. 配置 hosts 解析

Terminal window
cat << EOF > /etc/hosts
192.168.21.202 mysql-router01
192.168.72.42 mysql-router02
192.168.21.203 mysql-innodb01
192.168.21.204 mysql-innodb02
192.168.21.205 mysql-innodb03
EOF

另一种配置示例:

Terminal window
cat << EOF > /etc/hosts
10.10.3.35 mysql-router01
10.10.3.189 mysql-router02
10.10.3.168 mysql-innodb01
10.10.3.182 mysql-innodb02
10.10.3.248 mysql-innodb03
EOF

分别在每个节点配置 hosts 解析。 3. 添加 mysql 官方软件源https://dev.mysql.com/downloads/repo/apt/ 4. 安装软件包

Terminal window
apt install gpg -y

mysql 版本建议大于 8.0.11 ,在 centos7 上使用 mysql5.7.44 。 5. 安装软件源配置包(不同版本示例): - 8.4 版本示例

Terminal window
wget https://repo.mysql.com//mysql-apt-config_0.8.32-1_all.deb
dpkg -i mysql-apt-config_0.8.32-1_all.deb
apt update -y
- **5.7 debian10 版本示例**:
Terminal window
wget https://dev.mysql.com/get/mysql-apt-config_0.8.24-1_all.deb
dpkg -i mysql-apt-config_0.8.24-1_all.deb
- **centos7 安装 5.7 版本示例**:
Terminal window
wget https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm
sudo rpm -ivh mysql57-community-release-el7-11.noarch.rpm
  1. 添加 key
Terminal window
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys B7B3B788A8D3785C

centos 示例:

Terminal window
sudo yum info mysql-community-server
Terminal window
cd /etc/apt;cp trusted.gpg trusted.gpg.d
Terminal window
rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022
  1. 更新和升级系统
Terminal window
apt update;apt upgrade -y

debian/ubuntu 最大 5.7.42 ,推荐使用 centos7 系统安装 5.7.44 。 centos 另一种添加 key 示例:

Terminal window
rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2023

2. 在所有 innodb 节点执行以下操作

  1. 安装 innodb 集群
Terminal window
apt update -y
apt install -y mysql-server mysql-shell

centos 安装命令:

Terminal window
yum install mysql-community-server mysql-shell -y
  1. 修改配置文件
Terminal window
sed -i 's/127.0.0.1/0.0.0.0/g' /etc/mysql/mysql.conf.d/mysqld.cnf

将 127.0.0.1 修改为 0.0.0.0 ,重要,必须修改。 3. 创建独立账号

Terminal window
mysqlsh -uroot -pqwer1234 -h mysql-innodb01
Terminal window
dba.configureInstance()

选择 2 ,用户名 icadmin ,密码 hc123456 。 4. 重启 mysql 使配置生效

Terminal window
systemctl restart mysql
  1. 查看生成的配置
Terminal window
cat /etc/mysql/conf.d/mysql.cnf
  1. 创建数据库用户
SET SQL_LOG_BIN=0;
CREATE USER icadmin IDENTIFIED BY 'hc123456';
GRANT ALL ON *.* TO icadmin WITH GRANT OPTION;
SET SQL_LOG_BIN=1;
  1. 检查实例配置
Terminal window
mysqlsh -uicadmin -phc123456 -h localhost --sql
\s
select @@gtid_mode, @@server_id;
\js
dba.checkInstanceConfiguration()

确认 status 参数为 ok ,处理表的问题时,一定要先关 binlog 再执行 ddl/dml ,表必须要有主键,不然报错。 8. 确认参数

Terminal window
cat /etc/mysql/conf.d/mysql.cnf

确认参数 gtid 和 server_id 。 9. 重置所有 gtid 同步日志

Terminal window
mysqlsh -uicadmin -phc123456 -h localhost --sql
reset master;

重置所有 gtid 同步日志,不然在添加节点到集群时会报错,从已有数据恢复时一定要执行这个操作后才能建立集群。

3. 在 innodb01 节点执行以下操作

  1. 创建 innodb 集群
Terminal window
mysqlsh -uicadmin -phc123456 -h mysql-innodb01
dba.createCluster('my_innodb_cluster')
dba.getCluster()
herc = dba.getCluster()
herc.status()
herc.rescan()
herc.addInstance('admin2@mysql-innodb02')

添加 innodb02 节点到集群,报 gtid 错误执行 reset master 。 2. 查看集群状态

herc.status()

如果添加失败,错误:ERROR: RuntimeError: The instance ‘mysql-innodb02:3306’ is already part of another Replication Group 。 处理方法:

Terminal window
vi /etc/mysql/conf.d/mysql.cnf
删除掉自动增加的gtid等配置项
systemctl restart mysql
mysqlsh -uroot -pqwer1234 -h mysql-innodb02
dba.configureInstance()
systemctl restart mysql

stop group_replication;
  1. 处理版本问题: 问题:WARNING: Instance ‘mysql-innodb01:3306’ cannot persist configuration since MySQL version 5.7.42 does not support the SET PERSIST command (MySQL version >= 8.0.11 required). Please use the dba.configureLocalInstance() command locally to persist the changes. 8.0.11 以下版本重启后,组复制信息会丢失,不能自动恢复到集群。必须执行下面本地文件持久化才能自动恢复。 处理,集群 3 个节点都添加好后,每个节点执行:
dba.configureLocalInstance()
cat /etc/mysql/conf.d/mysql.cnf
  1. 添加 innodb03 节点到集群
herc.addInstance('icadmin@mysql-innodb03')
herc.status()
\sql select @@super_read_only;
  1. 查看库及表
\sql
show schemas;
use mysql_innodb_cluster_metadata;
show tables;
use performance_schema;
show tables;
select * from performance_schema.replication_group_members;
  1. 删除集群
dba.dropMetadataSchema()
cluster = dba.getCluster()
dba.rebootClusterFromCompleteOutage()
cluster.describe()
dba.configureLocalInstance()
cluster.status()
Terminal window
vi /etc/my.cnf
删除集群配置
systemctl restart mysqld

4. 部署 mysql-router

  1. 添加 key
Terminal window
rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2023
  1. 安装 mysql-router
Terminal window
apt install -y mysql-router mysql-client

centos 安装命令:

Terminal window
yum install -y mysql-router mysql
  1. 配置 apparmor
Terminal window
nano /etc/apparmor.d/usr.bin.mysqlrouter

添加配置:

# Allow directory for MySQL InnoDB cluster
/var/lib/mysqlrouter/ rw,
/var/lib/mysqlrouter/** rw,
}
Terminal window
systemctl reload apparmor
  1. 引导 mysql-router
Terminal window
mysqlrouter --bootstrap icadmin@mysql-innodb01:3306 --directory /var/lib/mysqlrouter \
--conf-bind-address 0.0.0.0 --user=mysqlrouter

连接 innodb 集群,MySQL Classic protocol :

  • Read/Write Connections: localhost:6446
  • Read/Only Connections: localhost:6447
  • Read/Write Split Connections: localhost:6450 MySQL X protocol :
  • Read/Write Connections: localhost:6448
  • Read/Only Connections: localhost:6449 另一种引导示例:
Terminal window
mysqlrouter --bootstrap admin2@mysql-innodb01:3306 --directory /var/lib/mysqlrouter \
--conf-bind-address 0.0.0.0 --user=mysqlrouter --force
  1. 查看网络连接
Terminal window
ss -antulp
  1. 配置 mysql-router 认证: 参考链接:https://dev.mysql.com/doc/mysql-router/8.0/en/mysql-router-rest-api-setup.html
Terminal window
vi /var/lib/mysqlrouter/mysqlrouter.conf

添加配置:

[http_auth_backend:default_auth_backend]
#backend=metadata_cache
backend=file
filename=/etc/mysqlrouter.pwd

修改最大连接数:

max_connections=10000 #修改最大连接数,默认512
max_total_connections=20000 #默认512

参考:https://mysql.net.cn/doc/mysql-router/8.0/en/mysql-router-conf-options.html 7. 查看配置文件

Terminal window
cat /var/lib/mysqlrouter/mysqlrouter.conf
cat /var/lib/mysqlrouter/data/state.json
  1. 禁用默认的 systemd 服务
Terminal window
systemctl stop mysqlrouter.service
rm -rf /etc/init.d/mysqlrouter
systemctl daemon-reload
  1. 配置 mysql-router 服务开机自启动
Terminal window
cat >/etc/systemd/system/mysqlrouter.service<<EOF
[Unit]
Description=MySQL Router
After=network.target
After=syslog.target
[Service]
Type=notify
User=mysqlrouter
Group=mysqlrouter
# Start main service
ExecStart=/usr/bin/mysqlrouter -c /var/lib/mysqlrouter/mysqlrouter.conf --user=mysqlrouter
# Sets open_files_limit
LimitNOFILE = 10000
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
Terminal window
systemctl enable --now mysqlrouter.service
cat /var/lib/mysqlrouter/log/mysqlrouter.log
  1. 验证 reset api
    • 建立 reset api 账号
Terminal window
mysqlrouter_passwd set /etc/mysqlrouter.pwd apiuser X9DGc6j0W4aUBiN
mysqlrouter_passwd list /etc/mysqlrouter.pwd
chmod a+r /etc/mysqlrouter.pwd
systemctl restart mysqlrouter
- **测试 api**:
Terminal window
curl -XGET -I -k https://localhost:8443/api/20190715/metadata --user apiuser X9DGc6j0W4aUBiN

5. 读写验证和故障自动切换

  1. 写入数据(主节点)
Terminal window
mysqlsh -uicadmin -phc123456 -h mysql-innodb01
herc = dba.getCluster()
herc.status()
CREATE DATABASE gaojinbo;
CREATE TABLE t1(id int,name varchar(30),primary key (id));
INSERT into gaojinbo.t1 VALUE(1001,'gaojinbo');
select * from gaojinbo.t1;

其他节点也能查到数据,其他节点 insert 会报错。 2. 模拟故障切换

Terminal window
关闭innodb01
systemctl stop mysql

innodb02 会自动成为主节点。

Terminal window
mysqlsh -uicadmin -phc123456 -h mysql-innodb02
INSERT into gaojinbo.t1 VALUE(1002,'gaojinbo');
select * from gaojinbo.t1;

6. 连接数据库

  1. 创建示例用户
Terminal window
mysql -uroot -p
create user app@'%' identified by 'App@123456';
grant all on *.* to app@'%';
flush privileges;
  1. 连接到读写数据库
Terminal window
mysql -h127.0.0.1 -P 6446 -u app -p'App@123456'
select @@hostname;
create database mydb;
  1. 连接到只读数据库
Terminal window
mysql -h127.0.0.1 -P 6447 -u app -p'App@123456'
select @@hostname;
create database mydb1; #报错
select user, host from mysql.user;