InnoDB ReplicaSet ,即 InnoDB 副本集,是一组由 AdminAPI 管理的一组使用基于 GTID 的异步复制的 MySQL 实例组成的集群集合。它由单 主(服务器实例)和多 辅助(服务器实例)组成(在 MySQL 复制 中通常叫做 源 和 副本)。
类似于 InnoDB Cluster ,InnoDB ReplicaSet 深度依赖 MySQL Shell 和 MySQL Router ,但它不提供 InnoDB Cluster 所具备的高可用性。通过 AdminAPI ,可以使用 ReplicaSet 对象来管理它。同时, MySQL Router 也支持对其进行引导,引导过程是自动配置的。因此,它适用于在不需要高可用的使用场景中横向扩展读取能力,并提供手动故障转移功能。
InnoDB ReplicaSet 底层基于 MySQL 异步复制技术。因而,它适用于 MySQL 服务器实例部署在广域网(WAN,Wide Area Network),彼此通过异步复制通道连接,辅助实例可容忍更大程度的复制延迟,且不需要在事务上达成共识的场景。
此外,你可以使用 AdminAPI 采用一个已有的复制拓扑来部署一个 InnoDB ReplicaSet ,之后可以像管理从头创建的 InnoDB ReplicaSet 一样管理它。InnoDB ReplicaSet 相较于 MySQL 复制 的优势在于可以使用 MySQL Shell 和 MySQL Router 更简单、方便、快捷的管理,而不需要使用第三方中间件来管理主从架构、故障转移、路由、重定向。
上面其实已经提及了它的优缺点,按参照对象分析如下:
部署过程类似于部署 InnoDB Cluster,但因基于复制而非组复制,故仅最少需要两个实例即可部署一个 InnoDB ReplicaSet 实例。
以下介绍的是从头部署一个 InnoDB ReplicaSet 实例,采用已有的 MySQL 复制拓扑的部署请参考我的后续文章。
/etc/my.cnf
在 ic-source 主机上/etc/my.cnf
中添加如下内容创建 MySQL 实例 replica01:
[mysqld@replica01]
datadir=/var/lib/mysql/replica01
port=3308
mysqlx_port=33080
admin_port=33082
socket=/var/lib/mysql/replica01/mysql.sock
log-error=/var/log/mysql-replica01.log
innodb_buffer_pool_size=256M
innodb_redo_log_capacity=100M
innodb_flush_method=O_DIRECT_NO_FSYNC
在 ic-replica1 主机上/etc/my.cnf
中添加如下内容创建 MySQL 实例 replica02:
[mysqld@replica02]
datadir=/var/lib/mysql/replica02
port=3310
mysqlx_port=33100
admin_port=33102
socket=/var/lib/mysql/replica02/mysql.sock
log-error=/var/log/mysql-replica02.log
innodb_buffer_pool_size=256M
innodb_redo_log_capacity=100M
innodb_flush_method=O_DIRECT_NO_FSYNC
分别在两台主机上执行如下操作:
$ systemctl start mysqld@replica01
$ systemctl status mysqld@replica01
在 ic-replica1 主机上启动 mysqld@replica02 :
$ systemctl start mysqld@replica02
$ systemctl status mysqld@replica02
$ grep temporary /var/log/mysql-replica01.log
# 替换为你配置的socket
$ mysql -uroot -p -S /var/lib/mysql/replica01/mysql.sock
执行如下 SQL 修改 root@localhost 用户的密码,创建用于远程登录的 root@`%` 用户:
mysql> alter user root@localhost identified by '要为本地root设置的密码';
mysql> create user root@`%` identified by '要为远程root设置的密码';
mysql> grant all on *.* to root@`%` with grant option;
在 ic-source 主机上启动 mysqlsh 连接到 root@ic-source:3308 :
$ mysqlsh --quiet-start=2 root@ic-source:3308
在 mysqlsh 中执行:
MySQL ic-source:3308 ssl JS > dba.configureReplicaSetInstance('root@ic-source:3308',{clusterAdmin: "rs_config"})
MySQL ic-source:3308 ssl JS > dba.configureReplicaSetInstance('root@ic-replica1:3310',{clusterAdmin: "rs_config"})
此处我限制了一下复制通道允许的 IP 网段,试一下安全功能。出于安全考虑,生产环境中也应该这么做。
MySQL ic-source:3308 ssl JS > rs=dba.createReplicaSet('ReplicaSet01',{replicationAllowedHost: '192.168.52.0/24'})
MySQL ic-source:3308 ssl JS > rs.addInstance('ic-replica1:3310')
MySQL ic-source:3308 ssl JS > rs.status({extended: 1})
为了更清晰的权限管理,我们应将配置账户和管理员账户进行权限分离,即便一般情况下二者是同一个。
说明
此步骤也可以放在第二步后执行,然后通过克隆复制,而不是现在所使用的增量复制。
MySQL ic-source:3308 ssl JS > rs.setupAdminAccount('rs_admin01')
执行完后,我们应该可以在 replica02 实例的 relaylog 和 binlog 中查看到。
建议使用 less
查看,直接 grep
会使你的终端显示字符集乱码,需要 reset 重置才行。
$ mysqlbinlog binlog.000002| less
$ mysqlbinlog binlog.000002| grep rs_admin
$ mysqlbinlog ic-replica1-relay-bin.000002| grep rs_admin
$ mysqlrouter --bootstrap rs_config@ic-source:3308 --account rsRouter01 --user=mysqlrouter --directory=/var/lib/mysqlro
因为我这台主机上还有之前搭建的 InnoDB Cluster 和 InnoDB ClusterSet 的路由,所以此处需要修改 mysqlrouter 配置文件 mysqlrouter.conf 的端口号。简单起见,我将前四个 默认端口号 乘 10 ,http_port 加 100 设置为 8543 。
[routing:bootstrap_rw]
bind_address=0.0.0.0
bind_port=64460
[routing:bootstrap_ro]
bind_address=0.0.0.0
bind_port=64470
[routing:bootstrap_x_rw]
bind_address=0.0.0.0
bind_port=64480
[routing:bootstrap_x_ro]
bind_address=0.0.0.0
bind_port=64490
[http_server]
port=8543
MySQL ic-source:3308 ssl JS > rs.listRouters()
$ mysqlsh --sql rsRouter01@ic-source:64460 -e 'select @@hostname,@@port;'
$ mysqlsh --sql rsRouter01@ic-source:64470 -e 'select @@hostname,@@port;'
$ mysqlsh --sql rsRouter01@ic-source:64480 -e 'select @@hostname,@@port;'
$ mysqlsh --sql rsRouter01@ic-source:64490 -e 'select @@hostname,@@port;'
因为只有两个实例,主实例负责写,辅助实例负责读,所以无需像验证 InnoDB Cluster 时执行三次来验证。
$ mysqlsh --quiet-start=2 root@ic-source:33080
在 mysqlsh 中执行:
MySQL ic-source:33080+ ssl JS > rs=dba.getReplicaSet()
MySQL ic-source:33080+ ssl JS > rs.setPrimaryInstance('replica1:3310')
有关 InnoDB ReplicaSet 的手动强制故障转移、打标签、升级等其他信息,请参阅 我的 《MySQL Shell 8.0 》专栏。
InnoDB ReplicaSet 的关键字是 AdminAPI,MySQL Shell,MySQL Router,MySQL 异步复制 。其功能同比传统 MyCat 等中间构成的 MMM 、MHA 主从架构相差不大,可以理解为 MySQL 官方实现发行版本,但 MySQL Shell 这个 MySQL 未来主打的 DevOps 工具还是更具优势的。