Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> Linux 教學

Linux 秒級定位 IO 繁忙進程:vm.block_dump + dmesg + awk 一鍵分析法

編輯:Linux 教學

當 iostat 顯示磁碟 %util 100%、await 飆升,但 top/pidstat -d 卻看不出明顯大戶時,往往是大量小 IO、元資料操作或核心執行緒(如 kjournald、flush-*)在作祟。Linux 內核提供 vm.block_dump 參數,可將所有塊裝置讀寫事件實時導出至 dmesg,配合 awk 聚合即可秒級鎖定「真兇」。本文詳述開啟方法、輸出解讀、一鍵分析腳本與生產環境注意事項。

一、開啟區塊轉储

# 方法 1:sysctl(即時生效,重啟失效)
sysctl -w vm.block_dump=1

# 方法 2:直接寫入 /proc(同效)
echo 1 > /proc/sys/vm/block_dump

# 關閉
sysctl -w vm.block_dump=0
# 或
echo 0 > /proc/sys/vm/block_dump

作用範圍:全域,所有塊裝置(含 dm、md、loop、nvme)。

性能影響:極高 IO 時每秒產生大量日誌,可能佔用 CPU/磁碟,建議開啟 10-30 秒即關閉,或導出至專用日誌檔(dmesg -w | tee /tmp/block_dump.log)。

二、dmesg 輸出解讀

# 典型輸出
mysqld(7822): READ block 78196624 on dm-0
kjournald(529): WRITE block 211136 on dm-0
bash(8336): dirtied inode 7391146 (dmesg) on dm-0
systemd-journald(412): WRITE block 123456 on dm-1
python3(12345): READ block 987654 on dm-0
python3(12345): WRITE block 987655 on dm-0

欄位含義:

  • 進程名(PID):發起 IO 的進程。
  • READ/WRITE/dirtied:操作類型(dirtied = 標記 inode 髒頁,待回寫)。
  • block 號:邏輯塊號(相對於該裝置起始)。
  • on 裝置:目標塊裝置(dm-0、sda、nvme0n1 等)。
  • (檔案名):dirtied inode 時顯示檔案名(若可解析)。

三、一鍵分析:Top 10 IO 進程

# 統計當前 dmesg 緩衝區中 IO 事件最多的前 10 個進程
dmesg -T | awk -F'[()]' '/READ|WRITE|dirtied/ {print $1}' | sort | uniq -c | sort -rn | head -10

輸出範例:

  1245 mysqld
   312 kjournald
   198 python3
    87 systemd-journald
    45 rsyslogd

四、進階分析腳本:按裝置/操作類型/時間窗口聚合

#!/bin/bash
# analyze_block_dump.sh [duration_sec] [top_n]
# 需 root 權限;會自動開啟 block_dump、採樣、關閉、分析

DURATION=${1:-15}
TOP_N=${2:-20}
OUT=/tmp/block_dump_$(date +%s).log

echo "[$(date)] Enabling vm.block_dump=1 ..."
sysctl -w vm.block_dump=1 >/dev/null

echo "[$(date)] Capturing dmesg for ${DURATION}s ..."
dmesg -w -T > "$OUT" &
DMESG_PID=$!
sleep $DURATION
kill $DMESG_PID 2>/dev/null

echo "[$(date)] Disabling vm.block_dump ..."
sysctl -w vm.block_dump=0 >/dev/null

echo "=== Top $TOP_N processes by IO events ==="
awk -F'[()]' '/READ|WRITE|dirtied/ {print $1}' "$OUT" | sort | uniq -c | sort -rn | head -$TOP_N

echo -e "\n=== By device ==="
awk -F'on ' '/READ|WRITE|dirtied/ {split($2,a," "); print a[1]}' "$OUT" | sort | uniq -c | sort -rn

echo -e "\n=== By operation type ==="
awk '/READ/ {r++} /WRITE/ {w++} /dirtied/ {d++} END {print "READ:", r, "WRITE:", w, "DIRTIED:", d}' "$OUT"

echo -e "\n=== Sample raw lines (first 20) ==="
grep -E 'READ|WRITE|dirtied' "$OUT" | head -20

echo "Raw log saved to: $OUT"

五、生產環境實戰案例

案例 1:資料庫 checkpoint 暴衝

現象:凌晨 2 點磁碟 IO 飆升,應用響應變慢。
block_dump 顯示:postgres(1234): WRITE block ... 佔 85%,伴隨 checkpointer 進程大量 dirtied。
根因:checkpoint_timeout 過短 + checkpoint_completion_target 過低,導致检查點衝刷集中。
修正:調大 checkpoint_timeout=15min、checkpoint_completion_target=0.9,平滑寫入。

案例 2:日誌輪轉引發元資料風暴

現象:每小時整點 %util 瞬間 100%。
block_dump 顯示:logrotate(5678): dirtied inode ... 大量 WRITE block ... on dm-0,實為 rename()/unlink() 產生大量 inode/目錄項寫入。
修正:改用 copytruncate 或外部日誌收集(Filebeat/Fluentd),避免大量檔案操作。

案例 3:Swap 活動誤判為應用 IO

現象:iostat 顯示 sda 繁忙,但應用讀寫不大。
block_dump 顯示:kswapd0/kworker/u16:0 大量 READ/WRITE on dm-1(swap 分區)。
根因:記憶體不足觸發換頁。
修正:擴容記憶體或限制容器 cgroup memory.max。

六、注意事項與替代方案

項目說明
日誌緩衝區溢位高 IO 時 dmesg 環形緩衝區可能覆蓋舊事件,建議 dmesg -w 實時導出檔案
性能開銷每 IO 事件產生一次 printk,極高 IOPS 會明顯佔用 CPU,嚴禁長期開啟
容器環境宿主機開啟可見所有容器 IO;容器內無權限開啟
替代工具iotop -o(需內核 CONFIG_TASK_DELAY_ACCT)、pidstat -d 1、bpftrace -e 'tracepoint:block:block_rq_issue { @[comm] = count(); }' (eBPF,零開銷、可過濾)

掌握 vm.block_dump 這把「核級手術刀」,配合 dmesg/awk/bpftrace,即可在不安裝任何第三方工具、不重啟服務的前提下,於生產環境秒級定位 IO 熱點,從現象直達根因。

Copyright © Windows教程網 All Rights Reserved