View a markdown version of this page

CDC レコードについて - Amazon Aurora DSQL

CDC レコードについて

重要

この機能は AWS プレビューとして提供されており、変更される可能性があります。詳細については、「AWS のサービス条件」のセクション 2、「ベータ版とプレビュー」を参照してください。CDC ストリームの料金の詳細については、「Aurora DSQL の料金ページ」を参照してください。

一般提供する前に、ストリームペイロードに新しいオペレーションタイプ ("op": "u" 更新用) を追加します。アプリケーションがこれらの変更を修正せずに処理できるようにするには、after ペイロードを適用して、認識されない op 値をすべてアップサートとして扱います。詳細については、「CDC レコードについて」を参照してください。

Aurora DSQL CDC は、各変更を JSON レコードとして配信します。レコードは、オペレーションタイプ、前後の行イメージ、ソースメタデータを含むエンベロープ構造を使用します。

レコードが Amazon Kinesis にマッピングされる方法

Aurora DSQL は、各 CDC レコードを単一の Kinesis レコードとして書き込みます。Kinesis レコードの Data フィールドには、JSON ペイロードが含まれています。Aurora DSQL は、ランダム化された Kinesis パーティションキーを使用して CDC レコードをシャード間で均等に分散します。すべての変更を読み取るには、Kinesis データストリームのすべてのシャードを消費します。レコードが Kinesis レコードのサイズ制限を超えると、Aurora DSQL はそれを複数の Kinesis レコードに分割します。詳細については、「サイズの大きいレコードの処理」を参照してください。

注記

Kinesis レコードには 1 つの Data BLOB があります。プライマリキー値は、削除の場合は JSON ペイロードの before フィールドに、挿入および更新の場合は after フィールドに表示されます。ダウンストリーム処理用のプライマリキーを抽出するには、ペイロードの適切なフィールドから読み取ります。

ペイロードのプライマリキー

プライマリキーを持つテーブルの場合、プライマリキー列の値がペイロードに表示されます。

  • 挿入更新の場合、ペイロードにはプライマリキー列と after フィールド内の他のすべての列が含まれます。

  • 削除の場合、プライマリキー列が before フィールドに表示されます。

例えば、複合プライマリキーを持つテーブルがあるとします。

CREATE TABLE order_items ( order_id INT, item_id INT, quantity INT, price NUMERIC, PRIMARY KEY (order_id, item_id) );

このテーブルを削除すると、"before": {"order_id": 1001, "item_id": 42} というペイロードが生成されます。

レコードのペイロード

ペイロードは次の JSON エンベロープ形式を使用します。

INSERT の例

次の例は、挿入オペレーションの CDC レコードを示しています。

{ "type": "full", "op": "c", "before": null, "after": {"order_id": 1001, "item_id": 42, "quantity": 5, "price": "29.99"}, "source": { "version": "1.0", "ts_ms": 1705318200000, "ts_ns": 1705318200000000000, "txId": "ffthunp5stx6ffs2vyfqoatmfu", "schema": "public", "table": "order_items", "db": "postgres", "cluster": "kmabugltfmjdaj2siqr2qbxgju" }, "ts_ms": 1705318200125, "ts_ns": 1705318200125483291 }
UPDATE の例

次の例は、Aurora DSQL が op: "u" の出力を開始した後、UPDATE ステートメントによって生成された CDC レコードがどのようになるかを示しています。

重要

現在、Aurora DSQL は挿入と更新の両方に対して op: "c" を出力します。後続のリリースでは、更新の場合は op: "u"、挿入の場合は op: "c" が出力されます。cu、および d を処理するようにアプリケーションを設計し、コンシューマーが移行後も動作し続けるようにします。

{ "type": "full", "op": "u", "before": null, "after": {"order_id": 1001, "item_id": 42, "quantity": 10, "price": "29.99"}, "source": { "version": "1.0", "ts_ms": 1705318300000, "ts_ns": 1705318300000000000, "txId": "qvtiesgmd55cvlfukm3dfuotji", "schema": "public", "table": "order_items", "db": "postgres", "cluster": "kmabugltfmjdaj2siqr2qbxgju" }, "ts_ms": 1705318300125, "ts_ns": 1705318300125483291 }
DELETE の例

プライマリキーを持つテーブルの削除の場合、before フィールドには削除された行のプライマリキー値が含まれます。

{ "type": "full", "op": "d", "before": {"order_id": 1001, "item_id": 42}, "after": null, "source": { "version": "1.0", "ts_ms": 1705318400000, "ts_ns": 1705318400000000000, "txId": "xyzabc123def456ghi789jklmno", "schema": "public", "table": "order_items", "db": "postgres", "cluster": "kmabugltfmjdaj2siqr2qbxgju" }, "ts_ms": 1705318400125, "ts_ns": 1705318400125483291 }

ペイロードフィールド

フィールド 説明
The record type. フル for a complete record that includes inline 前に and 後に values. chunked for a main record that references fragment records for one or both images. fragment for an individual piece of a chunked image. For details, see サイズの大きいレコードの処理.
op Operation type. c = create (insert), u = update, d = delete. Currently Aurora DSQL emits c for both inserts and updates. A subsequent release will emit u for updates, and c for inserts. Design your app to handle all three values.
前に For deletes on tables with a primary key, contains the primary key values of the deleted row. Aurora DSQL sets this field to null for inserts, updates, and deletes on tables without a primary key.
後に The full row state after the change, including all columns. Aurora DSQL sets this field to null for deletes.
chunked Present only when is chunked. Contains reassembly metadata for the 前に image, the 後に image, or both. Aurora DSQL omits the chunked image from the top-level 前に or 後に field and places it under chunked instead. For details, see サイズの大きいレコードの処理.
source.version The CDC source metadata format version. The current version is 1.0.
source.ts_ms The transaction commit timestamp in milliseconds since the Unix epoch, Coordinated Universal Time (UTC).
source.ts_ns Transaction commit timestamp in nanoseconds, UTC. The highest precision timestamp available. Use this field to establish a total order of transactions.
source.txId A unique transaction identifier, encoded as base32. All records from the same transaction share the same txId value. Use this field to group records that belong to the same transaction.
source.schema The PostgreSQL schema name (for example, パブリック).
source.table The table name.
source.db The database name. Always postgres for Aurora DSQL.
source.cluster The Aurora DSQL cluster identifier.
ts_ms The time at which the CDC system processed the record, in milliseconds, UTC. The difference between ts_ms and source.ts_ms is a measure of replication lag.
ts_ns The time at which the CDC system processed the record, in nanoseconds, UTC.

フォーマットの詳細

以下の詳細では、Aurora DSQL CDC がレコードをフォーマットする方法について説明します。これらの動作に対応できるようにアプリケーションを設計します。

  • 挿入と更新の完全な後のイメージ。Aurora DSQL は、すべての書き込みの after フィールドに完全な行状態を含めます。挿入および更新の場合、before フィールドは null になります。現在、挿入と更新の両方で op: "c" が使用されますが、それ以降のリリースでは更新のために op: "u" が出力されます。挿入と更新を区別するために op フィールドに依存するのではなく、プライマリキーごとに source.ts_ns を使用して順序付けするようにアプリケーションを設計します。

  • 変更後の行の状態のみ。CDC レコードには、変更後の各行の状態がすべて含まれます。更新前の行の状態は含まれません。プライマリキーを持つテーブルの削除の場合、before フィールドにはプライマリキー値が含まれます。

  • 文字列としてシリアル化された数値型。Aurora DSQL は、正確な精度を維持するために numeric および decimal 値を JSON 文字列としてシリアル化します。

  • Base64 でエンコードされたバイナリデータ。Aurora DSQL は、bytea 値を Base64 文字列としてエンコードします。

  • 特殊な浮動小数点値と数値。Aurora DSQL は NaN と ±Infinity を文字列 "NaN""Infinity"、および "-Infinity" としてシリアル化します。これは、realdouble precision、および numeric タイプに適用されます。

  • JSON 文字列としてシリアル化された JSON 列。Aurora DSQL は、json 列に格納されている未加工の JSON テキストを含む JSON 文字列として列の値をシリアル化します。アプリケーションで文字列値を解析し (JavaScript の JSON.parse や Python の json.loads など)、基になる JSON 値にアクセスします。

  • null として出力されるオーバーフロー値。シリアル化中にターゲット JSON タイプで値を表現できない場合、Aurora DSQL はその列に対して JSON の null を出力します。これは、合計マイクロ秒が 64 ビット符号付き整数範囲 (±9,223,372,036,854,775,807 マイクロ秒、約 ±292,271 年) を超える interval 値に適用されます。データベーススキーマで null を許容しない列における予期しない null 値を処理できるようにアプリケーションを設計します。

  • サイズの大きいレコードはチャンクに分割されます。レコードが Amazon Kinesis レコードのサイズ制限を超えると、Aurora DSQL は影響を受ける before または after イメージをフラグメントに分割し、個別の Kinesis レコードとして配信するため、変更を受け取ることができます。イメージを再構成するようにアプリケーションを設計します。詳細については、「サイズの大きいレコードの処理」を参照してください。

サイズの大きいレコードの処理

CDC レコードのシリアル化された JSON が 9 MiB を超えると、Aurora DSQL は before および/または after イメージを分割し、複数の Kinesis レコードを配信します。各レコードには、その構造を示す最上位の type フィールドが含まれています。完全なレコードの場合は full、フラグメントを参照するメインレコードの場合は chunked、チャンクイメージの個々の部分の場合は fragment です。チャンク化されたメインレコードの opsourcets_ms、および ts_ns フィールドは、完全なレコードの場合と同じように動作します。単一の Kinesis レコードに収まるレコードは typefull に設定されており、追加の処理は必要ありません。

chunk_id は再試行間で安定しています。Aurora DSQL がフラグメントを再配信する場合、元の配信と同じ chunk_id を保持するため、アプリケーションは以前の試行の部分的なセットを処理せずに、同じ識別子でバッファリングを続行できます。

メインレコード

チャンク化されたメインレコードは、分割されたイメージの最上位の before または after フィールドを、再構成する方法を説明する chunked オブジェクトに置き換えます。chunked の各エントリには、chunk_id (フラグメントをこのレコードにリンクする識別子)、total_fragments (そのイメージを構成するフラグメントの数)、crc32c (再アセンブルされたイメージテキストに対する 10 進文字列の CRC32C チェックサム) があります。1 つのイメージがインラインで、もう 1 つのイメージがチャンク化されている場合、インラインイメージは依然として最上位レベルに値または null として表示されます。

{ "type": "chunked", "op": "c", "before": null, "after": null, "source": { "version": "1.0", "ts_ms": 1705318200000, "ts_ns": 1705318200000000000, "txId": "ffthunp5stx6ffs2vyfqoatmfu", "schema": "public", "table": "order_items", "db": "postgres", "cluster": "cluster-id" }, "chunked": { "after": { "chunk_id": "chunk-id", "total_fragments": 3, "crc32c": "2073618257" } }, "ts_ms": 1705318200125, "ts_ns": 1705318200125483291 }
フラグメントレコード

各フラグメントは、typefragment に設定され、3 つのフィールドを持つ独自の Kinesis レコードです。chunk_id は、メインレコードの対応する chunked.before.chunk_id または chunked.after.chunk_id の値と一致し、index はイメージ内のフラグメントのゼロベースの位置であり、data は UTF-8 文字境界で分割されたイメージの JSON テキストのセグメントです (各フラグメントの data 値は、それ自体が有効な UTF-8 文字列です)。Aurora DSQL CDC は UNORDERED モードとランダム化されたパーティションキーを使用するため、フラグメントとメインレコードは異なるシャードに任意の順序で到着する可能性があります。すべてのフラグメントを読み取るには、Kinesis データストリーム上のすべてのシャードを消費します。配信の順序付けの詳細については、「順序付け」を参照してください。

{ "type": "fragment", "chunk_id": "chunk-id", "index": 0, "data": "partial-JSON-text" }

サイズの大きいイメージを再構成するには、typefragment の各レコードを chunk_id でバッファします。typechunked のメインレコードを受け取ったら、chunked.before または chunked.after で参照される各 chunk_id に対して、total_fragments のフラグメントが揃うまで待機し、フラグメントを index の昇順にソートして、data 文字列を連結します。連結結果は、元の before または after オブジェクトを JSON テキストとして表したものです。これを解析して列の値にアクセスします。配信の整合性を検証するには、連結された文字列に対して CRC32C を計算し、結果を chunked.before.crc32c または chunked.after.crc32c と比較します。

データ型のシリアル化

次の表は、Aurora DSQL が CDC レコードの各 PostgreSQL データ型をシリアル化する方法を示しています。

整数タイプ

PostgreSQL タイプ JSON 表現
smallint (int2) JSON number 42
integer (int4) JSON number 1001
bigint (int8) JSON number 9223372036854775807
oid JSON number (unsigned) 16384

JavaScript 環境では、bigint の値が ±2^53 を超えると精度が低下する可能性があります。このような場合は、BigInt または任意精度のライブラリを使用します。

浮動小数点型

PostgreSQL タイプ JSON 表現 注意事項
real (float4) JSON number 3.14159 NaN and ±Infinity are serialized as the strings "NaN", "Infinity", "-Infinity".
double precision (float8) JSON number 3.141592653589793 Same special value handling as real.
numeric / decimal JSON string "123.45" Always a string to preserve exact precision. NaN and ±Infinity are serialized as the strings "NaN", "Infinity", "-Infinity".

ブール値

PostgreSQL タイプ JSON 表現
boolean JSON boolean true or false

文字型

PostgreSQL タイプ JSON 表現
varchar / テキスト JSON string "Hello, world!"
bpchar (char(n)) JSON string "ABC" (trailing spaces stripped)
名前 JSON string "pg_class"
"char" (single-byte) JSON string 「A」

バイナリ

PostgreSQL タイプ JSON 表現
bytea JSON string (Base64) "SGVsbG8gV29ybGQh"

日付と時刻の型

PostgreSQL タイプ JSON 表現 注意事項
date JSON number (days since Unix epoch) 19,797 +infinity and -infinity are represented as sentinel day counts derived from epoch-offset arithmetic. These values don't correspond to meaningful calendar dates.
時間 JSON number (microseconds since midnight) 52200123456
timetz JSON number (microseconds since midnight, UTC) 52200123456 The local time is adjusted to UTC by applying the stored timezone offset (seconds west of UTC). The result is wrapped to the range [0, 86400000000) microseconds.
timestamp JSON number (microseconds since Unix epoch) 1710510600123456 ±Infinity maps to sentinel values: 9223372036825200000 for +infinity and -9223372036832400000 for -infinity.
timestamptz JSON number (microseconds since Unix epoch) 1710510600123456 Stored and emitted in UTC. Same ±infinity sentinel values as timestamp.
interval JSON number (approximate total microseconds) 2802603000000 Months are approximated as 30.4375 days (2,629,800 seconds). The total is computed as (月 × 2,629,800 + 日 × 86,400) × 1,000,000 + マイクロ秒. If the result exceeds the 64-bit signed integer range (±9,223,372,036,854,775,807 microseconds, approximately ±292,271 years), Aurora DSQL emits JSON null for the column.

その他の型

PostgreSQL タイプ JSON 表現
uuid JSON string (standard 8-4-4-4-12 hex format) "550e8400-e29b-41d4-a716-446655440000"
oidvector JSON empty array []
json JSON string containing the raw JSON text "{\"key\": \"value\"}"

NULL 値

どのデータ型でも、NULL 列の値は JSON の null として表されます。

CDC レコードにおけるスキーマの進化

列の追加、削除、名前の変更などによってテーブルのスキーマを変更すると、CDC レコードには DDL の変更をコミットしたトランザクション以降の変更が反映されます。DDL の変更前にコミットされたトランザクションのレコードは、以前のスキーマを使用します。例えば、次のようになります。

  • 列を追加すると、それ以前のトランザクションのレコードに新しい列が含まれなくなります。追加トランザクション以降のレコードには、新しい列が含まれます。

  • 列を削除すると、削除されたトランザクション以降のレコードにその列が含まれなくなります。

  • 列の名前を変更すると、名前変更トランザクション以降のレコードでは新しい列名が使用されます。

各レコードの after および before フィールドに存在する列名を調べて、ダウンストリームのコンシューマーのスキーマの変更を追跡します。各レコードの source.version フィールドは、CDC エンベロープ形式を識別します。