Synology Docker Jellyfin 媒体库新增/删除文件后不更新:一次完整排查与修复记录

StoneHoo Lv4

最近遇到一个比较奇怪的 Jellyfin 问题:Jellyfin 通过 Docker 跑在 Synology NAS 上,媒体目录映射正常,但在 NAS 中新增视频、删除旧视频以后,Jellyfin 完全没有变化。

重启 Jellyfin 容器、在 Dashboard 中执行 Scan All Libraries 都没有效果。最终发现其实同时存在两个问题:

  1. Synology 主机的 inotify watch 上限只有 8192,导致 Jellyfin 实时目录监控失败。
  2. 更关键的是 Jellyfin 的 jellyfin.dbUserData 数据触发 SQLite UNIQUE constraint 冲突,使媒体库扫描在清理已删除项目时异常中断。

下面记录完整排查过程,方便以后再次遇到类似问题时快速定位。

环境

  • NAS:Synology
  • Jellyfin:Docker / Container Manager
  • Jellyfin 版本:10.11.6
  • 媒体目录:
1
/volume1/stone/movie
  • Docker 映射:
1
2
/volume1/stone/movie -> /media
/volume1/docker/jellyfin -> /config

实际容器名:

1
jellyfin-jellyfin-1-1

故障现象

NAS 的:

1
/volume1/stone/movie

中新增了视频,同时删除了一些旧视频。

但是 Jellyfin 中:

  • 新视频不出现
  • 已删除的视频仍然存在
  • 重启容器无效
  • Scan All Libraries 无效
  • Dashboard 一直显示 84 个项目

其中一个用于测试的新文件是:

1
Toy Story 5 2026 2160p WEB-DL DoVi HDR10 H 265 DDP 5 1 Atmos.mkv

第一步:确认 Docker Volume 映射

首先不要急着修改 Jellyfin 数据库,先确认容器实际看到的媒体目录。

1
sudo docker exec jellyfin-jellyfin-1-1 ls -lah /media

容器中能够看到媒体文件。

然后检查实际 Docker mount:

1
2
sudo docker inspect jellyfin-jellyfin-1-1 \
--format '{{range .Mounts}}{{println .Source " -> " .Destination}}{{end}}'

结果:

1
2
3
/volume1/@docker/volumes/.../_data -> /cache
/volume1/docker/jellyfin -> /config
/volume1/stone/movie -> /media

因此 Docker volume 映射正确。


第二步:比较 NAS 和容器中的视频数量

NAS 主机:

1
2
3
find /volume1/stone/movie -type f \
\( -iname "*.mkv" -o -iname "*.mp4" -o -iname "*.avi" -o -iname "*.m4v" \) \
| wc -l

结果:

1
84

Docker 容器:

1
2
sudo docker exec jellyfin-jellyfin-1-1 sh -c \
'find /media -type f \( -iname "*.mkv" -o -iname "*.mp4" -o -iname "*.avi" -o -iname "*.m4v" \) | wc -l'

结果同样:

1
84

这说明 NAS 与容器看到的是同一套媒体文件。

这里也发现了一个容易误判的地方:

Jellyfin Dashboard 显示的数字和 find 统计的视频文件数量恰好都是 84,并不能单凭这个数字判断 Jellyfin 是否正确更新。

后来问题修复后,新增文件已经正常出现,而 84 本身确实是正确的视频文件总数。


第三步:检查容器读取权限

检查 Jellyfin 容器运行身份:

1
sudo docker exec jellyfin-jellyfin-1-1 id

结果:

1
uid=0(root) gid=0(root) groups=0(root)

再针对新加入的 Toy Story 文件测试:

1
2
sudo docker exec jellyfin-jellyfin-1-1 sh -c \
'find /media -maxdepth 1 -iname "*Toy Story*" -ls'

能够找到文件。

进一步直接读取文件:

1
2
sudo docker exec jellyfin-jellyfin-1-1 sh -c \
'head -c 1024 /media/"Toy Story 5 2026 2160p WEB-DL DoVi HDR10 H 265 DDP 5 1 Atmos.mkv" >/dev/null && echo "READ OK"'

结果:

1
READ OK

至此可以基本排除:

  • Docker mount 错误
  • 文件不存在
  • Jellyfin 容器无法读取媒体文件
  • 普通文件权限问题

第四步:发现 inotify watch 上限问题

检查 Jellyfin 日志时发现:

1
2
System.IO.IOException:
The configured user limit (8192) on the number of inotify watches has been reached

同时还有:

1
LibraryMonitor: Error in Directory watcher for: /media

Jellyfin 在 Linux 上依赖 inotify 实现媒体目录的实时监控。官方文档也明确说明,大型媒体库可能遇到 max_user_watches=8192 不够的问题;Docker 环境下需要在 Docker Host 上调整,而不是在容器内部调整。

查看当前值:

1
2
cat /proc/sys/fs/inotify/max_user_watches
cat /proc/sys/fs/inotify/max_user_instances

原来的 max_user_watches 是:

1
8192

临时提高:

1
sudo sysctl -w fs.inotify.max_user_watches=524288

确认:

1
cat /proc/sys/fs/inotify/max_user_watches

结果:

1
524288

然后重启 Jellyfin:

1
sudo docker restart jellyfin-jellyfin-1-1

注意:sysctl -w 通常只是运行时修改。Synology 重启以后可能恢复默认值,最好另外通过 DSM Task Scheduler 或适合当前 DSM 版本的启动机制持久化该设置。

这个问题修复了 Jellyfin 的实时目录监控,但手动扫描仍然没有正常更新媒体库,因此继续排查。


第五步:真正的关键,SQLite UNIQUE constraint 错误

重新执行媒体库扫描后查看日志:

1
2
sudo docker logs jellyfin-jellyfin-1-1 --since 5m 2>&1 | \
grep -i -E 'toy|scan|media|error|warn'

发现真正关键的错误:

1
2
3
4
Microsoft.Data.Sqlite.SqliteException:
SQLite Error 19:
'UNIQUE constraint failed:
UserData.ItemId, UserData.UserId, UserData.CustomDataKey'.

紧接着:

1
Error while performing a library operation

日志同时显示 Jellyfin 正在尝试删除数据库中已经不存在的旧媒体,例如:

1
2
Removing item, Type: Folder,
Name: [白莲花度假村 第二季]...

随后又出现:

1
2
System.IO.DirectoryNotFoundException:
Could not find a part of the path '/media/[白莲花度假村 第二季]...'

也就是说:

  1. 文件已经从 NAS 删除
  2. Jellyfin 扫描发现数据库中的旧媒体路径不存在
  3. Jellyfin 开始清理旧项目
  4. 清理过程中触发 UserData 唯一约束冲突
  5. Library operation 报错
  6. 后续媒体库更新无法正常完成

这也解释了为什么会同时出现:

  • 删除的视频仍然留在 Jellyfin
  • 新增的视频不出现

第六步:先备份,再检查数据库

在任何 SQLite 修改之前先停止 Jellyfin:

1
sudo docker stop jellyfin-jellyfin-1-1

完整备份 Jellyfin 配置:

1
2
sudo cp -a /volume1/docker/jellyfin \
/volume1/docker/jellyfin-backup-20260907

确认:

1
ls -ld /volume1/docker/jellyfin-backup-20260907

数据库实际位于:

1
/volume1/docker/jellyfin/data/jellyfin.db

检查 SQLite 完整性:

1
2
sudo sqlite3 /volume1/docker/jellyfin-backup-20260907/data/jellyfin.db \
'PRAGMA integrity_check;'

结果:

1
ok

检查 foreign key:

1
2
sudo sqlite3 /volume1/docker/jellyfin-backup-20260907/data/jellyfin.db \
'PRAGMA foreign_key_check;'

没有输出。

说明:

jellyfin.db 整体并没有损坏,问题集中在 Jellyfin 清理媒体时涉及的 UserData 数据/约束。

查看 UserData 表后可以看到其主键:

1
PRIMARY KEY ("ItemId", "UserId", "CustomDataKey")

这正对应日志中的:

1
2
3
4
UNIQUE constraint failed:
UserData.ItemId,
UserData.UserId,
UserData.CustomDataKey

第七步:快速修复,清空 UserData

因为我的 Jellyfin 主要用于个人媒体播放,并不在意:

  • 观看历史
  • 播放进度
  • Favorite 状态
  • 用户针对媒体保存的播放状态

所以没有继续尝试逐条修复异常记录,而是选择最简单的办法:

清空 UserData,但保留整个 Jellyfin 媒体数据库。

再次确认 Jellyfin 已停止,然后执行:

1
2
sudo sqlite3 /volume1/docker/jellyfin/data/jellyfin.db \
'DELETE FROM UserData;'

确认:

1
2
sudo sqlite3 /volume1/docker/jellyfin/data/jellyfin.db \
'SELECT COUNT(*) FROM UserData;'

结果:

1
0

再次检查数据库:

1
2
sudo sqlite3 /volume1/docker/jellyfin/data/jellyfin.db \
'PRAGMA integrity_check;'

结果:

1
ok

启动 Jellyfin:

1
sudo docker start jellyfin-jellyfin-1-1

然后重新执行:

Dashboard → Scan All Libraries


修复后的日志

这一次日志明显不同。

Jellyfin 成功删除了数据库中的旧项目:

1
2
3
4
5
6
7
8
Removing item, Type: Folder,
Name: [白莲花度假村 第二季]...

Removing item, Type: Folder,
Name: [白莲花度假村 第一季]...

Removing item, Type: Movie,
Name: Silenced...

随后:

1
Scan Media Library Completed after 0 minute(s) and 16 seconds

之前异常时扫描只用了大约 3 秒,并伴随 SQLite UNIQUE constraint 错误。

修复后再次扫描,新增的媒体文件全部正常出现在 Jellyfin 中,包括之前一直无法识别的新文件。

最终 Dashboard 仍然显示:

1
84

但这是正确的,因为 NAS 当前确实有 84 个视频文件。


最终结论

这次实际上同时遇到了两个问题。

1. inotify watch 不够

症状:

1
2
The configured user limit (8192)
on the number of inotify watches has been reached

修复:

1
sudo sysctl -w fs.inotify.max_user_watches=524288

它主要影响 Jellyfin 对媒体目录的实时监控。

2. Jellyfin UserData UNIQUE constraint 冲突

症状:

1
2
3
4
5
SQLite Error 19:
UNIQUE constraint failed:
UserData.ItemId,
UserData.UserId,
UserData.CustomDataKey

它会导致 Jellyfin 在清理已经删除的媒体时 library operation 失败,进而表现为:

1
2
3
4
5
6
7
8
9
删除旧媒体

Jellyfin 无法正确清理旧数据库记录

Library Scan 异常

旧项目仍存在
+
新增项目也不出现

在不需要保留观看历史的情况下,快速修复方式是:

1
2
3
4
5
6
7
8
9
10
11
12
sudo docker stop jellyfin-jellyfin-1-1

sudo cp -a /volume1/docker/jellyfin \
/volume1/docker/jellyfin-backup-$(date +%Y%m%d)

sudo sqlite3 /volume1/docker/jellyfin/data/jellyfin.db \
'DELETE FROM UserData;'

sudo sqlite3 /volume1/docker/jellyfin/data/jellyfin.db \
'PRAGMA integrity_check;'

sudo docker start jellyfin-jellyfin-1-1

然后重新扫描媒体库。


以后再次出现类似问题时的快速排查顺序

以后如果 Jellyfin 再次出现“新增/删除文件后媒体库不更新”,可以按这个顺序检查。

1. Docker 是否真的能看到媒体

1
sudo docker exec jellyfin-jellyfin-1-1 ls -lah /media

2. Docker mount 是否正确

1
2
sudo docker inspect jellyfin-jellyfin-1-1 \
--format '{{range .Mounts}}{{println .Source " -> " .Destination}}{{end}}'

应该看到:

1
/volume1/stone/movie -> /media

3. NAS 和容器的视频数量是否一致

NAS:

1
2
3
find /volume1/stone/movie -type f \
\( -iname "*.mkv" -o -iname "*.mp4" -o -iname "*.avi" -o -iname "*.m4v" \) \
| wc -l

容器:

1
2
sudo docker exec jellyfin-jellyfin-1-1 sh -c \
'find /media -type f \( -iname "*.mkv" -o -iname "*.mp4" -o -iname "*.avi" -o -iname "*.m4v" \) | wc -l'

4. 检查 inotify

1
cat /proc/sys/fs/inotify/max_user_watches

如果仍是:

1
8192

而日志出现 watch limit 错误,可以提高:

1
sudo sysctl -w fs.inotify.max_user_watches=524288

5. 重点检查 Jellyfin 扫描日志

1
2
sudo docker logs jellyfin-jellyfin-1-1 --since 10m 2>&1 | \
grep -i -E 'unique constraint|error while performing|directory watcher|scan media'

如果再次看到:

1
2
3
4
UNIQUE constraint failed:
UserData.ItemId,
UserData.UserId,
UserData.CustomDataKey

基本可以直接判断是同类问题。

6. 修改数据库前一定先备份

1
2
3
4
sudo docker stop jellyfin-jellyfin-1-1

sudo cp -a /volume1/docker/jellyfin \
/volume1/docker/jellyfin-backup-$(date +%Y%m%d-%H%M)

这一点比任何修复命令都重要。


关于以后删除媒体

这次问题并不意味着以后不能删除 Jellyfin 媒体。

正常情况下,可以直接从 NAS 删除文件,再让 Jellyfin 自动监测或执行 Library Scan。Jellyfin 应该自动清理已经不存在的项目。

如果以后再次发生同样的 SQLite constraint 错误,再针对数据库处理即可,不需要为了避免 bug 而停止正常删除媒体文件。

另外建议:

  • 保持 Jellyfin 使用最新稳定版本
  • 持久化 Synology 的 fs.inotify.max_user_watches=524288
  • 定期备份 /volume1/docker/jellyfin
  • 出现扫描异常时先看日志,不要第一时间删除整个 jellyfin.db
  • 如果在意观看历史,不要直接执行 DELETE FROM UserData;,而应该先定位具体异常记录

参考

  • Jellyfin 官方 Troubleshooting:Real Time Monitoring / inotify
  • Jellyfin 官方 Libraries 文档
  • Jellyfin 官方 Scheduled Tasks 文档

这次排查最有价值的一点是:看到“Jellyfin 扫描完成”并不代表扫描真正成功。

如果媒体库新增和删除同时失效,应该优先检查扫描日志。像 UNIQUE constraint failed 这样的数据库错误,很可能才是真正阻断媒体库更新的原因。

  • Title: Synology Docker Jellyfin 媒体库新增/删除文件后不更新:一次完整排查与修复记录
  • Author: StoneHoo
  • Created at : 2026-09-07 23:20:00
  • Updated at : 2026-09-07 23:27:10
  • Link: https://www.ozak.ca/2026/09/07/jellyfin-synology-library-scan-sqlite-fix/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments