版本控制与回收站
文件版本控制
自动归档
文件覆盖上传时自动归档旧版本:
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