
迁移顺不顺利通常不看它有没有报错。同步结束了、日志里没有失败项、控制台上一片正常这些都是过程指标跟数据对不对是两件不同的事。真正让人睡不着的场景是第二天业务侧发现少了几十个小对象而你拿不出任何证据证明昨天那趟同步是完整的。这份清单不依赖某个厂商的迁移工具用的都是 S3 生态里本来就有的客户端和命令往任何 S3 兼容存储上迁都成立。每过一关你手上的证据就硬一分。六道关的分工是前四关解决搬没搬完、搬得对不对第五关验收元数据和特殊桶第六关交给业务方确认。下面一关一关过。第一关先把两边的账摆出来验证之前先留底。迁移开始前把源端的对象数和总字节数记下来官方推荐的做法是让mc stat直接报桶统计而不是自己去列举mcstatalias/src-bucketmcstatalias/src-bucket--json|jq.Usage.objectsCount第一条会打出Total size、Objects count、Versions count以及一张对象大小分布直方图。第二条只取对象数。桶级统计是服务端算好的不像列举那样要逐个对象过一遍桶大的时候差别很明显。迁完再对目标端跑一次同样的命令。这一步只能证明两个桶看起来规模一样但它有一个不可替代的作用它是后面所有争论的基准数字。版本桶这里要特别留个心眼。如果源桶开了版本控制一次删除会留下一个删除标记列举出来的是历史版本的总数不等于当前生效对象的数量。mc stat把Objects count和Versions count分两行给正好可以用来做这个交叉核对。更要紧的是mc mirror自己那句限定它只同步当前对象不带任何版本信息也不带除标签以外的元数据。所以版本桶想靠 mirror 搬历史版本会直接丢掉对象锁的保留期和法律保留状态属于除标签以外的元数据同样不在同步范围内。这两样要一起迁官方给的方向是用mc replicate做桶复制或者用mc admin replicate做站点复制不是 mirror。这条路径和后面的校验流程是两回事别混在一起验收。第二关同步工具说一致不代表内容一样这是最容易误判的一关。mc diff的官方定义是比对两个目录或两个桶列出一边缺失的对象以及大小或校验和不同的对象并且明确写了它不读取对象内容。同理mc mirror判断要不要复制一个对象比较的是对象名、大小、修改时间和校验和也不读内容。这就带来一个具体陷阱。mc mirror --remove的作用是把目标端有、源端没有的对象删掉让两边名字一致。官方文档对它的说明很坦率它不校验对象内容是否相同只确认两边都存在一个叫同一个名字的对象想让两边名字和内容都对上得用--overwrite或--watch。开了--overwrite也不等于内容校验。它的行为是发现目标端已存在一个同名对象时按元数据判断要不要覆盖需要覆盖就直接从源端拉一份盖上去。整个过程没有把两边的内容读出来逐字节比对。判断依据里虽然包含校验和字段但拿到的只是服务端返回的那一个值不是对内容的复核。所以正确的理解是--overwrite解决的是目标端这份是不是旧的让它变新它解决不了这份是不是和源端那份一模一样那要靠后面的rclone check --checksum。换句话说mc mirror --remove只能告诉你两边都有这东西不能告诉你这东西和原来那个是一个东西。把这句话记牢能省掉事后一大堆口舌。这张表把本篇用到的命令放在一处只有最后一行真正读过数据前面几行报的一致都是元数据口径。第三关校验和本身也有盲区工具比对的依据是服务端返回的校验和。问题在于校验和怎么来的。对分片上传的对象工具拿到的是复合校验和官方文档的说法是复合校验和是各段哈希的哈希。这意味着两段布局变了、内容其实没变校验和也会跟着变。反过来算法不同也没法直接比。拿本地算的 SHA-256 去和 S3 返回的 MD5 比比出来的差异毫无意义。要避免这个盲区可以在写入时就指定算法。mc cp的--checksum参数支持 CRC64NVME、CRC32、CRC32C、SHA1、SHA256、MD5 等取值代价是要求服务端支持响应尾头部。上传侧统一了算法比对侧才有可比性。第四关真正把内容读一遍前面三关都建立在一个前提上两边的元数据是可信的。想彻底压实得让内容真的流过一次。小数据量直接全量比对。rclone check默认是比对修改时间和大小加--checksum之后按哈希加大小判定rclone check--checksumalias:src-bucket alias:dst-bucket数据量大的时候全量哈希的代价不小因为意味着把每个字节从磁盘或出网口读一遍。这时按前缀抽样挑出分布最广的几个前缀各抽一批算哈希对比并在验收文档里写清楚这是抽样不是全量。别为了省事把抽样说成全量那是给自己埋雷。抽样也不能只抽大文件。丢东西最常见的场景是小对象没搬过去按大小排序抽前 100 个一项也测不出问题。rclone check不加参数时的判定依据是修改时间和大小这也意味着改动过修改时间、大小没变的文件会被判成相同。加--checksum之后才走哈希加大小的口径比对结果更可信代价是要多读一遍数据。跨网络跑全量哈希还有一个现实问题耗时长、容易被连接中断打断而rclone check没有断点续算这回事中断之后重跑已经算过的那些对象要重新算一遍。所以更划算的做法是先把全量校验放在内网或机房内做源端和目标端之间的网络稳定又不要流量费真要跨公网就把它切成按前缀分段跑每段单独出报告中断影响的范围也就限在那一段。第四关之外这笔账什么时候花得起全量哈希的本质是把每个字节读一遍。数据在机房内、源端和目标端都在本地盘这件事可能几小时就跑完数据跨公网搬带宽就成了瓶颈读一遍等于再付一次流量费。动笔做计划之前先算清楚这两笔。抽样比例也没有通用答案。比较实用的分法是三条线都抽按前缀抽挑分布最广的几个、按大小档抽大中小各一批、按时间抽横跨迁移窗口的前中后。三条线的交集不见得覆盖全部但覆盖了绝大多数实际会出问题的形态。还有一点容易被忽略校验期间源端不能停写。业务还在往老桶写数据你比对的那个快照从第一分钟起就过期了。双写或短暂停写是绕不开的这也是为什么前面那份迁前底表要尽早固化。采用双写不停机的话还要多想一层这种方式下不存在一个所有数据都定格在同一秒的完整时刻。所以得先划定切换窗口比如某日 22:00 到 22:15 停止对老桶写入或者把窗口内的增量切到新桶窗口一结束对这段增量单独跑一遍校验再和业务确认业务侧已经完全切走。跳过这一步最后那批增量数据就既没被校验过也没人认领。第五关元数据与特殊桶单独走一遍清单类的东西特殊桶最容易漏。这几项要单独确认版本控制。目标端是否也开了版本控制没有的话后续写入的行为会变。开了的桶还要确认历史版本有没有一起过来这一项靠复制不靠 mirror。对象锁。保留期和法律保留设置是mc mirror不带的那类元数据迁移完成后要在目标端重新施加一遍合规模式下必须单独出一份验证结论。加密。用 SSE-C 的话密钥的交接方式得先定好用 KMS 的话密钥后端在目标环境是否可达、默认密钥是否配好迁移前后是否一致。元数据。自建时附加的自定义头、/content-type 之类的差异列举时看不出来抽样比对时一并核对。第六关让业务侧自己读一遍工具全绿不代表业务能跑。抽几个真实用例让业务方在目标端读一遍、写一遍、删一遍记录结果。这一关的价值不在技术精度在于它把你认为是坏的变成有人确认过是好的。出了问题也有个明确的时点验收之前是迁移方负责验收之后是业务侧。对不上账的时候按这个顺序查mc diff的输出符号是常驻记忆点它把差异分成了三类。FIRST SECOND表示对象只在一边存在也就是目标端缺了。常见原因是同步工具对某段前缀跳过了或者中途被中断过。FIRST SECOND表示目标端多出来一份。这个方向最容易被忽略如果同步时用了--remove目标端多出来的部分会被删掉如果你反过来发现自己这侧凭空少了东西第一反应应该是有人往老桶写了新数据。FIRST ! SECOND表示两边都有、但大小或校验和不同。按前面的逻辑先排除复合校验和的干扰分片布局变了再确认两边上报的算法是否一致最后才怀疑内容真的不一样。这个顺序能避免把大量时间花在一个假警报上。排查的时候有个前提常被跳过先确认两次列举的口径一致。版本桶按不按版本计、前缀带不带尾斜杠、有没有包含当前前缀下的子目录这些只要有一项不一致后面的差异全是噪声。往 RustFS 上迁时这几项落点不同上面这些命令跟服务端是谁没关系换成任何 S3 兼容存储都一样。mc alias set配好别名之后同一套流程可以直接对着 RustFS 跑一遍。真正需要提前确认的是 RustFS 那侧的能力边界。它支持 S3 协议、桶复制和站点复制这两项决定了你是搬一次还是两边持续同步相当长时间版本历史、保留策略这些跟着一起走的路径也落在这两项上它支持版本控制和对象锁意味着目标端能承接锁桶但承接不等于自动施加锁策略还得迁移完再确认一遍服务端加密分 SSE-S、SSE-C 和 KMS 三种KMS 那条路径需要显式开启并配好后端迁移前先确认密钥在目标环境可达。收尾留证也简单。rustfs info --all --json能把系统、运行时、构建、配置和依赖信息一次性落成一个 JSON迁移前后各存一份后面要解释环境差异时有据可查。还有rustfs inspect可以在服务没启动的情况下查看持久化的桶元数据rustfs diagnose则用来分析日志、给出可能的原因遇到迁移期间报错的对象先跑它再看告警。一张可以打印出来的验收清单项目迁前迁后通过标准对象总数记录重新统计数字与迁前一致版本桶按同口径总字节数记录重新统计数字与迁前一致mc diff跑一次跑一次无!行缺失项为 0抽样内容哈希算出源端值算出目标端值哈希逐一相同版本 / 对象锁 / 加密配置截图留档截图留档配置一致业务侧读写删不涉及抽 3 类用例业务方确认可用最后一行之外的每一项都能自动化最后一行只能靠人。清单跑完把这张表连同两份rustfs info --json一起归档下次复盘时这就叫证据。