留存要的从来不是备份一份监管对留存的要求很少以备份的形式出现。审计日志、交易凭证、病案影像这几类数据要求方通常表述为规定期内不可修改或删除。落到存储层它要的不是多一份副本而是一段时间从对象写入的那一刻起到保留期届满为止谁都改不动、删不掉。默认的语义做不到这一点。对象存储里最后写入者覆盖权限配宽一点一条删除命令或者一次勒索加密就能把整条证据链抹掉。留存场景真正要补的不是备份策略而是写入之后的不可变性。WORMwrite once, read many说的就是这件事。各家对象存储的实现一般会拆成两层版本控制负责留下被覆盖和被删掉的旧版对象锁定负责在窗口期内挡住修改与删除。这两层是叠加关系不是二选一。RustFS 的对象锁定要求桶先开版本控制两个机制因此天然要用在一起。两道锁的分工一个管误操作一个管防篡改版本控制同一个键每次覆盖都生成新的版本 ID删除键产生删除标记而不是抹掉历史。它能接住误覆盖和误删但接不住有权限的人把当前版删掉。对象锁定作用在单个对象版本上给版本钉上保留期或依法保留。保留期内这个版本改不了也删不掉但它管不着覆盖有没有留下旧版。只开版本控制历史还在当前版照样能被删只开对象锁定覆盖这个动作本身不留痕。合规归档的常规做法是两者都开。三种保护行为的差别很实在挑错模式后面很难补救。GOVERNANCE 保留挡住删除和缩短保留期持有绕过权限并在请求里显式声明时可以绕过延长保留期则不需要绕过。COMPLIANCE 保留更硬即使调用者持有治理绕过权限也照样挡住保留截止日期可以延长但不能缩短。依法保留没有到期日状态不改回 OFF 就一直挡着治理绕过同样覆盖不了。选哪种取决于出事时你希望谁还能动手。合规证据要的是谁都动不了内部归档要的是平时锁着、急事能解。删除键但不带版本 ID 时系统生成的是删除标记受保护的版本仍然留在原地可以按版本 ID 取回。这一点决定了验证方式要验的是某个版本删不掉不是某个键删不掉。建桶与开启锁保护的是版本不是键前提先摆正。对象锁定要求桶的版本控制处于开启状态开启时机有两条建桶时一起开或者对已经开了版本控制的现有桶调用 S3 的 PutObjectLockConfiguration。准确的说法是没有版本控制的桶上加不了锁开了版本控制的桶可以补。控制台是官方明确验证过的建锁桶路径。Buckets 里选 Create Bucket填桶名打开 Object Lock控制台这时会同时打开 Version因为对象锁必须有版本控制支撑。如果还希望新写入自动带上保留期再打开 Retention选 COMPLIANCE 或 GOVERNANCE、填时长、选 Day 或 Year然后 Create。控制台的保留期输入框默认显示 180 天这是界面初始值不是推荐值按自己的留存政策改。想查看某个受保护对象打开桶选对象名Versions 和 Info 两个标签页分别能看到版本列表和 Legal Hold、RetentionPolicy 字段。命令行这边有个坑要避开。rc 0.1.29 的rc bucket create --with-lock、--with-versioning都会出现在帮助输出里但执行返回 not implemented建锁桶不要在这上面试。能正常用的是版本控制那几条rcaliassetrustfs http://localhost:9000$ACCESS_KEY$SECRET_KEY\--regionus-east-1 --bucket-lookup path rc bucket create rustfs/compliance-bucket rc bucket versionenablerustfs/compliance-bucket给具体版本上锁最直接的写法是在上传时把请求头带上官方针对 RustFS 验证过下面这两条rc object copy ./report.pdf rustfs/compliance-bucket/report.pdf\-Hx-amz-object-lock-mode:GOVERNANCE\-Hx-amz-object-lock-retain-until-date:2027-01-01T00:00:00Zrc object copy ./evidence.zip rustfs/compliance-bucket/evidence.zip\-Hx-amz-object-lock-legal-hold:ON两个保留请求头要一起给时间戳用未来的 RFC 3339 UTC 格式。查版本 ID、确认某个版本还活着rc bucket version list rustfs/compliance-bucket--jsonrc objectstatrustfs/compliance-bucket/report.pdf --version-idversion-id--jsonrc 0.1.29 不提供修改保留期或在 ON 与 OFF 之间切换依法保留的命令这类操作走控制台或 S3 SDK。保留期与依法保留两条独立的时间线桶级默认保留和显式保留是两条线。桶级默认在发起新对象版本或分段上传时计算之后放进桶的新对象自动继承显式保留设在单个版本上覆盖桶级默认。复制一个带锁对象会在目标侧生成新版本目标保留策略独立应用桶级默认不追溯已有版本。以天计最长 36,500 天以年计最长 100 年。保留期届满后这个版本可以删除非它同时挂着依法保留。依法保留和保留期互不干扰可以同时生效。保留期管时间依法保留管这件事还没了结比如处在诉讼期的凭证。保留期到了依法保留还在对象照样删不掉。S3 标准侧的对应调用是 PutObjectRetention 和 PutObjectLegalHold控制台的 Info 页能直接看到某个版本的 Legal Hold 和 RetentionPolicy 字段。上生产前先看这几条边界别暂停对象锁定桶的版本控制。暂停之后历史版本和锁定状态就失去了保护对象锁定桶不合适这么做。生命周期删不掉锁内的版本。保留期或依法保留挡着的时候过期规则对该版本无效只能等它到期。想用生命周期强删锁内数据不会奏效。复制和备份都不会继承保留策略。复制在目标侧生成的是新版本保留策略按目标桶自己的规则独立应用源桶的保留期、依法保留一个都不会跟过去跨区域复制、备份软件拉一份副本、手工拷到别的桶都属于这一类。想要副本同样受保护得在目标桶上单独设保留期或依法保留。如果业务是靠这份保留期做归档声明的把它写进复制之后的处理流程别假设它会跟着继承。先测再上。保护生产数据之前在非生产桶跑一遍把时间同步、权限、生命周期规则、复制和备份流程都验一遍。时钟偏差会直接影响保留期的实际生效窗口。版本控制会涨存储。覆盖和删除都留着旧数据恢复期和保留期定义清楚之后再给非当前版本配生命周期规则否则成本会失控。落地之前把这几条跑一遍顺序照着来建完锁桶确认版本控制已在、桶级默认保留已设控制台的 Info 页能看到 RetentionPolicy。上传一个测试对象rc bucket version list把它的版本 ID 记下来。用普通身份不带任何绕过地删这个版本期望返回AccessDenied删键不带版本 ID 时产生的删除标记不算数。带s3:BypassGovernanceRetention的专用管理身份在 GOVERNANCE 桶上再删一次确认只有这条路走得通且 COMPLIANCE 桶和挂着依法保留的对象不吃这一套。删除标记产生之后用rc object stat --version-id version-id确认旧版本还在、还能读回内容。把保留期设成几分钟跑一次到期验证确认届满且没有依法保留时版本可删。时钟是这套机制的地基不能省。保留期的截止时间戳来自请求头里的时间它由调用方的时钟给出不是存储端自己算的。写入节点的系统时间偏快几分钟就少保护几分钟偏慢几分钟保留期可能提前届满。所以建锁桶之前先把存储节点和调用侧的 NTP 对齐验收时记一下两端的偏移量生产上把时钟偏移做成一条监控项比事后翻审计日志有效。监管口径这边官方给出的对应是 SEC Rule 17a-4(f)、FINRA Rule 4511 和 CFTC Regulation 1.31对象锁定、保留期与依法保留符合 Cohasset Associates 的验证标准。自己那套审计怎么过需要拿这份验证报告去逐条对齐。合规归档的落地动作其实不多建桶时把版本控制和对象锁一起打开挑对保护模式给关键对象设上保留期然后把锁内删除被拒当成一条常态断言。难点不在配置在把保留期、复制目标和生命周期这几次交互先想清楚再写入。RustFS 1.0.0 已于 2026 年 9 月 16 日 GA源码和 issue 在 github.com/rustfs/rustfs对象锁定与保留的完整说明在 RustFS 文档的对象锁定页。
