← 中文资源

简体中文版本

用检查点表与演练安全执行批量删除

先把待删行落进检查点表,核对演练计数,再分批有界删除,全程保留即时恢复路径。

阅读英文原文

目标

每一次批量删除灾难的形状都相同:差一个运算符的 WHERE、放进单个事务、唯一的恢复手段是几小时前的备份。检查点模式把“勇气需求”从流程里拿掉:先把待删 id 落进草稿表、把选择当数据来评审、由该表驱动分批删除、并在签署确认前一直保留 id 清单。恢复路径从此是一条 INSERT SELECT,而不是一个周末。

步骤要点

  1. 用 CREATE TABLE AS 把符合保留策略的 id 落入检查点表并建唯一索引,此步对生产数据只读。
  2. 演练评审:统计检查点行数与被选行的 last_seen_at 上下界,确认 3000 万行与 18 个月口径吻合。
  3. 循环执行“CTE 取 5 万 id → DELETE 主表 → 删除检查点对应行”,剩余检查点行数即实时进度。
  4. 完成后先别删表:错误可凭检查点残余/归档一键 INSERT SELECT 恢复。
  5. pg_dump 导出检查点表留作审计记录,再 DROP 清理草稿 schema。

排错提示

运行期间又有新行符合谓词是正常的,检查点冻结了选择、正好避免追赶移动靶,下一轮再处理;批次越跑越慢多因外键逐行校验,可在窗口期 DEFERRABLE 化或先批量处理子表;检查点表堆积是草稿债,归档与 DROP 必须写进同一步骤。另外恢复路径只恢复行,不恢复已发出的下游事件,需与消费方协调。

适用边界

检查点会多付一次全表扫描与临时存储,极小规模清理用单个事务更简单;归档清单回答“删了什么”,但不回答外键约束重建等结构副作用。

代码示例

-- Stage first, delete later
CREATE TABLE purge_sessions_2026_10 AS
SELECT id FROM sessions
WHERE last_seen_at < now() - interval '18 months';

-- The batch loop consumes the checkpoint
WITH batch AS (SELECT id FROM purge_sessions_2026_10 LIMIT 50000)
DELETE FROM sessions WHERE id IN (SELECT id FROM batch);