
[TOC]
## 一、Canal是如何偽裝為mysql的slave的?
### 回顧mysql的主從復制步驟
首先,我覺得我們有必要回顧一下mysql主從復制配置過程的步驟:
1. 主庫開啟binlog,并創建復制賬號;
2. 從庫設置復制賬號,以及binlog文件和pos位置。

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
- 優質開源項目備忘