孤儿文件怎么清
先设一个规模:季度对存储账单,附件表 8 万行,桶里躺着 9.3 万个对象,多出的 1.3 万个没人叫得出名字;报障从反方向来,附件列表里几条记录点开是 404。一边是桶里有、库里没有,一边是库里有、桶里没有,桶那边差得大得多,库那边那几条却是用户直接撞上的。(这两个数是示例口径,按常见 B 端附件量级取整,不是某个真实项目的账单;换成你系统里的真实数字,下面每一步照走。)
结论一句话:孤儿文件靠定期对账加宽限期清,删任何东西之前先按成因分类——桶和附件表是两套各记各的账(直传架构里字节不经过应用服务器,这篇系列反复出现这句),没有一方天然是对的。
按成因分三类,对策不一样:
| 成因 | 特征 | 对策 |
|---|---|---|
| 传了没落库 | 对象上传成功但回调丢失、用户传一半放弃 | 宽限 7 天后删对象,库里本来就没有行 |
| 业务删了记录 | 行软删,桶里对象还在等回收 | 软删满 30 天删对象,回填 purged_at |
| 库里有、桶里没有 | 预览 404,多半是桶被手动清过或对象名改过 | 不清,进告警让人判断 |
对账脚本每天跑一次,两个方向分开列。第二类能自动处理的前提是那条判定 SQL 站得住:
-- 软删满 30 天、还没回填 purged_at 的附件,桶里对象等回收
SELECT id, object_key, deleted_at
FROM attachment
WHERE deleted_at IS NOT NULL
AND deleted_at < NOW() - INTERVAL 30 DAY
AND purged_at IS NULL
LIMIT 500;
三条注意,每条带一个不做会怎样的后果。宽限期必须隔开删除动作和业务动作,用户点错删除要能恢复,30 天是这个恢复窗口的下限;桶对象的删除要留下记录,purged_at 就是干这个的,没有它,同一批对象每次扫描都会被判成待删,重跑一脚本就是一次事故;库里有、桶里没有的那一类不进自动清理队列,它自己就是事故现场,自动化的任务是把人带到现场,不是替人打扫。
系列:深文 对象存储:目录、权限、生命周期 | 相关 文件上传:直传、断点续传、秒传各解决什么 | 技术纵深系列索引
相关文章
多租户不是加一个 tenant_id:三种隔离模型与选型
多租户不是加个 tenant_id 就完了。共享表、独立 schema、独立库,三种模型的成本和失效方式不一样。这篇按 Spring Boot + MySQL 讲我怎么选、怎么落地,以及异步、定时任务、MQ、导出这些地方怎么漏。
部门、门店、代理商,一张 sys_dept 表撑不住这三层
需求说“要加门店”,开发在 sys_dept 上加了一列 type,两行代码当天上线。三个月后加代理商,type 多个值;半年后要求门店同时归区域运营、归总部核算,parent_id 只有一个。行政组织、经营单元、外部主体这三层的差别不在层级深浅,在于谁需要历史、谁会算钱、谁是外部人。
权限系统:RBAC 不够用的地方,数据权限怎么补
一句“销售只能看自己的客户”,里面藏着行、列、入口、失效四个判定,RBAC 一个都答不了。这篇讲数据范围怎么落成一条 SQL、@DataScope 这类拼法会在哪一层漏、成本价为什么会整整齐齐出现在导出的 Excel 里,以及为什么详情接口是行级权限最大的口子。