跳到主要内容

~/posts · 2026.11.06

引用能省一份文件,也得防止另一台设备把它删了

S3 上的发布和回收没有跨对象事务,进程内加锁挡不住另一个客户端。

2 分钟 devshan

附件改成内容引用以后,保存省下了重新传文件的流量,删除却多了个并发问题。

设备 A 准备保存新引用,设备 B 同时删掉最后一个旧引用。B 扫描时还看不到 A 的操作,接着 A 发布了新条目,B 再把底下的内容删掉,就留下一个名字正常却打不开的文件。两台设备各有自己的 Go 核心,本机 mutex 管不到对方。

我保留了明确的持有记录:文件条目、记录附件、未完成提交和活跃读取分别用了什么。引用计数只作辅助,查问题时能沿着持有关系找到来源。

内容准备回收时会进入退休状态,停止接受新引用。迟到的发布要失败或重新读取状态。

留下能恢复的发布记录

S3 条件写入能保护一个对象,多对象操作还得自己处理。发布前先记录意图,取得当前操作的持有,再进入允许发布的阶段。目标文档带回执按预期版本写入,失败尝试也只能释放自己的持有。

响应丢失后,另一个核心可以用同一操作身份继续核对。已被接受但结果未确认的发布会保留,等恢复流程查清楚再处理。一组文件的目录和条目也一起对外可见。

测试用了两个独立核心,在关键写入处交错创建、删除和保存,再插入失败让另一端恢复。我核对重复条目、引用、真实附件字节和回收结果。引用读取不全时延后清理,能够确认无持有的内容再回收。