linux進(jìn)程D狀態(tài)的解決思路分享
1. 問(wèn)題描述
在Linux系統(tǒng)環(huán)境,進(jìn)程在內(nèi)核模式下等待I/O完成時(shí)通常會(huì)進(jìn)入不間斷睡眠狀態(tài),此時(shí)使用ps或top命令輸出的進(jìn)程顯示為D狀態(tài)。
當(dāng)然我們也可以使用sysrq工具將有關(guān)進(jìn)程的信息發(fā)送到/var/log/messages。
2. 問(wèn)題分析
在正常情況下,不間斷狀態(tài)只持續(xù)幾分之一秒。但是,異常情況下,進(jìn)程可能會(huì)停留在此狀態(tài)更長(zhǎng)的時(shí)間或(在最壞的情況下)無(wú)限期地停留。
這種狀態(tài)下,即使使用“kill -9”也無(wú)法殺死進(jìn)程,因?yàn)樵谶M(jìn)程喚醒之前,kill信號(hào)無(wú)法傳遞給進(jìn)程。
3. 實(shí)驗(yàn)?zāi)M
在CentOS 7.9環(huán)境模擬一個(gè)處于D狀態(tài)的進(jìn)程并進(jìn)行實(shí)驗(yàn)分析:
使用LVM卷的 suspend 特性,暫停IO,使得上層應(yīng)用程序處于D狀態(tài)。
3.1 使用losetup創(chuàng)建一個(gè)卷作為pv的磁盤
losetup命令概述
losetup命令用來(lái)設(shè)置loop設(shè)備,loop設(shè)備可以將文件虛擬成塊設(shè)備,這樣用戶就可以對(duì)其進(jìn)行掛載,
比如常見(jiàn)的ISO光盤鏡像、img鏡像都可以被虛擬成塊設(shè)備,然后進(jìn)行掛載和訪問(wèn)。
# dd寫入一個(gè)2G的文件 $ dd if=/dev/zero of=/tmp/diskfile count=2048 bs=1M # 將2G的文件虛擬成塊設(shè)備 $ losetup --show -f /tmp/diskfile
3.2 使用/dev/loop0塊設(shè)備創(chuàng)建pv, vg和lv
[root@node-1 ~]# pvcreate /dev/loop0 Physical volume "/dev/loop0" successfully created. [root@node-1 ~]# vgcreate vg01 /dev/loop0 Volume group "vg01" successfully created [root@node-1 ~]# lvcreate -n lv01 -L 1G vg01 Logical volume "lv01" created.
3.3 使用剛創(chuàng)建的lv
創(chuàng)建一個(gè)文件系統(tǒng)并掛載到/mnt目錄
[root@node-1 ~]# mkfs.ext4 /dev/vg01/lv01 [root@node-1 ~]# mount /dev/vg01/lv01 /mnt
3.4 dmsetup suspend 命令暫停 lv 同時(shí)進(jìn)行IO
[root@node-1 ~]# dmsetup suspend /dev/vg01/lv01 && dd if=/dev/urandom of=/mnt/iotest.img count=1024 bs=1M
此時(shí),該進(jìn)程就會(huì)處于D狀態(tài),命令不會(huì)返回到shell提示符。
可以通過(guò)另一個(gè) shell 終端來(lái)查看這個(gè)進(jìn)程:
[root@node-1 ~]# ps -aux | awk '$8 == "D+" {print $0}' root 1685 0.0 0.0 108096 620 pts/0 D+ 15:57 0:00 dd if=/dev/urandom of=/mnt/iotest.img count=1024 bs=1M
通過(guò)kill -9 1685也殺死不掉該進(jìn)程
[root@node-1 ~]# kill -9 1685 [root@node-1 ~]# ps -aux | awk '$8 == "D+" {print $0}' root 1685 0.0 0.0 108096 620 pts/0 D+ 16:21 0:00 dd if=/dev/urandom of=/mnt/iotest.img count=1024 bs=1M
3.5 對(duì)/var/log/messages日志文件進(jìn)行分析
看到“task dd:1685 blocked for more than 120 seconds.”這樣的消息時(shí),這通常意味著有一個(gè)名為dd的進(jìn)程(進(jìn)程ID為1685)在執(zhí)行過(guò)程中被阻塞了超過(guò)120秒。
但dd進(jìn)程為什么會(huì)被堵塞我們也不知道,應(yīng)需要開(kāi)發(fā)人員去分析call trace信息。
但由于這是通過(guò)測(cè)試模擬的,我知道是什么原因堵塞,所以我們通過(guò)dmsetup resume命令進(jìn)行恢復(fù)lv, 然后dd命令io就正常寫入了,進(jìn)程狀態(tài)也由D變?yōu)镽 。
[root@node-1 ~]# dmsetup resume /dev/vg01/lv01
4. 問(wèn)題總節(jié)
1、如果生產(chǎn)環(huán)境遇到進(jìn)程一直處于D狀態(tài),無(wú)法kill 掉, 重啟服務(wù)器解決
2、運(yùn)維側(cè)分析日志或者事件升級(jí)到研發(fā),找到進(jìn)程處于D狀態(tài)的原因,讓進(jìn)程從D狀態(tài)恢復(fù)到R狀態(tài)。
通過(guò)sysrq工具進(jìn)行手動(dòng)從內(nèi)核收集D進(jìn)程信息轉(zhuǎn)存到messages,拿到日志進(jìn)一步分析或升級(jí)到研發(fā)分析:
# 啟用sysrq的功能: $ echo 1 > /proc/sys/kernel/sysrq # 轉(zhuǎn)儲(chǔ)處于不可中斷(阻塞)狀態(tài)的任務(wù)。 $ echo w > /proc/sysrq-trigger # 將當(dāng)前任務(wù)列表及其信息轉(zhuǎn)儲(chǔ)到您的控制臺(tái)。 $ echo t > /proc/sysrq-trigger # 顯示所有活動(dòng) CPU 的堆?;厮?。 $ echo l > /proc/sysrq-trigger 這會(huì)將任務(wù)和線程信息轉(zhuǎn)儲(chǔ)到/var/log/messages,進(jìn)行進(jìn)一步分析
5. linux常見(jiàn)幾種狀態(tài)
這里只列出4種狀態(tài)
5.1 TASK_RUNNING:(R)
進(jìn)程當(dāng)前正在運(yùn)行,或者正在運(yùn)行隊(duì)列中等待調(diào)度。
只有在該狀態(tài)的進(jìn)程才可能在CPU上運(yùn)行,同一時(shí)刻可能有多個(gè)進(jìn)程處于運(yùn)行狀態(tài)。
5.2 TASK_INTERRUPTIBLE:(S)
進(jìn)程處于睡眠狀態(tài),處于這個(gè)狀態(tài)的進(jìn)程因?yàn)榈却呈录陌l(fā)生(比如等待socket連接、等待信號(hào)量),而被掛起。當(dāng)這些事件發(fā)生時(shí),對(duì)應(yīng)的等待隊(duì)列中的一個(gè)或多個(gè)進(jìn)程將被喚醒。
一般情況下,進(jìn)程列表中的絕大多數(shù)進(jìn)程都處于TASK_INTERRUPTIBLE狀態(tài)。進(jìn)程可以被信號(hào)中斷。接收到信號(hào)或被顯式的喚醒呼叫喚醒之后,進(jìn)程將轉(zhuǎn)變?yōu)門ASK_RUNNING 狀態(tài)。
5.3 TASK_UNINTERRUPTIBLE:(D)
不可中斷的睡眠狀態(tài),此進(jìn)程狀態(tài)類似于 TASK_INTERRUPTIBLE,只是它不會(huì)處理信號(hào)。
不可中斷,指的是進(jìn)程不響應(yīng)異步信號(hào),無(wú)法用kill命令關(guān)閉處于TASK_UNINTERRUPTIBLE狀態(tài)的進(jìn)程。
5.4 EXIT_ZOMBIE:(Z)
進(jìn)程已終止,它正等待其父進(jìn)程收集關(guān)于它的一些統(tǒng)計(jì)信息。
不可被kill, 即不響應(yīng)任務(wù)信號(hào), 無(wú)法用SIGKILL殺死
6. 關(guān)于SysRq
6.1 什么是SysRq鍵?
“SysRq”鍵也稱為“Print Screen”鍵,按下SysRq鍵,LINUX內(nèi)核會(huì)響應(yīng),除非內(nèi)核完全崩潰。
關(guān)于SysRq的參考鏈接:參考點(diǎn)這里
6.2 如何啟用SysRq鍵
在配置LINUX內(nèi)核時(shí),如果對(duì)CONFIG_MAGIC_SYSRQ配置Y選項(xiàng),完成內(nèi)核編譯后,可以通過(guò)/proc/sys/kernel/sysrq來(lái)調(diào)用SysRq 鍵調(diào)用的函數(shù)。
以下是 /proc/sys/kernel/sysrq 中支持的值列表:
- 0 完全禁用 sysrq。
- 1 啟用 sysrq 的所有功能。
- >1 允許的 sysrq 函數(shù)的位掩碼
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
在CentOS7上搭建Jenkins+Maven+Git持續(xù)集成環(huán)境的方法
這篇文章主要介紹了在CentOS7上搭建Jenkins+Maven+Git持續(xù)集成環(huán)境的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-01-01Linux系統(tǒng)下SystemC環(huán)境配置方法
大家好,本篇文章主要講的是Linux系統(tǒng)下SystemC環(huán)境配置方法,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽2021-12-12wamp2.2e 64位 curl 開(kāi)啟不了的解決辦法
這篇文章主要介紹了wamp2.2e 64位 curl 開(kāi)啟不了的解決辦法,需要的朋友可以參考下2014-12-12Linux下安裝MariaDB數(shù)據(jù)庫(kù)問(wèn)題及解決方法(二進(jìn)制版本的安裝)
MariaDB數(shù)據(jù)庫(kù) 分為源代碼版本和二進(jìn)制版本,源代碼版本需要cmake編譯,這里是二進(jìn)制版本的安裝。下面通過(guò)本文給大家介紹Linux下安裝MariaDB數(shù)據(jù)庫(kù)問(wèn)題及解決方法(二進(jìn)制版本的安裝),感興趣的朋友參考下吧2016-11-11Ubuntu 20.04 CUDA&cuDNN安裝方法(圖文教程)
這篇文章主要介紹了Ubuntu 20.04 CUDA&cuDNN安裝方法(圖文教程),文中通過(guò)圖文代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07centos系統(tǒng)搭建本地yum服務(wù)器的方法
YUM是Yellow dog Updater, Modified的縮寫,是由Duke University所發(fā)起的計(jì)劃,目的就是為了解決RPM的依賴關(guān)系的問(wèn)題,方便使用者進(jìn)行軟件的安裝、升級(jí)等等工作。這篇文章主要給大家介紹了在centos系統(tǒng)搭建本地yum服務(wù)器的方法,有需要的朋友們可以參考借鑒。2016-12-12centos7 無(wú)線網(wǎng)卡驅(qū)動(dòng)的安裝及無(wú)線網(wǎng)絡(luò)的配置詳解
本篇文章主要介紹了centos7 無(wú)線網(wǎng)卡驅(qū)動(dòng)的安裝及無(wú)線網(wǎng)絡(luò)的配置詳解,具有一定的參考價(jià)值,有興趣的可以了解一下。2017-03-03