mysql的binlog解析

  1. binlog是什麼

    mysql用於主從同步的二進制日誌,主服務器數據發生更新後會把變動記錄binlog文件,然後從服務器會拉取binlog文件解析,實現數據同步。
    
  2. Binlog記錄更新的方式

  3. Statement:文件中存的是sql語句,優點是傳輸的數據量比較少,缺點是很難保證主從一致。比如rand()會在不同的地方產生不同的值。
  4. Row:文件中存的是更新的那一行的數據內容,優點是不會出錯,缺點是傳輸的數據量比較大
  5. Mixed:兼顧兩種優點,會產生歧義的用row模式,不會產生歧義的用state模式
    我們這裏要解析的是row模式的binlog,sql語句解出來對我們並沒有什麼用

  6. 解析的目的

    針對一些需要頻繁在數據庫中查找的數據,在內存或者redis中維護一塊緩存鏡像,通過解析binlog實現鏡像數據的增量同步。

  7. 利用mysql內部通訊協議獲取binlog

  8. 拉取過程:連接mysql服務器後,發送一個請求包過去,然後就對那個socket一直不斷的拉取數據。
  9. 請求包的格式:3字節的包長 + 1字節的 seq + payload
  10. payload
字段類型 字段名 字段說明
1 [12] COM_BINLOG_DUMP dump命令,值爲12
4 binlog-pos 請求的binglog的位置,server從這個位置開始返回數據流
2 flags 0x01表示非阻塞,沒有新數據時會返回eof_packet,默認爲阻塞
4 server-id 從服務器的server-id
string[EOF] binlog-filename 請求的binglog文件名

注意:flag 設爲0x00 在Maria db 表現還是爲非阻塞,請在mysql上測試。

發送包的組包代碼如下

int32_t bus_dump_cmd_t::write_packet(int fd)
    {
        char buf[1024];
        uint32_t bodysz = 0;
        uint32_t offset = 4;
        buf[offset] = _cmd;
        bodysz += 1;
        int4store(buf + offset + bodysz, _binlog_pos);
        bodysz += 4;
        int2store(buf + offset + bodysz, _flags);
        bodysz += 2;
        int4store(buf + offset + bodysz, _server_id);
        bodysz += 4;

        std::size_t binlog_filename_len = _binlog_filename.size();
        memcpy(buf + offset + bodysz, _binlog_filename.c_str(), binlog_filename_len);
        bodysz += binlog_filename_len;

        /* set seq id */
        buf[offset - 1] = 0x00;

        int3store(buf, bodysz);

        int ret = write(fd, buf, bodysz + 4);
        if (ret != int(bodysz + 4))
        {
            g_logger.error("write dump cmd packet fail, error:%s", strerror(errno));
            return -1;
        }
        return 0;
    }
  • 返回包的格式
  • 3 字節包長 + 1字節的seq + 一字節狀態碼 + event
  • 包長爲 小端模式
  • 狀態碼 有兩個 0x00 表示後面是正常event, 0xff 表示是一個 ERR_packet,裏面是一些錯誤信息。
  • 錯誤包的格式
Type Name Description
int<1> header [ff] header of the ERR packet
int<2> error_code error-code
if capabilities & CLIENT_PROTOCOL_41 {
string[1] sql_state_marker marker of the SQL State
string[5] sql_stateSQL State
}
string error_message human readable error message

如上圖所示,有 2字節的錯誤碼 + 6字節的狀態碼 + 一串錯誤信息

詳細的代碼和文檔

https://github.com/liujian0616/binlogsub

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章