LINUX云服務器進程D狀態問題分析
問題描述
在linux系統環境,進程在內核模式下等待I/O完成時通常會進入不間斷睡眠狀態,此時使用ps或top命令輸出的進程顯示為D狀態。
問題分析
在正常情況下,不間斷狀態只持續幾分之一秒。但是,異常情況下,進程可能會停留在此狀態更長的時間或(在最壞的情況下)無限期地停留。這種狀態下,即使使用“kill -9”也無法殺死進程,因為在進程喚醒之前,kill信號無法傳遞給進程。
要確定進程不可中斷的原因,就需要找出進程正在等待什么的更多信息。
從RHEL5.5?版開始,RHEL包含一個內核線程,用于監視停留在D狀態超過指定超時時間的進程。默認情況下,超時時間為120秒,可以使用內核參數?kernel.hung_task_timeout?修改或禁用它。當檢測到此類進程時,該內核線程將有關該進程的信息(包括其內核堆棧跟蹤)轉儲到?/var/log/messages。
我們也可以使用sysrq工具將有關進程的信息發送到/var/log/messages。
實驗模擬
在CentOS 8.2環境模擬一個處于D狀態的進程并進行實驗分析:使用LVM卷的?suspend?特性,暫停IO,使得上層應用程序處于D狀態。
(1)使用losetup創建一個卷作為pv的磁盤。
# dd if=/dev/zero of=/tmp/diskfile count=2048 bs=1M
# losetup --show -f /tmp/diskfile
(2)使用/dev/loop0創建pv, vg和lv。
# pvcreate /dev/loop0
# vgcreate vg01 /dev/loop0
# lvcreate -n lv01 -L 1G vg01
(3)在lv上創建一個文件系統并掛載到/mnt目錄。
# mkfs.ext4 /dev/vg01/lv01
# mount /dev/vg01/lv01 /mnt
(4)寫IO同時暫停?lv。
# dmsetup suspend /dev/vg01/lv01 && dd if=/dev/urandom of=/mnt/iotest.img count=1024 bs=1M
此時,該進程就會處于D狀態,命令不會返回到shell提示符。
可以通過另一個?shell?終端來查看這個進程:
# ps axl | awk ‘ ~ /D/’?(5)分析/var/log/messages日志文件。
在當前實驗場景,我們通過暫停進程使用的lv,使進程的IO操作發生阻塞,模擬出D進程現象。我們從/var/log/messages也看到了較為詳細的相關日志信息。
在實際生產環境中,當出現D進程時,進程無法被殺死,通常需要重新啟動系統來解決問題。/var/log/messages日志中也并不一定會有相關日志信息輸出。這時我們可以使用sysrq工具手動從內核收集D進程信息,以進行問題分析。
# less /var/log/messages
我們依舊在當前實驗環境使用sysrq工具進行手動從內核收集D進程信息的實驗操作:
啟用sysrq的功能:
# echo 1 > /proc/sys/kernel/sysrq
轉儲處于不可中斷(阻塞)狀態的任務。
# echo w > /proc/sysrq-trigger
將當前任務列表及其信息轉儲到您的控制臺。
# echo t > /proc/sysrq-trigger
顯示所有活動?CPU?的堆棧回溯。
# echo l > /proc/sysrq-trigger
這會將任務和線程信息轉儲到/var/log/messages:
問題解決
將任務和線程信息轉儲到/var/log/messages,恢復lv的IO:
# dmsetup resume /dev/vg01/lv01
恢復LV的IO后,進程狀態也由D變為R
背景知識
1、linux進程的幾種狀態:
(1)TASK_RUNNING:(R)
進程當前正在運行,或者正在運行隊列中等待調度。只有在該狀態的進程才可能在CPU上運行,同一時刻可能有多個進程處于運行狀態。
(2)TASK_INTERRUPTIBLE:(S)
進程處于睡眠狀態,處于這個狀態的進程因為等待某事件的發生(比如等待socket連接、等待信號量),而被掛起。當這些事件發生時,對應的等待隊列中的一個或多個進程將被喚醒。一般情況下,進程列表中的絕大多數進程都處于TASK_INTERRUPTIBLE狀態。進程可以被信號中斷。接收到信號或被顯式的喚醒呼叫喚醒之后,進程將轉變為TASK_RUNNING?狀態。
(3)TASK_UNINTERRUPTIBLE:(D)
不可中斷的睡眠狀態,此進程狀態類似于?TASK_INTERRUPTIBLE,只是它不會處理信號。不可中斷,指的是進程不響應異步信號,無法用kill命令關閉處于TASK_UNINTERRUPTIBLE狀態的進程。
(4)TASK_STOPPED:
進程已中止執行,它沒有運行,并且不能運行。接收到?SIGSTOP?和?SIGTSTP?等信號時,進程將進入這種狀態。接收到?SIGCONT?信號之后,進程將再次變得可運行。
(5)TASK_TRACED:(T)
正被調試程序等其他進程監控時,進程將進入這種狀態。
(6)EXIT_ZOMBIE:(Z)
進程已終止,它正等待其父進程收集關于它的一些統計信息。不可被kill, 即不響應任務信號, 無法用SIGKILL殺死
(7)EXIT_DEAD:(X)
最終狀態(正如其名)。將進程從系統中刪除時,它將進入此狀態,因為其父進程已經通過?wait4()?或?waitpid()?調用收集了所有統計信息。EXIT_DEAD狀態是非常短暫的,幾乎不可能通過ps命令捕捉到。
(8)TASK_KILLABLE:
Linux? kernel 2.6.25?引入了這種進程狀態,用于將進程置為睡眠狀態,它可以替代有效但可能無法終止的?TASK_UNINTERRUPTIBLE?進程狀態,以及易于喚醒但更加安全的?TASK_INTERRUPTIBLE?進程狀態。
2、關于SysRq:
(1)什么是SysRq鍵?
“SysRq”鍵也稱為“Print Screen”鍵,按下SysRq鍵,LINUX內核會響應,除非內核完全崩潰。關于SysRq的參考鏈接:https://www.kernel.org/doc/html/latest/admin-guide/sysrq.html
(2)如何啟用SysRq鍵:
在配置LINUX內核時,如果對CONFIG_MAGIC_SYSRQ配置Y選項,完成內核編譯后,可以通過/proc/sys/kernel/sysrq來調用SysRq?鍵調用的函數。
以下是?/proc/sys/kernel/sysrq?中支持的值列表:
0?完全禁用?sysrq。
1?啟用?sysrq?的所有功能。
>1?允許的?sysrq?函數的位掩碼(有關詳細的函數說明,請參見下文):
2 =?? 0x2 - enable control of console logging level
4 =?? 0x4 - enable control of keyboard (SAK, unraw)
8 =?? 0x8 - enable debugging dumps of processes etc.
16 =? 0x10 - enable sync command
32 =? 0x20 - enable remount read-only
64 =? 0x40 - enable signalling of processes (term, kill, oom-kill)
128 =? 0x80 - allow reboot/poweroff
256 = 0x100 - allow nicing of all RT tasks
您可以通過以下命令在文件中設置值:
echo "number" >/proc/sys/kernel/sysrq
注意:?/proc/sys/kernel/sysrq的值僅影響通過鍵盤進行的調用;/proc/sysrq-trigger則允許通過命令進行操作(需要具有管理員權限)。/proc/sysrq-trigger支持的命令及對應的功能如下:
命令
功能
b
將立即重新啟動系統而不同步或卸載您的磁盤。
c
如果配置,將執行系統崩潰并進行故障轉儲。
d
顯示持有的所有鎖。
e
向除?init?之外的所有進程發送?SIGTERM。
f
將調用?oom?殺手來殺死一個內存占用進程,但如果沒有任何東西可以殺死,請不要驚慌。
g
由?kgdb(內核調試器)使用
h
將顯示幫助(實際上,此處列出的任何其他鍵都將顯示幫助。但h很容易記住:-)
i
向除?init?之外的所有進程發送?SIGKILL。
j
強行“解凍” -?文件系統被?FIFREEZE ioctl?凍結。
k
安全訪問密鑰?(SAK)?殺死當前虛擬控制臺上的所有程序。注意:請參閱下面?SAK?部分中的重要注釋。
l
顯示所有活動?CPU?的堆棧回溯。
m
將當前內存信息轉儲到您的控制臺。
n
用于使?RT?任務變得很好
o
將關閉您的系統(如果已配置和支持)。
p
將當前的寄存器和標志轉儲到您的控制臺。
q
將轉儲每個?CPU?的所有武裝?hrtimer?列表(但不是常規?timer_list?計時器)以及有關所有時鐘事件設備的詳細信息。
r
關閉鍵盤原始模式并將其設置為?XLATE。
s
將嘗試同步所有已安裝的文件系統。
t
將當前任務列表及其信息轉儲到您的控制臺。
u
將嘗試以只讀方式重新掛載所有已掛載的文件系統。
v
強制恢復幀緩沖控制臺。
v
導致?ETM?緩沖區轉儲?[ARM?特定]
w
轉儲處于不可中斷(阻塞)狀態的任務。
x
由?ppc/powerpc?平臺上的?xmon?接口使用。在?sparc64?上顯示全局?PMU?寄存器。轉儲?MIPS?上的所有?TLB?條目。
y
顯示全局?CPU?寄存器?[SPARC-64?特定]。
z
轉儲?ftrace?緩沖區。
0——9
設置控制臺日志級別,控制將打印到控制臺的內核消息。(0,例如,將使得只有像?PANICs?或?OOPSes?這樣的緊急消息才能發送到您的控制臺。)
Linux 任務調度 通用安全
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。