

# Descripción de los registros de CDC
<a name="cdc-record-format"></a>

**importante**  
Esta característica se ofrece como versión preliminar de AWS y está sujeta a cambios. Para obtener más información, consulte la sección 2, Betas y versiones preliminares, del documento [Términos de servicio de AWS](https://aws.amazon.com/service-terms/). Para obtener más información acerca de los precios de los flujos de CDC, visite la [página Precios de Amazon Aurora DSQL](https://aws.amazon.com/rds/aurora/dsql/pricing/).  
Antes de la disponibilidad general, añadiremos nuevos tipos de operaciones (`"op": "u"` para actualizaciones) a la carga útil de su flujo. Para garantizar que su aplicación gestione estos cambios sin necesidad de modificaciones, trate cualquier valor `op` no reconocido como una operación upsert aplicando la carga útil `after`. Para obtener más información, consulte [Descripción de los registros de CDC](#cdc-record-format).

La CDC de Aurora DSQL entrega cada cambio como un registro JSON. El registro utiliza una estructura de sobre que incluye el tipo de operación, imágenes de la fila antes y después, y metadatos de origen.

## Cómo se asignan los registros a Amazon Kinesis
<a name="cdc-kinesis-mapping"></a>

Aurora DSQL escribe cada registro de CDC como un único registro de Kinesis. El campo `Data` del registro de Kinesis contiene la carga útil JSON. Aurora DSQL utiliza una clave de partición de Kinesis asignada al azar para distribuir los registros de CDC de manera uniforme entre las particiones. Para leer todos los cambios, consuma todas las particiones del flujo de datos de Kinesis. Si un registro supera el límite de tamaño de los registros de Kinesis, Aurora DSQL lo divide en varios registros de Kinesis. Para obtener más información, consulte [Gestión de los registros sobredimensionados](#cdc-oversized-records).

**nota**  
Un registro de Kinesis contiene un solo blob `Data`. Los valores de la clave principal aparecen en el campo `before` de la carga útil JSON en el caso de las eliminaciones, o en el campo `after` en el caso de las inserciones y actualizaciones. Para extraer la clave principal para el procesamiento posterior, léala en el campo correspondiente de la carga útil.

## Clave principal de la carga útil
<a name="cdc-primary-key-payload"></a>

En el caso de las tablas con una clave principal, los valores de la columna de la clave principal aparecen en la carga útil:
+ En el caso de las **inserciones** y **actualizaciones**, la carga útil incluye las columnas de clave principal junto con todas las demás columnas en el campo `after`.
+ En el caso de las **eliminaciones**, las columnas de la clave principal aparecen en el campo `before`.

Veamos como ejemplo una tabla con una clave primaria compuesta:

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

Si se realiza una eliminación en esta tabla, se genera una carga útil, donde `"before": {"order_id": 1001, "item_id": 42}`.

## Carga útil de registro
<a name="cdc-record-payload"></a>

La carga útil utiliza el siguiente formato de sobre JSON.

**Ejemplo de INSERT**  
En el siguiente ejemplo, se muestra un registro de CDC para una operación de inserción:

```
{
    "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
}
```

**Ejemplo de UPDATE**  
En el siguiente ejemplo, se muestra cómo será un registro de CDC generado por una instrucción `UPDATE` una vez que Aurora DSQL comience a emitir `op: "u"`:

**importante**  
Actualmente, Aurora DSQL emite `op: "c"` tanto para inserciones como para actualizaciones. En una versión posterior, se emitirá `op: "u"` para las actualizaciones y `op: "c"` para las inserciones. Diseñe la aplicación para que gestione `c`, `u` y `d`, de modo que el consumidor siga funcionando durante la transición.

```
{
    "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
}
```

**Ejemplo de DELETE**  
En el caso de las eliminaciones en tablas con una clave principal, el campo `before` contiene los valores de la clave principal de la fila eliminada:

```
{
    "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
}
```

## Campos de carga útil
<a name="cdc-payload-fields"></a>


| Campo | Descripción | 
| --- |--- |
| tipo | The record type. completo for a complete record that includes inline antes and después 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 [Gestión de los registros sobredimensionados](#cdc-oversized-records). | 
| 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. | 
| antes | 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. | 
| después | The full row state after the change, including all columns. Aurora DSQL sets this field to null for deletes. | 
| chunked | Present only when tipo is chunked. Contains reassembly metadata for the antes image, the después image, or both. Aurora DSQL omits the chunked image from the top-level antes or después field and places it under chunked instead. For details, see [Gestión de los registros sobredimensionados](#cdc-oversized-records). | 
| 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, público). | 
| 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. | 

## Detalles del formato
<a name="cdc-format-behavior"></a>

En los siguientes detalles se describe cómo la CDC de Aurora DSQL formatea los registros. Diseñe la aplicación para gestionar estos comportamientos.
+ **Imagen completa posterior para inserciones y actualizaciones.** Aurora DSQL incluye el estado completo de la fila en el campo `after` para todas las escrituras. El campo `before` es `null` para inserciones y actualizaciones. Actualmente, tanto las inserciones como las actualizaciones utilizan `op: "c"`, pero en una versión posterior se emitirá `op: "u"` para las actualizaciones. Diseñe la aplicación para utilizar `source.ts_ns` por clave principal para la ordenación, en lugar de basarse en el campo `op` para distinguir entre inserciones y actualizaciones.
+ **Solo el estado de la fila después del cambio.** Los registros de CDC incluyen el estado completo de la fila después de cada cambio. No se incluye el estado de la fila antes de una actualización. En el caso de las eliminaciones en tablas con una clave principal, el campo `before` contiene los valores de la clave principal.
+ **Tipos numéricos serializados como cadenas.** Aurora DSQL serializa los valores `numeric` y `decimal` como cadenas JSON para conservar la precisión exacta.
+ **Datos binarios codificados como Base64.** Aurora DSQL codifica los valores `bytea` como cadenas de Base64.
+ **Valores numéricos y de punto flotante especiales.** Aurora DSQL serializa NaN y ±Infinity como cadenas `"NaN"`, `"Infinity"` y `"-Infinity"`. Esto se aplica a los tipos `real`, `double precision` y `numeric`.
+ **Columnas JSON serializadas como cadenas JSON.** Aurora DSQL serializa los valores de las columnas `json` como cadenas JSON que contienen el texto JSON sin procesar almacenado en la columna. Analice el valor de la cadena en su aplicación (por ejemplo, con `JSON.parse` en JavaScript o `json.loads` en Python) para acceder al valor JSON subyacente.
+ **Los valores de desbordamiento se emiten como nulos.** Si no se puede representar un valor en el tipo JSON de destino durante la serialización, Aurora DSQL emite un `null` JSON para esa columna. Esto se aplica a los valores de `interval` cuyos microsegundos totales superen el rango de los enteros con signo de 64 bits (±9 223 372 036 854 775 807 microsegundos, aproximadamente ± 292 271 años). Diseñe la aplicación para gestionar valores `null` inesperados en columnas que no admiten valores null en el esquema de la base de datos.
+ **Los registros sobredimensionados se dividen en fragmentos.** Si un registro supera el límite de tamaño de registro de Amazon Kinesis, Aurora DSQL divide la imagen `before` o `after` afectada en fragmentos y los entrega como registros de Kinesis independientes para que usted siga recibiendo el cambio. Diseñe la aplicación para volver a ensamblar las imágenes. Para obtener más información, consulte [Gestión de los registros sobredimensionados](#cdc-oversized-records).

## Gestión de los registros sobredimensionados
<a name="cdc-oversized-records"></a>

Cuando el JSON serializado de un registro de CDC supera los 9 MiB, Aurora DSQL divide las imágenes `before` y `after`, y entrega varios registros de Kinesis. Cada registro contiene un campo `type` de nivel superior que indica su estructura: `full` para un registro completo, `chunked` para un registro principal que hace referencia a fragmentos y `fragment` para una parte individual de una imagen fragmentada. Los campos `op`, `source`, `ts_ms` y `ts_ns` de un registro principal fragmentado se comportan igual que en un registro completo. Los registros que caben en un único registro de Kinesis tienen `type` establecido en `full` y no requieren ningún tratamiento adicional.

Un `chunk_id` es estable en todos los reintentos. Si Aurora DSQL vuelve a entregar un fragmento, este contiene el mismo `chunk_id` que la entrega original, por lo que su aplicación puede continuar almacenando en búfer bajo el mismo identificador sin tener que gestionar conjuntos parciales de intentos anteriores.

**Registro principal**  
Un registro principal fragmentado sustituye el campo `before` o `after` de nivel superior de la imagen dividida por un objeto `chunked` que describe cómo volver a ensamblarla. Cada entrada bajo `chunked` tiene `chunk_id` (el identificador que vincula los fragmentos a este registro), `total_fragments` (el número de fragmentos que componen esa imagen) y `crc32c` (una suma de comprobación de CRC32C, como cadena decimal, sobre el texto de la imagen reensamblada). Si una imagen está en línea y la otra está fragmentada, la imagen en línea sigue apareciendo en el nivel superior como un valor o como `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
}
```

**Registro de fragmentos**  
Cada fragmento constituye un registro independiente de Kinesis con `type` establecido en `fragment` y tres campos: `chunk_id` coincide con el valor del campo `chunked.before.chunk_id` o `chunked.after.chunk_id` del registro principal; `index` es la posición, contada a partir de cero, del fragmento dentro de la imagen; y `data` es un segmento del texto JSON de la imagen dividido de acuerdo con los límites de caracteres UTF-8 (el valor `data` de cada fragmento es, por sí mismo, una cadena UTF-8 válida). Dado que CDC de Aurora DSQL utiliza el modo `UNORDERED` y claves de partición asignadas al azar, los fragmentos y el registro principal pueden llegar a diferentes particiones y en cualquier orden. Para leer todos los fragmentos, consuma todas las particiones del flujo de datos de Kinesis. Para obtener más información acerca del orden de entrega, consulte [Ordenación](cdc-streams.md#cdc-ordering).

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

Para volver a ensamblar una imagen sobredimensionada, almacene cada registro en búfer con `type` `fragment` por su `chunk_id`. Cuando reciba un registro principal con `type` `chunked`, espere hasta tener `total_fragments` fragmentos para cada `chunk_id` al que se hace referencia en `chunked.before` o `chunked.after`, ordene los fragmentos por `index` en orden ascendente y concatene las cadenas `data`. El resultado concatenado es el objeto original `before` o `after` como texto JSON; analícelo para acceder a los valores de las columnas. Para verificar la integridad de la entrega, calcule el CRC32C sobre la cadena concatenada y compare el resultado con `chunked.before.crc32c` o `chunked.after.crc32c`.

## Serialización de tipos de datos
<a name="cdc-data-types"></a>

En las siguientes tablas se describe cómo Aurora DSQL serializa cada tipo de datos de PostgreSQL en registros de CDC.

### Tipos de enteros
<a name="cdc-integer-types"></a>


| Tipo de PostgreSQL | Representación JSON | Ejemplo | 
| --- |--- |--- |
| smallint (int2) | JSON number | 42 | 
| entero (int4) | JSON number | 1001 | 
| bigint (int8) | JSON number | 9223372036854775807 | 
| oid | JSON number (unsigned) | 16384 | 

Los valores de `bigint` superiores a ±2^53 pueden perder precisión en los entornos de JavaScript. En esos casos, utilice BigInt o bibliotecas de precisión arbitraria.

### Tipos de números en coma flotante
<a name="cdc-float-types"></a>


| Tipo de PostgreSQL | Representación JSON | Ejemplo | Notas | 
| --- |--- |--- |--- |
| 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. | 
| numérico / decimal | JSON string | "123,45" | Always a string to preserve exact precision. NaN and ±Infinity are serialized as the strings "NaN", "Infinity", "-Infinity". | 

### Booleano
<a name="cdc-boolean-type"></a>


| Tipo de PostgreSQL | Representación JSON | Ejemplo | 
| --- |--- |--- |
| booleano | JSON boolean | true or false | 

### Tipos de caracteres
<a name="cdc-character-types"></a>


| Tipo de PostgreSQL | Representación JSON | Ejemplo | 
| --- |--- |--- |
| varchar / text | JSON string | "Hello, world\!" | 
| BPCHAR (char(n)) | JSON string | "ABC" (trailing spaces stripped) | 
| name | JSON string | "pg\_class" | 
| “char” (single-byte) | JSON string | “A” | 

### Binario
<a name="cdc-binary-type"></a>


| Tipo de PostgreSQL | Representación JSON | Ejemplo | 
| --- |--- |--- |
| bytea | JSON string (Base64) | "SGVsbG8gV29ybGQh" | 

### Tipos de fecha y hora
<a name="cdc-datetime-types"></a>


| Tipo de PostgreSQL | Representación JSON | Ejemplo | Notas | 
| --- |--- |--- |--- |
| date | JSON number (days since Unix epoch) | 19797 | \+infinity and -infinity are represented as sentinel day counts derived from epoch-offset arithmetic. These values don't correspond to meaningful calendar dates. | 
| hora | 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. | 
| marca de tiempo | 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 marca de tiempo. | 
| intervalo | JSON number (approximate total microseconds) | 2802603000000 | Months are approximated as 30.4375 days (2,629,800 seconds). The total is computed as (meses × 2 629 800 \+ días × 86 400) × 1 000 000 \+ microsegundos. 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. | 

### Otros tipos
<a name="cdc-other-types"></a>


| Tipo de PostgreSQL | Representación JSON | Ejemplo | 
| --- |--- |--- |
| 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\\"}" | 

### Valores NULL
<a name="cdc-null-values"></a>

Para cualquier tipo de datos, los valores de las columnas `NULL` se representan como JSON `null`.

## Evolución del esquema en los registros de CDC
<a name="cdc-schema-evolution"></a>

Cuando se modifica el esquema de una tabla —por ejemplo, al añadir, eliminar o renombrar una columna—, los registros de CDC reflejan el cambio a partir de la transacción que confirmó el cambio de DDL. Los registros de las transacciones confirmadas antes del cambio de DDL utilizan el esquema anterior. Por ejemplo:
+ Si se añade una columna, los registros de las transacciones anteriores no incluyen la nueva columna. Los registros a partir de la transacción en la que se añadió la columna incluyen la nueva columna.
+ Si elimina una columna, los registros a partir de la transacción de eliminación ya no incluirán dicha columna.
+ Si cambia el nombre de una columna, los registros a partir de la transacción de cambio de nombre utilizarán el nuevo nombre de columna.

Realice un seguimiento de los cambios de esquema en su consumidor posterior inspeccionando los nombres de columna presentes en los campos `after` y `before` de cada registro. El campo `source.version` de cada registro identifica el formato del sobre de CDC.