☰
Linux运维必备:yum异常日志全解析与排查实战指南
2026/9/29 16:05:06 网站建设 项目流程

你有没有遇到过这种情况:在 Linux 服务器上执行 yum install 或者 yum update,命令卡住不动、报一连串奇怪的依赖错误、甚至连 yum 自己都报段错误(Segmentation fault),而你翻遍了网上的帖子也不知道系统里到底发生了什么。

我早期的运维生涯有一大半时间都在跟 yum 相爱相杀。用得越多,我越是意识到一个关键问题:yum 命令本身几乎不会告诉你真正的原因,真正的原因全部藏在日志和系统记录里。谁的排查速度快,取决于谁更会看这些“异常记录”。

这篇文章我就把多年攒下来的 yum 异常记录查看方法、日志体系、排查思路和实操案例全部拆开讲一遍,希望能帮你少走几趟弯路。

1. yum 异常日志体系:先搞清楚日志都在哪

1.1 yum 自己写的日志:/var/log/yum.log

yum 从 CentOS 6 时代开始就有自己的日志文件,位置固定在 /var/log/yum.log。这个文件记录的是 yum 执行过程中的安装、更新、删除动作,格式类似这样:

Jun 10 10:23:45 Installed: tigervnc-server-1.13.1-9.el9.x86_64 Jun 10 10:25:02 Updated: kernel-5.14.0-362.13.1.el9_3.x86_64 Jun 10 10:26:18 Erased: telnet-0.17-87.el9.x86_64

这个文件最重要的价值在于——它能还原你在某一天到底执行过哪些包操作。很多“yum 突然异常”的问题,根本原因就是某次安装时锁文件没释放,或者某个包被更新坏了,通过这个日志可以直接回推时间线。

不过有个坑需要注意:在 CentOS 8 / RHEL 8 之后的系统里,默认只有 dnf,不再自动生成 /var/log/yum.log。如果你装的是兼容包 yum(CentOS 8 自带一个指向 dnf 的 yum 软链),日志会写到 /var/log/dnf.log。所以排查前先确认系统版本和实际日志路径,别在 /var/log/yum.log 里翻半天,结果系统里压根没有这个文件。

1.2 dnf 的日志:/var/log/dnf.log 与 /var/log/dnf.librepo.log

有人说 CentOS 8 抛弃了 yum,其实只是把 yum 的底层实现换成了 dnf,然后把 yum 命令做成一个薄壳。dnf 自己有两套日志:

  • /var/log/dnf.log:记录 dnf 的事务、安装、更新、错误信息,内容比 yum.log 详细得多
  • /var/log/dnf.librepo.log:记录库(repo)下载相关日志,比如某个 rpm 包下载失败、镜像源超时

看 dnf 日志的时候我一般直接 grep 关键词,因为日志量非常大,一屏刷完很浪费眼神:

grep -E "ERROR|WARNING|failure|Fail" /var/log/dnf.log | tail -50

注意:/var/log/dnf.log 并不是默认开启的,需要在 /etc/dnf/dnf.conf 的 [main] 字段下加上logfile=/var/log/dnf.log才会持久化。如果没配过,dnf 默认把日志打到 journald 里,所以后边第六节讲的 journalctl 才是 dnf 日志的真正主战场。

1.3 系统层面的日志:/var/log/messages 与 journalct

yum 本身是 Python 写的,它在执行时会调用系统的 RPM 库、网络库、文件系统接口。如果执行过程中系统层面报错,比如磁盘 IO 错误、内存不足、Python 依赖损坏等,yum 往往不会写日志,而是把错误信息吞掉,只给你一个半截的提示。这时候就得去翻 /var/log/messages 或者用 journalctl 查看内核和系统服务的记录。

我遇到过一个很典型的案例:yum install 执行到一半就提示“段错误”。当时 yum.log 里什么也没有,但 journalctl 里赫然写了十几条 python3 进程 OOM(内存不足)的记录。所以,当 yum 异常时,只盯着 yum 自己的日志是不够的,系统日志同样关键。

2. 实时排查异常:journalctl 的正确用法

2.1 查看某一次 yum 执行的实时日志

journalctl 是 systemd 自带的日志工具,从 CentOS 7 起就成了标配。它记录 systemd 管理的所有服务的输出,包括命令行里手动执行的程序(前提是那条命令在 systemd 的会话中执行过)。想看 yum 或 dnf 的实时日志,这两个命令最常用:

# 查看今天 dnf/yum 相关日志(dnf 的进程名是 dnf,yum 兼容包也是调到 dnf) journalctl --since today | grep -E "yum|dnf" | tail -100 # 实时跟踪日志输出,另开一个终端窗口执行 yum 命令,方便现场定位 journalctl -f | grep -E "yum|dnf"

第二条命令我强烈推荐。你在一个终端里跑 journalctl -f 跟着输出,另一个终端执行复现问题的 yum 操作,异常发生的那一刻,journald 里会非常清晰地记录下 dnf 到底在哪个环节出的错。

2.2 如何找到某次事务的精确日志

如果你执行的是 dnf install,那么 packagekitd 或 dnf 对应的可执行文件名会在 journald 里留下 _COMM 字段。针对某个特定命令的所有进程输出,可以用:

journalctl _COMM=dnf --since "2025-01-10 10:00:00" --until "2025-01-10 10:30:00"

时间范围从你执行命令的前一两分钟开始算起,因为 dnf 启动时还要先加载插件和仓库缓存,真正干活的时间比命令行长很多。

2.3 用 journalctl 查看系统启动以来的所有 RPM 事务

有时候 yum 异常不是现在发生的,而是某个包在一个月前就被更坏了。这时候可以搜索 rpm 相关日志,把系统层和 rpm 层的事故记录下来:

journalctl | grep -i "rpm" | grep -E "error|fail|missing" | tail -50

这个组合搜索能帮你发现很多 yum 层发现不了的底层隐患,比如某个 rpm 脚本let报错、某个文件被覆盖等。rpm 是 yum 的后端,yum 只是前端包装,很多“yum 异常”本质上是“rpm 事务异常”,后面第四节会细讲这个关系。

3. 打开 yum 的 debug 模式:让日志告诉你一切

3.1 debuglevel 参数:yum 日志详细程度的开关

yum 默认只记录安装、更新、删除这种级别的事件。想要更详细的过程信息,比如它到底访问了哪个镜像地址、连接哪个 IP、下载了哪个文件、失败在哪个阶段,就要调高 debug 级别。

编辑 /etc/yum.conf,在 [main] 段下加一行:

[main] debuglevel=6

debuglevel 的取值范围是 0 到 10,默认值是 2。这个值越高,日志越详细。我在实际生产环境里通常只开到 4 或 5,因为调到 6 以上日志量极其恐怖,刷屏速度远比你看得快。真正紧要的排查窗口期,再开到 6,定位到问题之后马上调回 2,否则日志文件一天能撑爆几个 GB。

调完 debuglevel 之后重新执行 yum 命令,然后把输出重定向到文件里方便分析:

yum install -y tigervnc-server 2>&1 | tee /tmp/yum_debug_$(date +%F).log

3.2 用 verbose 读心术分析调试日志

debuglevel 打开后,yum 会输出大量以Config time、Loading mirror speeds、Retrieving、Package、Transaction开头的行。信息量最大的几个关键节点:

  • Loading mirror speeds from cached hostfile:说明 yum 正在读取镜像源列表,如果卡在这一行之后,说明网络层或 DNS 解析出了问题
  • Retrieving:正在从仓库下载软件包元数据(repomd.xml),如果反复重试,说明镜像源对应包索引不完整或版本不对
  • Running transaction check:正在检查依赖关系,后续跟着的Error: Package或者Nothing provides就是依赖冲突的具体原因

我见过不少新人根本不看这些日志,靠猜去试错误提示。其实 yum 的 debug 日志已经把每个步骤都写得很清楚了,照着日志看,排查效率能翻倍。

3.3 更细粒度的 dnf debug 配置

如果你用的是 dnf 作为后端(CentOS 8+),也可以给 dnf 单独设置日志级别。在 /etc/dnf/dnf.conf 中加:

[main] debuglevel=6

与 yum.conf 的设置是等效的。逻辑一样,详细程度分分钟能让你看到一次事务的完整调用链和下载链。

4. 深入 RPM 事务层:yum 异常的真正幕后

4.1 yum 与 rpm 的关系:前端和后端

在讲 rpm 层之前,必须先把 yum 和 rpm 的关系理清楚。rpm 是真正执行软件包安装、升级、删除的程序,它直接操作文件系统、写数据库(/var/lib/rpm)。yum/dnf 则是“包管理器管家”,它负责解析依赖、下载软件包、配置仓库,最后把批量执行事务的指令交给 rpm 来落地。

所以 yum 报错的最后一公里,绝大多数跑在 rpm 层。如果 rpm 层出问题,比如 rpm 数据库损坏、软件包脚本执行失败、文件被第三方覆盖,那 yum 层显示的只会是一串看不懂的依赖冲突或者事务中断。

4.2 查看 RPM 事务日志和数据库状态

要查看 rpm 层的事务历史,最直接的是看 rpm 数据库。rpm 把每个已安装包的信息保存在 /var/lib/rpm,如果这个目录损坏或 rpm 数据库版本不一致,yum 会直接崩溃。

首先确认 rpm 数据库是否健全:

rpm -qa | wc -l

如果这条命令能正常返回包总数,说明 rpm 数据库基本可用。如果命令卡住、报错或返回为空,那么十有八九 rpm 数据库坏了,yum 也会跟着废掉。

检查 rpm 数据库目录大小和状态:

ls -lh /var/lib/rpm/ # 正常情况下至少应该有 Packages、Name、Basenames 等文件,单文件大小几 MB 到几十 MB

4.3 用 rpm -Va 验证已安装文件的完整性

当你怀疑某个包的文件被改坏导致 yum 依赖校验失败时,可以用 rpm 自带的验证命令:

rpm -Va

这条命令会把所有安装包的文件逐一比对校验和。如果输出里出现S(大小变化)、M(权限变化)、5(md5 校验失败)等标志,对应的文件就有问题了。例如:

S.5....T. /usr/lib64/libcurl.so.4.8.0

出现这种记录,表示 libcurl 这个被 yum 依赖的核心库文件被改动过,此时 yum install 大概率会报错。处理方案是用 rpm 强制重装这个包:

rpm -ivh --force /var/cache/yum/.../libcurl-版本.rpm

4.4 修复 rpm 数据库的常见操作

如果 rpm 数据库确实损坏,比较轻的修复手段是重建 rpm 数据库索引:

rpm --rebuilddb

重建过程中会把 /var/lib/rpm 下的临时文件清理干净,并重建索引。如果重建没用,再考虑把损坏的 rpmdb 备份后清空,然后用 rpm -qa 重新扫描 /var/lib/rpm 目录下的所有旧文件来恢复。这些操作在生产环境里务必先备份目录:

cp -a /var/lib/rpm /var/lib/rpm.bak.$(date +%F)

5. yum history 与事务历史:精准还原现场

5.1 用 yum history 查看历史事务

yum 本身也维护了一套事务历史,CentOS 7 及以下版本用 yum history 查看,CentOS 8+ 则用 dnf history。这套历史记录其实是从 rmpdb 或者后台数据库里整理出来的。

# 查看最近 50 次事务 yum history | head -50 # 查看某一次特定事务的详细信息,注意编号从 1 开始 yum history info 15

输出里会显示这次事务的时间、操作命令、涉及的包、事务状态(成功/失败/中断)。这个信息在复盘问题时价值巨大——你能直接看到是哪次操作把环境弄坏的。

5.2 归档 yum history 的备份位置

yum history 的数据存放在 /var/lib/yum/history/ 目录(CentOS 7)或 /var/lib/dnf/history/ 目录(CentOS 8+),每个事务对应一个以 ID 命名的目录。如果这个目录被误删了,yum history 就会变成空的,但包依旧装得好好的。

如果在排查大量问题时发现 history 是空的,别慌,优先去看 /var/log/yum.log 或 dnf.log,这两个文件才是时间线的“硬证据”。

5.3 结合历史排查的实用思路

我通常的排查习惯是:

  1. 先yum history | tail -20,确认最近有没有异常事务
  2. 再查看那个异常事务的 info,确认到底装了什么、卸载了什么
  3. 根据异常时间点,回到 yum.log 里找同时间段的安装记录
  4. 最后从前端(yum)推到后端(rpm),验证文件完整性

这套流程基本能覆盖大多数“莫名异常”的定位需求。

6. 实战排查:三个典型 yum 异常的日志定位实录

6.1 案例一:yum install 卡在 “Loading mirror speeds from cached hostfile”

现象:执行 yum install tigervnc-server,卡在这一行超过 5 分钟,无任何网络错误提示。

排查过程:

第一步,看 dnf/yum 实时日志:

journalctl -f | grep -E "yum|dnf"

发现日志静止在 DNS 解析阶段。第二步,手动测试解析:

curl -I http://mirrors.aliyun.com/centos/ --connect-timeout 5

能通,但很慢。第三步,查 /var/log/messages,发现网卡 eth0 有大量 RX errors 和丢包记录。结论是网络质量差导致的超时,yum 自己没有日志,但系统网卡层已经给出了信号。

处理:更换更快的镜像源,或者提升 yum 超时时间。在 /etc/yum.conf 里加:

timeout=120 retries=5

把默认的 30 秒超时调大,网络环境差的时候效果立竿见影。

6.2 案例二:yum 报依赖冲突,但 rpm 层文件异常

现象:yum install nginx,报错:

Error: Package: nginx-1.20.1-10.el9.x86_64 requires: libssl.so.3()(64bit) Not found

而系统里明明装了 openssl。

排查过程:

先rpm -qa openssl,发现 openssl 已经装了新版。再rpm -V openssl,发现文件校验失败。继续看 journalctl 里有没有 openssl 相关更新记录,终于看到一条某天dnf update openssl后文件校验失败的信息。最终原因:更新开头时网络中断,rpm 事务没有完整提交,导致部分文件缺失。

处理:用dnf reinstall openssl强制重装该包,然后rpm -Va复查,问题消失。

6.3 案例三:yum 提示 “Another app is currently holding the yum lock”

现象:

Another app is currently holding the yum lock; waiting for it to exit...

排查过程:

先看是什么进程占用锁:

cat /var/run/yum.pid # 列出该进程信息 ps -ef | grep $(cat /var/run/yum.pid | awk '{print $1}')

发现是一个卡死的 packagekitd 进程在后台自动更新。查 journalctl 确认它在跑什么任务,然后用kill -9干掉占锁进程,并在 /etc/yum/pluginconf.d/ 下禁用自动更新插件。

处理:

rm -f /var/run/yum.pid systemctl stop packagekit systemctl disable packagekit

7. 常见 yum 异常速查对照表

我把多年遇到的 yum 异常整理成一个速查表,排查时直接对照,能大幅缩短定位时间:

异常现象优先查看的日志/文件常见根因核心排查命令
安装卡在镜像源加载/var/log/dnf.log、journalctl 网络层记录DNS 慢、镜像源超时、镜像源缓存损坏curl 测速镜像源、journalctl -f
依赖冲突但包已安装/var/log/yum.log、rpm -Va 输出rpm 数据库损坏、文件被覆盖、事务中断rpm -Va、rpm --rebuilddb
yum 锁占用/var/run/yum.pid残留进程、自动更新插件、packagekit 抢占ps 查 pid、kill 锁进程
段错误/Python tracebackjournalctl 中的 OOM 记录、/var/log/messages内存耗尽、python 依赖损坏free -m 看内存、rpm -Va python3
仓库元数据下载失败/var/log/dnf.librepo.log、/var/log/messages镜像源地址失效、防火墙拦截、时间不同步curl -I 仓库 URL、date 看时间同步
事务中断后再次安装失败/var/log/yum.log 历史事务记录、rpmdb 事务残留上次事务没有正确完成yum-complete-transaction、package-cleanup

提示:上面所有排查命令里,第一条永远是“先确认时间同步”。NTP 时间不同步会让 yum 判定仓库元数据过期,导致大量奇怪的下载错误。我踩过不只一次,先看时间再看日志能省掉很多无用功。

8. 几个老手才知道的日志查看心得

最后分享几个平时文档里很少写的细节经验。

第一个心得是别开 debuglevel 到 10。这不是越详细越好,debuglevel=8 以上,yum 会连每个 socket 读了多少字节都打印出来,输出大到让人头皮发麻。真要深挖,6 已经足够了。

第二个心得是重定向日志要带时间戳。用2>&1 | tee /tmp/yum_debug.log的时候,配合script -q -c "yum install xxx" /tmp/yum_session.log还能把完整的交互式会话和时间戳一起录下来,复盘的时候能准确对齐每一步耗时。

第三个心得是日志不会说谎,但日志也可能缺失。当你在 /var/log/yum.log、/var/log/messages、journalctl 里都找不到线索时,先别怀疑日志工具出了问题,大概率是你自己当年的运维操作习惯埋下了隐患——比如手动编辑过 rpm 数据库、清过 /var/lib/rpm、删过历史事务目录。这种时候,破局思路是从业务影响反推:谁能动这个包?什么时候动的?当初有没有备份?顺着这个思路,多半能挖出真相。

我自己这几年配合 yum 异常排查做的最有用的一个习惯,是每次执行高危的 yum 操作之前先把系统关键状态快照下来:

# 操作前记录包列表、RPM 校验、yum history 快照 rpm -qa > /tmp/rpm.list.$(date +%F) rpm -Va > /tmp/rpm.verify.$(date +%F) yum history > /tmp/yum.history.$(date +%F)

这个成本几乎为零的习惯,让后续任何一次“yum 异常记录”都变得有据可查。毕竟,排障最快的路径,永远不是现场抓包,而是对比变化。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询