FEATURED · 精选文章

Immich 系统完整性检查与存储挂载校验:完整性报告、SHA1 校验和与 .immich 标记文件机制

发布时间 / 2026/9/7 3:31:20
来源 / 创域科博编辑部
栏目 / 资讯中心
Immich 系统完整性检查与存储挂载校验:完整性报告、SHA1 校验和与 .immich 标记文件机制 Immich 系统完整性检查与存储挂载校验完整性报告、SHA1 校验和与 .immich 标记文件机制【免费下载链接】immichHigh performance self-hosted photo and video management solution.项目地址: https://gitcode.com/GitHub_Trending/im/immichImmich 内置了一套存储系统完整性保障机制包含运行期定时执行的三类完整性检查未跟踪文件、缺失文件、校验和不匹配以及服务启动时执行的存储挂载目录校验。本文基于官方文档 system-integrity 展开并结合服务端源码说明每类检查的调度方式、默认参数、底层实现以及报出问题的处理手段帮助你在自托管 Immich 时尽早发现并定位存储层面的数据不一致问题。一、完整性检查Integrity Report1.1 三类完整性问题Immich 会按照可自定义的时间间隔运行完整性检查以确保媒体库仍然完整、不存在损坏的文件。检查覆盖三类问题问题类型定义典型成因未跟踪文件Untracked files文件存在于 Immich 的存储目录中但未被数据库引用曾生成到一半的缩略图或转码视频未清理干净缺失文件Missing files路径存在于数据库记录中但磁盘上实际不存在手动删除了内部库目录中的文件不被支持、存储出现问题校验和不匹配Checksum mismatches数据库中存储的校验和与文件实际校验和不一致文件系统损坏、直接在磁盘上修改了内部库中的文件1.2 调度机制与默认参数三类检查默认每天凌晨 3 点各运行一次。其中 Checksum files校验和检查是最耗时的检查因此额外带有时间上限与进度上限使 Immich 可以在几天内缓慢地把全库文件的校验和检查完。从源码可以确认这一调度链路完整性检查在管理配置integrityChecks中定义每个检查项包含enabled与cronExpression字段校验和检查额外带有timeLimit与percentageLimit两个字段见 config.dto.tsintegrityChecks: z .object({ missingFiles: AdminConfigIntegrityJobSchema, untrackedFiles: AdminConfigIntegrityJobSchema, checksumFiles: AdminConfigIntegrityJobSchema.extend({ timeLimit: z.int().nonnegative().describe(How long the integrity checksum job may run for), percentageLimit: z .float32() .nonnegative() .max(1) .describe(Percentage limit of the integrity checksum job) }), })对应的出厂默认值config.dto.tsintegrityChecks: { missingFiles: { enabled: true, cronExpression: CronExpression.EVERY_DAY_AT_3AM }, untrackedFiles: { enabled: true, cronExpression: CronExpression.EVERY_DAY_AT_3AM }, checksumFiles: { enabled: true, cronExpression: CronExpression.EVERY_DAY_AT_3AM, timeLimit: 60 * 60 * 1000, // 1 小时 percentageLimit: 1, // 单次运行最多处理 100% 的 assets }, },其中timeLimit的单位是毫秒z.int().nonnegative()percentageLimit是 0–1 之间的小数表示单次运行最多处理的 asset 比例。此外完整性检查队列的并发度默认为 1config.dto.ts 中integrityCheck: { concurrency: 1 }。在 integrity.service.ts 中服务监听ConfigInit与ConfigUpdate事件在拿到数据库锁DatabaseLock.IntegrityCheck防止多实例重复调度后为三类检查各注册一个 cron 任务当管理界面修改配置时onConfigUpdate会同步更新这三个 cron 表达式与启用状态即可自定义间隔在运行期即时生效。1.3 查看结果与手动触发检查结果可在管理界面的 Maintenance维护页面查看你也可以在该页面针对特定任务或全部任务手动触发一次完整扫描check还可以执行 refresh刷新操作——refresh 只会针对当前已被报告的问题项复查判断它们是否已经被修复。这与源码实现一一对应三类...QueueAll任务都接受refreshOnly参数integrity.service.tsrefreshOnlyfalse完整扫描未跟踪文件检查会遍历encoded-video/、library/、upload/对照 asset 表以及thumbs/对照 asset_file 与 person 缩略图缺失文件检查从数据库流式取出全部 asset/asset_file 路径逐批入队做stat探测。refreshOnlytruerefresh仅流式读取integrity_report表中已有报告streamIntegrityReportsWithAssetChecksum分批入队复查文件已恢复/已消失时删除过期报告。报告数据持久化在integrity_report表中integrity.repository.ts 的写入逻辑以(path, type)为冲突键做 upsert同一文件同一类型的问题不会产生重复条目getIntegrityReportSummary按类型聚合计数供维护页面的汇总展示使用。1.4 常见成因与处置建议未跟踪文件是最常见的一类。很多情况下是损坏的缩略图或只生成了一部分的转码视频从未被正确清理这类文件通常可以安全删除因为它们后续总能重新生成。其他文件则需逐案排查确认该文件对应的资产是否已在 Immich 中存在并思考它是如何变成未跟踪状态的。提示建议针对缩略图和转码视频运行 queues队列中的 missing 任务确保所有资产都有正确的缩略图和转码视频。运行期间请留意服务端日志确认个别资产没有出现问题。缺失文件是指 Immich 内部引用了某个文件但磁盘对应位置并不存在。可能原因包括你从内部库目录中手动删除了文件请勿这样做Immich 不支持这种做法或者文件存储本身存在问题。请仔细排查缺失文件如有疑问不要犹豫随时向社区求助。校验和不匹配往往意味着文件系统损坏也可能是你此前直接在磁盘上编辑了内部库中的文件同样不受支持会导致校验和不匹配。推荐的处理方式是逐条查看报告项回忆是否改动过该文件或它的元数据如果确实编辑过受支持的解决方式是从 Immich 中删除该资产然后作为新资产重新上传。1.5 报告项的删除语义维护页面对单个报告项的删除操作其实际行为取决于报告类型见 integrity.service.ts 的deleteIntegrityReport报告关联assetId将资产置为Trashed并触发AssetTrashAll事件走资产回收流程报告关联fileAssetId删除对应的资产文件记录两者都无如未跟踪文件直接unlink磁盘文件并删除报告。这意味着处理报告的删除动作不是简单丢弃一条记录而是会联动清理磁盘与数据库状态。二、校验和检查的断点续跑实现校验和检查是整个完整性体系中唯一跑不完一轮的设计每次 cron 触发后它从上一次保存的检查点checkpoint继续直到达到时间或进度上限才停下因此大媒体库的全库校验会跨越多天逐步完成。从源码integrity.service.ts 的handleChecksumFiles可以看到关键机制读取配置从系统配置中取出checksumFiles.timeLimit与percentageLimit日志会打印本次最长运行时长与目标进度断点恢复从系统元数据SystemMetadataKey.IntegrityChecksumCheckpoint读取上次的createdAt时间戳streamAssetChecksums(startMarker)按createdAt升序流式输出该时间点之后的资产integrity.repository.ts流式 SHA1checkAssetChecksum用createHash(sha1)对文件流逐块计算摘要与数据库中的asset.checksum比对integrity.service.ts——这也是为什么直接在磁盘上编辑文件必然触发不匹配报告停止条件每处理一个文件后检查Date.now() startedAt timeLimit || processed count * percentageLimit满足即保存最后一条资产的createdAt为检查点下次运行从这里继续边界处理读取文件时若返回ENOENT文件不存在该报告会被移除——缺失情形交由缺失文件检查统一处理避免两类报告互相重叠。三、存储挂载目录校验Folder checks3.1 启动时的读写校验除了运行期的完整性检查Immich 在每次启动时还会执行一组校验以确认它能够在存储系统使用的卷挂载目录中正常读写文件若无法完成全部必要操作服务将启动失败。检查覆盖的目录包括upload/ library/ thumbs/ encoded-video/ profile/ backups/这与源码中StorageFolder枚举完全一致enum.tsexport enum StorageFolder { EncodedVideo encoded-video, Library library, Upload upload, Profile profile, Thumbnails thumbs, Backups backups, }检查的具体动作实现于 storage.service.ts 的onBootstrap在SystemFileMounts数据库锁内逐目录执行创建每个目录下的初始隐藏文件.immich——仅在尚未创建过时执行文件内容为创建时刻的时间戳读取每个目录下的隐藏文件.immich覆写每个目录下的隐藏文件.immich。这一组检查专门用于捕捉两类故障场景权限不正确无法读取/写入文件卷挂载缺失.immich文件本应存在但实际缺失。校验结果通过SystemMetadataKey.SystemFlags中的mountChecks标记记录某目录首次校验成功后标记为true后续启动只需执行读/写校验若标记已存在但.immich文件读不到即可推断出挂载发生了变化。任一环节失败会抛出ImmichStartupError阻止服务启动。3.2 常见问题缺失的 .immich 文件典型报错形如Verifying system mount folder checks (enabledtrue) ... ENOENT: no such file or directory, open upload/encoded-video/.immich该报错说明服务器此前曾成功向各目录写入过.immich文件但现在检测不到它们可能原因包括权限错误文件存在但无法读取卷挂载发生了变化文件确实不存在应修正挂载配置用户手动删除了该文件应手动重新创建touch .immich从备份恢复时未恢复全部目录应恢复所有目录或在缺失的目录中手动创建.immich。注意.immich文件充当标记用于跟踪哪些卷挂载目录正被 Immich 使用。除上述列出的情形外永远不要手动创建或删除这些文件。3.3 禁用启动校验:::danger这些检查旨在捕捉过去用户实际遇到过的常见故障报错往往意味着存在应当解决的问题。如果你清楚自己在做什么、确实需要禁用这些检查可以设置以下环境变量IMMICH_IGNORE_MOUNT_CHECK_ERRORStrue:::该变量在环境变量 DTO 中定义为可选项env.dto.ts并在 config.repository.ts 中映射为配置项storage.ignoreMountCheckErrors。其生效逻辑在 storage.service.ts启动校验抛出异常时若该开关为真仅记录错误日志并输出 Ignoring mount folder errors 后继续启动否则异常向上传播服务启动失败。需要强调这是一项逃生阀而非推荐做法——跳过校验后权限错误或挂载丢失将不再在启动期被拦截而会延后暴露为不可读/不可写的运行期故障。四、小结Immich 的系统完整性保障由两条防线组成启动期的.immich挂载目录读写校验快速失败防住权限与挂载类事故和运行期三类按 cron 调度的完整性检查未跟踪文件、缺失文件、SHA1 校验和不匹配报告沉淀在integrity_report表并支持断点续跑与增量 refresh。日常运维中建议保持默认配置每日凌晨 3 点检查、校验和单次限 1 小时 / 100% 进度上限在维护页面定期查看报告对缺失与不匹配项逐条人工核实后再处理切勿绕过 Immich 直接改动内部库文件也尽量保留启动校验不被IMMICH_IGNORE_MOUNT_CHECK_ERRORS关闭。【免费下载链接】immichHigh performance self-hosted photo and video management solution.项目地址: https://gitcode.com/GitHub_Trending/im/immich创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻