You need to enable JavaScript to run this app.
ByteHouse Cloud Data Warehouse Version

ByteHouse Cloud Data Warehouse Version

Copy page
Download PDF
Data subscription (Binlog)
Subscribe to ByteHouse CDW Binlog
Copy page
Download PDF
Subscribe to ByteHouse CDW Binlog

To capture events from the ByteHouse Cloud Data Warehouse (CDW) Database for Data Copy and Sync between Data, or to forward these Events as Message streams to different consumers for Processing, ByteHouse provides the Binlog Function. Consuming ByteHouse CDW Binlog can enhance data reuse capabilities and allows detection of insert, delete, and update operations on related ByteHouse CDW tables. This article will explain how to subscribe to the Binlog and related operations in ByteHouse.

Binlog introduction

ByteHouse CDW Binlog is similar to MySQL Binlog and supports recording all data change event logs in the Database. With ByteHouse CDW Binlog, Data Copy and Sync can be achieved very conveniently and flexibly. However, ByteHouse CDW Binlog is typically only used for Data synchronization, while MySQL Binlog is also used for primary and secondary instance synchronization, data recovery, and other high-availability scenarios. Therefore, there are certain differences in their implementation, mainly reflected in the following aspects:

  • ByteHouse CDW Binlog does not record DDL operations.
  • ByteHouse CDW Binlog is more flexible, operates at the table level, can be enabled as needed, and allows different Binlog TTL (time-to-live) settings for different tables.
  • ByteHouse CDW Binlog can be queried very easily.

Meanwhile, in big data scenarios, Flink can directly consume ByteHouse CDW Binlog. Compared to traditional data warehouse layering, Flink + ByteHouse CDW Binlog enables complete event-driven processing, achieving real-time processing from the operational data storage layer (ODS) to the data warehouse dimension layer (DWD), from DWD to the data service layer (DWS), and so on. This meets the requirements of layered governance, achieves unified storage, enhances data reuse, shortens end-to-end data processing latency, and provides users with a one-stop real-time data warehouse solution.
ByteHouse CDW Binlog recommended use cases are as follows:

  • Target scenarios: support downstream subscription, for example, ByteHouse ELT calculation results flowing back to the TP Database, together with Flink supporting complete event-driven processing.
  • Non-target scenarios: ByteHouse's own data synchronization/cross-region replication.

Usage limitations
  1. Please ensure that the ByteHouse CDW engine version you are using is v2.3.1 or above. You can log in to the ByteHouse CDW console, click the top Tenant management tab, and view the engine version in Basic info. Launching the Binlog function with an engine version lower than this will result in an error. To upgrade, please submit a ticket.

  2. Currently, only CnchMergeTree is supported. For new tables, the ENGINE must be set to CnchMergeTree when creating; for existing tables, you can use the following command to query the table engine in use.

    SHOW CREATE TABLE your_table_name;
    
  3. ByteHouse CDW Binlog is at the table level, and DDL actions are not recorded.

  4. After ByteHouse CDW Binlog is activated, it cannot be terminated. Please evaluate business requirements before activating. To terminate after activation, please submit a ticket to contact the ByteHouse team.

  5. Function list of supported (✅) and not supported (❌) Binlog output.

    Statement

    Non-unique key table

    Unique key table

    INSERT

    ✅

    UPSERT, partial column update

    ❌

    ✅

    UPDATE、DELETE

    ❌

    ✅

    DDL

    1. CREATE TABLE
    2. DROP/UNDROP TABLE
    3. ADD/DROP/MODIFY COLUMN
    4. TRUNCATE
    5. ALTER PARTITION / PART (ATTACH/DETACH/DROP)

    ❌

    TTL expression

    ❌

    tip

    Data deleted by TTL expressions does not generate Binlog.

  6. Currently, ByteHouse CDW Binlog only supports incremental data consumption. Unified full incremental consumption scenarios are not supported yet.

Binlog format and principles

Binlog publishing and data storage

After activating Binlog, when executing Data Manipulation Language (DML), ByteHouse will perform write, delete, or update operations on the original table, and simultaneously write to Binlog, converting the generated data into Binlog and assigning a BSN (Binlog Sequence Number).
Image

  • Data written to ByteHouse forms parts (data fragments), each fragment contains part of the data. Binlog data is also stored as parts, and the data of the original table and Binlog each have independent TTL and GC (garbage collection).
  • Binlog publishing runs asynchronously. Background tasks periodically convert table data updates into Binlog and publish them (assigning BSN). After a table data change, the corresponding Binlog message is generally visible after 500ms to 5s.

warning

After enabling Binlog, DML operations need to be performed on both the original table and the Binlog, which will have some impact on write performance. In addition, Binlog data itself will occupy some storage space. Please enable Binlog as needed and configure an appropriate time-to-live (TTL).

Binlog field description

Binlog records consist of Binlog system fields and user table fields. The specific field definitions are shown in the following table.

Column name

Data type

Description

_binlog_bsn & _part_row_number

UInt64

Binlog system fields that indicate the BSN of the Binlog to which the current record belongs and the row number within that BSN.

  • _binlog_bsn and _part_row_number together uniquely identify a Binlog record.
  • _binlog_bsn starts from 1 and increments consecutively; _part_row_number starts from 0 and increments consecutively.
  • Both columns are virtual, do not occupy storage space, and are not displayed by default in queries; to query these columns, you must specify them explicitly.

binlog_shard_id

UInt16

Binlog system field that indicates the shard number of the Binlog to which the current record belongs. This is used to support multiple consumers for parallel consumption (each consumer thread reads data within its own binlog_shard_id).

  • The number of binlog_shard_id values is determined by the table-level configuration binlog_shard_num (for details, see parameter descriptionParameter description (table-level configuration)).
    • For tables with a defined unique key, binlog_shard_id is calculated as the hash value of the unique key modulo binlog_shard_num.
    • For tables without a defined unique key, binlog_shard_id is calculated as the hash value of the sorting key modulo binlog_shard_num.
  • Data within a Binlog part is sorted in ascending order by this column. This sorting improves the read speed for data in a specific shard during queries.

binlog_event_type

Enum8

Binlog system field that indicates the type of change represented by the current record. There are 4 possible values:

  • 'I': Insert, indicates the current record is an insertion of a new record.
  • 'D': Delete, indicates the current record is the deletion of an existing record.
  • 'U-': Update Before, indicates the current record is the state before updating an existing record.
  • 'U+': Update After, indicates the current record is the state after updating an existing record.

tip

Update operations generate two Binlog records, corresponding to the record before and after the update ('U-' and 'U+'). The ByteHouse Binlog function ensures that these two records belong to the same BSN, are consecutive, and that U- comes before U+.

user_table_column_1

User-defined

User table field.

...

...

...

user_table_column_n

User-defined

User table field.

Binlog configuration and activation

Parameter description (table-level configuration)

ByteHouse Binlog supports configuration of the following parameters:

Configuration

Required

Default

Description

enable_binlog

Yes

0

Whether to enable Binlog. If this parameter is set to 1, Binlog is enabled; if set to 0, Binlog is not enabled. Once enabled, it cannot be disabled.

binlog_lifetime

No

86400

TTL of Binlog, in seconds.

binlog_shard_num

No

64

The number of Binlog shards, used to increase the parallelism of Binlog consumption. Supports Flink multi-consumer parallel consumption**.** This parameter must be set before enabling Binlog via the enable_binlog parameter, or set at the same time as enabling Binlog. After Binlog is enabled, this parameter cannot be modified independently.

binlog_row_deduplicate

No

false

After enabling this option, if the values before and after an update ('U-' and 'U+') are completely identical, Binlog will not output these records.
This function does not affect write performance. After filtering out a large amount of redundant Data, it may improve write performance to some extent by reducing disk I/O.

warning

This configuration change only takes effect for newly generated Binlogs and does not affect historical Binlogs.

Enable Binlog

  • Example 1: Enable Binlog when creating a new table.

    CREATE TABLE binlog_test(
        `id` Int32,
        `a` Int64,
        `b` String
    )
    ENGINE = CnchMergeTree
    ORDER BY a
    UNIQUE KEY id
    SETTINGS
    enable_binlog = 1, -- Required, enable Binlog
    binlog_lifetime = 86400, -- Optional
    binlog_shard_num = 4, -- Optional
    binlog_row_deduplicate = false; -- Optional
    
  • Example 2: Enable Binlog for existing tables.

    ALTER TABLE binlog_test MODIFY SETTING binlog_lifetime = 3600; -- Optional, adjust TTL
    ALTER TABLE binlog_test MODIFY SETTING binlog_shard_num = 4; -- Optional, adjust the number of shards
    ALTER TABLE binlog_test MODIFY SETTING enable_binlog = 1; -- Required, enable Binlog
    

Change Binlog configuration

After enabling Binlog, you can use ALTER TABLE to modify Binlog configuration.

Adjust Binlog TTL

ALTER TABLE binlog_test MODIFY SETTING binlog_lifetime = 7200; 

Records with identical values before and after update do not output Binlog.

ALTER TABLE binlog_test MODIFY SETTING binlog_row_deduplicate = true; 

Query Binlog

ByteHouse supports viewing all Binlog data for a table, and also supports querying Binlog for a specified BSN range only. If you are not sure about the BSN range, you can first query the system table system.cnch_table_info to determine the BSN range to query. You can also query system tables system.cnch_binlogs to view detailed information about the corresponding binlog part. For example, you can query the number of shard records in the current binlog part in advance and customize your reading behavior accordingly to improve query efficiency.
After enabling Binlog, you can query the Binlog of a table by adding $binlog after the table name. For example, you can query the Binlog of db_test.binlog_test using the following SQL statement.

SELECT * FROM db_test.binlog_test$binlog; 

ByteHouse supports querying Binlog within a specified BSN range. When querying, you need to add a hint in the form bsn(table_name$binlog, A, B), indicating that you are querying the Binlog whose BSN range in the table is within (A,B]. For example, you can query the Binlog in db_test.binlog_test where BSN is 2 or 3 using the following command.

SELECT /*+ bsn(db_test.binlog_test$binlog, 1, 3) */ * FROM db_test.binlog_test$binlog; 

The following examples demonstrate how to query Binlog in several common scenarios.
Suppose we have already executed some DML operations on the table db_test.binlog_test:

INSERT INTO binlog_test VALUES (1,2,'string1-1'),(2,1,'string2-1'),(3,3,'string3-1');
INSERT INTO binlog_test VALUES (1,1,'string1-1'),(2,1,'string2-2'),(4,2,'string4-1');
DELETE FROM binlog_test WHERE id < 3; 

Example 1: Query all Binlog in the table

Query all Binlog in db_test.binlog_test.

SELECT
    _binlog_bsn,
    _part_row_number,
    *
FROM `db_test.binlog_test$binlog`
ORDER BY _binlog_bsn ASC 

The query result is as follows:

┌─_binlog_bsn─┬─_part_row_number─┬─binlog_shard_id─┬─binlog_event_type─┬─id─┬─a─┬─b─────┐
│           1  │                0  │               1   │ I                  │  1   │ 2  │ string1-1 │
│           1  │                1  │               2   │ I                  │  2   │ 1  │ string2-1 │
│           1  │                2  │               3   │ I                  │  3   │ 3  │ string3-1 │
└────────┴────────────┴───────────┴────────────┴────┴──┴───────┘
┌─_binlog_bsn─┬─_part_row_number─┬─binlog_shard_id─┬─binlog_event_type─┬─id─┬─a─┬─b─────┐
│           2  │                0   │               1  │ U-                 │  1   │ 2  │ string1-1 │
│           2  │                1   │               1  │ U+                 │  1   │ 1  │ string1-1 │
│           2  │                2   │               1  │ I                  │  4   │ 2  │ string4-1 │
│           2  │                3   │               2  │ U-                 │  2   │ 1  │ string2-1 │
│           2  │                4   │               2  │ U+                 │  2   │ 1  │ string2-2 │
└────────┴─────────────┴──────────┴────────────┴────┴──┴───────┘
┌─_binlog_bsn─┬─_part_row_number─┬─binlog_shard_id─┬─binlog_event_type─┬─id─┬─a─┬─b─────┐
│           3  │                0  │               1   │ D                  │  1   │ 1  │ string1-1 │
│           3  │                1  │               2   │ D                  │  2   │ 1  │ string2-2 │
└────────┴────────────┴───────────┴────────────┴────┴──┴───────┘

Example 2: Query Binlog within a specified BSN range in the table

Query the Binlog in db_test.binlog_test where BSN is 2 or 3.

SELECT /*+ bsn(db_test.binlog_test$binlog, 1, 3) */
    _binlog_bsn,
    _part_row_number,
    *
FROM `db_test.binlog_test$binlog`
ORDER BY _binlog_bsn ASC 

The query result is as follows:

┌─_binlog_bsn─┬─_part_row_number─┬─binlog_shard_id─┬─binlog_event_type─┬─id─┬─a─┬─b─────┐
│           2  │                0   │               1  │ U-                  │  1  │ 2  │ string1-1 │
│           2  │                1   │               1  │ U+                  │  1  │ 1  │ string1-1 │
│           2  │                2   │               1  │ I                   │  4  │ 2  │ string4-1 │
│           2  │                3   │               2  │ U-                  │  2  │ 1  │ string2-1 │
│           2  │                4   │               2  │ U+                  │  2  │ 1  │ string2-2 │
└────────┴─────────────┴──────────┴─────────────┴───┴──┴───────┘
┌─_binlog_bsn─┬─_part_row_number─┬─binlog_shard_id─┬─binlog_event_type─┬─id─┬─a─┬─b─────┐
│           3  │                0   │               1  │ D                  │  1   │ 1  │ string1-1 │
│           3  │                1   │               2  │ D                  │  2   │ 1  │ string2-2 │
└────────┴────────────┴───────────┴────────────┴────┴──┴───────┘

Example 3: Query Binlog within a specified BSN range and shard ID in the table

Query the Binlog in db_test.binlog_test where BSN is 2 or 3 and binlog_shard_id is 2.

SELECT /*+ bsn(db_test.binlog_test$binlog, 1, 3) */
    _binlog_bsn,
    _part_row_number,
    *
FROM `db_test.binlog_test$binlog`
WHERE binlog_shard_id = 2
ORDER BY _binlog_bsn ASC 

The query result is as follows:

┌─_binlog_bsn─┬─_part_row_number─┬─binlog_shard_id─┬─binlog_event_type─┬─id─┬─a─┬─b─────┐
│           2  │                3  │               2   │ U-                 │  2  │ 1   │ string2-1 │
│           2  │                4  │               2   │ U+                 │  2  │ 1   │ string2-2 │
└────────┴────────────┴───────────┴────────────┴───┴───┴───────┘
┌─_binlog_bsn─┬─_part_row_number─┬─binlog_shard_id─┬─binlog_event_type─┬─id─┬─a─┬─b─────┐
│           3  │                1   │               2  │ D                   │  2  │ 1  │ string2-2 │
└────────┴────────────┴───────────┴─────────────┴───┴──┴───────┘

Example 4: Query Binlog of newly inserted data

Query all newly inserted data in db_test.binlog_test (binlog_event_type is 'I'), and do not output Binlog system fields.

SELECT * EXCEPT (binlog_event_type, binlog_shard_id)
FROM `db_test.binlog_test$binlog`
WHERE binlog_event_type = 'I'

The query result is as follows:

┌─id─┬─a─┬─b─────┐
│  1  │ 2  │ string1-1 │
│  2  │ 1  │ string2-1 │
│  3  │ 3  │ string3-1 │
└───┴──┴───────┘
┌─id─┬─a─┬─b─────┐
│  4  │ 2   │ string4-1 │
└───┴───┴───────┘

Real-time consumption of Binlog

ByteHouse CDW currently supports consuming ByteHouse CDW Binlog via Flink. For operation details, please refer to Real-time consumption of ByteHouse CDW Binlog with Flink.

Query Binlog system tables

ByteHouse provides two system tables, system.cnch_table_info and system.cnch_binlogs, to display the status information of a table's Binlog.

System table

Purpose

Speed

Recommended use cases

system.cnch_table_info

Displays the current maximum and minimum BSN of a table.

Fast

Only need to query the maximum and minimum BSN of the table.

system.cnch_binlogs

Displays detailed information for each Binlog part of a table.

Slow

You can query detailed information before reading a Binlog part to customize the reading method.

system.cnch_table_info

Displays the current maximum and minimum BSN of a table.

Column name

Data type

Description

database

String

Database name

table

String

Table name

min_bsn

Nullable(UInt64)

Minimum BSN within TTL. For tables where Binlog is not enabled or does not exist, this field is NULL.

max_bsn

Nullable(UInt64)

Maximum BSN within TTL. For tables where Binlog is not enabled or does not exist, this field is NULL.

Example: Query the maximum and minimum BSN of db_test.binlog_test.

SELECT
    database,
    table,
    min_bsn,
    max_bsn 
FROM system.cnch_table_info
WHERE (database = 'db_test') AND (table = 'binlog_test')

The query result is as follows:

┌─database─┬─table───┬─min_bsn─┬─max_bsn─┐
│ db_test   │ binlog_test│       10 │    20     │
└──────┴────────┴──────┴──────┘

system.cnch_binlogs

Displays detailed information about each Binlog part of a table. When querying this system table, you must use equality filter conditions for database and table.

Column name

Data type

Description

database

String

Name of the database being queried.

table

String

Name of the table being queried.

part_name

String

Name of the current Binlog part.

bsn

UInt64

BSN of the current Binlog part.

rows

UInt64

Number of records in the current Binlog part.

bytes

UInt64

Storage bytes of the current Binlog part.

txn_id

UInt64

Transaction ID that generated the current Binlog part.

commit_time

DateTime

Commit time of the transaction that generated the current Binlog part.

published_time

DateTime

Time when the current Binlog part was published.

active

UInt8

Whether the current Binlog part is active (within TTL and published).

is_staged

UInt8

Whether the current Binlog part is published.

shard_stats

String

Number of records for each Shard in the current Binlog part.

Example: Query information about all Binlog parts of db_test.binlog_test.

SELECT
    database,
    table,
    bsn,
    rows,
    bytes,
    active,
    shard_stats
FROM system.cnch_binlogs
WHERE (database = 'db_test') AND (table = 'binlog_test') 

The query result is as follows:

┌─database─┬─table───┬─bsn─┬─rows─┬─bytes─┬─active─┬─shard_stats────┐
│ db_test   │ binlog_test │   1 │    3  │  1416   │      1 │ [ 0, 1, 1, 1 ]     │
│ db_test   │ binlog_test │   2 │    5  │  1437   │      1 │ [ 0, 3, 2, 0 ]     │
│ db_test   │ binlog_test │   3 │    2  │  1403   │      1 │ [ 0, 1, 1, 0 ]     │
└──────┴────────┴───┴────┴──────┴─────┴────────────┘
Last updated: 2026.07.01 14:58:24