变更数据流会近乎实时地监视 Spanner 数据库的数据更改(插入、更新和删除)并将其流式传输出去。
本页面简要介绍了 Spanner 更改流:它们的作用以及工作方式。如需了解如何在数据库中创建和管理变更数据流,以及如何将更改流与其他服务相关联,请点击后续步骤中的链接。
变更数据流的用途
变更数据流提供了一种灵活且可伸缩的方式,可将数据变更流式传输到其他服务。常见用例包括:
将 Spanner 数据更改复制到数据仓库(例如 BigQuery)以进行分析。
根据发送到消息队列(例如 Pub/Sub)的数据更改触发应用逻辑。
将数据更改存储在 Cloud Storage 中,以满足合规性或归档要求。
更改数据流配置
Spanner 将变更数据流视为架构对象,与表和索引非常相似。因此,您可以使用 DDL 语句创建、修改和删除变更数据流,并且可以像其他 DDL 管理的架构对象一样查看数据库的变更数据流。
您可以将变更数据流配置为监控整个数据库中的数据更改,也可以将其范围限制为特定表和列。一个数据库可以有多个变更数据流,而一个特定的表或列可以有多个数据流对其进行监控,但有一定限制。
您可以选择使用以下任一项配置变更数据流:
- 指定数据保留期限以替换默认的一天保留期限。
- 指定值捕获类型以替换默认值捕获类型
OLD_AND_NEW_VALUES
。 - 应用基于 TTL 的删除过滤条件,以从变更数据流中过滤掉基于 TTL 的删除操作。
- 应用表格修改过滤条件,以排除所有
INSERT
、UPDATE
或DELETE
表格修改。 - 启用事务级记录排除,以从变更数据流中排除某些事务。
发出用于创建变更数据流的 DDL 会启动一项长时间运行的操作。完成后,新的变更数据流会立即开始监控分配给它的表和列。
隐式监控表和列
监控整个表的变更数据流会隐式监控该表中的所有列,即使该表定义已更新也是如此。例如,当您向该表添加新列时,变更数据流会自动开始监控这些新列,而无需对该变更数据流的配置进行任何修改。同样,变更数据流会自动停止监控从相应表中删除的任何列。
整个数据库的变更数据流的工作方式相同。它们会隐式监控每个表中的每一列,自动监控在创建变更数据流后添加的任何表或列,并停止监控任何已删除的表或列。
明确监控表和列
如果您将变更数据流配置为仅监控表中的特定列,并且您稍后向该表添加了列,则除非您重新配置该变更数据流,否则该变更数据流不会开始监控这些列。
数据库的架构将变更数据流视为其明确监控的任何列或表的依赖对象。在舍弃任何此类列或表之前,您必须先手动将其从明确监控它的任何变更流的配置中移除。
变更数据流监控的数据变更类型
变更数据流监控的数据变更包括对所监控的表和列进行的所有插入、更新和删除操作。这些更改可能来自:
变更数据流只能监控用户创建的列和表中的数据更改。它们不会监控索引、视图、其他变更数据流或信息架构或统计信息表等系统表。除非生成的列是主键的一部分,否则变更数据流不会监控该列。系统始终会跟踪主键列。
此外,变更数据流不会监控架构更改或直接由架构更改导致的任何数据更改,但会监控默认值的回填。例如,监控整个数据库的变更数据流不会将表删除视为数据变更,即使此操作会从数据库中删除相应表的所有数据,也不会考虑和记录此操作。
Spanner 如何写入和存储变更数据流
每当 Spanner 检测到变更数据流正在监控的列中的数据发生变化时,它都会将数据更改记录写入其内部存储空间。数据更改写入和数据更改记录是在同一事务中写入的。Spanner 会将这两个写入操作并置,以便由同一服务器处理,从而最大限度地减少写入处理。然后,事务会在数据库的副本之间复制,从而产生存储和复制费用。 如需了解详情,请参阅 Spanner 价格。
数据更改记录的内容
变更数据流写入的每条数据更改记录都包含有关数据更改的以下信息:
受影响表的名称
用于标识已更改行的主键的名称、值和数据类型
根据变更数据流定义捕获的已更改行的列的名称和数据类型。
相应行的列的旧值。旧值的可用性及其跟踪的内容(可以是仅修改的列,也可以是整个跟踪的行)取决于用户配置的值捕获类型。
相应行的新列值。新值的可用性及其跟踪的内容取决于用户配置的价值捕获类型。
修改类型(插入、更新或删除)
提交时间戳
交易 ID
记录序列号
数据更改记录的值捕获类型。
如需深入了解数据更改记录的结构,请参阅数据更改记录。
数据保留
变更数据流会将其数据变更记录保留一段时间,该时间介于 1 天到 30 天之间。您可以使用 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
。您可以同时设置一个或多个过滤条件。
您可以在创建变更数据流时添加表修改类型过滤条件,也可以修改现有变更数据流的表修改类型过滤条件。
事务级记录排除
默认情况下,变更数据流会监控数据库中的所有写入事务,因为 allow_txn_exclusion
DDL 选项设置为 false
。您可以将 allow_txn_exclusion
选项设置为 true
,以使变更数据流忽略指定写入事务中的记录。如果您未将此选项设置为 true
,则系统会监控所有写入事务,即使您在写入事务中使用 exclude_txn_from_change_streams
参数也是如此。
您可以在创建变更数据流时启用此选项,也可以修改现有变更数据流。
从变更数据流中排除写入事务
如需从变更数据流中排除写入事务,您必须将 exclude_txn_from_change_streams
参数设为 true
。此参数是 TransactionOptions
和 BatchWriteRequest
方法的一部分。此参数的默认值为 false
。您可以使用 RPC API、REST API 或客户端库设置此参数。如需了解详情,请参阅指定要从变更数据流中排除的写入事务。
对于只读事务,您无法将此参数设置为 true
。如果您这样做,API 会返回无效实参错误。
对于监控事务修改的列的变更数据流,当 exclude_txn_from_change_streams
设置为 true
时,可能会出现以下两种情况:
- 如果 DDL 选项
allow_txn_exclusion
设置为true
,则相应事务中进行的更新不会记录在更改流中。 - 如果您未设置 DDL 选项
allow_txn_exclusion
,或者将其设置为false
,则此事务中进行的更新会记录在变更数据流中。
如果您未设置 exclude_txn_from_change_streams
选项,或者将其设置为 false
,则任何监控事务修改的列的变更数据流都会捕获相应事务中进行的更新。
读取变更数据流
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 连接器一样读取数据更改记录,在读取变更数据流数据时提供尽可能低的延迟时间,而不是提供 Dataflow 的灵活性。
如需了解详情,请参阅查询变更数据流。如需更详细地了解如何查询变更数据流以及如何解读返回的记录,请参阅变更数据流分区、记录和查询。
使用 Kafka 连接器
Kafka 连接器会将变更数据流记录直接输出到 Kafka 主题中。它抽象化了使用 Spanner API 查询变更数据流的细节。
如需详细了解变更数据流和 Kafka 连接器如何协同工作,请参阅使用 Kafka 连接器构建变更数据流连接。
限制
变更数据流存在多项限制,包括数据库可拥有的变更数据流数量上限,以及可监控单个列的数据流数量上限。如需查看完整列表,请参阅更改流限制。
权限
更改流使用以下内容:
创建、更新或舍弃变更数据流需要
spanner.databases.updateDdl
。读取变更数据流的数据需要
spanner.databases.select
。
如果使用 SpannerIO 连接器,则读取变更数据流数据的 Dataflow 作业的所有者需要在应用数据库或单独的元数据数据库中拥有额外的 IAM 权限;请参阅创建元数据数据库。
后续步骤
了解用于创建和管理变更数据流的 DDL 语法。
使用变更数据流和模板将 Spanner 中的更改复制到 BigQuery 或 Cloud Storage。
详细了解如何构建 Dataflow 流水线来处理变更数据流数据。
进一步了解变更数据流详情,包括变更数据流架构的更多详情、如何使用 API 查询变更数据流以及如何解读返回的记录。
详细了解如何使用 Kafka 连接器处理变更数据流数据。