Seafile 使用存储去重技术来减少存储使用量。在你删除文件或资料库后,底层的数据块不会立即被移除。因此,Seafile 服务器上的未使用数据块数量会不断增加。
为了释放未使用数据块所占用的存储空间,你需要运行一个“垃圾回收(GC)”程序来清理服务器上的未使用数据块。
GC 程序会清理两类未使用的数据块:
-
没有任何资料库引用的块,即属于已删除资料库的块;
-
如果你在某些资料库上设置了历史长度限制,这些资料库中过期的块也会被移除。
运行 GC
注意:
如果你的 Seafile 服务器是通过 Docker 部署的,在执行脚本之前,请确保你已经进入容器:
docker exec -it seafile bash
本文档中的所有脚本都位于 /opt/seafile/seafile-server-latest
cd /opt/seafile/seafile-server-latest # 适用于基于 Docker 的 Seafile 和基于二进制包的 Seafile
本文档中的其他脚本也需要这样操作。
Dry-run 模式
要查看能回收多少垃圾而不实际删除任何垃圾,请使用 dry-run 选项:
./seaf-gc.sh --dry-run [repo-id1] [repo-id2] ...
输出应类似于:
[03/19/15 19:41:49] seafserv-gc.c(115): GC version 1 repo My Library(ffa57d93)
[03/19/15 19:41:49] gc-core.c(394): GC started. Total block number is 265.
[03/19/15 19:41:49] gc-core.c(75): GC index size is 1024 Byte.
[03/19/15 19:41:49] gc-core.c(408): Populating index.
[03/19/15 19:41:49] gc-core.c(262): Populating index for repo ffa57d93.
[03/19/15 19:41:49] gc-core.c(308): Traversed 5 commits, 265 blocks.
[03/19/15 19:41:49] gc-core.c(440): Scanning unused blocks.
[03/19/15 19:41:49] gc-core.c(472): GC finished. 265 blocks total, about 265 reachable blocks, 0 blocks can be removed.
[03/19/15 19:41:49] seafserv-gc.c(115): GC version 1 repo aa(f3d0a8d0)
[03/19/15 19:41:49] gc-core.c(394): GC started. Total block number is 5.
[03/19/15 19:41:49] gc-core.c(75): GC index size is 1024 Byte.
[03/19/15 19:41:49] gc-core.c(408): Populating index.
[03/19/15 19:41:49] gc-core.c(262): Populating index for repo f3d0a8d0.
[03/19/15 19:41:49] gc-core.c(308): Traversed 8 commits, 5 blocks.
[03/19/15 19:41:49] gc-core.c(264): Populating index for sub-repo 9217622a.
[03/19/15 19:41:49] gc-core.c(308): Traversed 4 commits, 4 blocks.
[03/19/15 19:41:49] gc-core.c(440): Scanning unused blocks.
[03/19/15 19:41:49] gc-core.c(472): GC finished. 5 blocks total, about 9 reachable blocks, 0 blocks can be removed.
[03/19/15 19:41:49] seafserv-gc.c(115): GC version 1 repo test2(e7d26d93)
[03/19/15 19:41:49] gc-core.c(394): GC started. Total block number is 507.
[03/19/15 19:41:49] gc-core.c(75): GC index size is 1024 Byte.
[03/19/15 19:41:49] gc-core.c(408): Populating index.
[03/19/15 19:41:49] gc-core.c(262): Populating index for repo e7d26d93.
[03/19/15 19:41:49] gc-core.c(308): Traversed 577 commits, 507 blocks.
[03/19/15 19:41:49] gc-core.c(440): Scanning unused blocks.
[03/19/15 19:41:49] gc-core.c(472): GC finished. 507 blocks total, about 507 reachable blocks, 0 blocks can be removed.
[03/19/15 19:41:50] seafserv-gc.c(124): === Repos deleted by users ===
[03/19/15 19:41:50] seafserv-gc.c(145): === GC is finished ===
[03/19/15 19:41:50] Following repos have blocks to be removed:
repo-id1
repo-id2
repo-id3
如果你指定了具体的资料库 ID,就只会检查这些资料库;否则会检查所有资料库。
注意输出末尾有一个“repos have blocks to be removed”部分,其中包含有垃圾块的资料库列表。之后在你运行不带 --dry-run 选项的 GC 时,可以将这些资料库 ID 作为输入参数传递给 GC 程序。
删除垃圾数据块
要实际删除垃圾块,请在不加 --dry-run 选项的情况下运行:
./seaf-gc.sh [repo-id1] [repo-id2] ...
如果指定了资料库 ID,则只检查这些资料库的垃圾。
如前所述,有两类垃圾块需要删除。有时只删除第一类块(属于已删除资料库的块)就足够了。在这种情况下,GC 程序不会去检查资料库中过期的历史块。"-r" 选项实现了这个功能:
./seaf-gc.sh -r
成功:
用户删除的资料库不会立即从系统中移除,而是被移到系统管理页面的“回收站”中。在它们从回收站中清除之前,其数据块不会被垃圾回收。
删除 FS 对象
从专业版 8.0.6 和社区版 9.0 开始,你可以删除垃圾文件系统对象。必须在不加 --dry-run 选项的情况下运行:
./seaf-gc.sh --rm-fs
注意:
在专业版 10.0.15 之前和社区版 11.0.7 之前,这个命令存在 bug。它可能会导致虚拟资料库(如共享文件夹)无法合并到它们的父资料库中。在受影响的版本中请避免使用此选项。如果你受该 bug 影响,请联系技术支持团队。
在 GC 中使用多线程
你可以在 GC 中指定线程数量。默认情况下:
-
如果存储后端是 S3/Swift/Ceph,则会启动 10 个线程执行 GC;
-
如果存储后端是文件系统,则只会启动 1 个线程。
你可以使用 "-t" 选项指定线程数量。"-t" 选项可以和所有其他选项一起使用。每个线程会在一个资料库上执行 GC。例如,以下命令会使用 20 个线程对所有资料库进行 GC:
./seaf-gc.sh -t 20
由于线程是并发运行的,各线程的输出可能会混杂在一起。输出的每一行中都会打印资料库 ID。
根据库ID前缀运行GC
由于 GC 需要遍历整个资料库历史,通常运行得很慢。你可以使用多线程并行运行 GC。对于更大规模的部署,也可以在多台服务器上并行运行 GC。
一个简单的方式是根据资料库 ID 将资料库分配到不同的 GC 服务器上。从专业版 7.1.5 开始支持这一点。你可以在 seaf-gc.sh 中添加 "--id-prefix" 选项来指定资料库 ID 前缀。例如,以下命令只会处理 ID 前缀为 "a123" 的资料库:
./seaf-gc.sh --id-prefix a123