本页面介绍了如何在 Spanner 表上使用存留时间 (TTL)。接收者 如需了解详情,请参阅 TTL 简介。
准备工作
开始之前,请遵循以下最佳实践。
启用备份和时间点恢复
在将 TTL 添加到您的表之前,我们建议您先启用 Spanner 备份和恢复。这样, 您可以完全恢复数据库,以防您不小心删除 TTL 政策。
如果您已启用时间点恢复,并且已删除的数据在已配置的版本保留期限内,则可以查看和恢复这些数据,而不必从备份进行完全恢复。如需了解如何读取过去的数据,请参阅执行过时读取。
清理旧数据
如果这是您第一次使用 TTL,并且您希望首次运行 删除多行,请考虑先使用以下代码手动清理旧数据 分区 DML。 这样,您就可以更好地控制资源使用情况,而不必将其留给 TTL 后台进程。TTL 以低优先级运行,非常适合用于增量更改 清理。但是,这可能会延长删除 由于 Spanner 的内部原因, 工作调度程序会优先处理其他工作,例如用户查询。
验证您的条件
对于 GoogleSQL 表,如果您希望在启用 TTL 之前验证行删除政策将会影响的数据,则可以使用相同的条件查询表。例如:
GoogleSQL
SELECT COUNT(*)
FROM CalculatedRoutes
WHERE TIMESTAMP_ADD(CreatedAt, INTERVAL 30 DAY) < CURRENT_TIMESTAMP();
所需权限
如需更改数据库的架构,您必须具有 spanner.databases.updateDdl 权限。有关详情,请参阅 Spanner 的访问权限控制。
创建行删除政策
GoogleSQL
如需使用 GoogleSQL 创建行删除政策,您可以在创建新表时定义 ROW DELETION POLICY
子句,也可以向现有表添加政策。此子句包含一个列的表达式和一个
。
如需在创建表时添加政策,请执行以下操作:
CREATE TABLE MyTable( Key INT64, CreatedAt TIMESTAMP, ) PRIMARY KEY (Key), ROW DELETION POLICY (OLDER_THAN(timestamp_column, INTERVAL num_days DAY));
其中:
“
timestamp_column
”必须是现有列 类型为TIMESTAMP
。包含以下内容的列 提交时间戳有效,同样 生成的列。但是,您不能 指定引用了提交时间戳列的生成列。num_days
是timestamp_column
(其中相应行被标记了)中的时间戳 删除。该值必须是非负整数,DAY
是唯一的 支持的单位。
如需向现有表添加政策,请使用 ALTER TABLE
语句。每个表最多只能有一个行删除政策。添加行删除政策
附加到具有现有政策的表将失败并显示错误。请参阅生成的列上的 TTL 以指定更复杂的行删除逻辑。
ALTER TABLE Albums ADD ROW DELETION POLICY (OLDER_THAN(timestamp_column, INTERVAL num_days DAY));
PostgreSQL
如需使用 PostgreSQL 创建行删除政策,您可以在创建新表时定义 TTL INTERVAL
子句,也可以向现有表添加政策。
如需在创建表时添加政策,请执行以下操作:
CREATE TABLE mytable ( key bigint NOT NULL, timestamp_column_name TIMESTAMPTZ, PRIMARY KEY(key) ) TTL INTERVAL interval_spec ON timestamp_column_name;
其中:
“
timestamp_column_name
”必须是包含 数据类型为TIMESTAMPTZ
。您需要在CREATE TABLE
语句中创建此列。包含以下内容的列 提交时间戳有效,同样 生成的列。但是,您不能 指定引用了提交时间戳列的生成列。interval_spec
是timestamp_column_name
中将行标记为待删除的时间戳之后的天数。该值必须是非负整数,并且必须为整数天数。例如,允许使用'3 days'
,但'3 days - 2 minutes'
会返回错误。
如需向现有表添加政策,请使用 ALTER TABLE
语句。答
表最多只能有一项 TTL 政策。将 TTL 政策添加到采用如下设置的表
现有政策因错误而失败。请参阅
对生成的列采用 TTL 来指定更多
复杂的 TTL 逻辑。
如需向现有表添加政策,请执行以下操作:
ALTER TABLE albums
ADD COLUMN timestampcolumn TIMESTAMPTZ;
ALTER TABLE albums
ADD TTL INTERVAL '5 days' ON timestampcolumn;
限制
行删除政策具有以下限制。
对外键引用的表使用 TTL
您无法在以下对象上创建行删除政策:
- 在由 不包含 ON 的外键 DELETE CASCADE 约束条件。
- 在由非外部键引用的表的父级上 包含 ON DELETE CASCADE 参照操作。
在以下示例中,您不能向
Customers
表,因为它由 Orders
中的外键引用
表,该表没有 ON DELETE CASCADE 约束条件。
删除客户可能会违反此外键限制条件。此外,你也不能
向 Districts
表添加行删除政策。从以下位置删除行:
Districts
可能会导致删除操作在子 Customers
表中级联,这
可能违反 Orders
表的外键约束条件。
GoogleSQL
CREATE TABLE Districts (
DistrictID INT64
) PRIMARY KEY (DistrictID);
CREATE TABLE Customers (
DistrictID INT64,
CustomerID INT64,
CreatedAt TIMESTAMP
) PRIMARY KEY (DistrictID, CustomerID),
INTERLEAVE IN PARENT Districts ON DELETE CASCADE;
CREATE TABLE Orders (
OrderID INT64,
DistrictID INT64,
CustomerID INT64,
CONSTRAINT FK_CustomerOrder FOREIGN KEY (DistrictID, CustomerID) REFERENCES Customers (DistrictID, CustomerID)
) PRIMARY KEY (OrderID);
PostgreSQL
CREATE TABLE districts (
districtid bigint NOT NULL,
PRIMARY KEY(districtid)
);
CREATE TABLE customers (
districtid bigint NOT NULL,
customerid bigint NOT NULL,
createdat timestamptz,
PRIMARY KEY(districtid, customerid)
) INTERLEAVE IN PARENT districts ON DELETE CASCADE;
CREATE TABLE orders (
orderid bigint NOT NULL,
districtid bigint,
customerid bigint,
PRIMARY KEY(orderid),
CONSTRAINT fk_customerorder FOREIGN KEY (districtid, customerid) REFERENCES customers (districtid, customerid)
);
您可以在由使用 ON DELETE CASCADE
的外键约束条件引用的表上创建行删除政策。在以下示例中,您可以
在 Customers
表上创建行删除政策
在 Orders
表中定义的外键约束条件 CustomerOrder
。时间
TTL 会删除 Customers
中的行,删除操作会级联到匹配的行
位于“Orders
”表中
GoogleSQL
CREATE TABLE Districts (
DistrictID INT64,
CreatedAt TIMESTAMP
) PRIMARY KEY (DistrictID),
ROW DELETION POLICY (OLDER_THAN(CreatedAt, INTERVAL 1 DAY));
CREATE TABLE Customers (
DistrictID INT64,
CustomerID INT64,
CreatedAt TIMESTAMP
) PRIMARY KEY (DistrictID, CustomerID),
INTERLEAVE IN PARENT Districts ON DELETE CASCADE,
ROW DELETION POLICY (OLDER_THAN(CreatedAt, INTERVAL 1 DAY));
CREATE TABLE Orders (
OrderID INT64,
DistrictID INT64,
CustomerID INT64,
CONSTRAINT FK_CustomerOrder FOREIGN KEY (DistrictID, CustomerID) REFERENCES Customers (DistrictID, CustomerID) ON DELETE CASCADE
) PRIMARY KEY (OrderID);
PostgreSQL
CREATE TABLE districts (
districtid bigint NOT NULL,
createdat timestamptz,
PRIMARY KEY(districtid)
) TTL INTERVAL '1 day' ON createdat;
CREATE TABLE customers (
districtid bigint NOT NULL,
customerid bigint NOT NULL,
createdat timestamptz,
PRIMARY KEY(districtid, customerid)
) INTERLEAVE IN PARENT districts ON DELETE CASCADE
TTL INTERVAL '1 day' ON createdat;
CREATE TABLE orders (
orderid bigint NOT NULL,
districtid bigint,
customerid bigint,
PRIMARY KEY(orderid),
CONSTRAINT fk_customerorder FOREIGN KEY (districtid, customerid) REFERENCES customers (districtid, customerid) ON DELETE CASCADE
);
同样,您可以在一个表的父表上创建行删除政策,
由 ON DELETE CASCADE
外键约束条件引用。
采用默认值的列的 TTL
行删除政策可以使用具有默认值的时间戳列。典型
默认值为 CURRENT_TIMESTAMP
。如果没有明确向
或者通过 INSERT
将此列设置为默认值,或者
UPDATE
语句,则在规则计算中使用默认值。
在以下示例中,表中 CreatedAt
列的默认值
Customers
是创建该行的时间戳。
GoogleSQL
CREATE TABLE Customers (
CustomerID INT64,
CreatedAt TIMESTAMP DEFAULT (CURRENT_TIMESTAMP())
) PRIMARY KEY (CustomerID);
如需了解详情,请参阅“GoogleSQL 数据定义语言”中的 DEFAULT (expression)。
PostgreSQL
CREATE TABLE customers (
customerid bigint NOT NULL,
createdat timestamptz DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY(customerid)
);
如需了解详情,请参阅创建表 。
生成的列上的 TTL
行删除政策可以使用生成的列
来表达更复杂的规则例如,您可以定义删除行
针对多列的 greatest
时间戳(GoogleSQL 或 PostgreSQL)应用的政策,或者将另一个值映射到
时间戳。
GoogleSQL
下表(名为 Orders
)用于跟踪销售订单。
表所有者想要设置一个行删除政策,以便在 30 天后删除已取消的订单,并在 180 天后删除未取消的订单。
Spanner TTL 仅允许每个表有一项行删除政策。接收者
在单个列中表示两个条件,您可以使用生成的列
使用 IF
语句:
CREATE TABLE Orders (
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
列中存储的日期过期。
PostgreSQL
下表(名为 Orders
)用于跟踪销售订单。
表所有者想要设置用于删除行的行删除政策
处于非活跃状态 30 天后。
Spanner TTL 仅允许每个表有一项行删除政策。接收者 在单个列中表示两个条件,则可以创建一个生成的 列:
CREATE TABLE orders (
orderid bigint NOT NULL,
orderstatus varchar(30) NOT NULL,
createdate timestamptz NOT NULL,
lastmodifieddate timestamptz,
expireddate timestamptz GENERATED ALWAYS AS (GREATEST(createdate, lastmodifieddate)) STORED,
PRIMARY KEY(orderid)
) TTL INTERVAL '30 days' ON expireddate;
该语句会创建一个名为 ExpiredDate
的生成列,用于评估
两个日期(LastModifiedDate
或 CreateDate
)中最近的那个日期。
然后,定义行删除政策,使行在
订单,或者订单在这 30 天内发生了修改
则会将删除期限再延长 30 天。
TTL 和交错表
交错表是将一对多子表中的相关行与父表中的行相关联的性能优化。如需在父表上添加行删除政策,所有交错子表都必须指定 ON DELETE CASCADE
,这意味着子行将与父行一起以原子方式删除。这样可以确保参照完整性,以便父表上的删除也会删除同一事务中的相关子行。Spanner TTL 的用途
不支持 ON DELETE NO ACTION
。
事务大小上限
Spanner 设有事务大小限制。 在具有索引列的大型父子层次结构上执行级联删除 超出这些限制,并导致一项或多项 TTL 操作失败。对于失败的操作,TTL 将使用较小的批量进行重试,最小的批量为单个父行。但是,即使是单个父行的大型子层次结构仍有可能超出变更限制。
TTL 指标中将会报告失败的操作。
如果单行及其交错的子项因太大而无法删除,可以 除了 一个父表。子表上的政策应配置为 先删除父行,再删除子行。
当以下两个语句适用时,请考虑将行删除政策附加到子表:
- 子表具有任何与之关联的全局索引;且
- 每个父行预计包含大量 (>100) 子行。
删除行删除政策
您可以从表中删除现有行删除政策。如果表上没有行删除政策,则返回错误。
GoogleSQL
ALTER TABLE MyTable
DROP ROW DELETION POLICY;
PostgreSQL
ALTER TABLE mytable
DROP TTL;
删除行删除政策会立即中止在后台运行的任何 TTL 进程。正在进行的进程已删除的所有行都将被删除。
删除行删除政策引用的列
Spanner 不允许您删除被引用的列 行删除政策您必须先删除行删除政策,然后才能删除该列。
查看表的行删除政策
您可以查看 Spanner 表的行删除政策。
GoogleSQL
SELECT TABLE_NAME, ROW_DELETION_POLICY_EXPRESSION
FROM INFORMATION_SCHEMA.TABLES
WHERE ROW_DELETION_POLICY_EXPRESSION IS NOT NULL;
如需了解详情,请参阅 GoogleSQL 方言数据库的信息架构。
PostgreSQL
SELECT table_name, row_deletion_policy_expression
FROM information_schema.tables
WHERE row_deletion_policy_expression is not null;
如需了解详情,请参阅 PostgreSQL 方言数据库的信息架构。
修改行删除政策
您可以更改现有行删除政策的列或间隔表达式。以下示例将列从 CreatedAt
切换为
ModifiedAt
,并将间隔从 1 DAY
延长到 7 DAY
。这将返回一个
错误。
GoogleSQL
ALTER TABLE MyTable
REPLACE ROW DELETION POLICY (OLDER_THAN(ModifiedAt, INTERVAL 7 DAY));
PostgreSQL
ALTER TABLE mytable
ALTER TTL INTERVAL '7 days' ON timestampcolumn;