在服务器端,Seafile 将资料库中的文件存储为一种内部格式。Seafile 有自己对目录和文件的表示方式(类似于 Git)。
在默认安装情况下,这些内部对象直接存储在服务器的文件系统中(如 Ext4、NTFS)。但是大多数文件系统在系统突然关闭或崩溃后,并不能保证文件内容的完整性。因此,如果系统崩溃时新的 Seafile 内部对象正在写入,系统重启后它们可能会损坏。这会导致对应资料库的一部分无法访问。
警告:
如果你将 seafile-data 目录存储在带电源保护的 NAS(如 EMC 或 NetApp),或者使用专业版中提供的 S3 后端,内部对象就不会损坏。
注意:
如果你的 Seafile 服务器是通过 Docker 部署的,在执行本手册中的以下命令之前,请确保你已经进入容器,并进入到下面目录:
docker exec -it seafile bash,
cd
/opt/seafile/seafile-server-latest
,本文档中的其他脚本也需要这样操作。
我们提供了一个 seaf-fsck.sh 脚本来检查资料库的完整性。seaf-fsck 工具接受以下参数:
cd /opt/seafile/seafile-server-latest
./seaf-fsck.sh [--repair|-r] [--export|-E export_path] [repo_id_1 [repo_id_2 ...]]
seaf-fsck 有三种运行模式:
-
检查资料库的完整性。
-
修复损坏的资料库。
-
导出资料库。
检查资料库完整性
在不带任何参数的情况下运行 seaf-fsck.sh,会对所有资料库执行只读完整性检查。
./seaf-fsck.sh
如果你想检查特定的资料库,只需将资料库 ID 作为参数添加:
./seaf-fsck.sh [library-id1] [library-id2] ...
输出看起来像这样:
[02/13/15 16:21:07] fsck.c(470): Running fsck for repo ca1a860d-e1c1-4a52-8123-0bf9def8697f.
[02/13/15 16:21:07] fsck.c(413): Checking file system integrity of repo fsck(ca1a860d)...
[02/13/15 16:21:07] fsck.c(35): Dir 9c09d937397b51e1283d68ee7590cd9ce01fe4c9 is missing.
[02/13/15 16:21:07] fsck.c(200): Dir /bf/pk/(9c09d937) is corrupted.
[02/13/15 16:21:07] fsck.c(105): Block 36e3dd8757edeb97758b3b4d8530a4a8a045d3cb is corrupted.
[02/13/15 16:21:07] fsck.c(178): File /bf/02.1.md(ef37e350) is corrupted.
[02/13/15 16:21:07] fsck.c(85): Block 650fb22495b0b199cff0f1e1ebf036e548fcb95a is missing.
[02/13/15 16:21:07] fsck.c(178): File /01.2.md(4a73621f) is corrupted.
[02/13/15 16:21:07] fsck.c(514): Fsck finished for repo ca1a860d.
上面信息中会报告损坏的文件和目录。另外,你也可能会看到如下输出:
[02/13/15 16:36:11] Commit 6259251e2b0dd9a8e99925ae6199cbf4c134ec10 is missing
[02/13/15 16:36:11] fsck.c(476): Repo ca1a860d HEAD commit is corrupted, need to restore to an old version.
[02/13/15 16:36:11] fsck.c(314): Scanning available commits...
[02/13/15 16:36:11] fsck.c(376): Find available commit 1b26b13c(created at 2015-02-13 16:10:21) for repo ca1a860d.
这意味着记录在数据库中的 "head commit" (当前资料库状态的标识)与数据目录中的记录不一致。这种情况下,fsck 会试着找出最近可用的一致状态,并检查其完整性。
建议:
如果你有很多资料库,将 fsck 的输出保存到日志文件中以便后续分析会很有帮助。
修复损坏的资料库
seaf-fsck 的损坏修复基本分为两步:
-
如果数据库中记录的资料库状态(提交)在数据目录中找不到,则从数据目录中找到最后一个可用的状态。
-
检查该状态下的数据完整性。如果文件或目录损坏,则将其设为空文件或空目录。损坏的路径会被报告,以便用户可以从其他地方恢复。
运行以下命令可以修复所有资料库:
./seaf-fsck.sh --repair
大多数情况下我们建议你首先以只读方式检查资料库的完整性,找出损坏的资料库后,执行如下命令来修复指定的资料库:
./seaf-fsck.sh --repair [library-id1] [library-id2] ...
修复后,在资料库历史中,seaf-fsck 会包含损坏文件和文件夹的列表,这样更容易定位损坏的路径。
修复资料库的最佳方案
要检查所有资料库并找出哪些资料库已损坏,系统管理员可以运行 seaf-fsck.sh 而不加任何参数,并将输出保存到日志文件。在日志文件中搜索关键词 "Fail" 来定位损坏的资料库。你可以在 Seafile 服务器运行时检查所有资料库,它不会破坏或更改任何文件。
当系统管理员发现某个资料库损坏时,应对该资料库运行带 "--repair" 的 seaf-fsck.sh。命令修复该资料库后,管理员应通知用户从其他地方恢复文件。有两种方式:
-
通过Web界面上传损坏的文件或文件夹
-
如果该资料库已经同步到某台计算机,并且该计算机有已损坏文件的正确版本,则重新同步该计算机上的资料库,将已损坏文件的正确版本上传到服务器上。
通过不检查文件内容来加速FSCK
从专业版 7.1.5 开始,新增了一个选项用于加速 FSCK。seaf-fsck 的大部分运行时间花在计算文件内容的哈希值上。这个哈希会与块对象 ID 对比。如果它们不一致,则该块被检测为损坏。
在很多情况下,文件内容大多数时间不会损坏。只是系统中缺少某些对象。因此仅检查对象是否存在就足够了。这将大大加快 fsck 的过程。
要跳过文件内容检查,请在 seaf-fsck 中添加 --shallow 或 -s 参数。
将资料库导出到文件系统
你可以使用 seaf-fsck 将资料库中的所有文件导出到外部文件系统(如 Ext4)。这个过程不依赖于 Seafile 数据库。只要你有 seafile-data 目录,就可以随时从 Seafile 导出文件到外部文件系统。执行此操作的命令是:
./seaf-fsck.sh --export top_export_path [library-id1] [library-id2] ...
参数 top_export_path 是存放导出文件的目录。每个资料库会被导出为该目录下的一个子目录。如果你没有指定资料库 ID,则会导出所有资料库。
注意:
目前只能导出未加密的资料库。加密的资料库会被跳过。