rpm 数据库的作用
rpm 把所有已安装软件包的文件清单、依赖关系与校验信息记录在 /var/lib/rpm 目录下的数据库里,dnf/yum 的安装、卸载、查询全部建立在它之上。断电、根分区写满,或强制结束正在运行的 dnf 让事务中断后,数据库会出现不一致或残留锁,此后几乎所有包管理操作都会直接报错。
数据库为什么会损坏
rpm 数据库的写入没有应用级事务日志兜底:升级或卸载过程中断电,事务只写进去一半;根分区写满导致写索引中断;强杀 dnf 进程让它在写库时停住;把 /var/lib/rpm 放在快照回滚后状态不一致的存储上。机房非正常断电后出现数据库损坏的比例最高,所以把 /var/lib/rpm 纳入定期备份,比事后修复更划算。
基本信息
| 适用平台 | RHEL/CentOS/openEuler、银河麒麟、统信 UOS 等 rpm 系发行版 |
|---|---|
| 数据位置 | /var/lib/rpm,后端为 sqlite 或 Berkeley DB |
| 权限要求 | root |
| 修复命令 | rpm --rebuilddb,只重建索引不卸载软件 |
典型使用场景
- dnf 或 yum 报数据库错误,连 rpm -qa 都执行不了,需要先恢复包管理能力
- 服务器非正常断电重启后,所有软件包查询结果明显异常
- 误结束 dnf 事务进程后提示数据库被锁,后续命令持续阻塞
- 巡检发现已装包数量与台账差异很大,需要重建索引后重新核对基线
- 从克隆镜像批量部署的机器上出现包记录缺失,需要修复后重新纳入管理
标准修复流程
标准修复流程
pgrep -a -f 'dnf|yum|rpm|packagekit' # 确认没有残留的包管理进程
mkdir -p /root/rpmbak
tar -czf /root/rpmbak/rpmdb-$(date +%F).tgz /var/lib/rpm # 重建前整体备份
rm -f /var/lib/rpm/.rpm.lock # 只删锁文件,不动数据库本体
dnf clean all 2>/dev/null # 清掉元数据与缓存
rpm --rebuilddb # 重建数据库索引
rpm -qa | wc -l # 正常应有几百到上千条记录
rpm -V coreutils | head # 抽样校验,无输出表示文件校验通过常见报错对照
| 报错关键字 | 原因 | 处置 |
|---|---|---|
| BDB0113 / DB_RUNRECOVERY | Berkeley DB 后端损坏,事务无法继续 | 停掉包管理进程后执行 rpm --rebuilddb |
| rpmdb: Thread/process failed | 残留进程占用或锁文件未释放 | 先用 pgrep 确认进程退出,再清锁重建 |
| no space left on device | 根分区或 /var 空间不足导致写库失败 | 清理空间后重建,必要时先备份再腾挪 |
| cannot open Packages index | 后端文件缺失或属主权限异常 | 核对 /var/lib/rpm 属主与权限后重建 |
| error: cannot open rpmdb | 数据库文件被删或路径被改 | 从备份恢复目录后再重建,避免全量重装 |
重建前一定先备份 /var/lib/rpm。若重建后包数量与台账差距很大,应从备份回滚并安排重装异常包,不要在生产机上反复试错。
重建只修复索引,不校验已安装文件本身是否完整。若怀疑二进制被误删或改动,重建后按软件清单批量重装,或用 rpm -Va 全量校验后集中处理差异项。