HOME

麒麟 V10 内核升级实战:从 52.46 到 52.65 并验证 LVM 磁盘统计修复

文章目录28 节

在前一轮麒麟 V10 LVM 磁盘繁忙率异常复现实验中,我已经在 4.19.90-52.46.v2207.ky10.x86_64 内核上复现了 sar 807.70%atop 895%,并用一次 4 KiB 写入证明底层盘 sdcio_ticks 会异常增加 86999 ms

为了验证问题是否能通过麒麟维护内核解决,我没有升级 sysstat、atop、fio,也没有重建磁盘、LVM、XFS 或测试文件,只把运行内核升级到 4.19.90-52.65.v2207.ky10.x86_64。升级后,同样的 4 KiB 写入只让 sdc io_ticks 增加 4 ms,完整 LVM fio 测试中 sar sdc %util 峰值回到 94.30%

这篇文章只记录从 52.46 升级到 52.65 的详细过程:如何在安装前确认仓库、空间、存储拓扑和回滚条件,如何安装并检查四个内核包,如何验证 initramfs 与 GRUB 启动项,如何重启验收,以及如何用同条件 A/B 测试确认修复,而不是把“系统能启动”当成升级完成。

一、本次升级的对象、目标和证据边界

实验机为 Kylin Linux Advanced Server V10 SP3,Build23,构建日期为 2023-03-24。升级前后的关键变量如下:

项目升级前升级后
操作系统Kylin V10 SP3 Build23不变
运行内核4.19.90-52.46.v2207.ky10.x86_644.19.90-52.65.v2207.ky10.x86_64
sysstat12.2.1-1.p00.ky10.x86_64不变
atop2.7.1不变
fio3.7不变
LVMsdc1 → vg_atop_lab → lv_lvm_test不变
文件系统XFS不变
测试文件/mnt/atop-lvm/fio-test.bin不变

本次可以通过 DNF 事务、RPM 数据库、/boot 文件、GRUB 条目、启动时间和复测文件确认的事实是:

  1. 2026-08-13 20:13,通过 ks10-adv-updates 仓库开始安装 52.65
  2. DNF 事务耗时 221 秒,返回码为成功,安装了 kernelkernel-corekernel-moduleskernel-modules-extra 四个包。
  3. 52.65vmlinuz 与 initramfs 已生成,GRUB 中位于 index 0,并成为默认内核。
  4. 系统在 20:18 以 52.65 启动;52.4652.22 仍保留在 GRUB 菜单中。
  5. 重启后系统盘 LVM、direct 测试盘和 LVM 测试盘均正常挂载,当前启动没有新增块层、XFS 或 device-mapper 错误。
  6. 同条件复测中,旧内核的 io_ticks +86999 ms 降为 +4 ms

需要特别说明:DNF 安装后,实验机上的 52.65 已经自动成为 GRUB index 0 和默认启动项。现有 shell 历史没有证明我曾手动执行 grubby --set-default,所以本文不会把该命令写成本次已执行事实;它只作为“目标内核没有自动成为默认项时”的备用步骤。

二、升级前先确认这是不是同一条麒麟版本线

内核包与发行版仓库强相关。本文目标版本属于本次 Kylin V10 SP3/v2207 环境,不能看到“麒麟 V10”四个字就直接照搬到其他 Service Pack、架构或仓库分支。

下面的命令只读取发行版、运行内核和现有工具版本。/etc/.kyinfo 可能包含构建信息,复制到公开工单或文章前应检查是否需要脱敏。

风险等级:INFO(只读)

作用: 确认目标主机确实属于 Kylin V10 SP3/v2207 版本线,并保存升级前的内核与监控工具基线。 执行对象: 待升级的麒麟 Linux 主机;建议使用 root 执行,以免部分系统文件无法读取。 完成验证: 发行版、架构、当前内核和目标仓库分支必须匹配;如果不是 V10 SP3/v2207,应停止套用本文的具体版本号,转而查询该主机仓库提供的维护内核。

cat /etc/.kyinfo
uname -a
uname -r
rpm -q sysstat fio iotop lvm2 device-mapper
/usr/local/sbin/atop -V 2>/dev/null || atop -V

本次升级前的关键输出为:

Kylin-Server-V10-SP3-General-Release-2303-x86_64
4.19.90-52.46.v2207.ky10.x86_64
sysstat-12.2.1-1.p00.ky10.x86_64
fio-3.7-6.p01.ky10.x86_64
iotop-0.6-20.p01.ky10.noarch
atop 2.7.1

三、升级前完整检查:仓库、空间、启动项与存储拓扑

1. 查询仓库是否提供目标内核

这里必须让 DNF 明确查到目标版本,而不是从不明来源下载单独的 RPM。--showduplicates 会列出仓库中可用的所有匹配版本,但不会安装软件。

风险等级:INFO(只读仓库查询)

作用: 确认目标 52.65 内核来自当前主机已配置的可信麒麟更新仓库。 执行对象: Kylin V10 SP3 测试机;需要能访问相应软件仓库。 需要替换: 如果读者的目标版本不同,应把 target 改为经厂商或内部兼容性评估确认的完整版本。 完成验证: 输出应显示目标包来自预期仓库。本次实测来源为 ks10-adv-updates;如果只有未知第三方仓库或查不到目标版本,应停止安装。

target=4.19.90-52.65.v2207.ky10.x86_64

dnf --showduplicates list "kernel-$target"

本次安装后的仓库回读显示:

kernel.x86_64  4.19.90-52.65.v2207.ky10  @ks10-adv-updates

2. 检查 /boot 与根文件系统空间

安装一个维护内核不只写入一个 vmlinuz 文件,还会安装模块并生成普通 initramfs;启动后 kdump 还可能生成单独的 kdump initramfs。空间不足会导致 RPM 事务或引导文件生成不完整。

风险等级:INFO(只读)

作用: 确认 /boot 和根文件系统有足够空间容纳新内核、模块与 initramfs。 执行对象: 待升级主机。 完成验证: 不应只看百分比,还要看实际可用容量和已有内核数量。本次实验升级完成后 /boot 为 1 GiB,使用 290 MiB,可用 725 MiB。

df -h /boot /
du -sh /usr/lib/modules/* 2>/dev/null | sort -h
find /boot -maxdepth 1 -type f \
  \( -name 'vmlinuz-*' -o -name 'initramfs-*.img' \) \
  -printf '%f %s bytes\n' \
  | sort

如果 /boot 空间不足,不要直接用通配符删除旧内核文件。应先确认仍在使用的内核、GRUB 条目、回滚需求和包归属,再通过包管理器制定清理方案。本文实验机空间充足,因此没有删除任何旧内核。

3. 保存当前内核与 GRUB 基线

下面的命令用于确认当前正在运行的内核、默认启动内核和所有可启动条目。保存这份输出后,才能在升级后证明旧内核仍可回退。

风险等级:INFO(只读)

作用: 留存升级前的运行内核、默认内核和 GRUB 菜单,识别旧内核的准确路径。 执行对象: 待升级主机。 完成验证: 当前运行内核应与问题复现版本一致,旧内核的 kernel=initrd=title= 应完整可读。

uname -r
rpm -qa 'kernel*' | sort
grubby --default-kernel
grubby --info=ALL

4. 保存 LVM 根文件系统和实验盘拓扑

本次系统盘本身使用 LVM:sda3 → klas/root、klas/swap。因此升级后仅看到 SSH 能连接还不够,必须验证新 initramfs 能识别根卷,同时确认 direct 和 LVM 两块实验盘没有改变。

风险等级:INFO(只读)

作用: 保存升级前的块设备、文件系统、PV/VG/LV、device-mapper 和挂载关系,作为重启后结构比较的基线。 执行对象: 待升级主机;设备名和挂载点按实际环境理解,不要照抄为修改目标。 完成验证: 系统根卷、交换卷、测试 LV 及其底层设备关系均能对应,所有关键挂载点正常。

lsblk -o NAME,KNAME,MAJ:MIN,TYPE,SIZE,FSTYPE,LABEL,MOUNTPOINT
pvs -o pv_name,pv_uuid,pv_size,pv_free,vg_name
vgs -o vg_name,vg_uuid,vg_size,vg_free,pv_count,lv_count
lvs -a -o lv_name,vg_name,lv_uuid,lv_size,segtype,devices
dmsetup ls --tree
findmnt /
findmnt /boot
findmnt /mnt/atop-direct
findmnt /mnt/atop-lvm

本次升级前后的目标拓扑保持为:

sda3 → klas-root → /
     → klas-swap → [SWAP]

sdb1 → XFS ATOP_DIRECT → /mnt/atop-direct

sdc1 → vg_atop_lab/lv_lvm_test → XFS ATOP_LVM → /mnt/atop-lvm

5. 明确维护窗口和回滚条件

安装内核包本身通常不会立即中断当前业务,但切换运行内核必须重启整机。生产环境在进入安装阶段前,至少要确认:

  1. 已有可用备份或快照,并清楚快照是否覆盖外置 LUN 与数据库一致性。
  2. 有虚拟化控制台、KVM、BMC 等带外通道,不能只依赖 SSH。
  3. 旧内核仍在 /boot 和 GRUB 菜单中。
  4. HBA、多路径、网卡、备份、杀毒、EDR、内核模块和第三方驱动已完成兼容性核对。
  5. 业务已经批准维护窗口,重启和回退都在变更时段内。
  6. 已记录业务级验收项,而不仅是 uname -r

这部分属于生产实施建议。本次是在专用实验机上执行,没有业务停机影响,也没有验证 FC HBA、多路径或厂商第三方内核模块。

四、安装 52.65:本次实际执行的 DNF 命令

本次实验实际使用的命令是 dnf --refresh install -y--refresh 强制刷新仓库元数据;-y 会自动确认安装,因此只有在目标版本与仓库来源已经核对后才能使用。

风险等级:CAUTION(安装系统内核并写入 /boot

作用: 从已确认的麒麟更新仓库安装 52.65 内核,并由 DNF 解析、安装配套的 core、modules 和 modules-extra 包。 执行对象: 本次 Kylin V10 SP3 实验机;需要 root 权限。 执行前检查: 必须完成版本线、仓库、/boot 空间、GRUB 基线、LVM 根卷、第三方驱动和维护窗口检查。 重要参数: --refresh 刷新仓库元数据;-y 自动确认事务;target 必须是完整且已经核对的版本。 影响与恢复: 该命令会修改 RPM 数据库、写入 /usr/lib/modules/boot,但不会立刻切换当前运行内核。安装失败时不要删除旧内核,也不要重启;先查看 DNF 事务和磁盘空间,必要时使用 dnf history 诊断。 完成验证: DNF 必须返回成功,并且事务中出现四个目标内核包。随后还要独立检查 RPM、vmlinuz、initramfs 和 GRUB 条目,不能只相信命令退出码。

target=4.19.90-52.65.v2207.ky10.x86_64

dnf --refresh install -y "kernel-$target"

本次 DNF 事务记录为:

事务 ID:4
开始时间:2026-08-13 20:13:44
结束时间:2026-08-13 20:17:25
耗时:221 秒
返回码:成功
命令行:--refresh install -y kernel-4.19.90-52.65.v2207.ky10.x86_64
仓库:ks10-adv-updates

安装:
kernel-4.19.90-52.65.v2207.ky10.x86_64
kernel-core-4.19.90-52.65.v2207.ky10.x86_64
kernel-modules-4.19.90-52.65.v2207.ky10.x86_64
kernel-modules-extra-4.19.90-52.65.v2207.ky10.x86_64

五、安装后先验包和引导文件,不要立即重启

1. 回读 DNF 事务

下面的命令只读取事务记录。4 是本次实验事务号,其他环境应使用 dnf history list 查到的实际 ID。

风险等级:INFO(只读)

作用: 确认安装命令、返回码、来源仓库、耗时和实际变更的包。 执行对象: 刚完成内核安装的主机。 需要替换:4 替换为本机内核安装事务的实际 ID。 完成验证: 返回码必须为成功,包来源应可信,四个内核包版本必须完全一致。

dnf history list
dnf history info 4

2. 验证四个 RPM 均已安装

只执行 rpm -q kernel 不能证明模块包完整。LVM 根文件系统、存储驱动和网卡驱动可能依赖 kernel-moduleskernel-modules-extra,因此应显式查询四个包。

风险等级:INFO(只读)

作用: 验证目标内核的主包、核心、常规模块和额外模块均已进入 RPM 数据库。 执行对象: 已完成安装的主机。 完成验证: 四行都应返回相同的完整 52.65 版本;任何一项显示未安装都不应重启。

target=4.19.90-52.65.v2207.ky10.x86_64

rpm -q \
  "kernel-$target" \
  "kernel-core-$target" \
  "kernel-modules-$target" \
  "kernel-modules-extra-$target"

3. 检查 vmlinuz 与普通 initramfs

本次 52.65 的普通 initramfs 大约为 28 MiB。只检查文件存在还不够,应确认它非空并能被 lsinitrd 正常解析。

风险等级:INFO(只读)

作用: 检查目标内核映像与 initramfs 是否存在、大小合理且结构可读取。 执行对象: 已安装目标内核的主机。 完成验证: test -s 成功,ls -lh 显示文件非空,lsinitrd 能输出 dracut 版本和模块列表。

target=4.19.90-52.65.v2207.ky10.x86_64

test -s "/boot/vmlinuz-$target"
test -s "/boot/initramfs-$target.img"
ls -lh "/boot/vmlinuz-$target" "/boot/initramfs-$target.img"
lsinitrd -m "/boot/initramfs-$target.img"

本次实测的 initramfs 包含:

dm
kernel-modules
kernel-modules-extra
lvm
qemu
qemu-net
rootfs-block

这说明本次 QEMU 虚拟机的 LVM 根卷所需基础路径已经进入 initramfs。生产服务器还应针对自己的 HBA、RAID、多路径、NVMe、网卡和加密根盘检查相应模块,不能只看本文列出的几项。

4. 检查 GRUB 是否已经生成目标条目

下面的命令不会改变默认项,只读取目标内核条目及全局默认内核。

风险等级:INFO(只读)

作用: 确认 GRUB 条目正确引用目标 vmlinuz、initramfs、LVM 根卷和交换卷参数,并确认旧内核仍在菜单中。 执行对象: 已安装目标内核、尚未重启的主机。 完成验证: 目标条目可读,root=rd.lvm.lv= 等参数与当前系统一致;grubby --info=ALL 仍能看到旧内核。

target=4.19.90-52.65.v2207.ky10.x86_64

grubby --info="/boot/vmlinuz-$target"
grubby --default-kernel
grubby --info=ALL

本次安装后,目标条目为 index 0,默认内核已经是:

/boot/vmlinuz-4.19.90-52.65.v2207.ky10.x86_64

对应启动参数仍指向原系统卷:

root=/dev/mapper/klas-root
rd.lvm.lv=klas/root
rd.lvm.lv=klas/swap

因此本次不需要额外执行 grubby --set-default

六、仅当目标内核没有自动成为默认项时,手动设置

本节是备用操作模板,不是本次实验已执行证据。只有在前一节确认目标条目完整、旧内核保留,但 grubby --default-kernel 仍指向旧版本时,才需要手动设置。

风险等级:CAUTION(改变下次启动使用的内核)

作用: 将已验证完整的目标 vmlinuz 设置为默认启动内核,但暂不重启。 执行对象: 目标条目已经由 grubby --info 验证的麒麟主机。 执行前检查: 确认目标 vmlinuz、initramfs、根卷参数正确,旧内核仍保留,带外控制台可用。 影响与恢复: 会改变下一次启动选择;当前运行内核不变。若设置错误,可在重启前将旧内核重新设为默认。 完成验证: grubby --default-kernel 必须精确返回目标 vmlinuz 路径,grubby --info=ALL 中旧内核条目仍存在。

target=4.19.90-52.65.v2207.ky10.x86_64

grubby --set-default "/boot/vmlinuz-$target"
grubby --default-kernel
grubby --info=ALL

七、维护窗口重启:真正切换运行内核

安装内核包和设置默认项都不会改变 uname -r。只有重启后,新的内核才会实际运行。这是整套流程中会造成主机级中断的步骤。

风险等级:DANGER(整机重启并可能因驱动或 initramfs 问题无法正常启动)

作用: 在维护窗口内停止当前系统并以默认的 52.65 内核重新启动。 执行对象: 已完成包、initramfs、GRUB、备份、业务停机和控制台检查的目标主机。 执行前检查: 再次执行 grubby --default-kernelgrubby --info=ALL;确认旧内核存在、控制台可操作、业务已经停止或允许中断。 不可恢复点: 命令会立即终止当前服务和 SSH 会话;如果新内核无法识别根盘、网络或第三方驱动,主机可能无法远程上线。 回滚路径: 通过 GRUB/虚拟化控制台选择旧内核启动;成功回到旧内核后,再将旧 vmlinuz 设置为默认。不要在新内核验收完成前删除旧内核。 完成验证: 主机重新可达后,必须先核对 uname -r、启动时间、根卷、网络、服务和内核日志,再进行 I/O 修复复测。

grubby --default-kernel
grubby --info=ALL
systemctl reboot

本次 DNF 事务在 20:17:25 完成,系统启动时间为 20:18:25;重连后运行内核为:

4.19.90-52.65.v2207.ky10.x86_64

八、重启后第一层验收:内核、启动项、存储和日志

1. 确认真的启动了目标内核

下面的命令只读取当前启动信息。/proc/cmdline 可以确认实际加载的 BOOT_IMAGE 与根卷参数,不应只看 GRUB 默认项。

风险等级:INFO(只读)

作用: 证明当前正在运行目标内核,而不是仅安装成功或仅设置了默认项。 执行对象: 重启后重新连接的目标主机。 完成验证: uname -rBOOT_IMAGEgrubby --default-kernel 都应指向目标版本。

date -Ins
uptime -s
uname -r
cat /proc/cmdline
grubby --default-kernel

本次 /proc/cmdline 的关键内容为:

BOOT_IMAGE=/vmlinuz-4.19.90-52.65.v2207.ky10.x86_64
root=/dev/mapper/klas-root
rd.lvm.lv=klas/root
rd.lvm.lv=klas/swap

2. 验证旧内核仍可回退

新内核能启动不等于可以删除旧内核。本次重启后仍保留:

4.19.90-52.65.v2207.ky10.x86_64  index 0
4.19.90-52.46.v2207.ky10.x86_64  index 1
4.19.90-52.22.v2207.ky10.x86_64  index 2
rescue                                index 3

下面的命令用于持续确认三个版本的 RPM 与 GRUB 条目仍存在。

风险等级:INFO(只读)

作用: 确认新旧内核均保留,回滚入口没有因升级或后续清理丢失。 执行对象: 已以新内核启动的主机。 完成验证: 至少保留一个经过验证可启动的旧内核,且其 vmlinuz、initramfs 和 GRUB 条目完整。

rpm -qa 'kernel*' | sort
grubby --info=ALL
find /boot -maxdepth 1 -type f \
  \( -name 'vmlinuz-*' -o -name 'initramfs-*.img' \) \
  -printf '%f %s bytes\n' \
  | sort

3. 验证 LVM 根卷与测试文件系统

下面的检查用于确认系统盘 LVM、direct 测试盘和 LVM 测试盘都与升级前一致。麒麟本机 util-linux 版本不支持 lsblkMOUNTPOINTS 列,因此使用兼容的 MOUNTPOINT

风险等级:INFO(只读)

作用: 确认新内核正确识别系统盘、PV/VG/LV、XFS 与所有关键挂载点。 执行对象: 重启后的主机。 完成验证: 根卷、交换卷、/boot、direct 测试盘和 LVM 测试盘均正常;设备映射与升级前基线一致。

lsblk -o NAME,KNAME,MAJ:MIN,TYPE,SIZE,FSTYPE,LABEL,MOUNTPOINT
pvs -o pv_name,pv_uuid,pv_size,pv_free,vg_name
vgs -o vg_name,vg_uuid,vg_size,vg_free,pv_count,lv_count
lvs -a -o lv_name,vg_name,lv_uuid,lv_size,segtype,devices
dmsetup ls --tree
findmnt /
findmnt /boot
findmnt /mnt/atop-direct
findmnt /mnt/atop-lvm

本次重启后,三个关键路径均正常:

/dev/mapper/klas-root                    → /
/dev/sdb1                                → /mnt/atop-direct
/dev/mapper/vg_atop_lab-lv_lvm_test      → /mnt/atop-lvm

4. 检查失败服务和块层错误

systemctl is-system-running 返回 degraded 不应直接判定升级失败,要比较升级前基线并定位具体单元。本次唯一失败项是实验前已存在的 lm_sensors.service,不是新内核引入的存储故障。

风险等级:INFO(只读)

作用: 检查失败服务,并从当前启动日志中筛选新的 I/O、XFS 和 device-mapper 错误。 执行对象: 重启后的目标主机;读取完整 dmesg 通常需要 root。 完成验证: 不应出现新的根盘、测试盘、XFS 或 device-mapper 错误;已知失败服务应能与升级前基线对应。

systemctl is-system-running || true
systemctl --failed --no-pager || true
dmesg -T | grep -Ei \
  'I/O error|blk_update_request|Buffer I/O|XFS.*(error|corrupt)|device-mapper.*error' \
  || true

本次当前启动中没有匹配到新的块层、XFS 或 device-mapper 错误。lm_sensors.service 仍因没有配置可加载的传感器模块而失败,升级前后状态一致。

九、第二层验收:用最小 4 KiB 写验证 io_ticks 修复

系统能正常启动,只能证明新内核可用,不能证明最初的磁盘统计问题已经修复。第一项功能验收仍然是原来的最小触发实验:LVM 路径空闲 35 秒后,对可丢弃的 fio 测试文件执行一次 4 KiB direct+dsync 写入,并比较 /proc/diskstats

这段命令会覆盖测试文件中的 4 KiB,只适用于专用实验文件。设备列表中的 sdcsdc1dm-2 必须根据实际映射调整。

风险等级:CAUTION(覆盖测试文件中的 4 KiB 数据)

作用: 在与旧内核相同的空闲和同步写入条件下,验证底层盘、分区和 LVM 逻辑卷的 io_ticks 是否仍会异常跳增。 执行对象: 本次专用文件 /mnt/atop-lvm/fio-test.bin;禁止替换为数据库文件、虚拟磁盘或其他业务数据。 执行前检查:findmnt 确认挂载来源,用 ls -lh 确认文件存在且可丢弃,并保存升级前的同条件结果。 影响与恢复: 只覆盖偏移 12288 字节处的 4 KiB;删除并重新创建 fio 测试文件即可恢复测试状态。 完成验证: 设备请求数只增加少量,io_ticks 应为毫秒级,不应再增加数万或数十万毫秒。

findmnt /mnt/atop-lvm
ls -lh /mnt/atop-lvm/fio-test.bin

awk '$3=="sdc" || $3=="sdc1" || $3=="dm-2" {print}' \
  /proc/diskstats > /var/tmp/diskstats-52.65-before-idle.txt

sleep 35

awk '$3=="sdc" || $3=="sdc1" || $3=="dm-2" {print}' \
  /proc/diskstats > /var/tmp/diskstats-52.65-after-idle.txt

dd if=/dev/zero \
  of=/mnt/atop-lvm/fio-test.bin \
  bs=4096 count=1 seek=3 conv=notrunc \
  oflag=direct,dsync status=none

awk '$3=="sdc" || $3=="sdc1" || $3=="dm-2" {print}' \
  /proc/diskstats > /var/tmp/diskstats-52.65-after-write.txt

本次自动差分得到:

设备空闲 Δio_ticks写请求增量flush 增量Δweighted触发 Δio_ticks
sdc0 ms322 ms4 ms
sdc10 ms202 ms4 ms
dm-20 ms304 ms4 ms

旧内核同条件下的关键结果是:

sdc: 2 个写请求,Δweighted=1 ms,Δio_ticks=86999 ms

升级后变为:

sdc: 3 个写请求,Δweighted=2 ms,Δio_ticks=4 ms

这一步证明修复发生在内核原始设备统计层,而不是因为 sysstat、atop 或 fio 被升级。

十、第三层验收:重复完整 LVM fio 与多工具采集

最小写入验证原始计数后,还需要重复业务型负载,确认 sar、atop、iostat 与 fio 能重新互相解释。

下面的监控命令都是只读采集,但 1 秒高频采样会产生少量 CPU 与输出开销。atop -P DSK,LVM 同时显示底层盘和逻辑卷;iostat -p ALL 用于覆盖整盘、分区与 device-mapper。

风险等级:INFO(只读监控,但会产生采样开销)

作用: 在 fio 运行期间,同时采集物理盘、分区、LVM 和进程层统计。 执行对象: 专用实验机;建议由采集脚本或多个终端并行运行。 完成验证: 所有工具的时间窗口应覆盖 fio 起止时间,设备名与 LVM 映射应能对应。

atop -P DSK,LVM 1 30
sar -d -p 1 30
iostat -dxm -p ALL 1 30
pidstat -d 1 30
iotop -b -o -P -k -d 1 -n 30

fio 会创建或覆盖 2 GiB 测试文件并制造持续随机写压力,只能在容量充足、可丢弃数据的测试文件系统上执行。

风险等级:CAUTION(持续写入 2 GiB 文件并制造磁盘压力)

作用: 使用与旧内核完全相同的 4 KiB 随机写参数,对 LVM 路径做 A/B 复测。 执行对象: /mnt/atop-lvm 专用测试文件系统;需要至少 2 GiB 可用空间。 重要参数: --direct=1 绕过页缓存,--iodepth=32 使用队列深度 32,--time_based=1 --runtime=20 持续 20 秒。 影响与恢复: 会占用磁盘带宽并覆盖 fio-test.bin;可中止 fio 停止压力,验证后删除测试文件回收空间。 完成验证: fio 正常结束,sar/atop 不再出现数百或数千百分比,底层盘、LV、IOPS、带宽、await 和队列长度能互相解释。

fio \
  --name=lvm_randwrite \
  --filename=/mnt/atop-lvm/fio-test.bin \
  --size=2G \
  --rw=randwrite \
  --bs=4k \
  --ioengine=libaio \
  --iodepth=32 \
  --direct=1 \
  --runtime=20 \
  --time_based=1 \
  --group_reporting \
  --eta=never \
  --output-format=json

52.65 的完整 LVM 复测结果为:

fio 带宽:31.27 MiB/s
fio IOPS:8004.60
sar sdc %util 峰值:94.30%
sar sdc %util 平均:56.86%
sar LVM %util 平均:65.96%
sdc/LVM 超过 110% 的 sar 样本:0

atop 的 LVM 行偶尔会出现 100%105% 的 1 秒近似值,这属于不同设备层级、采样边界和取整造成的小幅偏差;旧内核中的 807.70%895% 和现场几千百分比不再出现。

十一、生产环境的回滚步骤

下面是生产环境应该提前写入变更方案的回滚路径。本次实验没有发生升级失败,因此没有实际执行回滚;实验机目前仍运行 52.65,同时保留 52.4652.22

1. 新内核无法启动时

如果主机无法远程上线,应通过虚拟化控制台、KVM 或 BMC 打开 GRUB,选择经过验证的旧内核,例如:

Kylin Linux Advanced Server (4.19.90-52.46.v2207.ky10.x86_64) V10 (Lance)

这一步依赖带外控制台,不能通过已经失联的 SSH 执行。

2. 以旧内核启动后恢复默认项

下面是回滚模板,不是本次已执行命令。它会改变下一次默认启动内核,但不会卸载 52.65

风险等级:CAUTION(改变默认启动内核)

作用: 在已经通过 GRUB 使用旧内核成功启动后,将经过验证的 52.46 恢复为默认项。 执行对象: 当前已经运行在旧内核的麒麟主机。 执行前检查: uname -r 必须确认当前确实是旧内核,旧 vmlinuz 与 initramfs 均存在,业务和存储已恢复。 影响与恢复: 改变后续启动选择;不会删除新内核。若问题定位完成,可以再次把新内核设为默认进行受控复测。 完成验证: grubby --default-kernel 精确返回旧内核路径,grubby --info=ALL 仍保留新旧条目。

old=4.19.90-52.46.v2207.ky10.x86_64

uname -r
test -s "/boot/vmlinuz-$old"
test -s "/boot/initramfs-$old.img"
grubby --set-default "/boot/vmlinuz-$old"
grubby --default-kernel
grubby --info=ALL

3. 不要立即卸载新内核

回到旧内核后,应先保存失败启动的日志、控制台画面、驱动加载情况和 initramfs 信息,再决定是否卸载新内核。立即删除会损失复盘证据,也可能掩盖仓库、驱动或启动参数问题。

如果最终确认要卸载,应另开变更并精确指定四个 52.65 包;该操作不属于本次成功升级实验,因此本文不提供可直接复制的删除命令。

十二、如何判定升级真正完成

我把本次完成标准分成四层:

层级成功标准
包层DNF 事务成功,四个 52.65 包版本一致
启动层vmlinuz、initramfs、GRUB 条目完整,系统实际运行 52.65
系统层根卷、LVM、XFS、网络、关键服务正常,没有新增块层错误
问题层最小 4 KiB 写入的 io_ticks 回到毫秒级,完整负载不再出现极端 %util

只满足前两层,只能说明“新内核安装并启动了”;只有原问题的复测也通过,才能说明这次变更解决了目标故障。

本次最终状态为:

当前运行内核:4.19.90-52.65.v2207.ky10.x86_64
默认启动内核:4.19.90-52.65.v2207.ky10.x86_64
保留回退内核:4.19.90-52.46.v2207.ky10.x86_64
保留原始内核:4.19.90-52.22.v2207.ky10.x86_64
系统盘 LVM:正常
direct 测试盘:正常挂载
LVM 测试盘:正常挂载
当前启动块层/XFS/device-mapper 错误:未发现
已知失败服务:lm_sensors.service,升级前已存在
最小触发 sdc Δio_ticks:86999 ms → 4 ms
完整 LVM fio 的 sar sdc %util 峰值:807.70% → 94.30%

这次升级的关键不是某一条 dnf install 命令,而是完整的证据链:版本线与仓库确认、空间和回滚检查、四包安装验证、initramfs 和 GRUB 核对、受控重启、存储与日志验收、最后再用完全相同的 I/O 条件证明问题消失。对生产主机而言,只有把这条链写进变更和回滚方案,内核升级才是可控的修复,而不是一次碰运气的重启。

麒麟 Linux Linux 内核升级 LVM 性能监控 故障排查