fix: attachments→files 迁移增加内容回退策略,防重建表后 id 撞号漏搬 #7

Merged
kevin merged 1 commits from dsh/go_blog:fix/attachment-migration-content-fallback into main 2026-08-28 20:04:57 +08:00
Contributor

背景

生产环境踩到的问题:升级中途若短暂运行过旧版二进制,AutoMigrate 会把 attachments 表从 id=1 重新创建,新上传的行获得 1、2、3……与 files 表已迁移行的 id 撞号。原迁移按 id 对齐的 NOT EXISTS 会把这些行误判为“已迁移”,新上传数据被静默漏搬(files 表缺失记录,文章附件列表为空)。

修复

migrateAttachmentsToFiles 在 id 对齐迁移之后,追加一段按内容回退

-- id 已存在但指向不同内容(重建表后撞号)的行,省略 id 由数据库重新分配;
-- 内容(stored_name,SHA-256)已在 files 中登记的行跳过(去重)
INSERT INTO files (type, )
SELECT 'attachments', 
FROM attachments a
WHERE EXISTS (
    SELECT 1 FROM files f WHERE f.id = a.id AND f.stored_name <> a.stored_name
)
AND NOT EXISTS (
    SELECT 1 FROM files f WHERE f.stored_name = a.stored_name
);

仍保持幂等(重复启动不产生重复数据),仅在旧表仍存在时执行。

验证

本机线上库已按该策略手工恢复 3 条漏搬记录(文章 10/11/12 的真实上传,磁盘文件完整);go build + 全量测试通过。

## 背景 生产环境踩到的问题:升级中途若短暂运行过旧版二进制,AutoMigrate 会把 `attachments` 表从 id=1 重新创建,新上传的行获得 1、2、3……与 files 表已迁移行的 id 撞号。原迁移按 id 对齐的 `NOT EXISTS` 会把这些行误判为“已迁移”,**新上传数据被静默漏搬**(files 表缺失记录,文章附件列表为空)。 ## 修复 `migrateAttachmentsToFiles` 在 id 对齐迁移之后,追加一段**按内容回退**: ```sql -- id 已存在但指向不同内容(重建表后撞号)的行,省略 id 由数据库重新分配; -- 内容(stored_name,SHA-256)已在 files 中登记的行跳过(去重) INSERT INTO files (type, …) SELECT 'attachments', … FROM attachments a WHERE EXISTS ( SELECT 1 FROM files f WHERE f.id = a.id AND f.stored_name <> a.stored_name ) AND NOT EXISTS ( SELECT 1 FROM files f WHERE f.stored_name = a.stored_name ); ``` 仍保持幂等(重复启动不产生重复数据),仅在旧表仍存在时执行。 ## 验证 本机线上库已按该策略手工恢复 3 条漏搬记录(文章 10/11/12 的真实上传,磁盘文件完整);`go build` + 全量测试通过。
dsh added 1 commit 2026-08-28 20:04:24 +08:00
场景:中途部署过旧版二进制时 AutoMigrate 会把 attachments 以
id=1 重新编号;此前按 id 对齐的 NOT EXISTS 会误判已迁移,
导致新上传行静默丢失。现在第二段按 stored_name(内容 SHA-256)
补齐 id 冲突的行(省略 id 由数据库重新分配,内容已登记则跳过)。
kevin merged commit a6c1f92197 into main 2026-08-28 20:04:57 +08:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: kevin/go_blog#7