# 回收站删除引用索引修复 此前每条清理任务都现场重建全库文件引用。约 40 万条资产下,第一次优化仍需约 5 秒;这个耗时不是正常文件删除所需,而是全表扫描和路径转换造成的。原生后台任务、持久化清单和失败续跑保留,但生产清理不再调用全量扫描。 新增 `20261009_material_purge_reference_indexes` 迁移,在九个真实引用来源建立 GIN 表达式索引。文件地址、数组与 JSON 中的字符串生成检索键,由数据库在插入、更新、删除时自动维护,覆盖 Prisma 和直接 SQL 写入。历史记录在建索引时纳入,不需要应用双写、定期同步或引用缓存。 索引仅返回候选。应用仍用完整存储类型、桶及路径判定共享引用;哈希冲突只会增加候选。回收站素材、软删除 SKU、历史对象地址、白底派生文件和活动上传/审批引用继续受到保护。URL 点段和控制字符的少量特殊引用保留为索引候选,再交由原生 URL 规则核对;Windows Unicode 路径保守匹配。SQL 函数明确禁用并行执行,避免错误恢复子事务在并行查询内报错。 提交后立即唤醒已经启动的清理 worker。空队列检查与入队交错时保留唤醒信号,每轮满 20 条立即接着处理下一轮;5 秒定时器只用于恢复和到期重试。没有把排队或未完成的物理清理显示成成功。 ## 验证 - 21 个相关 Jest 测试,包括入队与空队列检查交错时不会丢失唤醒。 - 14 个真实 PostgreSQL/文件系统/MinIO 集成验证组;包括幂等、事务回滚、租约接管、真实删除、共享保护、直接 SQL 更新、队列状态变化、特殊地址和失败续跑。 - 独立数据库 400,000 条额外资产:引用检查 59ms,提交 24ms,4 个文件从提交到实际删除及审计完成 122ms;资产查询计划实际使用 `material_assets_purge_references_idx`。 - 已启动 worker 收到提交后 60ms 完成,不等待 5 秒轮询。 - 类型检查、存储边界检查和 14 个安全迁移测试通过。迁移审计核对九个索引的表达式、状态谓词、有效性及三个函数的完整定义。 生产验收只读核对原先 18 个任务的 1,276 个文件和现存引用样本,不由自动化提交真实素材删除。隔离测试耗时不等于生产完整物理清理耗时;生产查询耗时和发布凭据另存于发布回执。