seaf-gc提示repo有警告,但是fsck缺正常,请问应该如何处理?

环境:v12.0.14,linux docker部署

seaf-gc提示repo有警告,但是fsck缺正常,请问应该如何处理?

1、尝试GC回收

root@11b75af60406:/opt/seafile/seafile-server-latest# ./seaf-gc.sh e60c7fde-0d24-4752-bc57-72c40bfc0c1c

Starting seafserv-gc, please wait …
[2025-08-07 10:03:39] [INFO] gc-core.c(1139): Database is MySQL/Postgre/Oracle, use online GC.
[2025-08-07 10:03:39] [INFO] gc-core.c(1164): Using up to 1 threads to run GC.
[2025-08-07 10:03:39] [INFO] gc-core.c(1107): GC version 1 repo XXX_Laptop(e60c7fde-0d24-4752-bc57-72c40bfc0c1c)
[2025-08-07 10:03:39] [INFO] gc-core.c(777): GC started for repo e60c7fde. Total block number is 81128.
[2025-08-07 10:03:39] [INFO] gc-core.c(69): GC index size is 40564 Byte for repo e60c7fde.
[2025-08-07 10:03:39] [INFO] gc-core.c(403): Populating index for repo e60c7fde.
[2025-08-07 10:04:01] [WARNING] ../../common/fs-mgr.c(1288): [fs mgr] Failed to read file 7798db92cffd50966d0f1f434f91671d7601e4f6.
[2025-08-07 10:04:01] [WARNING] gc-core.c(112): Failed to find file e60c7fde-0d24-4752-bc57-72c40bfc0c1c:7798db92cffd50966d0f1f434f91671d7601e4f6.
[2025-08-07 10:04:01] [WARNING] ../../common/commit-mgr.c(506): [comit-mgr] CommitTraverseFunc failed
[2025-08-07 10:04:01] [WARNING] gc-core.c(415): Failed to populate index for repo e60c7fde.

[2025-08-07 10:04:01] [INFO] gc-core.c(1216): === GC is finished ===
[2025-08-07 10:04:01] [INFO] gc-core.c(1219): The following repos are damaged. You can run seaf-fsck to fix them.
[2025-08-07 10:04:01] [INFO] gc-core.c(1223): e60c7fde-0d24-4752-bc57-72c40bfc0c1c
seafserv-gc run done

Done.

2、同一repo尝试fsck
root@11b75af60406:/opt/seafile/seafile-server-latest# ./seaf-fsck.sh e60c7fde-0d24-4752-bc57-72c40bfc0c1c --repair

Starting seaf-fsck, please wait …

[2025-08-07 10:04:44] [INFO] fsck.c(606): Running fsck for repo e60c7fde-0d24-4752-bc57-72c40bfc0c1c.
[2025-08-07 10:04:44] [INFO] fsck.c(431): Checking file system integrity of repo XXX_Laptop(e60c7fde)…
[2025-08-07 10:05:49] [INFO] fsck.c(670): Fsck finished for repo e60c7fde.

seaf-fsck run done

时隔近3个月,最近看到seafile都到版本13了,于是升级体验,升级后尝试seaf-gc.sh仍然出错,无法清理回收空间,以下是摸索及解决过程。

seaf-gc.sh错误信息,看起来是丢失了数据/文件导致
[2025-10-29 17:24:17] [INFO] gc-core.c(1107): GC version 1 repo XXX(e60c7fde-0d24-4752-bc57-72c40bfc0c1c)
[2025-10-29 17:24:18] [INFO] gc-core.c(777): GC started for repo e60c7fde. Total block number is 83356.
[2025-10-29 17:24:18] [INFO] gc-core.c(69): GC index size is 41678 Byte for repo e60c7fde.
[2025-10-29 17:24:18] [INFO] gc-core.c(403): Populating index for repo e60c7fde.
[2025-10-29 17:24:43] [WARNING] ../../common/fs-mgr.c(1288): [fs mgr] Failed to read file 7798db92cffd50966d0f1f434f91671d7601e4f6.
[2025-10-29 17:24:43] [WARNING] gc-core.c(112): Failed to find file e60c7fde-0d24-4752-bc57-72c40bfc0c1c:7798db92cffd50966d0f1f434f91671d7601e4f6.
[2025-10-29 17:24:43] [WARNING] ../../common/commit-mgr.c(506): [comit-mgr] CommitTraverseFunc failed
[2025-10-29 17:24:43] [WARNING] gc-core.c(415): Failed to populate index for repo e60c7fde.

学习seafile数据结构,开始尝试过到 GitHub - haiwen/seafile-server: Seafile Server Core 学习fs-mgr.c等源码,进展缓慢;偶然发现 https://awant.medium.com/seafile-data-structure-c8a1e62a64e4 这篇文章,节省了99.9%的气力,还有2个python小工具,很棒!

1、存放数据目录在seafile-data/seafile/seafile-data/storage/,其中有fs(存储元信息)、blocks(文件快)、commits(提交过程?不详)三个目录

2、具体的目录结构seafile-data/seafile/seafile-data/storage/{fs/blocks/commits}/{repoID}/{objectID头2位}/{objectID第3位到最后}/

3、对照上面的错误,e60c7fde-0d24-4752-bc57-72c40bfc0c1c是repoID(资料库ID),7798db92cffd50966d0f1f434f91671d7601e4f6就是fs中的objectID,
对应的文件是seafile-data/seafile/seafile-data/storage/fs/e60c7fde-0d24-4752-bc57-72c40bfc0c1c/77/98db92cffd50966d0f1f434f91671d7601e4f6,用于记录文件存储的元信息,这个文件是zlib压缩的,出错的原因就是这个文件消失了!

4、在fs目录下找一个同类的文件来看下结构,例如
import zlib, json;
print(json.dumps(json.loads(zlib.decompress(open("93158ae38d26f9b57599edf10cb63fae1ed6d9", "rb").read())), indent=4))

内容为:
{
“block_ids”: [
“4053196cab68b2fe915456ffe0dc2252df5a52d2”
],
“size”: 85,
“type”: 1,
“version”: 1
}
block_ids对应seafile-data/seafile/seafile-data/storage/blocks下的文件块信息,就是存储文件真实数据的地方,这个例子的实际路径就是
seafile-data/seafile/seafile-data/storage/blocks/e60c7fde-0d24-4752-bc57-72c40bfc0c1c/40/53196cab68b2fe915456ffe0dc2252df5a52d2

5、仿照上面构造缺失的seafile-data/seafile/seafile-data/storage/fs/e60c7fde-0d24-4752-bc57-72c40bfc0c1c/77/98db92cffd50966d0f1f434f91671d7601e4f6文件,block_ids自己去产生一个没有对应文件的即可,我就是尾数+1,检查对应路径下面实际没有这个文件即可
import zlib, json;
compressed_data = zlib.compress("{\"block_ids\": [ \"4053196cab68b2fe915456ffe0dc2252df5a52d3\" ], \"size\": 85, \"type\": 1, \"version\": 1 }”.encode("utf-8"))
with open("98db92cffd50966d0f1f434f91671d7601e4f6", "wb") as f:
f.write(compressed_data)

6、将上面生成的98db92cffd50966d0f1f434f91671d7601e4f6文件放置到seafile-data/seafile/seafile-data/storage/fs/e60c7fde-0d24-4752-bc57-72c40bfc0c1c/77/98db92cffd50966d0f1f434f91671d7601e4f6

7、将例子对应文件seafile-data/seafile/seafile-data/storage/blocks/e60c7fde-0d24-4752-bc57-72c40bfc0c1c/40/53196cab68b2fe915456ffe0dc2252df5a52d2复制到seafile-data/seafile/seafile-data/storage/blocks/e60c7fde-0d24-4752-bc57-72c40bfc0c1c/40/53196cab68b2fe915456ffe0dc2252df5a52d3(尾数+1,用原来的文件只修改名字,大小这些都可以不变)

8、执行seaf-gc.sh,成功,回收20G空间