Ubuntu 的内核自动升级导致 Mongodb 无法正常启动,没有找到解决方案,本文记录问题出现和解救的过程。
问题描述
服务器在 2025.07.08 Ubuntu 22.04 自动升级系统内核,从 6.8.0-52-generic 升级到 6.8.0-60-generic
之后 MongoDB 7.0.12 便无法正常启动
-
日志中显示 WiredTiger 存储引擎遇到了严重的损坏问题,关键错误信息
1 2 3
| WiredTiger error: WT_TRY_SALVAGE: database corruption detected __wt_turtle_read: fatal turtle file read error WT_PANIC: WiredTiger library panic
|
核心问题是WiredTiger存储引擎无法读取WiredTiger.turtle文件,这是存储元数据的关键文件。
-
在 Docker 的错误日志中最后一句,错误码 6:
1
| subprocess.CalledProcessError: Command '['mongod', '--configsvr', '--directoryperdb', '--replSet', 'fates-mongo-config', '--bind_ip_all']' died with <Signals.SIGABRT: 6>.
|
挣扎过程记录
Mongo 啊,崩了啊,天塌了
- 尝试修复 MongoDB
1
| docker run -it --rm -v /data/mongo/db:/data/db mongodb/mongodb-community-server:7.0.12-ubuntu2204 mongod --repair --directoryperdb
|
依然报错。
- 尝试更加激进的修复
1
| docker run -it --rm -v /data/mongo/db:/data/db mongodb/mongodb-community-server:7.0.12-ubuntu2204 mongod --repair --directoryperdb --wiredTigerEngineConfigString="salvage=true"
|
修复没有成功,修复报错检测到硬件级的数据损坏(checksum 不匹配):
1
| potential hardware corruption, read checksum error for 4096B block at offset 16384
|
多次尝试恢复失败:
1 2
| Failed to start up WiredTiger under any compatibility version Failed to salvage WiredTiger metadata
|
最终错误:
1 2
| -31809: WT_TRY_SALVAGE: database corruption detected
|
重新运行 MongoDB 依然报错,但是错误信息变了,错误码 14。
1
| subprocess.CalledProcessError: Command '['mongod', '--repair', '--dbpath', '/data/db', '--directoryperdb', '--wiredTigerEngineConfigString=salvage=true', '--bind_ip_all']' returned non-zero exit status 14.
|
-
硬件状态检查
此时怀疑硬件出错,检查了半天硬盘、Raid,都没有问题。
-
数据回溯
无奈没有检查到问题原因,启动群晖的数据恢复功能,回档了一个月,我确定那时候的数据库是可以用的。
当数据回溯结束后再次启动 MongoDB 时,却依然报错 !!!! ???
此时基本可以确定不是 MongoDB 、文件、硬盘的问题,八成是内核升级导致的不兼容问题。
-
检查系统内核升级记录
查看已安装的内核:
1 2 3 4 5 6 7 8
| apt list --installed | grep linux-image--> WARNING: apt does not have a stable CLI interface. Use with caution in scripts. linux-image-6.8.0-52-generic/jammy-updates,jammy-security,now 6.8.0-52.53~22.04.1 amd64 [已安装,自动] linux-image-6.8.0-60-generic/jammy-updates,jammy-security,now 6.8.0-60.63~22.04.1 amd64 [已安装,自动] linux-image-generic-hwe-22.04/jammy-updates,jammy-security,now 6.8.0-60.63~22.04.1 amd64 [已安装,自动]
|
发现有多个版本,存在版本切换的可能
查看内核启动日志
1 2 3 4 5 6 7 8
| $ sudo journalctl -k --list-boots--> -5 e1093f0931924eea9f9ea8649be2d057 Wed 2025-02-05 05:45:33 CST—Fri 2025-02-07 10:24:25 CST -4 7d68ae798d8746c1bca73101205d7f95 Fri 2025-02-07 10:28:20 CST—Tue 2025-02-11 09:30:08 CST -3 ca1b8e8e753e4e15993b193dfc1e79fc Tue 2025-02-11 09:33:52 CST—Thu 2025-02-13 12:28:32 CST -2 7ba7c096953445eebb8191bff3897ec5 Thu 2025-02-13 12:32:14 CST—Thu 2025-06-26 18:32:10 CST -1 05b99060b7894fdb8c91c6c58dbfcbea Tue 2025-07-08 09:19:50 CST—Wed 2025-07-09 13:12:58 CST
|
我的问题就是出现在 2025-07-08,当时确实出现了内核版本切换
查看某次启动的内核版本:
1 2 3 4 5 6 7 8 9 10 11 12
| sudo journalctl -k -b | grep "Linux version" # 当前内核 Jul 09 13:14:44 bolight-PowerEdge-T640 kernel: Linux version 6.8.0-52-generic (buildd@lcy02-amd64-099) (x86_64-linux-gnu-gcc-12 (Ubuntu 12.3.0-1ubuntu1~22.04) 12.3.0, GNU ld (GNU Binutils for Ubuntu) 2.38) #53~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Wed Jan 15 19:18:46 UTC 2 (Ubuntu 6.8.0-52.53~22.04.1-generic 6.8.12)sudo journalctl -k -b -1 | grep "Linux version" # 上次切换 Jul 08 09:19:50 bolight-PowerEdge-T640 kernel: Linux version 6.8.0-60-generic (buildd@lcy02-amd64-098) (x86_64-linux-gnu-gcc-12 (Ubuntu 12.3.0-1ubuntu1~22.04) 12.3.0, GNU ld (GNU Binutils for Ubuntu) 2.38) #63~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Tue Apr 22 19:00:15 UTC 2 (Ubuntu 6.8.0-60.63~22.04.1-generic 6.8.12) sudo journalctl -k -b -2 | grep "Linux version" # 上上次 Feb 13 12:32:14 bolight-PowerEdge-T640 kernel: Linux version 6.8.0-52-generic (buildd@lcy02-amd64-099) (x86_64-linux-gnu-gcc-12 (Ubuntu 12.3.0-1ubuntu1~22.04) 12.3.0, GNU ld (GNU Binutils for Ubuntu) 2.38) #53~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Wed Jan 15 19:18:46 UTC 2 (Ubuntu 6.8.0-52.53~22.04.1-generic 6.8.12)
|
可以看到,原本 2月份的内核 (6.8.0-52) 在 7月8日 切换到了 6.8.0-60,导致问题出现,直到我切换回 6.8.0-52。
-
切换回原来的内核后重启 MongoDB
1 2
| sudo grub-reboot 'Advanced options for Ubuntu>Ubuntu, with Linux 6.8.0-52-generic' sudo reboot
|
这会让你下次启动时使用 6.8.0-52 内核。
编辑 /etc/default/grub 文件:
1
| sudo vim /etc/default/grub
|
找到 GRUB_DEFAULT 行,修改为:
1
| GRUB_DEFAULT="Advanced options for Ubuntu>Ubuntu, with Linux 6.8.0-52-generic"
|
然后更新 GRUB:
1 2
| sudo update-grub sudo reboot
|
仍然报错 14
此时是因为数据恢复后数据本是正确的,但是我用过高版本的内核启动过这些 MongoDB,又给改坏了,导致降低内核版本后仍无法读取
-
再次回溯数据
MongoDB 仍然无法正常运行,这是一次失败的抢救,记录于此 …
关闭内核升级
方法一:使用 apt-mark hold 锁定内核版本
1 2 3
| uname -r6.8.0-52-generic
|
1 2 3 4 5 6 7 8
| sudo apt-mark hold linux-image-generic linux-headers-generic sudo apt-mark hold linux-image-$(uname -r) linux-headers-$(uname -r)--> linux-image-generic 设置为保留。 linux-headers-generic 设置为保留。 linux-image-6.8.0-52-generic 设置为保留。 linux-headers-6.8.0-52-generic 设置为保留。
|
1 2 3 4 5
| $ apt-mark showhold linux-headers-6.8.0-52-generic linux-headers-generic linux-image-6.8.0-52-generic linux-image-generic
|
这样 apt upgrade 或 unattended-upgrades 就不会自动升级内核。
方法二:禁用 unattended-upgrades 自动更新内核
Ubuntu 默认启用 unattended-upgrades 自动更新,我们可以配置它不更新内核。
- 编辑
unattended-upgrades 配置
1
| sudo vim /etc/apt/apt.conf.d/50unattended-upgrades
|
1 2 3 4 5
| Unattended-Upgrade::Allowed-Origins { "${distro_id}:${distro_codename}"; "${distro_id}:${distro_codename}-security"; "${distro_id}ESM:${distro_codename}"; };
|
1 2 3 4 5
| Unattended-Upgrade::Package-Blacklist { "linux-image-*"; "linux-headers-*"; "linux-modules-*"; };
|
1
| sudo systemctl restart unattended-upgrades
|
1
| sudo unattended-upgrade --dry-run --debug
|
检查输出是否跳过了 linux-image-* 和 linux-headers-* 相关包。
文章链接:
https://www.zywvvd.com/notes/coding/dataset/ubuntu-kernel-mongo-error/ubuntu-kernel-mongo-error/