全部產品
Search
文件中心

Hologres:訂閱Hologres Binlog

更新時間:Aug 17, 2024

當您需要捕獲Hologres資料庫事件,用於資料之間的複製、同步或將這些事件作為訊息流程轉寄給不同的消費者處理時,Hologres支援Binlog功能,消費Hologres Binlog來提升資料複用能力,縮短資料加工端到端延遲。本文為您介紹在Hologres訂閱Hologres Binlog及相關操作。

Binlog介紹

Hologres同傳統MySQL資料庫一樣,支援通過Binlog記錄資料庫中所有資料的變化事件記錄。通過Hologres Binlog,可以非常方便靈活的實現資料之間的複製、同步。但是Hologres Binlog一般只用於資料同步,而傳統資料庫Binlog還應用於主從執行個體同步和資料恢複等高可用情境。因此兩者地實現存在一定差別,主要體現在以下方面:

  • Hologres Binlog不會記錄DDL操作。

  • Hologres Binlog較為靈活,是表層級的,可以按需開啟和關閉,且可以為不同的表設定不同的TTL。

  • Hologres作為分布式的即時數倉,Binlog同樣也是分布式的。

  • Hologres Binlog可以非常方便地進行查詢。

同時在巨量資料情境上,支援Flink直接消費Hologres Binlog,相較於傳統數倉分層,Flink+Hologres Binlog可以實現完整的事件驅動,完成操作資料儲存層(ODS)向資料倉儲維度層(DWD)、DWD向資料服務層(DWS)等的全即時加工作業,滿足分層治理的前提下統一儲存,提升資料複用能力,並且縮短資料加工端到端延遲,為使用者提供一站式的即時資料倉庫解決方案。

使用限制

在Hologres中訂閱Hologres Binlog需要注意如下事項:

  • 僅Hologres V0.9及以上版本支援訂閱Hologres Binlog,如果您的執行個體是V0.9以下版本,請您加入線上支援DingTalk群,詳情請參見如何擷取更多的線上支援?

  • Hologres V0.9以及V0.10版本,已存在的表無法修改表屬性開啟Binlog,需重建立表。從V1.1版本開始,可以按需開啟Binlog。

  • Hologres V1.3.14和V1.1.82之前的版本僅支援Superuser消費Binlog,如果使用其他低許可權帳號消費Binlog會出現沒有許可權的報錯:permission denied for table hg_replication_slot_properties。從Hologres V1.3.14和V1.1.82版本開始,若使用Flink消費Binlog,僅需帳號具備查詢表的許可權即可。對於使用JDBC消費Hologres Binlog需要帳號在Replication Role中。

  • Hologres支援單表層級的Binlog功能,支援行存表和列存表。當前訂閱Hologres Binlog支援的情況如下表。

    Flink分類

    Hologres行存表Binlog

    Hologres列存表Binlog

    Hologres行列共存表Binlog(從Hologres V1.1版本開始支援)

    Realtime ComputeBlink

    支援

    支援

    支援

    全託管Flink

    支援

    支援

    支援

    開源Flink

    不支援

    不支援

    不支援

    JDBC

    Hologres V1.1版本開始支援

    Hologres V1.1版本開始支援

    Hologres V1.1版本開始支援

  • Blink消費Hologres Binlog暫不支援Hologres的TIMESTAMP類型,在Hologres建表時,請使用TIMESTAMPTZ類型。同時也不支援SMALLINT等特殊類型。

  • 不支援消費分區表父表的Binlog,請使用分區子表或者普通表(非分區表)。Hologres從 V1.3.24版本開始,支援按需修改分區子表的Binlog TTL,若是沒有顯式指定分區子表的Binlog TTL,則與父表的Binlog TTL保持一致。同時需要注意Binlog TTL不是精準的時間,系統不會強保證Binlog到期後立馬刪除Binlog,將會在到期後的某個時間刪除。

  • 對於更新頻繁的情境,理論上列存表開啟Binlog的開銷要大於行存表的開銷,所以建議使用行存表開啟Binlog。

  • 僅Hologres內部表支援開啟Binlog,外部表格不支援開啟Binlog。

Binlog格式與原理

Binlog記錄由Binlog系統欄位和使用者Table欄位組成,具體欄位定義如下表。

欄位名稱

欄位類型

說明

hg_binlog_lsn

BIGINT

Binlog的系統欄位,表示Binlog序號。Shard內部單調遞增不保證連續,不同Shard之間不保證唯一和有序。

hg_binlog_event_type

BIGINT

Binlog的系統欄位,表示當前Record所表示的修改類型。

  • hg_binlog_event_type有如下4種可能的取值:

    • INSERT=5,表示當前Binlog為插入一條新的記錄。

    • DELETE=2,表示當前Binlog為刪除一條已有的記錄。

    • BEFORE_UPDATE=3,表示當前Binlog為一條已有記錄其更新前的記錄。

    • AFTER_UPDATE=7,表示當前Binlog為一條已有記錄其更新後的記錄。

hg_binlog_timestamp_us

BIGINT

Binlog的系統欄位,系統時間戳,單位為us。

user_table_column_1

使用者自訂

使用者Table欄位。

...

...

...

user_table_column_n

使用者自訂

使用者Table欄位。

  • UPDATE操作會產生兩條Binlog記錄,分別為更新前和更新後的記錄。訂閱Binlog功能會保證這兩條記錄是連續的且更新前的Binlog記錄在前,更新後的Binlog記錄在後。

  • 通過Hologres Connector(如Holo Client、Flink Connector、Data Integration)等方式執行的UPDATE,Connector會將BEFORE_UPDATE翻譯為DELETE,將AFTER_UPDATE翻譯為INSERT,因此在hg_binlog_event_type欄位中看到的是2,5,但Connector會保證資料的最終一致性。

  • 只有純SQL方式執行UPDATE,hg_binlog_event_type欄位的記錄是BEFORE_UPDATE和AFTER_UPDATE。

Hologres的Binlog可以看作是一張特殊的行存表,為某張表開啟Binlog,可以理解為是新建立了一張以hg_binlog_lsn為Key, 業務表原有欄位、hg_binlog_event_type以及hg_binlog_timestamp_us欄位則組合起來作為Value的行存表。Binlog表的欄位是固定的,也可以說是強Schema的,使用者欄位順序與業務表DDL定義的順序一致。因此建議開啟Binlog的表使用行存表或者行列共存表,會使得讀Binlog時會有更好的效能。

開啟Binlog

Hologres中,Binlog功能預設關閉,您可以通過設定表屬性binlog.levelbinlog.ttl開啟該功能。如下樣本開啟Binlog,更多關於建立表的參數說明,請參見CREATE TABLE

說明

理論上列存表開啟Binlog功能的成本要大於行存表。如果您對錶格的更新比較頻繁,建議您使用行存表開啟Binlog功能。

  • V2.1版本起支援的文法:

    binlog.levelbinlog.ttl表屬性名稱更新為binlog_levelbinlog_ttl

    CREATE TABLE test_message_src (
        id int PRIMARY KEY,
        title text NOT NULL,
        body text
    )
    WITH (
        orientation = 'row',
        clustering_key = 'id',
        binlog_level = 'replica',
        binlog_ttl = '86400' -- Binlog的TTL,單位為秒
    );
  • 所有版本支援的文法:

    begin;
    create table test_message_src(
      id int primary key, 
      title text not null, 
      body text);
    call set_table_property('test_message_src', 'orientation', 'row');--建立行存表test_message_src
    call set_table_property('test_message_src', 'clustering_key', 'id');--在id列建立聚簇索引
    call set_table_property('test_message_src', 'binlog.level', 'replica');--設定表屬性開啟Binlog功能
    call set_table_property('test_message_src', 'binlog.ttl', '86400');--binlog.ttl,Binlog的TTL,單位為秒
    commit;

參數說明如下。

參數

說明

binlog_levelbinlog.level

是否開啟Binlog,可選擇:

  • replica:開啟。

  • none:關閉。

binlog_ttlbinlog.ttl

Binlog的TTL,單位秒。預設為30天,即預設值為2592000。

按需開啟Binlog

從Hologres V1.1版本開始,可以根據業務需要選擇開啟/關閉Binlog能力,同時支援配置TTL滿足不同業務情境對Binlog保留時間的訴求,已有表無需重建立表就能開啟Binlog,操作方便快捷。

說明

以下功能僅針對Hologres V1.1及以上版本,如果您的執行個體是V1.1以下版本,請您使用自助升級或加入HologresDingTalk交流群反饋,詳情請參見如何擷取更多的線上支援?

  • 開啟Binlog

    可以使用以下語句對已有表開啟Binlog並設定Binlog TTL時間。

    -- 設定表屬性開啟Binlog功能
    begin;
    call set_table_property('<table_name>', 'binlog.level', 'replica');
    commit;
    
    -- 設定表屬性,配置Binlog TTL時間,單位秒
    begin;
    call set_table_property('<table_name>', 'binlog.ttl', '2592000');
    commit;

    table_name為開啟Binlog的表名稱。

  • 關閉Binlog

    可以使用以下語句對已開啟Binlog的表關閉Binlog。

    -- 設定表屬性關閉Binlog功能
    begin; 
    call set_table_property('<table_name>', 'binlog.level', 'none'); 
    commit; 

    table_name為需要關閉Binlog的表名稱。

  • 修改Binlog的TTL

    通過以下語句可以對已開啟Binlog的表修改TTL,滿足業務對Binlog不同保留時間的訴求。

    說明

    Hologres從 V1.3.24版本開始,支援按需開啟分區子表的Binlog TTL。如果沒有顯示修改子表的Binlog TTL,則預設與父表的Binlog TTL保持一致。

    call set_table_property('<table_name>', 'binlog.ttl', '8640000'); --單位秒

    table_name為修改Binlog TTL的表名稱。

查詢Binlog

Hologres表的Binlog資料採用強Schema格式。要查詢特定表的Binlog,可通過將Binlog內建額外欄位與表原有欄位進行組合來實現。此外,Hologres還提供了一些函數,以便查詢最新或最早的Binlog,或者通過已知的LSN和TIMESTAMP來查詢相應的Binlog資訊。

通過內建特殊欄位直接查詢Binlog

使用Binlog內建額外欄位與表原有欄位組合的方式查詢Binlog,樣本如下。

SELECT hg_binlog_lsn,hg_binlog_event_type,hg_binlog_timestamp_us,* FROM test_message_src;

查詢結果樣本如下。

image

查詢表指定Shard上最早或最新的Binlog

使用hg_get_binlog_cursor函數的方式查詢Binlog,文法如下。

-- OLDEST,此shard上最早的Binlog
SELECT * FROM hg_get_binlog_cursor('<table_name>','OLDEST',<shard_id>);

-- LATEST,此shard上最新的Binlog
SELECT * FROM hg_get_binlog_cursor('<table_name>','LATEST',<shard_id>);

樣本如下。

SELECT * FROM hg_get_binlog_cursor('test_message_src','OLDEST',0);

查詢結果樣本如下。

image

通過Binlog LSN查詢相應Binlog的時間戳記

使用hg_get_binlog_cursor_by_lsn函數查詢相應Binlog的時間戳記,可返回大於等於所查詢LSN(記錄序號)的第一條Binlog的資訊,如果當前LSN不存在,返回結果中的hg_binlog_timestamp_us欄位是目前時間。文法如下。

SELECT * FROM hg_get_binlog_cursor_by_lsn('<table_name>',<lsn>,<shard_id>);--LSN值(bigint類型)

樣本如下。

SELECT * FROM hg_get_binlog_cursor_by_lsn('test_message_src',152,0);

查詢結果樣本如下。

image

通過Binlog TIMESTAMP查詢相應Binlog的LSN

使用hg_get_binlog_cursor_by_timestamp函數查詢相應Binlog的LSN,可返回大於等於所查詢時間的第一條Binlog的資訊,如果已經是最新的,返回結果中的hg_binlog_timestamp_us欄位是目前時間,hg_binlog_lsn欄位是下一條資料插入時將會分配的LSN。文法如下。

說明

如果傳入的TIMESTAMP大於目前時間(now()函數返回的時間),SQL查詢會拋出異常"get binlog cursor in future time"。

SELECT * FROM hg_get_binlog_cursor_by_timestamp('<table_name>',<timestamp>,<shard_id>);

樣本如下。

SELECT *,to_timestamp(hg_binlog_timestamp_us/1000000.0) FROM hg_get_binlog_cursor_by_timestamp('test_message_src','2024-05-20 19:34:53.791+08',0);

查詢結果樣本如下。

image

即時消費Hologres Binlog

當前支援通過Flink、Blink以及JDBC(包括Holo Client)消費Hologres Binlog,詳情請參見文檔:

查看開啟了Binlog的表

您可以使用如下SQL查看哪些表開啟了Binlog。

SELECT
    *
FROM
    hologres.hg_table_properties
WHERE
    property_key = 'binlog.level'
    AND property_value = 'replica';

返回結果樣本如下。開啟了binlog的表

查看Binlog儲存空間大小

  • Hologres支援通過pg_relation_size函數擷取表格儲存體空間的大小,該大小包括了Binlog儲存空間的大小,詳情請參見查看錶的儲存大小

  • Hologres從V2.1版本開始,支援通過hologres.hg_relation_size函數查看錶的明細儲存,包括資料、Binlog等儲存明細,詳情請參見查看錶儲存明細

關閉表DML過程中的Binlog

通過如下GUC可以使某個表在DML過程中不產生Binlog。Session層級開啟,需添加在DML前一起執行。

--session層級開啟
SET hg_experimental_generate_binlog=off;