![伪装的树蛙](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)
- 写在前面
- 如何阅读源码
- 第一部分 开源框架
- Netty
- 启动过程
- SpringSecurityOauth2
- Quartz
- quartz启动原理
- quartz定时调度任务触发流程
- 第二部分 优质中间件源码分析
- Canal
- Canal是如何伪装为mysql的slave的?
- canal源码调试
- Sentinel
- 核心概念梳理
- 滑动窗口实现原理
- jvm-sandbox
- jvm-sandbox-repeater
- Windows环境安装
- 结果比对
- 第三部分 优质行业项目源码分析
- 第一章 分库分表实践
- sharding-jdbc
- 第二章 DDD领域驱动
- 享同科技DDD开源框架
- J-IM
- 功能测试
- 悟空CRM
- 项目搭建
- 默认密码
- dataX-web
- 项目搭建
- 部署报错
- dolphinscheduler
- awescnb
- geek
- chrome插件-funds
- 优质开源项目备忘