版本控制与回收站

文件版本控制

自动归档

文件覆盖上传时自动归档旧版本:

PUT /dav/file.txt(内容变化)
→ archiveCurrentVersion(归档当前版本到 storage_path_versions)
→ writeChunk(写入新内容)
→ linkChunksToPath(更新索引指向新 chunk)

归档机制

  • 归档只复制 storage_chunks 索引行(指向已有 chunk_md5)
  • 物理 chunk 通过 MD5 全局共享,零拷贝
  • storage_chunks.version_id:NULL = 当前版本,整数 = 归档版本(指向 storage_path_versions.id
  • 归档不产生物理 IO,成本接近零

版本字段

storage_path_versions 表字段与 storage_path 对齐:

字段 说明
storage_path_id 原文件 ID
etag 版本 etag
chunk_list_md5 chunk MD5 列表摘要
size 文件大小
content_type MIME 类型
properties_snapshot 属性快照(JSON)

管理后台

文件浏览器 → 文件详情 → 「历史版本」:

  • 查看所有历史版本列表
  • 下载指定版本(文件名加 .v{N} 后缀,如 report.v2.pdf
  • 归属校验防越权

配置

默认值 说明
version.max_versions 0 最大版本数(0 = 不限)

当前仅记录元数据,不主动清理超限版本(预留扩展)。

已知限制

  • 不支持恢复历史版本为当前版本
  • SabreDAV 无 DeltaV(版本控制协议)支持
  • 回收站不单独管理版本
  • gc:stale_cache 清缓存后归档可能不可读
  • dir_size 不含归档版本大小

回收站

软删除机制

WebDAV 和 admin 后台删除文件时,都先走软删除:

DELETE /dav/file.txt
→ trashFile(soft delete)
→ storage_path.delete_time = 当前时间戳
→ chunk 索引与物理 chunk 全部保留
→ readFile 自动过滤(delete_time > 0 的不返回)

目录级删除

目录删除走 trashTree(MySQL 8 CTE 批量软删):

WITH RECURSIVE descendants AS (
    SELECT id FROM uld_storage_path WHERE pid = {rootId}
    UNION ALL
    SELECT p.id FROM uld_storage_path p
    JOIN descendants d ON p.pid = d.id
)
UPDATE uld_storage_path SET delete_time = {now} WHERE id IN (SELECT id FROM descendants);

21x 加速 vs PHP 递归 baseline。根节点需调用方单独 trashFile

恢复文件

// 必须用 onlyTrashed 加载已软删的模型
$path = StoragePath::onlyTrashed()->find($id);
$storage->restoreFile($path);  // UPDATE delete_time = 0

管理后台 → 回收站 → 「恢复」按钮。

恢复冲突

如果同路径已有新文件,恢复操作被拒绝(返回冲突提示)。

彻底删除

$storage->deleteFileImmediate($path);
// force 删 path 行 + 逐 chunk 引用计数删 + 删本地缓存
  • gc:expired_trash 清理过期文件时调此方法
  • admin 后台「彻底删除」也调此方法
  • S3 DELETE 走此方法(立即彻底删,不进回收站)

管理后台

回收站页面功能:

  • 列表(文件名 / 原路径 / 删除时间 / 剩余保留天数)
  • 恢复
  • 彻底删除
  • 批量清空(每次最多 50 条)

侧边栏 badge 显示回收站文件数。

配置

默认值 说明
recycle.retention_days 30 保留期(天),最大 365

FPM 缓存窗口

ConfigService 使用静态数组缓存。retention_days 修改后:

  • 当前 FPM worker 立即生效
  • 其他 worker 仍持旧值直到自然回收
  • 影响回收站「已过期」按钮置灰显示
  • 不影响「彻底删除」admin 显式操作

LOCK 生命周期

  • WebDAV DELETE → SabreDAV afterUnbind 自动清锁
  • admin UI 删除 → 不清锁,依赖 SabreDAV 默认锁超时(数分钟)自然过期

GC 命令与回收站关系

命令 对回收站的影响
gc:expired_trash 真删超期文件(调 deleteFileImmediate,不可恢复)
gc:orphan_chunks 不影响回收站(仅检测孤儿 chunk)
gc:stale_cache 不影响回收站(仅清 .temp 缓存)

原文标题:版本控制与回收站

原文文档:uldisk

原文地址:/read/augushong/ul-disk/zh-cn/1.0.0/6a3e73c598601/6a3e73d9510cb.html

原文平台:奥宏文档

1.0.0