一 实验背景
有一套Mysql主从复制架构,想实现当主库宕机后,canal能自动指向从库继续同步。
二 实验环境
--canal版本1.1.4
三 实验步骤
3.1 前提条件
- 确保MairaDB主从是双向复制,即互相指向对方进行复制,否则当主库(逻辑上的概念)宕机,canal指向从库进行复制,源主库恢复后,中间的数据变更会丢失。
- 确保源端主从数据库都开启log_slave_updates=on
- 确保源端MairaDB主库故障后,从库可写
3.2 配置canal server
3.2.1 开启心跳检测
从canal admin管理界面上配置canal server:
## detecing config
canal.instance.detecting.enable = true #开启心跳检查
#canal.instance.detecting.sql = insert into retl.xdual values(1,now()) on duplicate key update x=now()
canal.instance.detecting.sql = select 1 #心跳检查sql
canal.instance.detecting.interval.time = 30 #心跳检查频率,单位是秒
canal.instance.detecting.retry.threshold = 4 # 心跳检查失败次数阀值,超过该阀值后会触发mysql链接切换,比如切换到standby机器上继续消费binlog
canal.instance.detecting.heartbeatHaEnable = true # 心跳检查超过失败次数阀值后,是否开启master/standby的切换
注意:
a. 填写master/standby的地址和各自的起始binlog位置,目前配置只支持一个standby配置.
b. 发生master/standby的切换的条件:(heartbeatHaEnable = true) && (失败次数>=retry.threshold).
c. 多引入一个heartbeatHaEnable的考虑:开启心跳sql有时候是为client检测canal server是否正常工作,如果定时收到了心跳语句,那说明整个canal server工作正常
3.2.2 配置canal.instance.tsdb
3.2.2.1 修改canal server操作系统上的canal properties文件
cd /opt/canal-server/conf
vi canal.properties
添加:
canal.instance.tsdb.url = jdbc:mysql://192.168.144.248:3306/canal_manager
canal.instance.tsdb.dbUsername = canal
canal.instance.tsdb.dbPassword = canal
#需要提前在canal admin所依赖的mariadb数据库(canal_manager所在数据库)上创建canal用户,需要如下权限:
GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%' IDENTIFIED BY 'canal';
GRANT SELECT, INSERT, UPDATE,DELETE,CREATE,ALTER ON `canal_manager`.* TO 'canal'@'%';
#重启canal server使之生效
sh /opt/canal-server/bin/stop.sh
sh /opt/canal-server/bin/startup.sh
3.2.2.2 通过canal admin管理界面配置canal server
确保类似如下配置:
3.3 配置canal instance
canal.instance.standby.address=192.168.144.247:3306
3.4 验证
关闭源端主库,canal instance日志报错:
ERROR com.alibaba.otter.canal.common.alarm.LogAlarmHandler - destination:baidd-test[com.alibaba.otter.canal.parse.exception.CanalParseException: java.io.IOException: connect /192.168.144.246:3306 failure
Caused by: java.io.IOException: connect /192.168.144.246:3306 failure
稍后看到开始主从切换:
2021-04-10 03:42:17.235 [destination = mubai-test , address = /192.168.144.246:3306 , HeartBeatTimeTask] WARN c.a.o.c.p.inbound.mysql.rds.RdsBinlogEventParserProxy - try to ha switch, old:192.168.144.246/192.168.144.247:3307, new:192.168.144.247/192.168.144.246:3306
2021-04-10 03:42:17.235 [destination = mubai-test , address =/192.168.144.246:3306 , HeartBeatTimeTask] ERROR com.alibaba.otter.canal.common.alarm.LogAlarmHandler - destination:mubai-test[try to ha switch, old:192.168.144.246/192.168.144.247:3306, new:192.168.144.247/192.168.144.244:3306]
……
2021-04-10 03:42:17.427 [destination = mubai-test , address = 192.168.144.244/192.168.144.244:3307 , EventParser] WARN c.a.o.c.p.inbound.mysql.rds.RdsBinlogEventParserProxy - --->find start position successfully, EntryPosition[included=false,journalName=mysql-bin.000003,position=6996,serverId=2,gtid=52bf92bc-991c-11eb-ba94-080027cdd386:1-47,d8cd7372-9919-11eb-84ed-0800279df615:1-22,timestamp=1617997192000] cost : 50ms , the next step is binlog dump
#上面找到的这个gtid和binlog position是记录的主库宕机时刻的gtid值,the next step is binlog dump表示下一步开始dump binlog,会从上面gtid的下一个位置开始dump binlog。
已验证,当主库192.168.144.246恢复后,canal仍然连从库192.168.144.247进行同步,所以是比较稳定的;当重启了该canal instance后,canal会重新加载配置文件,指向原主库192.168.144.246进行同步。
--备注:
使用canal同步,若想使用canal.instance.standby.address这一特性(即想实现源端数据库主库宕机后,自动将canal指向从库继续进行同步),源端数据库请勿使用mariadb,请使用mysql。
通过查看代码发现,canal 1.1.4不兼容mariadb的gtid,目前canal 1.1.5已支持mariadb的gtid。