前言
我们在上篇文章《图床的防盗链、缓存和清理怎么做?》里把图床的日常维护的步骤理顺了,清理那一步还专门说过"删图之前先查引用",查引用防的是"删了网站正在用的图",但是防不住真正的手滑——rm 命令的目录写错一层、控制台批量勾选时多点了一下、清理脚本里的匹配条件少写了一截、手滑误触等等,这类误删一旦发生,如果本地还没有备份,那就救不回来了。
那么有没有一层兜底,让删错的文件还能得救?这就是对象存储的版本控制(Versioning)要干的事了。我们今天就来详细地了解一下这个好用的功能,帮助大家更好地保存珍贵的数据。
对象存储为什么要做版本控制
如果没有版本控制:一个文件传上去,再传一个同名的,旧文件就被覆盖没了;删除一个文件,它就真的没了。覆盖和删除都是物理动作,执行完就没有回头路。
开启版本控制之后,覆盖和删除就有了别的功能:
覆盖变成"追加":每次上传同名文件,都会生成一个新版本,旧版本原地保留,每个版本有自己唯一的版本 ID。想找三天前的那版,按 ID 取就行;
删除变成"打标记":删除一个文件,系统并不是把它抹掉,而是给这个文件的位置插一个删除标记(Delete Marker)——一个零字节的占位对象。这时候用正常方式去访问这个文件会返回 404,看起来像删掉了,实际上所有历史版本都还躺在版本列表里。
版本控制开启后,"删除"就只是逻辑上的隐藏,数据本身并没有离开过存储。想让它重新可见,只需要把那个删除标记删掉就行,这就是误删除还能恢复的全部原理。
版本控制就是存储这边自动给每次上传留底,服务于数据安全。

误删除的文件怎么找回
找回的路径取决于误删是怎么发生的,但核心动作只有一个:删掉文件的删除标记。
控制台是最直观的恢复入口。 各家对象存储的控制台,文件列表里都有一个"显示历史版本"一类的开关(AWS S3 叫 List versions,阿里云 OSS 叫显示历史版本),打开之后,被删的文件会带着删除标记重新出现在列表里。选中那个文件,把删除标记删掉,它就恢复成可访问状态了,至于当前版本的文件则是最近的一个非删除标记的版本。
文件多的时候,可以用 rclone 来列出版本。 rclone 是命令行里管理云存储文件的工具。
配置好 rclone 的对象存储的接入信息,运行:
rclone config按安装提示走:
1.先新建一个 remote,起个好认的名字,之后提到的命令里的“图床remote”就是它;存储类型选 Amazon S3 Compliant Storage;
2.然后填 API 密钥两件套,Access Key 和 Secret Key,这两个可以在对象存储控制台里找到;
3.如果用的不是 AWS 官方 S3 的话,还要再填一个 endpoint,也就是 API 接入地址,可以再厂商的支持文档页查得到。配完验证一下:
rclone lsd 图床remote:lsd 是列出所有存储桶的命令。能打印出对象存储的存储桶名字,这个配置就通了。
之后列出存储桶里所有文件的所有历史版本靠 --s3-versions 这个参数:
rclone lsf 图床remote:photo --s3-versions 如果要连子目录一起列,后面再补一个 -R。rclone 会把旧版本显示成“原名+时间戳”的样子,比如 photo.webp 的旧版本是 photo-v2026-05-01-120000-000.webp,时间戳插在文件名和扩展名中间,看它就能知道版本的先后。
如果只想看某一个文件的历史版本,不能直接按原名查,那样只能查到当前版本那一条。用 Linux 自带的文本过滤工具 grep 按前缀筛就行,^photo 表示只留 photo 开头的行:
rclone lsf 图床remote:photo --s3-versions | grep "^photo"photo.webp 和它的一串旧版本都会显示在结果里,不过前缀相同的其他文件(比如 photo2.webp)也会被带出来,扫一眼时间戳后缀就能认出。误删的文件想连删除标记一起看,再加一个 --s3-version-deleted 参数,被删除的文件会显示为零字节的对象。
找到想恢复的历史版本后,就可以去厂商的控制台将文件的删除标记删掉,将其恢复。
还有一类误删是"覆盖":新图传上去发现传错了,把原图顶掉了。这种不用做任何恢复操作,在版本列表里找到前一个版本 ID,直接下载回来,或者把它重新上传一次即可。
开启之前想清楚的事
版本控制不是无脑开,有两个特性决定了它更适合"想好了再开":
开了就关不回去:版本控制一旦开启,就不能彻底关闭,最多只能暂停(suspend)。暂停后新上传的文件不再生成新版本,但已经产生的旧版本全都还在。这是一扇单向门,开之前值得在测试桶里先玩一圈;
旧版本占空间:每覆盖一次就多一份实体数据,它们都算在存储容量里。图床这种传完基本不动的场景没什么压力,但如果一个桶里跑着每天覆盖写入的日志或任务文件,版本会一层一层堆下去,容量和账单一起膨胀。
我的建议是:
图床桶、备份桶这类"改得少、删不起"的桶,放心开;
高频覆盖写入的桶,要么不开,要么开之前把清理规则一起配好。
旧版本怎么清理
清理旧版本有两条路,长期靠规则,临时用命令。
生命周期规则是长期方案。 对象存储的生命周期规则可以配到"非当前版本"上:旧版本在变成非当前版本 N 天后自动删除,或者每个文件只保留最近几份旧版本。之前的文章《通过对象存储做定时备份与异地容灾》里给备份桶配的"30 天自动过期",就是生命周期规则的同款用法,同样能管旧版本。
rclone 可以做一次性清理。 桶里已经堆了一批旧版本,想立刻清掉,rclone 有一条现成的命令:
rclone backend cleanup-hidden 图床remote:photo 这条命令的范围:它删的是 photo 桶里所有文件的所有旧版本,只保留每个文件的当前版本。只想清一部分,把目录带上就行,图床如果按年份建了目录,就可以单独清某一年的旧版本:
rclone backend cleanup-hidden 图床remote:photo/2025命令后面跟的路径管的是清理边界:不跟路径,清的是整个桶;跟了路径,就只清那个目录底下的旧版本。
特别注意:删旧版本是不可逆操作。确认过要恢复的都恢复了、要留的都留了,再动手。这条命令跑完,被它清掉的版本就真的找不回来了。
总结
把对象存储的版本控制这件事收拢成三句:
原理:覆盖是追加新版本、删除只打标记,数据不会离开存储,误删能够精确恢复;
恢复:控制台打开历史版本,删掉文件的删除标记就能复活,文件多就用 rclone 的
--s3-versions把历史版本都列出来;代价:对象存储的版本控制是一个单向门,开了关不回去;旧版本会逐渐占满空间,不过配好生命周期规则就能长期无忧。
对象存储是给一个博客以及服务器减负的很好用的工具,做好版本控制,更不用担心文件被误删,更好地保障我们的数据安全。
