3159 字
约 10 分钟
15
S11-A13 · 数据保留与归档:删到什么程度才算完
2024-12-31
2026-11-09

用户点了“删除账号”,接口返回 200,文档写“数据已删除”。实际上:主库那行没了,备份里还在,搜索索引还能搜到,宽表还在,日志里留着手机号。半年后有人问“真的删了吗”,没人答得上来。

保留与归档的分岔点不是“要不要留”,而是删除请求要覆盖哪些位置:答不上“一共几处存在这份数据”,删除就只删了看得见的那一处。


1. "删除"从来不是一次操作

位置 常见遗漏原因 删除难度
主库表 关联表、历史表未删 低
备份与快照 不可改,只能等过期 高
搜索/缓存索引 异步同步,有延迟 中
仓库与宽表 CDC 复制,源删不移 高
日志与遥测 文本带 PII,无人扫 高
派生数据(报表、样本) 脱敏但可反推 高

先做清单比先写脚本重要:漏一项,后面都有缺口。

判据:画不出这份数据的流转图(写到哪、复制到哪、谁加工),就不要宣称支持删除。


2. 保留期由三个来源叠加,取最严的那个

来源 典型要求 与谁冲突
业务需要 能查近 N 个月订单 成本:越长越贵
合规规定 某些数据必须留存 N 年 删除请求:不能删
诉讼与审计保全 争议期禁止删除 合规的最短期限

最终保留期取三者最长。常见错误是只按业务定,纠纷时发现数据已删;另一种是把合规要求套到所有数据上,成本翻倍。

冲突要显式登记:哪类数据因哪条要求留到何时、谁批准例外。口头例外会变成永久保留。


3. 软删与硬删:两种语义,别混用

软删:置 deleted_at,读写都过滤,物理行保留
  用途:误删恢复、审计留痕、外键完整性
  风险:所有查询必须过滤,漏一处就是数据泄漏
硬删:DELETE 或按分区 DROP
  用途:合规删除、大表清理
  风险:不可恢复,必须确认备份与派生数据也覆盖

最危险的是“软删当成硬删”:对外说已删除,实际只打了标记,任一处漏了过滤就还能读到。合规意义上软删≠删除。

判据:对外承诺“已删除”的路径必须走硬删 + 派生清理;软删只用于内部容错,且应在一周内转成硬删。


4. 三种归档形态与它们的代价

形态 保留什么 可查询性 成本
原表归档 完整行,同库异表 高,SQL 直查 存储最贵
列存/仓库归档 完整行,压缩列式 中,适合聚合 低,查询另建
文件归档 压缩包或 Parquet 低,需取回解析 最便宜,取回最慢

取决于归档后还有没有人查、多久查一次:一年查一次,文件归档足够;每周对账要查,等于每次写一个取回任务。

最常见的失误是没写取回路径:归档时觉得“反正不会查”,出事时要解压几十 GB 才查一行;取回脚本要随归档交付。


5. 可查询性:归档之后还能查什么

需求 可行做法 不可行的做法
查单条明细 主键索引 + 取回 每次全量解压
范围聚合 仓库预聚合表 直接扫归档
客服查历史 冷查询入口 + 权限 混在在线接口
审计导出 批量导出任务 逐条点查

关键是点查与聚合:点查要索引与快速定位,聚合要列存。一套归档满足两者,成本接近保留全量。

判据:归档前先统计“归档后还会执行的查询类型”,超过两类说明形态选错了。


6. 备份里的删除:只能等过期

备份不可变是设计目标,所以删除在备份侧的生效方式是等过期,而非“删掉备份里那条”。

可行:缩短备份保留期 + 加密密钥按期轮换销毁
      记录"某时间点之后写入的备份不含该用户数据"
不可行:修改已有备份、逐条删除备份中的记录

合规上通常接受“备份在 N 天后自然过期”,前提是N 写进对外承诺。写“立即删除”、实际 35 天才过期,是最容易被指出的差距。

密钥销毁是等效手段:备份加密,销毁密钥即不可读;前提是密钥管理真的按期执行。


7. 日志与遥测:最容易漏的一处

位置 为什么带 PII 处理
应用日志 打印完整请求体 结构化脱敏,禁整包打印
网关日志 URL 带手机号、token 参数白名单,其余丢弃
错误追踪 栈带上下文变量 采集端过滤字段
指标标签 user_id 当 label 禁止高基数标签

难处在已写下去无法追溯清理,所以治理只能在采集端:敏感字段写入前脱敏,保留期短于业务数据。

判据:日志保留期不应长于业务数据。日志 90 天、业务 3 年,意味着删除在日志侧要等 90 天,这数字必须能解释。


8. 派生数据:删了源,副本还在

必须一并处理的派生位置:
1 缓存(Redis / 本地缓存)          → 按 key 删 + 版本号失效
2 搜索索引                          → 按文档 id 删,再触发重建
3 数仓宽表与汇总表                  → 按分区重算,或整分区重建
4 报表快照与导出文件                → 记录生成批次,按批次清理
5 模型训练样本与特征库              → 记录样本来源,支持按用户撤回
6 消息队列的滞留消息                → 消费即删,或按 TTL 过期

第 5 项最难:样本混入数据集后,“撤回”需样本级溯源;做不到只能承诺“后续不再使用”,并写进说明。

判据:派生数据能否删除取决于是否记录来源 id;没有标记,删除只能整批重算。


9. 执行链路:一次删除要经过几步

1 受理:校验请求合法性,落一条删除工单(含请求时间与范围)
2 标记:主库软删,立即停止对外可见
3 传播:发出删除事件,各消费者幂等处理
4 硬删:按分区或按主键清理主库与历史表
5 派生清理:缓存、索引、宽表、导出文件
6 备份:记录"该时间点之后的备份不含此数据"
7 回执:工单置完成,保留执行日志(不含被删内容)

第 3 步事件必须幂等可重放:漏消费时要能重放,不能人工补。

判据:整条链路要能在无人干预下重跑;靠人工补的流程,第一次漏就永远漏。


10. 验证:怎么确认真的删了

-- 抽查脚本的骨架:按位置逐个确认,结果为 0 才算完成
SELECT COUNT(*) FROM orders        WHERE user_id = :uid;   -- 期望 0
SELECT COUNT(*) FROM orders_hist   WHERE user_id = :uid;   -- 期望 0
-- 搜索索引与缓存用各自的客户端按 id 校验存在性
-- 数仓按分区重算后校验汇总值

验证要留样本与时间戳,形成可复核证据链。只查主库等于没验证。

判据:每个位置都要有一条可执行断言,而非“人工确认过”,写进工单完成条件。


11. 配置与审计:把保留期写成代码

retention:
  order:        { keep: 3y,  basis: "business", archive: columnar, query: point }
  payment:      { keep: 10y, basis: "compliance", archive: original, query: audit }
  app_log:      { keep: 30d, basis: "ops", pii: scrubbed_at_ingest }
  trace:        { keep: 7d,  basis: "ops", sample: 0.1 }
  training_set: { keep: 1y,  basis: "product", revocable: true }

配置化的价值不是省事,而是可审计:有版本、有变更记录、有批准人。散在各服务的常量无法审计,也答不出为什么这张表留 5 年。

变更要留三字段:改了什么、依据哪条要求、谁批准。没有依据的保留期,半年后没人敢缩短。


12. 成本与合规的平衡

手段 省什么 代价
缩短热存期 存储与备份成本 回溯窗口变短
分层归档 存储单价 取回延迟与运维面
聚合后删明细 存储最多 失去单条追溯
加密 + 销毁密钥 备份成本 密钥管理成单点

第三项最易被误用:为省存储删明细只留汇总,遇单笔争议就无法举证。能删明细的前提是法律与业务都不再需要单条追溯,这判断不能由运维做。

判据:先算“保留成本”,再算“无法举证的成本”。后者通常更高,只是不在账单上。


13. 度量保留与删除是否真的在跑

各位置删除完成率 = 断言通过数 / 应删位置数      (目标 100%,缺口要有人认领)
超期保留量       = 超过保留期仍存在的行数        (应按月归零)
删除工单时长     = 受理 → 全链路回执的中位时间
备份过期偏差     = 实际过期 - 承诺过期           (应为 0 或负)

第二个指标最能暴露治理是否落地:写了保留期却没人执行,超期数据持续堆积。它长期不降,说明策略只是文档。


14. 排错:删除没生效的六种样子

现象 根因 处理
接口成功但数据还在 只做了软删 补硬删与派生清理
搜索还能搜到 索引未跟随删除 接事件,幂等消费
数仓仍有明细 CDC 只同步新增 透传删除 + 分区重算
备份里有 备份不可变 缩保留期 + 销毁密钥
日志有手机号 采集端未脱敏 写入前脱敏
样本无法撤回 无来源 id 补溯源或明示不可撤

15. 边界:什么时候不要做精细保留策略

场景 判断 替代做法
数据量小、无 PII 治理成本高于收益 统一保留期
必须长期留存 保留期不可调 只做归档与访问控制
单库、无派生链路 位置少,人工可控 清单 + 季度核对
业务尚未稳定 保留期频繁变 先定上限,不细分
已有合规系统 重复建设 复用审计与工单

最后一类:合规体系通常已含保留与删除要求,再建并行流程会生出两个口径。新体系的价值在执行与验证,不在再写策略文档。


16. 自测

  1. 为什么第一次交付必须是位置清单,而不是删除脚本?
  2. 保留期由三个来源叠加,冲突时按什么顺序取舍?
  3. 软删在什么情况下不能对外宣称"已删除"?
  4. 备份不可变,删除请求在备份侧靠什么生效?
  5. 派生数据里最难撤回的是哪一类,为什么?
  6. 验证删除时只查主库,会漏掉哪些位置?
S11-A13 · 数据保留与归档:删到什么程度才算完
https://www.clxhxhhr.top/posts/6251/
作者
clxstart
发布于
2024-12-31
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。