1 方案设计

参考文档(GitHub 的 MySQL 高可用性实践分享),

技术细节:

  • 当主库宕掉的时候,orchestrator 不仅会每隔 InstancePollSeconds(默认五秒)监测主库,也会检测从库(通过 select round(absolute_lag) from meta.heartbeat_view”检查,配置文件里自定义语句)。比如,要诊断出主库挂了的情况,必须满足以下两个条件:orchestrator 联系不到主库。登录到主库对应的从库,从库也连不上主库。
  • 使用伪 GTID 的时候需要建一个表专门存放 orchestrator 生成的 GTID,每次写入 binlog 的话会把这个表的 GTID 写进去,如下图

1643075087959

1643075108838

  • orchestrator 没有将错误按时间来进行分类,而是按复制拓扑服务器本身进行分类。当所有的从库都连不上主库的时候,说明复制拓扑被破坏,进行故障转移。
  • 通过 show slave hosts;命令发现实例,然后根据 host:port 访问实例
  • 高可用有两种方式,一直是多个实例一个数据库,只有数据库没宕掉就能正常使用.一直是奇数实例,每个实例都有自己的实例,然后通过 raft 协议保证数据一致性

1.1 环境规划

ip 端口 名称
10.1.1.1 5.6.51 3306 Master /var/lib/mysql/binlog/
10.1.1.2 5.6.51 3306 Slave1 /var/lib/mysql/binlog/
10.1.1.3 5.6.51 3306 Slave2 /var/lib/mysql/binlog/
10.1.1.4 3.2.6-1 3000 orchestrator

这里注意下,mysql 版本,详细分析查看 MySQL 主从同步分析 | 云原生基站

  • 5.6: I/O thread 同步并发线程是以库级别并行的,也就是说两个库可以并行两个线程,三个库可以并行三个线程,但是注意一个库不要开启并行,影响性能.而且就算开启也会存在 slave 同步延迟
  • 5.7: I/O thread 同步并发线程可以做到按行级别并行,线程数量一般与 CPU 数量一样,可以做到 slave 节点无延迟,slave_parallel_workers=4,slave_parallel_type=LOGICAL_CLOCK,这两个参数一定要加上

image-20220310101036147

1.2 先上总结:

此方案实现功能

  • 自身服务支持高可用
  • 自动故障转移
  • 支持自动修改拓扑,比如 slave2 同步过慢自动调整到 slave1 后面减少 master 读取负载
  • 故障转移的时候执行脚本,这点潜力无限
  • 基于 go 开源,可以自己二次开发
  • ui 管理友好

缺点:

  • 学习成本高,配置复杂
名称 MySQL 自己的 gtid orchestrator 的伪 gtid
故障转移 支持 支持
自动定位 binlog 断开位置 支持 不支持,但是可以从数据库查到 binlog 位置
使用限制 主从库的表存储引擎必须是一致的不允许一个 SQL 同时更新一个事务引擎和非事务引擎的表不支持 create table….select 语句复制(主库直接报错)不支持临时表 无限制,只需要在每个实例建个 gtid 表

2 部署 orchestrator

下载地址: Release GA release v3.2.6 · openark/orchestrator · GitHub

sudo yum localinstall -y orchestrator-3.2.6-1.x86_64.rpm

2.1 再 orchestrator 专用 mysql 上创建 orchestrator 需要的库,表会自动生成

1
2
3
CREATE DATABASE IF NOT EXISTS orchestrator;
CREATE USER 'orchestrator_srv'@'%' IDENTIFIED BY 'qweasd';
GRANT ALL ON orchestrator.* TO 'orchestrator_srv'@'%';

2.2 配置 orchestrator

有几个关注的配置:

1
2
3
4
5
6
7
8
9
10
11
12
ListenAddress:"ip:3000", -- web http tpc 监听端口
BackendDB:"mysql", --后端数据库类型,可选mysql或则sqlite3
MySQLOrchestratorPort:3306, --后端数据库端口
MySQLTopologyUser: "orchestrator", --实例监控账户,所有mysql都要有这账号
MySQLTopologyPassword: "qweasd", --实例监控密码
MySQLOrchestratorHost: "10.1.1.1", --orchestrator使用的数据库地址
MySQLOrchestratorPort: 3307, --orchestrator使用的数据库端口
MySQLOrchestratorDatabase: "orchestrator", --orchestrator使用的数据库名称
MySQLOrchestratorUser: "orchestrator_srv", --orchestrator使用的账户
MySQLOrchestratorPassword: "qweasd", --orchestrator使用的密码
ReplicationLagQuery: "select round(absolute_lag) from meta.heartbeat_view", --健康检查sql
AutoPseudoGTID: true, --自动注入伪GTID

完整配置 orchestrator.conf.json

带解释配置 orchestrator.conf.json

如果使用集群模式:

1
2
3
4
5
6
7
8
9
"RaftAdvertise": "mysql-operator-0-svc",
"RaftBind": "mysql-operator-0",
"RaftDataDir": "/var/lib/orchestrator",
"RaftEnabled": true,
"RaftNodes": [
"mysql-operator-0-svc",
"mysql-operator-1-svc",
"mysql-operator-2-svc"
],

2.2.1 启动

1
2
systemctl start orchestrator
systemctl enable orchestrator

2.3 启动报错查看日志

journalctl -xu orchestrator
没问题的话访问 http://ip:3000/

查看状态:

image-20220310101859616

添加服务

1643077735274

1643077940976

查看

1643077909835

3 测试故障转移

停掉 master

orchestrator 上显示 master 断开

1643077816765

4 orchestrator 显示切换信息

1643078029401

4.1 可以看到切换详情

1
2
3
4
5
可以看到主从切换的时候经历了这些操作
1. 摘除原有拓扑关系
2. 判断拓扑丛书关系
3. 选举新的master
4. 所有slave节点指向新的master

1643078108495

老 master 节点正常启动后

1
2
3
CHANGE MASTER TO MASTER_HOST='10.1.1.1',MASTER_USER='orchestrator',MASTER_PASSWORD='qweasd',MASTER_PORT=3306,MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=0;

START SLAVE;

查看最新拓扑图

1643078141329