修改Canal的消費位點指南

 日常的使用中,當使用 ZooKeeper 作爲高可用方案時,因某些原因需要重新採集數據,只要目標庫中的 binlog 文件依舊存在,那麼就能夠將 Canal 的解析位置重新定位,從指定的位置開始解析。
 Canal 默認在 ZooKeeper 中存儲的節點爲:

/otter/canal

一、停止 Canal 服務

 在有數據被消費時,客戶端的每次 Ack 都會使得服務端用本地緩存的位點信息去覆蓋 ZooKeeper 上的位點,所以在修改 ZooKeeper 的位點之前,應先避免其不再被覆蓋,即停止 Canal 服務。

亦可停止該 instance 對應的消費端程序,則不會再觸發服務端使用緩存中的位點信息去覆蓋 ZooKeeper 中的信息。

二、獲取位點信息

 停止服務後,可通過 zkCli.shZooInspectorzkui 等工具連接到相應的 ZooKeeper 服務器上,並獲取到當前的位點信息。
 默認情況下,位點信息存儲在下述節點中:

/otter/canal/destinations/${destination}/1001/cursor

注意:請將 ${destination} 替換成預期的 instance 名稱。

若 ZooKeeper 中並無 …/1001/cursor 節點,則表明該 instance 從未被消費過,可通過啓動一次對應的消費者,以生成該位點信息,但記得生成位點信息後要將其停止。

 本文僅以 zkCli.sh 方式示例如何獲取名爲 “example” 的 instance 的位點信息:

get /otter/canal/destinations/example/1001/cursor

 獲取到的位點信息結果爲:

{"@type":"com.alibaba.otter.canal.protocol.position.LogPosition","identity":{"slaveId":-1,"sourceAddress":{"address":"localhost","port":3306}},"postion":{"gtid":"","included":false,"journalName":"mysql-bin.000010","position":210013,"serverId":1,"timestamp":1590112037000}}

 從上述的結果可看出,位點信息是用 json 格式的字符串進行存儲的,裏面存放了許多信息,我們僅需要變更journalName”和“position”兩個屬性值,分別對應當前的 binlog 文件名以及該文件內的具體位置。

三、查詢數據庫位點

 我們既然已經確定了變更位點需要哪些信息,那麼又如何獲得預期的位點信息呢?這就需要視需求而定了,其實,一般來變更位點都是往當前位置的前面調整,再次採集已同步過的數據。本文僅給出如何在 MySQL 中通過 SQL 語句查詢 binlog 的位點信息示例:

  1. 查詢 binlog 文件

    show binary logs
    

     上述命令用於列出該 MySQL 服務當前有效的二進制日誌文件信息,具體輸出內容如下:

    Log_name File_size
    mysql-bin.000001 52302
    mysql-bin.000002 16902
    mysql-bin.000003 49094
    mysql-bin.000004 130772
    mysql-bin.000005 3492

     此處的輸出結果僅爲 binlog 文件名稱和大小,該如何確定具體的該使用哪個文件的哪個位置呢?請稍安勿躁,此步驟僅是爲了下一步作鋪墊。

  2. 查詢 binlog 事件
     binary log,顧名思義就是二進制日誌文件,裏面存放的信息無法直接被展示出來,但我們可以通過 MySQL 的 SQL 語句將其解析成對應的事件,通過判斷事件來找出對應的位點信息。
     用於查詢 binlog 事件的 SQL 語法如下:

    show binlog events [in 'binlog_name'] [from pos] [limit [offset,] row_count]
    

    在查詢 binlog 事件時,強烈建議儘可能多地增加限制結果集大小的條件,以降低對 MySQL 的性能損耗,這就是有1. 查詢 binlog 文件步驟的原因,爲此步驟提供信息。

     下述示例表示列出名爲“mysql-bin.000008”的文件內從第 4 個位點開始往後的 5 條記錄。

    show binlog events in 'mysql-bin.000008' from 4 limit 5
    

     輸出的結果爲:

    Log_name Pos Event_Type Server_id End_log_pos Info
    mysql-bin.000008 4 Format_desc 1 123 Server ver: 5.7.27-log, Binlog ver: 4
    mysql-bin.000008 123 Previous_gtids 1 154
    mysql-bin.000008 154 Anonymous_Gtid 1 219 SET @@SESSION.GTID_NEXT= ‘ANONYMOUS’
    mysql-bin.000008 219 Query 1 292 BEGIN
    mysql-bin.000008 292 Table_map 1 351 table_id: 109 (test2.user_info)

    當前僅能通過判斷具體的事件,來確定對應的位點值(Pos)。

四、變更位點信息

 假設我們需要的目標位點信息是:名爲 mysql-bin.000008 的日誌文件內位點值爲 4。那麼通過 zkCli.sh 的 set 方法進行變更,示例如下:

set /otter/canal/destinations/example/1001/cursor {"@type":"com.alibaba.otter.canal.protocol.position.LogPosition","identity":{"slaveId":-1,"sourceAddress":{"address":"localhost","port":3306}},"postion":{"gtid":"","included":false,"journalName":"mysql-bin.000008","position":4,"serverId":1,"timestamp":1590112037000}}

注意:節點名與節點值之間使用一個半角空格進行分隔。

五、啓動 Canal 服務

 啓動 Canal 服務端,以使新的位點生效。

如果之前通過停止消費端的方式來消除位點被覆蓋,那麼此時就需要通過重啓 Canal 服務端將 ZooKeeper 上新的位點信息去覆蓋 Canal 服務端緩存中的信息。

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