跳转到内容

小版本升级

小版本升级(如 EL 9.3 到 9.4)是日常运维中最常见的维护操作。本文档涵盖完整的 dnf update 工作流,包括预检、执行、验证和回滚。

在执行升级之前,先了解有哪些包可以更新。

检查可用更新
dnf check-update

该命令返回码为 100 表示有可用更新,0 表示没有更新,1 表示出错。

仅列出安全相关更新
dnf updateinfo list security
查看特定包的更新公告
dnf updateinfo info --advisories=ALSA-2025:1234
查看更新摘要统计
dnf updateinfo summary
执行全量更新
dnf update -y
仅安装安全补丁
dnf update --security -y
更新时排除某些包
dnf update -y --exclude=kernel* --exclude=php*
模拟更新过程以检查依赖问题
dnf update --assumeno

内核更新不会替换旧内核,而是并行安装新版本。

查看当前内核版本
uname -r
列出所有已安装内核
rpm -qa kernel-core | sort -V
仅更新内核
dnf update kernel -y

更新内核后必须重启系统才能使用新内核。

needs-restarting 工具用于判断更新后哪些服务或系统需要重启。

安装 dnf-plugins-core(包含 needs-restarting)
dnf install -y dnf-plugins-core
检查是否需要重启整个系统
needs-restarting -r

返回码 0 表示不需要重启,1 表示需要重启。

列出需要重启的服务
needs-restarting -s
重启所有需要重启的服务
needs-restarting -s | xargs -I {} systemctl restart {}
查看 dnf 操作历史
dnf history list
查看指定操作的详情
dnf history info <事务ID>
撤销某次更新操作
dnf history undo <事务ID> -y
回滚到指定事务之前的状态
dnf history rollback <事务ID> -y

如果新内核导致问题,可以在 GRUB 菜单中选择旧内核启动,无需回滚操作。

设置默认启动旧内核
grubby --set-default /boot/vmlinuz-<旧版本号>
  1. 提前通知 — 至少提前 48 小时通知相关团队
  2. 备份 — 创建系统快照或备份关键数据
  3. 预检 — 在测试环境验证更新
  4. 执行 — 在维护窗口内执行更新
  5. 验证 — 检查服务状态和功能
  6. 回滚准备 — 确认回滚方案可行
创建 LVM 快照
lvcreate -s -n pre-update-snap -L 10G /dev/vg0/root
维护窗口更新脚本示例
#!/bin/bash
set -e
echo "=== 维护更新开始: $(date) ==="
# 1. 记录当前状态
rpm -qa --qf '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' | sort > /root/pkg-before.txt
# 2. 执行更新
dnf update -y
# 3. 记录更新后状态
rpm -qa --qf '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' | sort > /root/pkg-after.txt
# 4. 输出变更差异
echo "=== 包变更列表 ==="
diff /root/pkg-before.txt /root/pkg-after.txt || true
# 5. 检查是否需要重启
if ! needs-restarting -r &>/dev/null; then
echo "*** 系统需要重启 ***"
fi
echo "=== 维护更新完成: $(date) ==="
安装并启用自动更新
dnf install -y dnf-automatic
# 编辑配置:仅应用安全更新
sed -i 's/^upgrade_type.*/upgrade_type = security/' /etc/dnf/automatic.conf
sed -i 's/^apply_updates.*/apply_updates = yes/' /etc/dnf/automatic.conf
systemctl enable --now dnf-automatic.timer
检查自动更新定时器状态
systemctl status dnf-automatic.timer