变更数据流概览

变更数据流可近乎实时地监视并流式传输 Spanner 数据库的数据更改(插入、更新和删除)。

本页面简要介绍了 Spanner 更改流:它们的功能和工作原理。如需了解如何在数据库中创建和管理变更数据流并将它们与其他服务连接,请点击后续步骤中的链接。

变更数据流的用途

变更数据流提供了一种灵活、可伸缩的方式来将数据更改流式传输到其他服务。常见用例包括:

  • 将 Spanner 数据更改复制到数据仓库(例如 BigQuery)以进行分析。

  • 根据发送到消息队列的数据更改(例如 Pub/Sub)触发应用逻辑。

  • Cloud Storage 中存储数据更改,以满足合规性或归档目的。

变更数据流配置

Spanner 将变更数据流视为架构对象,就像表和索引一样。因此,您可以使用 DDL 语句创建、修改和删除变更流,并且可以查看数据库的变更数据流,就像查看其他 DDL 管理的架构对象一样。

您可以配置变更数据流以监控整个数据库中的数据更改,也可以将其范围限制为特定表和列。一个数据库可以有多个变更数据流,一个特定的表或列可以有多个数据流在限制范围内对其进行监控。

您还可以配置变更数据流,以指定数据保留期限值捕获类型基于 TTL 的删除操作表修改过滤条件

发出可创建变更流的 DDL 会启动长时间运行的操作。完成后,新的变更数据流会立即开始观察分配给它的表和列。

隐式监控表和列

监控整个表的变更流会隐式监视该表中的所有列,即使该表定义已更新也是如此。例如,当您向该表添加新列时,变更数据流会自动开始监控这些新列,而无需对该变更数据流的配置进行任何修改。同样,变更数据流会自动停止监控从该表丢弃的任何列。

整个数据库变更数据流的工作原理相同。他们会隐式监视每个表中的每一列,自动监视在变更数据流创建之后添加的任何表或列,并停止监视删除的任何表或列。

显式监控表和列

如果您将变更数据流配置为仅监控表中的特定列,之后又向该表添加了列,那么除非您重新配置该变更数据流,否则变更数据流将不会开始监控这些列。

数据库的架构将变更数据流视为它们明确监控的任何列或表的从属对象。在删除任何此类列或表之前,您必须手动将其从任何明确监控的变更数据流的配置中移除。

变更数据流所监控的数据类型

变更数据流监控的数据更改包括对其所监控的表和列所做的所有插入、更新和删除操作。这些变化可能来自:

变更流只能观察用户创建的列和表中的数据更改。它们不会监视索引、视图、其他变更数据流或系统表(例如信息架构表或统计信息表)。变更数据流不会监控生成的列,除非该列是主键的一部分。始终跟踪主键列。

此外,变更数据流不会观察架构更改或直接由架构更改引起的任何数据更改。例如,监控整个数据库的变更流不会将删除表视为数据更改,即使此操作会从数据库中移除该表的所有数据。

Spanner 如何写入和存储变更数据流

每次 Spanner 检测到变更数据流所监控的列中的数据更改时,都会将数据更改记录写入其内部存储空间。它会在同一事务中与数据更改同步执行此操作。Spanner 会协同定位这两项写入操作,使其由同一服务器处理,从而最大限度地减少写入处理。

数据变更记录的内容

变更数据流写入的每条数据变更记录都包含有关数据变更的以下信息:

  • 受影响表的名称

  • 用于标识已更改行的主键的名称、值和数据类型

  • 根据变更数据流定义捕获的已更改行列的名称和数据类型。

  • 行列的旧值。旧值及其跟踪的内容(可能只是修改后的列,也可能是跟踪的整个行)是否可用取决于用户配置的值捕获类型

  • 该行的列的新值。新值的可用性及其跟踪的内容取决于用户配置的值捕获类型

  • 修改类型(插入、更新或删除)

  • 提交时间戳

  • 交易 ID

  • 记录序列号

  • 数据变更记录的值捕获类型。

如需深入了解数据变更记录的结构,请参阅数据变更记录

数据保留

变更数据流会将其数据变更记录保留 1 到 7 天。在最初创建变更数据流时,您可以使用 DDL 指定数据保留期限(而非一天的默认值),也可以在以后随时调整该上限。 请注意,降低变更数据流的数据保留限制后,变更数据流的读取者将立即并永久无法获取变更数据流的新限制之前的所有历史数据。

此数据保留期限进行了权衡;保留期限越长,对数据流数据库的存储空间需求就越大。

值捕获类型

变更数据流的值捕获类型配置选项可控制其存储已更改行的值的方式。您可以使用 DDL 为变更数据流指定以下值捕获类型之一:

  • OLD_AND_NEW_VALUES:捕获行的已修改列的旧值和新值。

  • NEW_VALUES:仅捕获非键列的新值,但不捕获旧值。

  • NEW_ROW:每当监控列发生更改时,捕获已修改和未修改的所有新值。不会捕获旧值。

  • NEW_ROW_AND_OLD_VALUES:捕获已修改和未修改列的所有新值,以及已修改列的旧值。

排除基于存留时间的删除

在 Spanner 中,您可以通过存留时间 (TTL) 设置政策来定期删除 Spanner 表中的数据。默认情况下,变更数据流包含所有基于 TTL 的删除操作。您可以使用 exclude_ttl_deletes 将变更数据流设置为排除基于 TTL 的删除操作。如果您将此过滤条件设置为排除基于 TTL 的删除,则只有未来的基于 TTL 的删除会从您的变更数据流中排除。

此过滤条件的默认值为 false。如需排除基于 TTL 的删除,请将过滤条件设置为 true。您可以在创建变更数据流时添加过滤条件,也可以修改现有变更数据流以包含该过滤条件

表修改类型

默认情况下,变更数据流包括所有表修改,例如插入、更新和删除。您可以使用以下可用的过滤选项,从变更数据流的范围中过滤一项或多项表修改:

  • exclude_insert:排除所有 INSERT 表修改
  • exclude_update:排除所有 UPDATE 表修改
  • exclude_delete:排除所有 DELETE 表修改

这些过滤条件的默认值为 false。如需排除特定类型的表修改,请将过滤条件设置为 true。您可以同时设置一个或多个过滤器。

创建变更数据流时,您可以添加表修改类型的过滤条件,也可以为现有变更数据流修改表修改类型的过滤条件

读取变更数据流

Spanner 提供了多种读取变更数据流数据的方法:

  • 通过 Dataflow(使用 Apache Beam SpannerIO 连接器)。 我们建议对于大多数变更数据流应用使用此解决方案。Google 还提供适用于常见用例的 Dataflow 模板。

  • 直接使用 Spanner API。这样会牺牲 Dataflow 流水线的抽象和功能,从而实现最高的速度和灵活性。

  • 通过使用基于 Debezium 的 Kafka 连接器处理 Spanner 变更数据流。此连接器将变更记录直接流式传输到 Kafka 主题。

您可以使用定向读取为变更数据流读取提供部分隔离。定向读取有助于最大限度地减少对数据库中事务性工作负载的影响。您可以使用 Spanner API 将变更数据流读取路由到多区域实例配置中的特定副本类型或区域,或具有可选只读区域的自定义区域配置。如需了解详情,请参阅定向读取

使用 Dataflow

使用 Apache Beam SpannerIO 连接器构建 Dataflow 流水线,以便从变更数据流读取数据。在您使用有关特定变更数据流的详细信息配置连接器后,它会自动将新的数据变更记录输出到单个无界限 PCollection 数据集中,以供 Dataflow 流水线中的后续转换做进一步处理。

Dataflow 使用数据选取函数将无界限集合划分为逻辑组件或窗口。因此,Dataflow 可在从变更数据流读取数据时提供近乎实时的数据流。

Google 提供了模板,可让您针对常见的变更数据流使用场景快速构建 Dataflow 流水线,包括将数据流的所有数据更改发送到 BigQuery 数据集,或将它们复制到 Cloud Storage 存储桶

如需详细了解变更数据流和 Dataflow 如何协同工作,请参阅使用 Dataflow 构建变更数据流连接

使用 API

除了使用 Dataflow 构建变更数据流流水线,您还可以编写使用 Spanner API 直接读取变更数据流记录的代码。这样,您就可以使用与 SpannerIO 连接器相同的方式读取数据更改记录,它牺牲了其提供的抽象,以换取读取变更数据流数据时可能的最低延迟时间。

如需了解详情,请参阅查询变更数据流。如需详细了解如何查询变更数据流和解释返回的记录,请参阅变更数据流分区、记录和查询

使用 Kafka 连接器

Kafka 连接器直接将变更数据流记录输出到 Kafka 主题中。它简化了使用 Spanner API 查询变更数据流的细节。

如需详细了解变更数据流和 Kafka 连接器如何协同工作,请参阅使用 Kafka 连接器构建变更数据流连接

限制

变更数据流有一些限制,包括数据库可拥有的变更数据流数量上限,以及可监控单个列的数据流数量上限。如需查看完整列表,请参阅更改数据流限制

权限

变更数据流使用以下数据:

  • 创建、更新或删除变更数据流需要 spanner.databases.updateDdl

  • 读取变更数据流的数据需要 spanner.databases.select

如果使用 SpannerIO 连接器,则读取变更数据流数据的 Dataflow 作业的所有者需要具有应用数据库或单独的元数据数据库的其他 IAM 权限;请参阅创建元数据数据库

后续步骤