🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
![伪装的树蛙](https://img.kancloud.cn/00/33/0033515082c1916dcbd4938f16012237_640x375.png) [TOC] ## 一、Canal是如何伪装为mysql的slave的? ### 回顾mysql的主从复制步骤 首先,我觉得我们有必要回顾一下mysql主从复制配置过程的步骤: 1. 主库开启binlog,并创建复制账号; 2. 从库设置复制账号,以及binlog文件和pos位置。 ![](https://img.kancloud.cn/91/09/9109491c19fb2004ba1299f3ae06b9c8_700x323.png) 1、主库创建复制账号 ``` create user 'canal'@'%' identified by 'canal%123'; GRANT SELECT,REPLICATION SLAVE ,REPLICATION CLIENT ON *.* TO 'canal'@'%' IDENTIFIED BY 'canal%123' WITH GRANT OPTION; GRANT SELECT ON performance_schema.* TO 'canal'@'%'; FLUSH PRIVILEGES; select * from mysql.user ``` 如果账户仅用于复制,那么replication slave的权限就足够了,但在本地查看从库(slave server)信息,还需要replication client权限。 ### Canal伪装实现模块 Canal的伪装功能由instance模块实现:一个server有多个instance。每个instance都会模拟成一个mysql实例的slave。instance模块有四个核心组成部分:parser模块、sink模块、store模块,meta模块。核心接口为CanalInstance。 deployer模块主要完成以下功能: 1、读取canal,properties配置文件 2、启动canal server,监听canal client的请求 3、启动canal instance,连接mysql数据库,伪装成slave,解析binlog 4、在canal的运行过程中,监听配置文件的变化 ``` public interface CanalService { //订阅 void subscribe(ClientIdentity clientIdentity) throws CanalServerException; //取消订阅 void unsubscribe(ClientIdentity clientIdentity) throws CanalServerException; //比例获取数据,并自动自行ack Message get(ClientIdentity clientIdentity, int batchSize) throws CanalServerException; //超时时间内批量获取数据,并自动进行ack Message get(ClientIdentity clientIdentity, int batchSize, Long timeout, TimeUnit unit) throws CanalServerException; //批量获取数据,不进行ack Message getWithoutAck(ClientIdentity clientIdentity, int batchSize) throws CanalServerException; //超时时间内批量获取数据,不进行ack Message getWithoutAck(ClientIdentity clientIdentity, int batchSize, Long timeout, TimeUnit unit) throws CanalServerException; //ack某个批次的数据 void ack(ClientIdentity clientIdentity, long batchId) throws CanalServerException; //回滚所有没有ack的批次的数据 void rollback(ClientIdentity clientIdentity) throws CanalServerException; //回滚某个批次的数据 void rollback(ClientIdentity clientIdentity, Long batchId) throws CanalServerException; } ``` ## 二、mysql binlog协议 Canal的成功离不开对mysql binlog协议的解析。mysql协议分析,请看这篇文章:[MySQL协议分析](https://www.cnblogs.com/davygeek/p/5647175.html) > https://github.com/alibaba/canal/wiki/BinlogChange%28mysql5.6%29 ### 伪装原理 MySQL伪装从库只需如下步骤: 1. Dial mysql dsn与mysql建立tcp连接后,ReadInitPacket, 获取auth-data 和版本信息。 2. 根据auth-data,加密用户密码后,WriteAuthPacket, 发送认证包。 3. 获取mysql server响应包,无报错后进入命令模式,向mysql 发送ComRegisterSlave。 4. 此时己经伪装成slave,发送ComBinlogDump,开始接受主库推送的数据。 5. 此时根据业务需求,解析不同event type的binlog,分别处理。 理论比较简单,难点在于高效的处理不同的协义。 ## 三、参考资料 1. [如何伪装为mysql从库](https://max.book118.com/html/2017/0722/123551042.shtm)