AdGuardHome 启动失败故障复盘

主机:Siche-Ubuntu (192.168.0.64)
服务:AdGuardHome v0.107.77
影响:DNS 解析服务中断
恢复时间:2026-07-09
状态:✅ 已恢复


一、问题摘要

AdGuardHome 服务反复重启失败,systemctl status 显示 Active: activating (auto-restart),进程退出码 1。经排查,根因由三类问题叠加形成:

# 类别 严重度 说明
1 端口占用 libvirt dnsmasq 抢占 UDP 53 端口
2 配置错误 bind_hosts 包含不存在的 IP (192.168.0.24)
3 数据损坏 sessions.db 损坏/锁定导致 SQLite 打开超时

二、时间线

时间点 操作
T0 用户发现 AdGuardHome 不可用
T1 journalctl / systemctl status 确认服务反复重启
T2 前台启动捕获错误:listen udp 192.168.0.24:53: bind: cannot assign requested address
T3 修正确认 192.168.0.24 不存在于任何网卡,仅 192.168.0.64 可用
T4 停止 libvirt dnsmasq,释放 192.168.122.1:53
T5 修改 bind_hosts[127.0.0.1, 192.168.0.64, ::1]
T6 再次启动,新错误:sessions.db: timeout
T7 排查磁盘 I/O(正常)、文件锁(无持有者)、权限(正常)
T8 发现 querylog.json 膨胀至 8.9 GB
T9 备份并删除 sessions.db,清空 querylog.json
T10 重新启动 → 成功,服务稳定运行

三、详细排查

3.1 UDP 53 端口占用

1
2
netstat -tulpn | grep ':53'
# 输出:192.168.122.1:53 被 dnsmasq (libvirt) 占用

根因:libvirt 默认虚拟网络 (virbr0) 自带的 dnsmasq 实例监听了 192.168.122.1:53,与 AdGuardHome 的 DNS 监听需求冲突。

修复

1
2
virsh net-destroy default
virsh net-autostart default --disable

3.2 bind_hosts 无效 IP

配置文件中 bind_hosts 数组包含 192.168.0.24,但该地址未被分配给任何接口:

1
2
ip addr show | grep 192.168.0.24
# 无输出 — IP 不存在

AdGuardHome 在初始化 DNS 监听器时 bind(2) 调用失败,返回 EADDRNOTAVAIL,直接阻止服务启动。

修复:将 bind_hosts 修正为实际存在的地址:

1
2
3
4
bind_hosts:
- 127.0.0.1
- 192.168.0.64
- "::1"

3.3 sessions.db 超时

端口和配置修复后,前台启动仍报错:

1
2
session_storage: opening db filename=/opt/AdGuardHome/data/sessions.db err=timeout
fatal: initializing auth module: creating session storage: timeout

排除因素:

  • 磁盘 I/Oiostat 显示 %util < 1%,排除性能瓶颈
  • 文件锁lsof /opt/AdGuardHome/data/sessions.db 无进程持有
  • 权限root:root / 600,正常

推测原因:

  • sessions.db 内部 SQLite 锁未正确释放(如上次进程被 SIGKILL)
  • querylog.json 高达 8.9 GB,文件系统元数据操作延迟间接影响 db 打开

修复

1
2
3
4
systemctl stop AdGuardHome
rm -f /opt/AdGuardHome/data/sessions.db
> /opt/AdGuardHome/data/querylog.json # 清空日志
systemctl start AdGuardHome

四、根因分析(5 Why)

  1. 为什么服务起不来? → DNS 监听器初始化失败 + session 存储初始化失败
  2. 为什么 DNS 监听失败? → 配置中绑定了不存在的 IP 192.168.0.24
  3. 为什么 session 也失败?sessions.db 损坏/锁定,SQLite 打开超时
  4. 为什么 db 会损坏? → 服务异常退出时未清理锁,且 querylog.json 过大加剧 I/O 延迟
  5. 为什么 querylog 这么大? → 查询日志无保留期限制,长期累积

五、修复措施

措施 操作
关闭 libvirt dnsmasq virsh net-destroy default && virsh net-autostart default --disable
修正 bind_hosts 移除 192.168.0.24,保留实际 IP
重建 sessions.db 删除损坏文件,让服务重建
清空 querylog.json 释放 8.9 GB 空间

六、预防改进

# 措施 优先级
1 日志轮转:在 AdGuardHome Web UI → 设置 → 查询日志,设置保留期限(建议 7 天) P0
2 配置校验:部署前运行 AdGuardHome --check-config 验证 bind_hosts P1
3 大文件告警:Prometheus 添加 node_filesystem_file_size_bytes 规则,querylog.json > 1GB 触发告警 P1
4 数据库保护:考虑将 sessions.db 移至 tmpfs(内存文件系统),避免磁盘 I/O 依赖 P2
5 升级 AdGuardHome:关注 v0.107.77 后续版本是否优化 session 超时机制 P2
6 端口规划:libvirt 如恢复使用,需配置 AdGuardHome 不监听 192.168.122.1:53(或给 virbr0 换网段) P3

七、验证结果

1
2
3
4
5
6
7
8
systemctl status AdGuardHome | head -3
# Active: active (running)

curl -sI http://192.168.0.64:8008 | head -1
# HTTP/1.1 200 OK

dig @192.168.0.64 baidu.com +short
# 返回正确 IP

八、附录

8.1 关键路径

文件 路径
二进制 /opt/AdGuardHome/AdGuardHome
配置 /opt/AdGuardHome/AdGuardHome.yaml
数据目录 /opt/AdGuardHome/data/
sessions.db /opt/AdGuardHome/data/sessions.db
querylog.json /opt/AdGuardHome/data/querylog.json

8.2 恢复 libvirt(如需)

1
2
3
virsh net-start default
virsh net-autostart default
# 注意:此时需调整 AdGuardHome 绑定,避免 53 端口冲突

8.3 重置管理员密码

1
2
# AdGuardHome 密码以 bcrypt 哈希存储在配置文件中
# 如需重置,停止服务后删除 users 段,重启后重新注册

AdGuardHome 启动失败故障复盘
https://bote798.top/2026/07/09/AdGuardHome启动失败故障复盘/
作者
bote798
发布于
2026年7月9日
更新于
2026年7月11日
许可协议