问题回顾
在一次使用执行yum安装软件时突然报错,紧接着发现连rpm命令也全部失效。
报错信息如下:
error: rpmdb: BDB0113 Thread/process 1801862/281471123884880 failed: BDB1507 Thread died in Berkeley DB libraryerror: db5 error(-30973) from dbenv->failchk: BDB0087 DB_RUNRECOVERY: Fatal error, run database recoveryerror: cannot open Packages index using db5 - (-30973)error: cannot open Packages database in /var/lib/rpmError: Error: rpmdb open failed
这个故障直接导致包管理彻底瘫痪,无法查询、安装或更新任何软件。
问题解决后,我把排查和修复过程记录下来,并延伸到背后的原理与防范措施,分享给可能遇到同样情况的兄弟。
错误信息中出现了几个关键线索:“BDB1507 Thread died in Berkeley DB library”、“DB_RUNRECOVERY”以及“cannot open Packages database”。
提示很明显——RPM使用的 Berkeley DB数据库出了问题,而且要求执行恢复,但恢复并没有成功。根据上面几个线索查询,这类问题通常不是软件自身缺陷,而是外部因素触发了数据库环境的不一致,比如强制杀进程、异常断电或磁盘 I/O错误。
为什么会出现这个问题?
这台服务器运行的是CentOS 7,RPM仍然使用Berkeley DB(BDB)作为数据库后端。BDB 是一种嵌入式键值数据库,它依赖一组环境文件来管理并发访问和事务。在/var/lib/rpm/ 目录下,除了PackagesBasenames等真正存储包信息的文件外,还有一系列以__db. 开头的文件(如__db.001__db.002)。这些就是所谓的“环境文件”。
环境文件的作用是维护数据库的运行时状态,包括锁表、共享内存缓冲、事务日志以及上一次关闭是否干净的标记。每当 RPM 进程启动并打开数据库时,它会在这些文件中记录当前访问状态;当进程正常退出时,环境文件会被同步并写入“干净关闭”标志。问题就出在这里:如果进程被意外终止(例如 kill -9、系统崩溃或磁盘满了),环境文件就会残留下未释放的锁、未提交的事务以及脏数据标记。
推测问题出现原因:
某个RPM或YUM操作正在进行,可能正在写入Packages索引或更新其他数据库文件;
此时进程被强行杀死(比如运维人员等不及直接 kill -9,或者系统突然断电);
线程死在 Berkeley DB 库内部,触发 BDB1507 错误,库函数直接终止;
下次再启动任何RPM进程时,Berkeley DB首先执行failchk检查环境状态,发现上一次的关闭异常,于是返回DB_RUNRECOVERY(-30973),强制要求进行恢复;
但 RPM 自带的恢复机制在面对严重不一致的环境文件时往往无能为力,最终抛出致命错误,拒绝打开 Packages 索引。
清楚了原因,修复的逻辑就很简单:既然只是环境文件记录的状态不一致,而真正的软件包数据可能没坏,那只要把损坏的环境文件清理掉,让Berkeley DB从干净状态重新打开,再让RPM根据已有包头部重建索引就可以了。
但是在清理之前首先先要完成备份,避免二次损坏。
3.1 备份现有数据(如有问题可进行回滚)
mkdir -p /root/rpm_backupcp -a /var/lib/rpm /root/rpm_backup/
3.2 删除损坏的环境文件
rm -f /var/lib/rpm/__db.*
这些 __db.* 文件被删除后,数据库环境相当于重置,所有残留的锁和事务信息都会消失。此时 Packages 等核心数据文件仍原封不动。
3.3 重建 RPM 数据库索引
rpm --rebuilddb
这个命令会扫描已安装软件包的头部信息,重新生成全部的索引文件(如Basenames、Name等)。执行过程可能需要几秒到几十秒,取决于安装包的数量。完成后,立即用rpm -qa测试,包列表正常输出,再执行yum check-update,包管理器完全恢复正常。
这次故障的根本原因之一,是 Berkeley DB 在非正常退出场景下的脆弱性。从 RPM 4.13 开始,社区已经默认将数据库后端换为 SQLite(NDB 格式),彻底告别了复杂的环境恢复问题。RHEL 8、CentOS 8 及以上版本默认就使用 NDB,不存在这类 BDB 报错。如果无法升级系统,至少保证 rpm 和 libdb 相关软件包更新到最新,部分版本已经增强了恢复的鲁棒性。