![我如何才能查明为什么我的服务器上的 rpm DB 不断损坏?](https://linux22.com/image/702558/%E6%88%91%E5%A6%82%E4%BD%95%E6%89%8D%E8%83%BD%E6%9F%A5%E6%98%8E%E4%B8%BA%E4%BB%80%E4%B9%88%E6%88%91%E7%9A%84%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%E7%9A%84%20rpm%20DB%20%E4%B8%8D%E6%96%AD%E6%8D%9F%E5%9D%8F%EF%BC%9F.png)
运行 Centos 7(各种版本)
我的服务器上的 rpm 数据库不断损坏。似乎每隔几周我就必须在一两台服务器上重建 rpm。
我应该在哪里查看罪魁祸首?我知道发生这种情况时如何修复,但我如何确定这是我正在安装的特定软件包还是有什么东西触发了这种情况?
答案1
有无数个 BDB 环境损坏的 bug,其中一些是 BDB bug(最近几年才发现几个),这些 bug 已在 Fedora/RHEL libdb 中得到修补,但上游 BDB 5.x 没有,不知道 6.x 有没有,但你会遇到许可方面的问题。这是一个众所周知的问题,没有永久的解决方案。
根本原因:
如果 rpm 或 yum 不能干净地退出,锁定文件就会被遗留。文件 (__db001 - __db005) 遗留在 /var/lib/rpm 中。我们可以看到留下文件的 pid。问题往往是我们没有日志或审计配置来查明到底是什么终止了进程。最常见的原因是自动化工具超时并突然结束进程而没有让 rpm 清除锁定文件。
一种可能的解决方法是强制使用私有环境。这也意味着实际上没有锁定,但至少意味着查询不会破坏任何东西(但是如果在写入操作中间运行,查询本身可能会返回垃圾)。如果您以非特权用户身份运行查询,就会发生这种情况,但由于您可以使用沙盒控制权限,因此您可以通过禁止打开 /var/lib/rpm/.dbenv.lock 来实现相同的目的,这会导致 rpm 回退到私有环境 - 这意味着它不会打开,更不用说写入那些 __db.* 文件了。
这开发商声明是它不会被彻底修复:
“要使 BDB 更加可靠,就需要使用事务,但这将是一种不兼容的更改,而这正是我们目前最不想做的事情,因为我们基本上即将弃用 BDB。这意味着我们无法在 Berkeley DB 后端对此采取任何措施,很遗憾。”
他们建议使用直流转速公用事业。
dcrpm(“检测和纠正 rpm”)是一种用于检测和纠正 RPM 数据库损坏常见问题的工具。它会尝试查询您的 RPM 数据库,如果数据库挂起或出现其他问题,它会运行 db4 的 db_recover。然后它会终止之前打开 RPM 数据库的所有作业,因为它们会陷入 libdb 中的无限循环,无法完全恢复。
以下是安装时需要做的事情:
# git clone https://github.com/facebookincubator/dcrpm.git
# cd dcrpm
# python setup.py install
安装后,您可以运行该工具并将其添加到 cron:
# dcrpm
不幸的是,由于 python 依赖项从未正确安装,因此在 CentOS 7 上安装总是失败。
error: Setup script exited with error in psutil setup command: 'extras_require' must be a dictionary whose values are strings or lists of strings containing valid project/version requirement specifiers.
尽管 psutil 已成功安装,但其他人报告说 dcrpm 对他们来说运行良好,所以请尝试一下。
我已经使用了另一个官方解决方案红帽(RHEL 7)。
# curl https://people.redhat.com/kwalker/repos/rpm-deathwatch/rhel7/rpm-deathwatch-rhel-7.repo -o /etc/yum.repos.d/rpm-deathwatch.repo
# yum install -y kernel-{devel,headers}-$(uname -r) systemtap && debuginfo-install -y kernel
# yum install rpm-deathwatch
# systemctl start rpm-deathwatch
# systemctl status rpm-deathwatch