使用 TTL

本页面讨论 Cloud Spanner 表上的存留时间 (TTL)。如需了解 TTL,请参阅 TTL 简介

准备工作

启用备份和时间点恢复

在向表添加行删除政策之前,建议您启用 Cloud Spanner 备份和恢复。这样,您就可以在意外删除具有行删除政策的数据的情况下完全恢复数据库。

如果您已启用时间点恢复,并且已删除的数据在已配置的版本保留期限内,则可以查看和恢复这些数据,而不必从备份进行完全恢复。如需了解如何读取过去的数据,请参阅执行过时读取

清理旧数据

如果这是您第一次向表中添加行删除政策,并且您希望第一次运行删除多个行,请考虑先通过 PartitionDML 手动清理旧数据。这样,您就可以更好地控制资源使用情况,而不是将其留给 TTL 后台进程。行删除政策以低优先级运行,非常适合增量清理。但是,由于 Cloud Spanner 的内部工作调度器会优先处理其他工作(例如用户查询),这可能会延长删除繁忙数据库中的初始行所需的时间。

验证您的条件

如果您希望在启用 TTL 之前验证行删除政策将会影响的数据,则可以使用相同的条件查询表。例如:

SELECT COUNT(*) FROM CalculatedRoutes
  WHERE TIMESTAMP_ADD(CreatedAt, INTERVAL 30 DAY) < CURRENT_TIMESTAMP();

所需权限

要更改数据库的架构,您必须具有 spanner.databases.updateDdl 权限。如需了解详情,请参阅 Cloud Spanner 的访问权限控制

Syntax

使用 CREATE TABLEALTER TABLE 语句中的行删除政策子句对表定义行删除政策。此子句包含列的表达式和间隔。

ROW DELETION POLICY (OLDER_THAN(timestamp_column, INTERVAL num_days DAY));

其中:

  • timestamp_column 必须是类型为 TIMESTAMP 的现有列。包含提交时间戳的列是有效的,生成的列也是如此。但是,您无法指定引用提交时间戳列的生成列。

  • num_daystimestamp_column 中将行标记为待删除的时间戳之后的天数。该值必须是非负整数,DAY 是唯一支持的单位。

创建行删除政策

您可以在创建新表时指定行删除政策,也可以向现有表添加政策。

如需在创建表时添加政策,请执行以下操作:

CREATE TABLE MyTable(
  Key INT64,
  CreatedAt TIMESTAMP,
) PRIMARY KEY (Key)
, ROW DELETION POLICY (OLDER_THAN(CreatedAt, INTERVAL 30 DAY));

如需向现有表添加政策,请使用 ALTER TABLE 语句。每个表最多只能有一个行删除政策。将行删除政策添加到具有现有政策的表将失败并报错。请参阅生成的列上的 TTL 以指定更复杂的行删除逻辑。

ALTER TABLE MyTable ADD ROW DELETION POLICY (OLDER_THAN(CreatedAt, INTERVAL 1 DAY));

限制

您无法在以下对象上创建行删除政策:

  • 外键引用的表上。
  • 在外键引用的表的父表上。

在以下示例中,您无法向 Customers 表添加行删除政策,因为 Orders 表中的外键引用了该政策,而删除客户可能会违反此限制条件。

CREATE TABLE Customers (
  CustomerID INT64,
  CreatedAt TIMESTAMP
) PRIMARY KEY (CustomerID)

CREATE TABLE Orders (
  OrderID INT64,
  CustomerID INT64,
  CONSTRAINT FK_CustomerOrder FOREIGN KEY (CustomerID) REFERENCES Customers (CustomerID)
) PRIMARY KEY (OrderID)

具有默认值的列的 TTL

行删除政策可以使用具有默认值的 TIMESTAMP 列。典型的默认值为 CURRENT_TIMESTAMP()。如果没有为列明确赋值,或者 INSERTUPDATE 语句将列设置为默认值,则规则计算会使用默认值。

在以下示例中,表 Customers 中列 CreatedAt 的默认值是创建该行的时间戳。

CREATE TABLE Customers (
   CustomerID INT64,
   CreatedAt TIMESTAMP DEFAULT (CURRENT_TIMESTAMP())
) PRIMARY KEY (CustomerID);

如需了解详情,请参阅“Google 标准 SQL 数据定义语言”中的 DEFAULT (表达式)

生成的列上的 TTL

行删除政策可以使用生成的列来表达更复杂的规则。例如,您可以为多个列的最大时间戳定义行删除政策,或将另一个值映射到时间戳。

示例

以下示例展示了用于跟踪 OrderTable 中销售订单的表。表所有者想要设置一个行删除政策,以便在 30 天后删除已取消的订单,并在 180 天后删除未取消的订单。

Cloud Spanner TTL 仅允许每个表有一个行删除政策。要在单个列中表示这两个条件,您可以将生成的列与 IF 语句结合使用:

CREATE TABLE OrderTable (
  OrderId INT64 NOT NULL,
  OrderStatus STRING(30) NOT NULL,
  LastModifiedDate TIMESTAMP NOT NULL,
  ExpiredDate TIMESTAMP AS (IF(OrderStatus = "Cancelled",
    TIMESTAMP_ADD(LastModifiedDate, INTERVAL 30 DAY),
    TIMESTAMP_ADD(LastModifiedDate, INTERVAL 180 DAY))) STORED,
) PRIMARY KEY(OrderId)
, ROW DELETION POLICY (OLDER_THAN(ExpiredDate, INTERVAL 0 DAY));

该语句会创建一个名为 ExpiredDate 的列,该列会根据订单状态向 LastModifiedDate 添加 30 天或 180 天。然后通过指定 INTERVAL 0 DAY,将行删除政策指定为让行在 ExpiredDate 列中存储的日期过期。

TTL 和交错表

交错表是将一对多子表中的相关行与父表中的行相关联的性能优化。如需在父表上添加行删除政策,所有交错子表都必须指定 ON DELETE CASCADE,这意味着子行将与父行一起以原子方式删除。这样可以确保参照完整性,以便父表上的删除也会删除同一事务中的相关子行。Cloud Spanner TTL 不支持 ON DELETE NO ACTION

事务大小上限

Cloud Spanner 具有事务大小限制。使用编入索引的列对大型父子层次结构进行级联删除可能会超出这些限制,并导致一个或多个 TTL 操作失败。对于失败的操作,TTL 将使用较小的批量进行重试,最小的批量为单个父行。但是,即使是单个父行的大型子层次结构仍有可能超出变更限制。

TTL 指标中将会报告失败的操作。

如果单个行由于太大而无法删除,则除了父表上的行之外,您还可以直接在子表上附加一个行删除政策。子表的政策应该配置为先删除子行,然后再删除父行。

当以下两个语句适用时,请考虑将行删除政策附加到子表:

  • 子表具有任何与之关联的全局索引;且
  • 每个父行预计包含大量 (>100) 子行。

删除行删除政策

您可以从表中删除现有行删除政策。如果表上没有行删除政策,则返回错误。

ALTER TABLE MyTable DROP ROW DELETION POLICY;

删除行删除政策会立即中止在后台运行的任何 TTL 进程。正在进行的进程已删除的所有行都将被删除。

删除行删除政策引用的列

Cloud Spanner 不允许删除行删除政策引用的列。您必须先删除行删除政策,然后才能删除该列。

修改行删除政策

您可以更改现有行删除政策的列或间隔表达式。以下示例将列从 CreatedAt 切换到 ModifiedAt,并将间隔从 1 DAY 扩展到 7 DAY。如果表上没有行删除政策,则返回错误。

ALTER TABLE MyTable REPLACE ROW DELETION POLICY (OLDER_THAN(ModifiedAt, INTERVAL 7 DAY));