Hologres は、データベースイベントをキャプチャするためのバイナリログ機能を提供します。これらのイベントは、データレプリケーション、データ同期、またはダウンストリームのコンシューマー向けのメッセージストリームとして使用できます。Hologres バイナリログを消費することで、データの再利用性が向上し、エンドツーエンドのデータ処理レイテンシが削減されます。このトピックでは、Hologres バイナリログをサブスクライブし、関連する操作を実行する方法について説明します。
バイナリログ
MySQL などの従来のデータベースと同様に、Hologres はバイナリログをサポートし、すべてのデータ変更イベントを記録します。Hologres バイナリログを使用して、データレプリケーションとデータ同期を実装できます。ただし、Hologres のバイナリログは通常、データ同期にのみ使用されるのに対し、従来のデータベースのバイナリログは、プライマリ/レプリカインスタンスの同期やデータ復旧などの高可用性シナリオにも使用されます。そのため、実装にはいくつかの重要な違いがあります。
-
Hologres のバイナリログは DDL 操作を記録しません。
-
Hologres のバイナリログは柔軟でテーブル固有です。テーブルごとに有効または無効にでき、テーブルごとに異なる Time to Live (TTL) を設定できます。
-
分散型リアルタイムデータウェアハウスとして、Hologres は分散バイナリログを備えています。
-
Hologres のバイナリログは簡単にクエリできます。
ビッグデータシナリオでは、Flink は Hologres バイナリログを直接消費できます。従来のデータウェアハウスの階層化と比較して、Flink と Hologres バイナリログの組み合わせは、完全なイベント駆動型アーキテクチャを可能にします。これにより、運用データストア (ODS) からデータウェアハウスディメンション (DWD) レイヤーへ、そして DWD レイヤーからデータサービスレイヤー (DWS) へのリアルタイム処理が可能になります。このアプローチは、階層化によるデータガバナンスをサポートしつつ、ストレージを統一し、データの再利用性を向上させ、エンドツーエンドの処理レイテンシを削減します。これにより、ワンストップのリアルタイムデータウェアハウスソリューションが提供されます。
制限事項
Hologres バイナリログをサブスクライブする際には、次の制限事項にご注意ください。
-
Hologres V0.9 以降のみがバイナリログのサブスクリプションをサポートしています。お使いのインスタンスがそれ以前のバージョンの場合は、オンラインサポートの DingTalk グループにご参加ください。詳細については、「オンラインサポートの利用方法」をご参照ください。
-
Hologres V0.9 および V0.10 では、プロパティを変更して既存のテーブルのバイナリログを有効にすることはできません。テーブルを再作成する必要があります。V1.1 からは、オンデマンドでバイナリログを有効にできます。
-
Hologres V1.3.14 および V1.1.82 より前では、スーパーユーザーのみがバイナリログを消費できました。権限の少ないアカウントを使用すると、
permission denied for table hg_replication_slot_propertiesというエラーが発生します。V1.3.14 および V1.1.82 からは、Flink でバイナリログを消費する場合、アカウントにはテーブルに対する SELECT 権限のみが必要です。JDBC でバイナリログを消費するには、アカウントがレプリケーションロールに属している必要があります。 -
Hologres は、行指向テーブルと列指向テーブルの両方でテーブルレベルのバイナリログをサポートしています。次の表に、サポートされている消費方法を示します。
Flink のカテゴリ
行指向テーブル
列指向テーブル
行列ハイブリッドテーブル (V1.1 以降でサポート)
Blink
サポート
サポート
サポート
Realtime Compute for Apache Flink
サポート
サポート
サポート
Apache Flink
非サポート
非サポート
非サポート
JDBC
V1.1 以降でサポート
V1.1 以降でサポート
V1.1 以降でサポート
-
Blink は、Hologres バイナリログを消費する際に
TIMESTAMPデータ型をサポートしていません。Hologres でテーブルを作成する際はTIMESTAMPTZ型を使用してください。SMALLINTなどの他の特殊な型もサポートされていません。 -
パーティションテーブルの親テーブルからバイナリログを消費することはできません。子テーブルまたは通常の (パーティション化されていない) テーブルを使用してください。Hologres V1.3.24 からは、子テーブルのバイナリログ TTL をオンデマンドで変更できます。子テーブルにバイナリログ TTL を明示的に指定しない場合、親テーブルから TTL を継承します。バイナリログの TTL は正確なタイマーではない点にご注意ください。システムは、バイナリログが期限切れになった直後に削除されることを保証するものではありません。システムは、期限切れになった後のいずれかの時点でバイナリログを削除します。
-
書き込み負荷が高いワークロードの場合、列指向テーブルでバイナリログを有効にすると、理論的には行指向テーブルよりも多くのオーバーヘッドが発生します。したがって、バイナリログを有効にする場合は、行指向テーブルの使用を推奨します。テーブルが OLAP クエリにも使用される場合は、行列ハイブリッドストレージ形式を使用してください。詳細については、「テーブルストレージ形式」をご参照ください。
-
Hologres の内部テーブルのみがバイナリログをサポートしています。外部テーブルはサポートしていません。
バイナリログの形式と原則
バイナリログレコードには、システムフィールドとユーザーテーブルの列が含まれます。次の表で、各フィールドについて説明します。
|
フィールド名 |
型 |
説明 |
|
hg_binlog_lsn |
BIGINT |
ログシーケンス番号 (LSN) を表すバイナリログのシステムフィールドです。値は単調増加ですが、シャード内で連続していることは保証されません。シャード間で一意であることや順序が保証されているわけではありません。 説明
バイナリログデータがシャード間でどのように分散されるかの詳細については、「分散キー」をご参照ください。 |
|
hg_binlog_event_type |
BIGINT |
変更イベントのタイプを示すバイナリログのシステムフィールドです。
|
|
hg_binlog_timestamp_us |
BIGINT |
システムタイムスタンプをマイクロ秒 (us) 単位で表すバイナリログのシステムフィールドです。 |
|
user_table_column_1 |
ユーザー定義 |
ユーザーテーブルの列です。 |
|
... |
... |
... |
|
user_table_column_n |
ユーザー定義 |
ユーザーテーブルの列です。 |
-
UPDATE操作は2つのバイナリログレコードを生成します。1つは更新前の行の状態で、もう1つは更新後の行の状態です。バイナリログのサブスクリプション機能は、これら2つのレコードが連続し、更新前のレコードが先に現れることを保証します。 -
Holo Client、Flink Connector、Data Integration などの Hologres Connector を使用して
UPDATEを実行すると、コネクタはBEFORE_UPDATEイベントをDELETEイベントに、AFTER_UPDATEイベントをINSERTイベントに変換します。したがって、hg_binlog_event_typeフィールドには2と5が表示されます。ただし、コネクタは結果整合性を保証します。 -
hg_binlog_event_typeフィールドは、純粋な SQL を使用してUPDATE文を実行した場合にのみ、BEFORE_UPDATEとAFTER_UPDATEイベントを記録します。
Hologres のバイナリログは、特殊な行指向テーブルと考えることができます。テーブルのバイナリログを有効にすることは、hg_binlog_lsn をキーとし、元のテーブルの列、hg_binlog_event_type、およびhg_binlog_timestamp_us を値とする新しい行指向テーブルを作成することに似ています。バイナリログテーブルは、固定の、つまり厳密に型付けされたスキーマを持っています。ユーザー列の順序は、テーブルの DDL で定義された順序と一致します。このため、バイナリログが有効なテーブルには行指向テーブルまたは行列ハイブリッドテーブルを使用することで、より良いバイナリログの読み取りパフォーマンスを実現できます。
バイナリログの有効化
デフォルトでは、Hologres のバイナリログ機能は無効になっています。テーブルプロパティのbinlog.level と binlog.ttl を設定することで有効にできます。以下の例は、バイナリログを有効にする方法を示しています。テーブル作成パラメーターの詳細については、「CREATE TABLE」をご参照ください。
理論上、列指向テーブルでバイナリログを有効にすると、行指向テーブルよりもコストがかかります。テーブルを頻繁に更新する場合は、行指向テーブルでバイナリログを有効にすることを推奨します。
-
V2.1 以降の構文:
テーブルプロパティ名
binlog.levelおよびbinlog.ttlは、binlog_levelおよびbinlog_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' -- バイナリログの 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');-- テーブルプロパティを設定してバイナリログ機能を有効にします。 call set_table_property('test_message_src', 'binlog.ttl', '86400');-- バイナリログの TTL (秒単位)。 commit;
次の表に、パラメーターについて説明します。
|
パラメーター |
説明 |
|
|
バイナリログを有効にするかどうかを指定します。有効な値は次のとおりです:
|
|
|
バイナリログの TTL (秒単位)。デフォルト値:2,592,000 (30日)。 |
オンデマンドでのバイナリログの有効化
Hologres V1.1 からは、バイナリログを有効または無効にできます。また、TTL を設定して、さまざまな保持要件に対応することもできます。既存のテーブルを再作成することなく、バイナリログを有効にできます。
以下の機能は Hologres V1.1 以降でのみ利用可能です。それ以前のバージョンをご利用の場合は、「アップグレード準備の失敗に関するトラブルシューティング」をご参照いただくか、Hologres の DingTalk グループからお問い合わせください。詳細については、「オンラインサポートの利用方法」をご参照ください。
-
バイナリログの有効化
次のステートメントを使用して、既存のテーブルのバイナリログを有効にし、バイナリログの TTL を設定します。
-- テーブルプロパティを設定してバイナリログを有効にします。 begin; call set_table_property('<table_name>', 'binlog.level', 'replica'); commit; -- テーブルプロパティを設定してバイナリログの TTL (秒単位) を設定します。 begin; call set_table_property('<table_name>', 'binlog.ttl', '2592000'); commit;<table_name> は、バイナリログを有効にするテーブルの名前です。
-
バイナリログの無効化
次のステートメントを使用して、テーブルのバイナリログを無効にします。
-- テーブルプロパティを設定してバイナリログを無効にします。 begin; call set_table_property('<table_name>', 'binlog.level', 'none'); commit;<table_name> は、バイナリログを無効にするテーブルの名前です。
-
バイナリログ TTL の変更
次のステートメントを使用して、バイナリログが有効になっているテーブルの TTL を変更できます。
説明Hologres V1.3.24 からは、パーティションテーブルの子テーブルにバイナリログ TTL を設定できます。子テーブルにバイナリログ TTL を明示的に設定しない場合、親テーブルのバイナリログ TTL を継承します。
call set_table_property('<table_name>', 'binlog.ttl', '8640000'); -- 単位は秒です。<table_name> は、バイナリログの TTL を変更するテーブルの名前です。
バイナリログのクエリ
Hologres のバイナリログデータは厳密に型付けされています。特定のテーブルのバイナリログをクエリするには、組み込みのバイナリログシステムフィールドと元のテーブルの列を組み合わせます。Hologres はまた、最も古い、または最新のバイナリログをクエリしたり、既知の LSN またはタイムスタンプによってバイナリログ情報をクエリしたりするための関数も提供します。
組み込みフィールドによるクエリ
次のステートメントを使用して、組み込みのバイナリログフィールドと元のテーブルフィールドを組み合わせてバイナリログをクエリします。
SELECT hg_binlog_lsn, hg_binlog_event_type, hg_binlog_timestamp_us, * FROM test_message_src;
次のコードは、結果のサンプルです。
postgres=# select hg_binlog_lsn, hg_binlog_event_type, hg_binlog_timestamp_us, * from test_message_src ;
hg_binlog_lsn | hg_binlog_event_type | hg_binlog_timestamp_us | id | title | body
---------------+----------------------+------------------------+----+---------+-------------------
1081 | 5 | 1626856018921653 | 1 | title 1 | body 1
1092 | 3 | 1626856054284918 | 1 | title 1 | body 1
1093 | 7 | 1626856054284918 | 1 | title 1 | body after update
1095 | 2 | 1626856059747536 | 1 | title 1 | body after update
(4 rows)
最も古い、または最新のバイナリログのクエリ
hg_get_binlog_cursor 関数を使用して、特定のシャードで最も古い、または最新のバイナリログをクエリします。次のコードは構文を示します。
-- OLDEST:このシャードで最も古いバイナリログをクエリします。
SELECT * FROM hg_get_binlog_cursor('<table_name>','OLDEST',<shard_id>);
-- LATEST:このシャードで最新のバイナリログをクエリします。
SELECT * FROM hg_get_binlog_cursor('<table_name>','LATEST',<shard_id>);
次のコードは例を示します。
SELECT * FROM hg_get_binlog_cursor('test_message_src','OLDEST',0);
次のコードは、結果のサンプルです。
test=# select * from hg_get_binlog_cursor('test_message_src','OLDEST',0);
hg_shard_id | hg_binlog_lsn | hg_binlog_timestamp_us
-------------+---------------+------------------------
0 | 152 | 1716204893791755
(1 row)
LSNによるタイムスタンプのクエリ
hg_get_binlog_cursor_by_lsn 関数を使用して、バイナリログのタイムスタンプをクエリします。この関数は、指定された LSN 以上の LSN を持つ最初のバイナリログレコードに関する情報を返します。指定された 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);
次のコードは、結果のサンプルです。
test=# select * from hg_get_binlog_cursor_by_lsn('test_message_src',152,0);
hg_shard_id | hg_binlog_lsn | hg_binlog_timestamp_us
-------------+---------------+------------------------
0 | 152 | 1716204893791755
(1 row)
タイムスタンプによる LSN のクエリ
hg_get_binlog_cursor_by_timestamp 関数を使用して、バイナリログの LSN をクエリします。この関数は、指定された時刻以上のタイムスタンプを持つ最初のバイナリログレコードに関する情報を返します。指定された時刻が最新のバイナリログエントリよりも後の場合、結果のhg_binlog_timestamp_us フィールドは現在時刻を返し、hg_binlog_lsn フィールドは次に挿入される行に割り当てられる LSN を返します。次のコードは構文を示します。
指定されたタイムスタンプが now() 関数によって返される現在時刻より後の場合、関数は "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);
次のコードは、結果のサンプルです。
test=# 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);
hg_shard_id | hg_binlog_lsn | hg_binlog_timestamp_us | to_timestamp
-------------+---------------+------------------------+-------------------------------
0 | 152 | 1716204893791755 | 2024-05-20 19:34:53.791755+08
(1 row)
バイナリログのリアルタイム消費
Flink、Blink、および JDBC (Holo Client を含む) を使用して Hologres バイナリログを消費できます。詳細については、次のトピックをご参照ください。
-
Flink または Blink を使用してリアルタイムでバイナリログを消費するには、「FlinkまたはBlinkを使用したHologresバイナリログのリアルタイム消費」をご参照ください。
-
JDBC を使用してバイナリログを消費するには、「JDBCを使用したHologresバイナリログの消費」をご参照ください。
バイナリログが有効なテーブルの表示
次の SQL 文を使用して、どのテーブルでバイナリログが有効になっているかを確認できます。
SELECT
*
FROM
hologres.hg_table_properties
WHERE
property_key = 'binlog.level'
AND property_value = 'replica';
以下は結果のサンプルです。クエリはtable_namespace、table_name、property_key、property_value の4つの列を返します。これらの列は、バイナリログが有効になっているすべてのテーブルに関する情報を提供します。
バイナリログストレージサイズの表示
-
pg_relation_size関数を使用して、テーブルのストレージサイズ (バイナリログのストレージサイズを含む) を取得できます。詳細については、「テーブルのストレージサイズのクエリ」をご参照ください。 -
Hologres V2.1 からは、
hologres.hg_relation_size関数を使用して、データとバイナリログを含むテーブルのストレージ詳細を表示できます。詳細については、「テーブルのストレージ詳細のクエリ」をご参照ください。
DML 操作中のバイナリログの無効化
次の GUC パラメーターを使用すると、DML 操作中に現在のセッションがバイナリログを生成しないようにすることができます。このパラメーターは、DML 文を実行する前にセッションレベルで設定してください。
-- セッションレベルで無効にします。
SET hg_experimental_generate_binlog=off;