docs(linux): normalize markdown heading levels in 00 小问题记录

- 每个问题作为一级标题
- 问题内小节 / 操作章节统一为二级标题
- 操作子项、解决步骤统一为三级标题
This commit is contained in:
Your Name
2026-10-10 11:31:34 +08:00
parent bdc37b3777
commit 3b0f68a42c
+27 -27
View File
@@ -1,15 +1,15 @@
## ECS 实例 dmesg 时间与真实时间存在 10 分钟偏差 # ECS 实例 dmesg 时间与真实时间存在 10 分钟偏差
- **记录日期**:2026-09-24 - **记录日期**:2026-09-24
- **现象**:`dmesg -T` 显示的时间戳与真实时间相差约 10 分钟(偏慢)。 - **现象**:`dmesg -T` 显示的时间戳与真实时间相差约 10 分钟(偏慢)。
- **根因**:系统默认时钟源(clocksource)为 `tsc`,该 TSC 频率偏慢 **33.7ppm**,累计 **220 天** 误差约 **641 秒**(≈ 10.7 分钟),导致系统时钟计数不准、dmesg 时间戳随之偏移。 - **根因**:系统默认时钟源(clocksource)为 `tsc`,该 TSC 频率偏慢 **33.7ppm**,累计 **220 天** 误差约 **641 秒**(≈ 10.7 分钟),导致系统时钟计数不准、dmesg 时间戳随之偏移。
- **解决**:GRUB 启动参数加入 `clocksource=kvm-clock` → 重新生成 grub 配置 → 重启实例,使 MONOTONIC 从 `kvm-clock` 重新起算。 - **解决**:GRUB 启动参数加入 `clocksource=kvm-clock` → 重新生成 grub 配置 → 重启实例,使 MONOTONIC 从 `kvm-clock` 重新起算。
### 1. 问题描述 ## 1. 问题描述
ECS 实例 `dmesg -T` 打印的时间与真实时间(`date`)存在约 10 分钟偏差,且偏差随运行时长持续累积。内核日志自身的时序(先后顺序)是正确的,但**时间戳的绝对刻度不准**。 ECS 实例 `dmesg -T` 打印的时间与真实时间(`date`)存在约 10 分钟偏差,且偏差随运行时长持续累积。内核日志自身的时序(先后顺序)是正确的,但**时间戳的绝对刻度不准**。
### 2. 原因分析 ## 2. 原因分析
- 内核中存在多个可选时钟源(TSC、kvm-clock、hpet、acpi_pm 等),启动时会按优先级选定一个作为当前时钟源。 - 内核中存在多个可选时钟源(TSC、kvm-clock、hpet、acpi_pm 等),启动时会按优先级选定一个作为当前时钟源。
- 本实例默认选中了 `tsc`(Time Stamp Counter,CPU 内部计数器)。该 CPU 的 TSC 计数频率与标称频率存在偏差,实测**偏慢 33.7ppm**。 - 本实例默认选中了 `tsc`(Time Stamp Counter,CPU 内部计数器)。该 CPU 的 TSC 计数频率与标称频率存在偏差,实测**偏慢 33.7ppm**。
@@ -25,9 +25,9 @@ ECS 实例 `dmesg -T` 打印的时间与真实时间(`date`)存在约 10 分
- `dmesg -T` 的时间戳由内核 `MONOTONIC` 时钟换算而来,时钟源偏慢直接反映为 dmesg 时间显示不准。 - `dmesg -T` 的时间戳由内核 `MONOTONIC` 时钟换算而来,时钟源偏慢直接反映为 dmesg 时间显示不准。
- `kvm-clock` 是 KVM 半虚拟化时钟源,直接读取宿主机提供的时钟信息,在同为虚拟机的 ECS 实例上精度显著更高,应优先使用。 - `kvm-clock` 是 KVM 半虚拟化时钟源,直接读取宿主机提供的时钟信息,在同为虚拟机的 ECS 实例上精度显著更高,应优先使用。
### 3. 解决方案 ## 3. 解决方案
#### 步骤 1:修改 GRUB 启动参数 ### 步骤 1:修改 GRUB 启动参数
编辑 `/etc/default/grub`,在 `GRUB_CMDLINE_LINUX` 中追加 `clocksource=kvm-clock`,例如: 编辑 `/etc/default/grub`,在 `GRUB_CMDLINE_LINUX` 中追加 `clocksource=kvm-clock`,例如:
@@ -42,7 +42,7 @@ sed -i 's/\(GRUB_CMDLINE_LINUX="[^"]*\)"/\1 clocksource=kvm-clock"/' /etc/defaul
grep GRUB_CMDLINE_LINUX /etc/default/grub grep GRUB_CMDLINE_LINUX /etc/default/grub
``` ```
#### 步骤 2:重新生成 GRUB 配置文件 ### 步骤 2:重新生成 GRUB 配置文件
> Alinux 的 grub 配置文件路径为 `/boot/efi/EFI/alinux/grub.cfg`(UEFI 引导)。 > Alinux 的 grub 配置文件路径为 `/boot/efi/EFI/alinux/grub.cfg`(UEFI 引导)。
@@ -50,7 +50,7 @@ grep GRUB_CMDLINE_LINUX /etc/default/grub
grub2-mkconfig -o /boot/efi/EFI/alinux/grub.cfg grub2-mkconfig -o /boot/efi/EFI/alinux/grub.cfg
``` ```
#### 步骤 3:重启实例 ### 步骤 3:重启实例
```sh ```sh
reboot reboot
@@ -58,7 +58,7 @@ reboot
重启的必要性:只有重启后才会以新的启动参数引导,`MONOTONIC` 从 `kvm-clock` **重新开始计数**,`dmesg -T` 的时间显示随之恢复正常。 重启的必要性:只有重启后才会以新的启动参数引导,`MONOTONIC` 从 `kvm-clock` **重新开始计数**,`dmesg -T` 的时间显示随之恢复正常。
#### 步骤 4:验证 ### 步骤 4:验证
```sh ```sh
# 当前时钟源,应显示 kvm-clock # 当前时钟源,应显示 kvm-clock
@@ -75,7 +75,7 @@ dmesg -T | tail
date date
``` ```
### 4. 备注 ## 4. 备注
- 修改后 `dmesg` 中已有的历史日志时间戳会因 MONOTONIC 重新起算而重新计算,属正常现象。 - 修改后 `dmesg` 中已有的历史日志时间戳会因 MONOTONIC 重新起算而重新计算,属正常现象。
- 若实例主要用于对时间精度敏感的场景(如日志审计、分布式追踪),建议同时确认 NTP/chrony 正常同步,二者互补:NTP 校正的是墙上时钟(`CLOCK_REALTIME`),clocksource 决定的是时基精度。 - 若实例主要用于对时间精度敏感的场景(如日志审计、分布式追踪),建议同时确认 NTP/chrony 正常同步,二者互补:NTP 校正的是墙上时钟(`CLOCK_REALTIME`),clocksource 决定的是时基精度。
@@ -83,9 +83,9 @@ date
--- ---
## kdump 实战:让 hung_task 与 softlockup 触发 vmcore # kdump 实战:让 hung_task 与 softlockup 触发 vmcore
### 0. 总结(TL;DR) ## 0. 总结(TL;DR)
目标是**在内核出现 hung_task(进程长期 D 状态不切出)或 softlockup(CPU 上任务长时间不让出)时,自动 panic 并触发 kdump,把现场落到 `/var/crash` 下的 vmcore**,供后续 `crash` 工具做根因分析。 目标是**在内核出现 hung_task(进程长期 D 状态不切出)或 softlockup(CPU 上任务长时间不让出)时,自动 panic 并触发 kdump,把现场落到 `/var/crash` 下的 vmcore**,供后续 `crash` 工具做根因分析。
@@ -110,9 +110,9 @@ crash /usr/lib/debug/lib/modules/$(uname -r)/vmlinux /var/crash/<时间戳>/vmco
--- ---
# 操作一:开启 kdump 服务 ## 操作一:开启 kdump 服务
## 1.1 确认内核已预留 crashkernel 内存 ### 1.1 确认内核已预留 crashkernel 内存
kdump 需要一个**独立预留的内存区域**(capture kernel)来在内核崩溃后接管系统。检查方式: kdump 需要一个**独立预留的内存区域**(capture kernel)来在内核崩溃后接管系统。检查方式:
@@ -134,7 +134,7 @@ grub2-mkconfig -o /boot/efi/EFI/centos/grub.cfg # UEFI(路径按发行版调
# 然后重启 # 然后重启
``` ```
## 1.2 安装并启动 kdump 服务 ### 1.2 安装并启动 kdump 服务
```bash ```bash
# 安装(按发行版) # 安装(按发行版)
@@ -149,14 +149,14 @@ systemctl status kdump
kdumpctl status 2>/dev/null || true kdumpctl status 2>/dev/null || true
``` ```
## 1.3 确认 kdump 就绪 ### 1.3 确认 kdump 就绪
```bash ```bash
cat /sys/kernel/kexec_crash_loaded # 期望 1 cat /sys/kernel/kexec_crash_loaded # 期望 1
ls -l /var/crash/ # 崩溃后 vmcore 落在这里 ls -l /var/crash/ # 崩溃后 vmcore 落在这里
``` ```
## 1.4 关键配置项(/etc/kdump.conf) ### 1.4 关键配置项(/etc/kdump.conf)
| 配置项 | 说明 | | 配置项 | 说明 |
|---|---| |---|---|
@@ -169,7 +169,7 @@ ls -l /var/crash/ # 崩溃后 vmcore 落在这里
--- ---
# 操作二:配置 hung_task 与 softlockup 触发 panic ## 操作二:配置 hung_task 与 softlockup 触发 panic
内核默认检测到 hung_task / softlockup 时**只打印告警日志,不会 panic**,所以现场不会产生 vmcore。需要打开 panic 开关。 内核默认检测到 hung_task / softlockup 时**只打印告警日志,不会 panic**,所以现场不会产生 vmcore。需要打开 panic 开关。
@@ -186,14 +186,14 @@ EOF
# EOF # EOF
``` ```
## 2.1 两个开关的含义 ### 2.1 两个开关的含义
| 参数 | 含义 | 默认值 | | 参数 | 含义 | 默认值 |
|---|---|---| |---|---|---|
| `kernel.hung_task_panic` | 检测到 D 状态(不可中断睡眠)任务超时后,触发 panic | 0(只告警) | | `kernel.hung_task_panic` | 检测到 D 状态(不可中断睡眠)任务超时后,触发 panic | 0(只告警) |
| `kernel.softlockup_panic` | 检测到 softlockup(某 CPU 上任务长时间不调度)后,触发 panic | 0(只告警) | | `kernel.softlockup_panic` | 检测到 softlockup(某 CPU 上任务长时间不调度)后,触发 panic | 0(只告警) |
## 2.2 配套可调参数(按需) ### 2.2 配套可调参数(按需)
```bash ```bash
kernel.hung_task_timeout_secs = 120 # hung_task 判定超时,默认 120s kernel.hung_task_timeout_secs = 120 # hung_task 判定超时,默认 120s
@@ -204,7 +204,7 @@ kernel.hardlockup_panic = 1 # 硬锁(中断被长时间关闭)也
kernel.panic_on_oops = 1 # Oops 即 panic,按需 kernel.panic_on_oops = 1 # Oops 即 panic,按需
``` ```
## 2.3 注意事项 ### 2.3 注意事项
- **softlockup 检测依赖 watchdog 线程本身能运行**:若 CPU 长时间关中断,属于 hardlockup,需靠 `nmi_watchdog` + `hardlockup_panic` 捕获。 - **softlockup 检测依赖 watchdog 线程本身能运行**:若 CPU 长时间关中断,属于 hardlockup,需靠 `nmi_watchdog` + `hardlockup_panic` 捕获。
- 部分内核 `softlockup_panic` 受编译选项约束;若写入失败,可检查 `CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC`,或改用内核启动参数 `softlockup_panic=1`。 - 部分内核 `softlockup_panic` 受编译选项约束;若写入失败,可检查 `CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC`,或改用内核启动参数 `softlockup_panic=1`。
@@ -212,7 +212,7 @@ kernel.panic_on_oops = 1 # Oops 即 panic,按需
--- ---
# 操作三:使配置生效 ## 操作三:使配置生效
```bash ```bash
# 方式一:立即加载 sysctl.conf # 方式一:立即加载 sysctl.conf
@@ -225,7 +225,7 @@ sysctl -p /etc/sysctl.d/99-kdump-panic.conf
reboot reboot
``` ```
## 3.1 生效校验 ### 3.1 生效校验
```bash ```bash
sysctl kernel.hung_task_panic kernel.softlockup_panic sysctl kernel.hung_task_panic kernel.softlockup_panic
@@ -241,9 +241,9 @@ cat /sys/kernel/kexec_crash_loaded # 1
--- ---
# 操作四:复现后取证与分析 ## 操作四:复现后取证与分析
## 4.1 vmcore 落盘位置 ### 4.1 vmcore 落盘位置
问题复现后,系统会 panic → kexec 启动 capture kernel → 由 kdump 把内存镜像写入: 问题复现后,系统会 panic → kexec 启动 capture kernel → 由 kdump 把内存镜像写入:
@@ -257,7 +257,7 @@ ls -lh /var/crash/
cat /var/crash/<时间戳>/vmcore-dmesg.txt | tail -50 # 先看崩溃瞬间的 dmesg cat /var/crash/<时间戳>/vmcore-dmesg.txt | tail -50 # 先看崩溃瞬间的 dmesg
``` ```
## 4.2 用 crash 工具做根因分析 ### 4.2 用 crash 工具做根因分析
```bash ```bash
# 安装 debuginfo(以 CentOS 为例) # 安装 debuginfo(以 CentOS 为例)
@@ -279,7 +279,7 @@ crash /usr/lib/debug/lib/modules/$(uname -r)/vmlinux \
| `sys` | 系统基本信息(版本、panic 原因等) | | `sys` | 系统基本信息(版本、panic 原因等) |
| `dis -l <addr>` | 反汇编定位到源码行 | | `dis -l <addr>` | 反汇编定位到源码行 |
## 4.3 可选:手动触发一次转储做演练 ### 4.3 可选:手动触发一次转储做演练
```bash ```bash
# 需确认 kernel.sysrq=1 且 kdump 已就绪,演练会重启系统 # 需确认 kernel.sysrq=1 且 kdump 已就绪,演练会重启系统
@@ -288,7 +288,7 @@ echo c > /proc/sysrq-trigger
--- ---
# 操作五:常见问题排查(Q&A) ## 操作五:常见问题排查(Q&A)
- **`/var/crash` 下没有 vmcore** - **`/var/crash` 下没有 vmcore**
- `kdump` 服务未运行或未开机自启:`systemctl is-active kdump` / `is-enabled`。 - `kdump` 服务未运行或未开机自启:`systemctl is-active kdump` / `is-enabled`。