在不丢失数据的情况下重命名站点
客户要求将站点从 acme-staging 重命名为 acme。
你在应用中更改了名称。
突然间,所有的数据库备份、截图和缩略图都消失了。
文件仍然存在于磁盘上。 新目录只是空的。 数据并没有随着名称的更改而迁移。
我们在最初的设计中犯了这个错误。 我们使用站点名称来决定存储文件的位置。
如果你将文件存储在 backups/acme-staging/ 中,然后将站点重命名为 acme,应用会去寻找 backups/acme/。
它会发现一个空文件夹。
旧数据留在旧文件夹中,但应用将其视为来自不同站点的陈旧数据。
站点名称经常更改。 客户会修正拼写错误。 团队会将测试站点迁移到生产环境。 公司会进行重组。
我们通过将显示名称与稳定的标识符分离解决了这个问题。
每个站点现在都有一个唯一的 ID。
它看起来像 site_a1b2c3d4e5f6。
这个 ID 永远不会改变。
我们现在使用 ID 而不是名称来存储文件。
目录路径看起来像 backups/site_a1b2c3d4e5f6/。
即使你重命名了站点,路径也保持不变。
数据得以保持关联。
将现有用户迁移到这个系统是最难的部分。 我们构建了一个幂等迁移。 这意味着系统在启动时会检查 ID。 如果站点缺少 ID,系统会分配一个。 如果已经有了,系统则不做处理。
我们还迁移了物理文件。 如果系统发现一个以站点命名的文件夹,它会将其重命名为新的 ID 格式。
我们甚至修复了日志。 新日志使用 ID。 旧日志使用站点名称。 UI 将两者结合,使你的历史记录看起来是连续的。
我们在验证方面吸取了一个惨痛的教训。 更新后,我们添加了一条规则来检查 ID 格式。 该规则过于严格。 它拒绝了一些迁移过来的旧 ID。 突然间,站点再次消失了。
教训很简单:在添加新规则之前,先审计你的数据。
将人类看到的与系统使用的分离是一个经典模式。 在发布后才这样做既昂贵又冒险。 从第一天起就使用不可变的 ID,以避免这个陷阱。