MySQL 官方高可用方案:Innodb ReplicaSet

文若2年前技术文章1530


说明

MySQL Innodb ReplicaSet 是 MySQL 团队在 2020 年推出的一款产品,用来帮助用户快速部署和管理主从复制,在数据库层仍然使用的是主从复制技术。

ReplicaSet 主要包含三个组件:MySQL Router、MySQL Server 以及 MySQL Shell 高级客户端。

MySQL Shell 负责管理 ReplicaSet 包括部署、切换、节点加入等,都可以通过内置 AdminAPI 自动化完成。

MySQL Router 是一款轻量级中间件,可在应用程序和 ReplicaSet 之间提供透明路由和读写分离功能。

未命名文件.png

基于系统的高可用要求,ReplicaSet 可提供 RTO 等于数分钟,RPO < 1 秒 的高可用性,适用于对高可用要求不高的场景。因为它无法自动进行故障转移,当发生故障时,需要运维人员通过 AdminAPI 进行主备切换。另外 MySQL Router 读写分离提供的是两个端口 r/w 和 ro 组,如果要使用读写分离功能,则需要应用适配。

1. 安装部署

1.1 环境说明

IP

hostname

Role

172.16.104.55

172-16-104-55

Master

172.16.104.56

172-16-104-56

Slave

vi /etc/hosts
172.16.104.55 172-16-104-55
172.16.104.56 172-16-104-56

1.2 MySQL Shell 安装

安装 MySQL Shell 前需要保证已经部署好两台 MySQL 8.0 版本的实例。

官方下载地址:MySQL Shell download

mv mysql-shell-8.0.31-linux-glibc2.12-x86-64bit /usr/local/mysqlsh
export PATH=/usr/local/mysqlsh/bin/:$PATH
echo 'PATH=$PATH:/usr/local/mysqlsh/bin/' >> /etc/profile

进入 MySQL Shell 使用 \py & \js 可以切换命令模式,本篇文章使用 python 模式演示:

截屏2023-02-21 上午10.45.13.png

1.3 配置 MySQL 实例

部署好 MySQL 实例后,需要创建一个用户,提供给 MySQL Shell 使用,这里演示创建的用户是:rw_shell

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 'rw_shell'@'%' WITH GRANT OPTION;
GRANT DELETE, INSERT, UPDATE ON mysql.* TO 'rw_shell'@'%' 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 'rw_shell'@'%' 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 'rw_shell'@'%' 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 'rw_shell'@'%' WITH GRANT OPTION;

配置 MySQL 实例,检查是否符合创建 ReplicaSet 的条件,如果发现需要修改的地方,就会提示确认修改。

执行次命令会让用户输入密码,保存后会进入检查阶段。

dba.configure_replica_set_instance('rw_shell@172-16-104-55:3306', {"clusterAdmin": "rw_shell@'%'"})
dba.configure_replica_set_instance('rw_shell@172-16-104-56:3306', {"clusterAdmin": "rw_shell@'%'"})

MySQL Shell 会检查数据库参数是否满足创建 ReplicaSet 条件,并提出修改建议:

截屏2023-02-21 上午11.15.53.png

此阶段执行完成后,表示实例都具备组成 ReplicaSet 条件,可进入下一步。

1.4 创建 ReplicaSet

使用 MySQL Shell 连接到主实例,否则测试中会报 session 错误。

An open session is required to perform this operation.

\c rw_shell@172-16-104-55:3306

截屏2023-02-21 下午2.50.04.png

创建 ReplicaSet 默认当前进入的实例为主库实例:

rs = dba.create_replica_set("prd_op_service")

可通过下方命令查看 ReplicaSet 状态:

rs.status()

此时只有主库实例在线:

{
  "replicaSet": {
    "name": "prd_op_service", 
    "primary": "172-16-104-55:3306", 
    "status": "AVAILABLE", 
    "statusText": "All instances available.", 
    "topology": {
      "172-16-104-55:3306": {
        "address": "172-16-104-55:3306", 
        "instanceRole": "PRIMARY", 
        "mode": "R/W", 
        "status": "ONLINE"
      }
    }
    "type": "ASYNC"
  }
}

添加新实例:

rs.add_instance("172-16-104-56:3306")

MySQL Shell 支持使用 Clone 模式,快速将一个新实例加入已有数据的 ReplicaSet

截屏2023-02-21 下午3.02.20.png

1.5 查询帮助

查看某个对象有多少种方法,当然也可以直接使用 help() 方法,打印帮助文档:

>> dir(rs)
[
    "add_instance", # 添加新实例到 ReplicaSet 中
    "disconnect",  # 断开当前会话
    "force_primary_instance", # 切换主实例
    "get_name", # 获取当前会话中,ReplicaSet 名称
    "help", # 打印帮助文档
    "list_routers", # 列出当前配置的 routers
    "name", 
    "options", # 查看配置
    "rejoin_instance", 
    "remove_instance", # 移除一个节点
    "remove_router_metadata", # 删除 router 元数据
    "set_instance_option", 
    "set_option", 
    "set_primary_instance", # 执行安全的主备切换
    "setup_admin_account", 
    "setup_router_account", 
    "status" # 查看 ReplicaSet 状态
]

1.6 切换上下文

退出 MySQL Shell 后,再次进入如何管理之前创建 ReplicaSet 呢?

截屏2023-02-21 下午3.14.38.png

首先进入主库实例:

\c rw_shell@172-16-104-55:3306

通过使用下方命令,获取当前会话的 ReplicaSet 操作对象:

rs = dba.get_replica_set()

截屏2023-02-21 下午3.18.33.png

2. Router 配置

MySQL Router 是一款轻量级的中间件,可以为 inoodb ReplicaSet 提供应用程序的透明路由和读写分离。

2.1 安装 router

官方下载地址:MySQL Router Donwload

xz -d mysql-router-8.0.30-linux-glibc2.12-x86_64.tar.xz
tar -xvf mysql-router-8.0.30-linux-glibc2.12-x86_64.tar

2.2 创建 router 用户

截屏2023-02-22 上午9.46.58.png

rs.setup_router_account('op_router')

2.3 启动 router

./mysqlrouter \
   --bootstrap rw_shell@172-16-104-55:3306 \
   --directory /data/myrouter \
   --conf-use-sockets \
   --account op_router \
   --user=root

bootstrap:引导实例的连接串 router 会通过该实例获取 ReplicaSet 元数据信息

directory:mysql-router 数据目录

conf-use-sockets:确认生成 socket 文件

account:router 连接 MySQL 的账号,上一步已使用 mysql shell 已创建

截屏2023-02-22 上午10.16.39-1.png

MySQL Router 会自动生成配置文件,启动命令也打印在终端中。

./mysqlrouter -c /data/myrouter/mysqlrouter.conf &

2.4 验证

MySQL Router 为用户提供四个端口:

-- MySQL 经典协议
- Read/Write Connections: localhost:6446, /data/myrouter/mysql.sock
- Read/Only Connections:  localhost:6447, /data/myrouter/mysqlro.sock

-- MySQL X 协议
- Read/Write Connections: localhost:6448, /data/myrouter/mysqlx.sock
- Read/Only Connections:  localhost:6449, /data/myrouter/mysqlxro.sock

截屏2023-02-22 上午10.18.50.png

3. ReplicaSet 维护

3.1 手动切换

使用 MySQL Sehll 连接到 ReplicaSet 中,此时 55 为 Primary 实例:

截屏2023-02-22 上午10.38.40.png

rs.set_primary_instance('172-16-104-56:3306')

截屏2023-02-22 上午10.40.37.png

查询 ReplicaSet 状态:

rs.status()

截屏2023-02-22 上午10.42.29.png

使用 6446 写端口连接数据库,查看 Server-id 是否为 56,验证 router 切换后是否路由正确:

mysql -h172.16.104.56 -P6446 -urw_shell -p -e'select @@server_id;'
-- result:563306

3.2 维护方法

AdminAPI 提供了一系列的方法,用户管理 ReplicaSet,运维人员可以通过这些方法对 ReplicaSet 实现日常运维管理。

截屏2023-02-22 上午11.34.13.png

3.2.1 add_instance

add_instance(instance, {options}) 方法用于给现有的 ReplicaSet 添加只读实例,可以通过 clone 模式完整数据 copy 到新实例。

  • dryRun:检查阶段记录需要修改的项目,不实际执行。

  • lebel:为实例添加标签,标签会现在在 ststus() 方法输出的内容中。

  • recoveryMethod:指定数据恢复方法,包括自动、克隆或增量。

  • waitRecovery:恢复过程的详细级别。

  • cloneDonor:克隆数据的提供者,使用 “主机:端口” 格式。

  • interactive:是否开启命令执行向导。

  • timeout:事务同步操作的超时设置,默认为 0 表示强制等待事务同步结束。

3.2.2 disconnect

disconnect() 方法用于断开当前使用 ReplicaSet 上下文环境,管理多个 ReplicaSet 时会用到。

3.2.3 force_primary_instance

force_primary_instance(instance, {options}) 在当前主节点不可用且无法恢复的创建中,该方法将执行主服务器的强制故障转移功能。目标实例将提升为主服务器,而其它服务器将切换到新的主服务器。

3.2.4 list_routers

list_routers() 列出现 MySQL Router 实例。该方法列出为集群注册的所有 MySQL Router 实例信息。

3.2.5 rejoin_instance

rejoin_instance(instance, {options}) 将 MySQL 实例重新加入 ReplicaSet 主,当某实例因意外原因离开,可以使用该方法重新加入 ReplicaSet。

3.2.6 remove_instance

remove_instance(instance, {options}) 从 ReplicaSet 中移除 MySQL 实例。

3.2.7 remove_router_metadata

remove_router_metadata(routerDef) 移除 MySQL Router 元数据信息,可以使用该方法清除已不存在的实例。

3.2.8 set_instance_option

set_instance_option(instance, option, value) 更改 ReplicaSet 成员的选项值。例如从 MySQL Router 中隐藏某台实例,不参与读写分离:

rs.set_instance_option("instance", "tag:_hidden", true)

3.2.9 set_option

set_option(option, value) 更改 ReplicaSet 整体的选项值。

3.2.10 set_primary_instance

set_primary_instance(instance, {options}) 执行主动切换,将一个选定的 MySQL 实例提升为主服务器。

3.2.11 setup_admin_account

创建或升级 innodb ReplicaSet 的管理账户。

3.2.12 setup_router_account

创建或升级 MySQL Router 的账号。

3.2.13 status

查询 ReplicaSet 状态,使用 rs.status(extended=0) 指定 extended 等级 0~2,获得更详细的信息。


4. 故障切换

4.1 查询当前状态

rs.status()

截屏2023-02-22 上午10.42.29.png

4.2 关闭主库实例

因为实验环境 MySQL Shell 和主库部署在同台机器上,所以本次试验通过 kill MySQL 进程进行测试。

kill -9 mysql—pid

此时程序就报出 2003 异常:

ERROR 2003 (HY000): Can't connect to MySQL server on '172.16.104.56:6446' (111)

4.3 使用 AdminAPI 切换

打开 MySQL Sehll 切换为 python 模式,登录到 55 会话:

\c rw_shell@172-16-104-55:3306

获取 ReplicaSet 对象:

rs = dba.get_replica_set()

查询 ReplicaSet 当前状态:

截屏2023-02-22 下午2.53.05.png

此时 MySQL Sehll 已经检测到主库不可用,并建议切换实例:

"PRIMARY instance is not available, but there is at least one SECONDARY that could be force-promoted."

使用 AdminAPi 进行切换:

rs.force_primary_instance('172-16-104-55:3306')

截屏2023-02-22 下午2.56.45-1.png

4.4 恢复 ReplicaSet

故障切换完成后,业务可以正常使用 Router 提供的端口连接,rw/ro 都分配到主库实例,因为当前只剩下主库。

此时需要手动将已恢复到 56 重新添加到 ReplicaSet 中,会自动补全期间的增量数据。

rs.rejoin_instance('172-16-104-56:3306')

截屏2023-02-22 下午3.07.42.png

查询当前 ReplicaSet 状态:

截屏2023-02-22 下午3.08.53.png

验证 MySQL Router 路由,备库恢复后,会自动修改路由策略,ro 端口重新路由到备库。

截屏2023-02-22 下午3.10.04.png


参考资料

【1】https://dev.mysql.com/doc/mysql-shell/8.0/en/mysql-innodb-replicaset.html

【2】https://dev.mysql.com/doc/mysql-shell/8.0/en/admin-api-deploy-router.html

【3】https://dev.mysql.com/doc/refman/8.0/en/replication.html

【4】《MySQL 高可用解决方案》


相关文章

迁移Cloudera Manager节点

迁移Cloudera Manager节点

1.概述1.CDH环境已搭建并正常运行2.旧Cloudera Manager节点包含Cloudera Manager Server(即cloudera-scm-server)服务和Cloudera M...

PG的analyze与vacuum

analyze-统计信息用于收集表的统计信息,只会对表加读锁,不影响表上其它SQL并发执行,对于大表只会读取表中部分数据 vacuum-碎片回收标记旧版本行的信息为可用,以重复使用这部分空间 更新统计...

Helm 控制函数

Helm 控制结构(在模板语言中称为 "actions")提供给你和模板作者控制模板迭代流的能力。 Helm 的模板语言提供了以下控制结构:if/else,用来创建条件语句with,用来指定范围ran...

SQL隐式转换导致索引失效_字符集不一致

3.字符集不一致导致索引失效示例 SQL 如下,通过查看执行计划发现 XXX 和 XXXX 表在进行表关联的时候没有走索引,导致 SQL 扫描数量较大。核实表结构发现表关联对应列都存在索引,最终查看字...

RAC和DG的选择

RAC和DG的选择

RAC和DG的选择一、RAC1、什么是RAC实时应用集群,是负载均衡模式,两台机器同时工作参与到业务系统中,如果其中一个节点出现问题,所有的会话连接会转到另一个节点,保证业务系统正常运行,但是数据只有...

开源大数据集群部署(十七)HADOOP集群配置(二)

开源大数据集群部署(十七)HADOOP集群配置(二)

1 HADOOP集群配置配置文件workers[root@hd1.dtstack.com software]# cd /opt/hadoop/etc/hadoop [root@hd1.dtstack...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。