
先說(shuō)說(shuō)這個(gè)標(biāo)題背后的真實(shí)場(chǎng)景。絕大多數(shù)人搜這句話的時(shí)候服務(wù)器磁盤已經(jīng)快滿了或者某個(gè)業(yè)務(wù)目錄增長(zhǎng)異常需要立刻定位到底哪個(gè)文件夾在吃空間。我自己處理過(guò)的磁盤告警少說(shuō)也有幾十次從一句話的需求出發(fā)實(shí)際上要解決的是“快速定位占用源頭并安全清理”這一整套動(dòng)作。這篇文章就把我在 Linux 服務(wù)器上查看文件夾占用空間、定位大目錄、排查空間異常的所有常用方法和踩坑記錄整理出來(lái)適合剛接觸運(yùn)維的開發(fā)者也適合需要臨時(shí)上服務(wù)器救火的業(yè)務(wù)同學(xué)。1. 需求拆解一句話標(biāo)題背后其實(shí)是三件事1.1 你真正想知道的是什么“查看某文件夾占用空間大小”這句話實(shí)在太籠統(tǒng)了實(shí)踐里它至少包含三層需求第一層是想知道某個(gè)目錄總共有多大比如 /var 已經(jīng) 50G 了這通常是看一眼就能回答的問(wèn)題。第二層是定位這個(gè)大目錄里到底哪個(gè)子目錄或者哪個(gè)文件最占空間這個(gè)才是排查磁盤告警的真正核心。如果只是知道 /var 有 50G 卻不知道里面是什么等于沒(méi)查。第三層是判斷整個(gè)磁盤分區(qū)還剩多少可用空間因?yàn)橛袝r(shí)候你看到的文件加起來(lái)并不大磁盤卻滿了這說(shuō)明空間掛在別的地方比如其他目錄、隱藏文件、或者被刪除但仍被進(jìn)程占用的文件。很多人一上來(lái)就敲du -sh 目錄名這個(gè)命令沒(méi)問(wèn)題但它只能回答第一層問(wèn)題。而真正難處理的是第二層和第三層這也是這篇文章的重點(diǎn)。1.2 兩條技術(shù)路線到底怎么選Linux 下查看空間占用有兩條完全不同的技術(shù)路線必須區(qū)分清楚。dudisk usage走的是目錄樹它從指定路徑開始逐個(gè)遍歷目錄項(xiàng)和文件累加每個(gè)文件實(shí)際占用的磁盤塊大小。它回答的問(wèn)題是“這個(gè)文件夾里的所有內(nèi)容加起來(lái)占了多少磁盤空間”。dfdisk free走的是文件系統(tǒng)元數(shù)據(jù)直接讀取超級(jí)塊里的統(tǒng)計(jì)信息打印整個(gè)文件系統(tǒng)分區(qū)的總?cè)萘?、已用量和剩余量。它回答的?wèn)題是“這個(gè)分區(qū)還有多少空間可用”。兩者看似差不多實(shí)際經(jīng)常不一致原因就是統(tǒng)計(jì)維度不同。后面第 4 節(jié)我會(huì)專門展開講兩者不一致的幾種情況。先記住一個(gè)原則看單個(gè)目錄或者整個(gè)目錄樹的大小用du看磁盤分區(qū)整體剩余空間用df兩個(gè)必須配合使用。2. du 命令的核心參數(shù)與統(tǒng)計(jì)原理2.1 為什么 du 顯示的數(shù)值和 ls 的 size 不一樣這是我被問(wèn)過(guò)最多的問(wèn)題。在某個(gè)目錄里執(zhí)行l(wèi)s -lh看到一個(gè)文件顯示 100M但du -h 文件名卻顯示 104M 或者 98M很多人就懵了。原因在于ls -l顯示的是文件的“邏輯大小”也就是文件內(nèi)容的實(shí)際字節(jié)數(shù)而du統(tǒng)計(jì)的是文件在磁盤上“物理占用”的塊大小。文件系統(tǒng)是按照塊block來(lái)分配空間的一個(gè)塊通常是 4K。哪怕一個(gè)文件只有 1 個(gè)字節(jié)它也要占一個(gè)完整的 4K 塊du就會(huì)按 4K 來(lái)算。反過(guò)來(lái)如果是稀疏文件文件中間有大量空洞文件邏輯大小可能很大但實(shí)際分配的塊很少du統(tǒng)計(jì)出來(lái)的就比ls -l小很多。所以當(dāng)你在博文或者文檔里看到du的結(jié)果和網(wǎng)頁(yè)上某個(gè)文件標(biāo)注的大小不一樣不要覺(jué)得是命令用錯(cuò)了這本身就是 Linux 文件系統(tǒng)分配機(jī)制的正常表現(xiàn)。你要做的是理解du統(tǒng)計(jì)的是“占磁盤空間”而不是“文件有多長(zhǎng)”。2.2 必須記住的常用參數(shù)組合du的參數(shù)不少但日常排查其實(shí)只需要記住我下面列出的這幾個(gè)組合基本覆蓋了絕大多數(shù)場(chǎng)景。先給出最基本的一些參數(shù)說(shuō)明參數(shù)作用使用場(chǎng)景-hhuman-readable以 K/M/G 為單位顯示幾乎所有場(chǎng)景-ssummarize只顯示指定目錄的總大小精確查看單個(gè)目錄-aall同時(shí)顯示目錄和文件需要看到具體文件時(shí)--max-depthN最多遞歸 N 層子目錄定位大目錄時(shí)最常用-c最后顯示所有目錄的總計(jì)統(tǒng)計(jì)多個(gè)目錄的和--excludePATTERN排除匹配模式的文件/目錄跳過(guò)日志或緩存目錄-x不跨越文件系統(tǒng)邊界避免統(tǒng)計(jì)到掛載的其他磁盤用的時(shí)候我建議直接按這樣的組合去記# 查看單個(gè)目錄總大小 du -sh /var # 查看當(dāng)前目錄下所有一級(jí)子目錄的大小并排序 du -h --max-depth1 . | sort -hr # 如果想連文件一起顯示 du -ah --max-depth1 . | sort -hr # 統(tǒng)計(jì)多個(gè)指定目錄的總大小 du -sch /var/log /tmp /home注意du -h --max-depth1和du -sh *執(zhí)行結(jié)果其實(shí)差不多但前者更規(guī)范。du -sh *的問(wèn)題在于它會(huì)把 command-line arguments 展開后才去統(tǒng)計(jì)如果當(dāng)前目錄下文件特別多會(huì)有一瞬間的參數(shù)列表過(guò)長(zhǎng)風(fēng)險(xiǎn)而且用*會(huì)漏掉隱藏文件這一點(diǎn)后面還要單獨(dú)說(shuō)。2.3 用 sort 把結(jié)果按大小排序du默認(rèn)輸出是不排序的目錄一多根本看不出來(lái)誰(shuí)最占空間。所以必須和sort配合。du -h --max-depth1 /var 2/dev/null | sort -hr | head -20sort -hr的意思是按人類可讀的數(shù)值4K、100M、2G 這種格式逆序排序。這里有一個(gè)關(guān)鍵細(xì)節(jié)如果你直接用sort -h它會(huì)正確識(shí)別 K/M/G 單位的大小關(guān)系但如果用sort -r普通排序會(huì)把帶 G 的和帶 M 的混在一起排錯(cuò)。我第一次用就犯過(guò)這個(gè)錯(cuò)誤以為 10M 比 2G 大其實(shí)是把字符串當(dāng)字典序排了。另外2/dev/null一定要加上因?yàn)閐u在遍歷過(guò)程中遇到?jīng)]有權(quán)限的目錄會(huì)輸出du: cannot read directory之類的報(bào)錯(cuò)這些錯(cuò)誤會(huì)混進(jìn)輸出里干擾排序。3. 一套可以直接抄作業(yè)的排查流程3.1 第一步用 df 判斷整體情況所有磁盤空間排查都應(yīng)該先從df開始而不是直接du。因?yàn)槟阈枰雀闱宄降资悄膫€(gè)分區(qū)滿了確認(rèn)優(yōu)先級(jí)。df -h df -idf -h是查看磁盤容量使用率df -i是查看 inode 使用率。我多次遇到一種情況磁盤容量顯示還有 20G 空余但業(yè)務(wù)報(bào)錯(cuò)“No space left on device”這時(shí)候df -i會(huì)發(fā)現(xiàn) inode 已經(jīng) 100% 占滿了。inode 是文件系統(tǒng)里記錄文件元數(shù)據(jù)的索引節(jié)點(diǎn)小文件特別多的目錄比如郵件隊(duì)列、緩存目錄、容器鏡像層最容易把 inode 耗盡。判斷順序應(yīng)該是先df -h看容量再用df -i查 inode兩個(gè)都正常再繼續(xù)往下走。3.2 第二步從根目錄逐層下鉆定位整體空間都確認(rèn)了之后進(jìn)入定位大目錄的環(huán)節(jié)。第一次先看根目錄下所有一級(jí)目錄的大小因?yàn)橐话悴粫?huì)一上來(lái)就有針對(duì)性的目錄猜測(cè)先看全局狀態(tài)du -h --max-depth1 / 2/dev/null | sort -hr | head -20輸出結(jié)果里通常會(huì)看到/var、/usr、/home里有一個(gè)特別大于是進(jìn)入對(duì)應(yīng)目錄再次執(zhí)行du -h --max-depth1 /var 2/dev/null | sort -hr | head -20就這樣一層一層往下鉆。這個(gè)過(guò)程我自己的經(jīng)驗(yàn)是“每次只看一級(jí)目錄”不要試圖一步到位直接du -h --max-depth3 /那樣的輸出會(huì)非常長(zhǎng)且雜亂因?yàn)樽畲笊疃?3 會(huì)把幾百個(gè)目錄全部列出來(lái)。你反而會(huì)被撲面而來(lái)的信息淹沒(méi)沒(méi)法判斷重點(diǎn)。逐層下鉆雖然多敲幾次命令但每次都只需要關(guān)注 top 10 的目錄思路非常清晰。到某一層出現(xiàn)大量平鋪的文件時(shí)再改用du -ah把文件也顯示出來(lái)直接定位到具體文件du -ah --max-depth2 /var/log 2/dev/null | sort -hr | head -203.3 第三步千萬(wàn)別漏了隱藏文件和掛載點(diǎn)這一步是新人最容易踩的坑。du -h --max-depth1統(tǒng)計(jì)的是當(dāng)前目錄下所有條目但如果你用du -sh *這種方式shell 的*默認(rèn)不會(huì)匹配以.開頭的隱藏文件和目錄。比如/home下用戶的.cache目錄、/var/spool下可能有隱藏目錄這些全都會(huì)被漏掉。結(jié)果就是排查了半天明明某文件夾占用很高但統(tǒng)計(jì)結(jié)果卻對(duì)不上。所以我特別建議你執(zhí)行下面的互補(bǔ)命令專門檢查隱藏目錄的大小du -h --max-depth1 /要查的目錄 2/dev/null | sort -hr du -sh /要查的目錄/.[!.]* 2/dev/null第二條命令里的.[!.]*匹配的是以點(diǎn)開頭但第二個(gè)字符不是點(diǎn)的條目也就是隱藏目錄和隱藏文件但不包括.和..。它的作用就是專門揪出被普通通配符漏掉的隱藏文件。遇到過(guò)最典型的一次某臺(tái)服務(wù)器/root下面看起來(lái)什么都沒(méi)有結(jié)果du -sh /root/.*一查一個(gè).maildump隱藏目錄占了 80G就是某個(gè)異常任務(wù)一直在往里面寫臨時(shí)文件。另外還要注意掛載點(diǎn)。du默認(rèn)會(huì)穿越文件系統(tǒng)邊界繼續(xù)統(tǒng)計(jì)比如某個(gè)目錄下面掛了一個(gè) NFS 或者另一塊數(shù)據(jù)盤du會(huì)把掛載點(diǎn)里的內(nèi)容也算到當(dāng)前目錄頭上導(dǎo)致這里顯示的占用不代表它占用了你當(dāng)前這個(gè)分區(qū)。這時(shí)候要加-x參數(shù)跳過(guò)其他文件系統(tǒng)du -x -h --max-depth1 / 2/dev/null | sort -hr3.4 找到大文件之后的清理驗(yàn)證定位到具體的大文件之后不要沖動(dòng)地直接rm。先確認(rèn)這個(gè)文件的用途特別是日志文件有些進(jìn)程會(huì)持續(xù)寫入你手動(dòng)刪掉了但進(jìn)程還持有文件句柄磁盤空間并不會(huì)釋放。確認(rèn)要清理之后在刪除前記錄一下刪前后空間情況df -h /var du -sh /var/log rm -f /var/log/某個(gè)大日志 df -h /var du -sh /var/log前后對(duì)比一下能確認(rèn)空間是否真的釋放了若刪除了但df顯示可用空間沒(méi)有增長(zhǎng)則說(shuō)明文件被某個(gè)進(jìn)程占用了具體處理方式我在第 4 節(jié)細(xì)說(shuō)。4. du 和 df 顯示不一致的深層原因4.1 文件被刪除但進(jìn)程仍持有句柄這是生產(chǎn)環(huán)境最經(jīng)典的問(wèn)題你在某個(gè)目錄里看到一個(gè)大文件執(zhí)行rm刪掉了目錄空間統(tǒng)計(jì)也正常了但df -h一看整個(gè)分區(qū)的可用空間沒(méi)有任何變化還是滿的。原因在于 Linux 的文件刪除機(jī)制。rm刪除的只是對(duì)文件的一個(gè)目錄項(xiàng)鏈接但如果有一個(gè)進(jìn)程正打開著這個(gè)文件文件仍然存在于磁盤上只是不再有路徑可以訪問(wèn)到它。那個(gè)進(jìn)程不關(guān)閉這個(gè)文件句柄空間就永遠(yuǎn)不會(huì)釋放。遇到這種情況用lsof找出持有已刪除文件的進(jìn)程lsof L1L1會(huì)列出“鏈接數(shù)小于 1”的文件也就是被刪除但仍被打開的文件。輸出里找到進(jìn)程 PID 后要么重啟該進(jìn)程要么讓服務(wù)方重新加載配置文件。如果是一臺(tái)臨時(shí)服務(wù)器急著要空間確認(rèn)進(jìn)程可以重啟就直接重啟服務(wù)。千萬(wàn)不要為了釋放空間去kill -9一個(gè)你不知道是什么的進(jìn)程先看lsof輸出里進(jìn)程名再判斷能不能重啟。文件被刪除但空間不釋放的問(wèn)題在日志類服務(wù)、數(shù)據(jù)庫(kù)、消息隊(duì)列上特別常見尤其是一些不會(huì)自動(dòng)logrotate的進(jìn)程日志被手動(dòng)刪了但 fd 還握著磁盤空間憑空消失幾十 G。4.2 根文件系統(tǒng)保留塊被算進(jìn)“已用”里我用df -h查看/分區(qū)時(shí)經(jīng)常看到已經(jīng)用了 95% 以上但du -h --max-depth1 /把所有目錄加起來(lái)也沒(méi)那么大中間就差了那么幾個(gè) G。這里面的主要原因之一是 ext4 等文件系統(tǒng)默認(rèn)會(huì)預(yù)留 5% 的空間給 root 用戶用來(lái)防止系統(tǒng)因?yàn)榭臻g耗盡而無(wú)法正常啟動(dòng)。這 5% 的保留塊在df里是算在“已用”里面的但du是完全感知不到這部分空間的。所以當(dāng)你的根分區(qū)使用率顯示 97%但du統(tǒng)計(jì)的總和只有 92% 左右不用太驚訝這 5% 是文件系統(tǒng)層面的保留。如果你確實(shí)需要釋放這部分空間用下面的命令調(diào)整保留比例tune2fs -m 1 /dev/sda1但不建議在生產(chǎn)服務(wù)器上隨意調(diào)整尤其是根分區(qū)。這 5% 空間在極端情況下是救命的數(shù)據(jù)盤的保留比例調(diào)低一些倒是無(wú)妨。4.3 掛載點(diǎn)、硬鏈接和稀疏文件的影響再補(bǔ)充幾種導(dǎo)致du和df不一致的情況。掛載點(diǎn)嵌套是最常見的誤判來(lái)源。你明明清理了/data下的一堆文件/data所在分區(qū)空間卻沒(méi)變化那是因?yàn)?data其實(shí)是一個(gè)獨(dú)立掛載的分區(qū)你在/data下清理的文件并不屬于你df -h時(shí)看的那個(gè)分區(qū)。硬鏈接會(huì)讓du重復(fù)計(jì)算。同一個(gè) inode 的同一個(gè)文件被硬鏈接到多個(gè)目錄路徑下du在遍歷每個(gè)路徑時(shí)都會(huì)把這份文件的大小加一遍導(dǎo)致總體統(tǒng)計(jì)結(jié)果比真實(shí)占用偏大。統(tǒng)計(jì)時(shí)若想按真實(shí)文件系統(tǒng)占用算可以用-P參數(shù)不跟隨符號(hào)鏈接但硬鏈接本身造成的重復(fù)統(tǒng)計(jì)沒(méi)有參數(shù)能完全規(guī)避。還有一個(gè)容易忽略的是 NFS 掛載目錄的st_nlink顯示異常。某些網(wǎng)絡(luò)文件系統(tǒng)上du會(huì)遍歷到無(wú)窮無(wú)盡的目錄循環(huán)直接導(dǎo)致du卡死甚至報(bào)錯(cuò)所以遇到 NFS 目錄建議用du -x或者直接跳過(guò)不要硬跑。稀疏文件的例子一個(gè) 10G 的文件實(shí)際磁盤占用可能只有 1G因?yàn)槲募?nèi)部有很多空洞。du統(tǒng)計(jì)的是實(shí)際分配的塊ls -lh顯示的是邏輯大小差距巨大是正常的你不要疑惑是不是統(tǒng)計(jì)錯(cuò)了。5. 更高效的工具與實(shí)用技巧5.1 用 ncdu 做交互式排查如果你完全不想一層層敲命令或者排查的是一個(gè)幾百 G 的大目錄用ncdu體驗(yàn)會(huì)好很多。它是基于ncurses的交互式磁盤占用分析工具安裝特別簡(jiǎn)單# Debian/Ubuntu apt install ncdu # CentOS/RHEL yum install ncdu然后直接執(zhí)行ncdu /var它會(huì)先把目錄結(jié)構(gòu)掃描一遍然后進(jìn)入交互界面直接按大小排序展示所有子目錄和文件。你可以用上下鍵移動(dòng)按回車進(jìn)入子目錄按d刪除當(dāng)前項(xiàng)按g重新掃描。這個(gè)工具在做臨時(shí)上臺(tái)機(jī)器快速排查時(shí)確實(shí)很順手所見即所得。不過(guò)ncdu也有短板它默認(rèn)不會(huì)掃描掛載點(diǎn)之外的文件系統(tǒng)對(duì)于跨分區(qū)的目錄結(jié)構(gòu)你需要在啟動(dòng)時(shí)加參數(shù)或者分多次掃描。另外它掃描大目錄時(shí)耗時(shí)會(huì)比直接du -h --max-depth1長(zhǎng)一些因?yàn)樗峭暾闅v所有子目錄。如果只是想快速看一級(jí)目錄大小我還是推薦命令行du sort的組合。5.2 常用別名與一鍵腳本排查的空間問(wèn)題時(shí)命令敲多了就希望能少敲幾個(gè)字。我習(xí)慣在自己的 shell 配置里加幾個(gè)別名這里直接分享給你alias duddu -h --max-depth1 2/dev/null | sort -hr alias dufdu -sh 2/dev/null alias dfhdf -hT這樣每次排查只需執(zhí)行dud /var dud /home dfh如果你經(jīng)常需要在不同服務(wù)器上處理磁盤問(wèn)題我建議寫一個(gè)簡(jiǎn)單的一鍵定位腳本比如下面這樣的bigfind.sh#!/bin/bash # 使用方式./bigfind.sh /var TARGET${1:-/} du -h --max-depth1 $TARGET 2/dev/null | sort -hr | head -20 echo 文件系統(tǒng)使用情況 df -hT $TARGET這個(gè)腳本會(huì)先列出指定目錄下最大的 20 個(gè)子目錄再顯示對(duì)應(yīng)分區(qū)的整體情況一次執(zhí)行就能同時(shí)完成“目錄內(nèi)定位”和“分區(qū)整體判斷”兩個(gè)任務(wù)。5.3 用 --exclude 和 -t 過(guò)濾掉不關(guān)心的目錄在實(shí)際的日志服務(wù)器上最容易占空間的通常是固定路徑比如/var/log、/tmp、某個(gè)應(yīng)用緩存目錄。如果你只是想找出那些不常規(guī)的大目錄可以用--exclude把已知的大目錄跳過(guò)du -h --max-depth1 / --exclude/proc --exclude/sys --exclude/data --exclude/var/cache 2/dev/null | sort -hr | head -20這樣可以把旅行加速的重點(diǎn)放在還沒(méi)排查過(guò)的目錄上。另外還有一個(gè)-t參數(shù)只顯示大于指定大小的目錄比如du -h -t 1G / 2/dev/null | sort -hr只輸出超過(guò) 1G 的目錄對(duì)某些磁盤容量超大的服務(wù)器來(lái)說(shuō)也能減少噪音。5.4 針對(duì)日志目錄的特殊排查技巧日志目錄是磁盤占用的重災(zāi)區(qū)。它的特點(diǎn)是子目錄多、文件名帶日期、且單個(gè)文件可能動(dòng)輒幾十 G。排查日志目錄時(shí)我更喜歡直接列文件而不是列目錄ls -lhS /var/log/*.logls -lhS可以直接按文件大小從大到小列出所有日志文件比先du再逐個(gè)看文件名更直觀。但在日志目錄里發(fā)現(xiàn)有超大日志文件時(shí)并不建議直接對(duì)這個(gè)目錄做rm操作。正確做法是確認(rèn)該日志對(duì)應(yīng)的服務(wù)優(yōu)先考慮# 查看日志服務(wù)是否支持配置 max size 和 rotation # 例如 rsyslog 的配置文件 /etc/logrotate.d/ # 針對(duì)某個(gè)具體 log 可以手動(dòng)觸發(fā) logrotate logrotate -f /etc/logrotate.d/rsysloglogrotate可以在保留最新日志的前提下壓縮和輪轉(zhuǎn)歷史日志避免磁盤空間被一個(gè)單調(diào)增長(zhǎng)的日志文件徹底占滿。在日志文件還在增長(zhǎng)的場(chǎng)景下手動(dòng)rm只是治標(biāo)不治本重點(diǎn)是把輪轉(zhuǎn)策略配置好。6. 常見問(wèn)題速查表與實(shí)操心得6.1 高頻問(wèn)題與解決方案現(xiàn)象可能原因排查命令處理建議du -sh 某目錄結(jié)果很大但df -h分區(qū)明明還很空該目錄在掛載的其他分區(qū)上或存在跨文件系統(tǒng)的目錄df -h 目錄名、mount | grep 目錄名確認(rèn)目錄所在分區(qū)使用du -x跳過(guò)其他文件系統(tǒng)刪除了大文件df -h可用空間沒(méi)增加文件被進(jìn)程持有句柄lsof L1重啟對(duì)應(yīng)進(jìn)程或讓進(jìn)程關(guān)閉文件句柄磁盤容量顯示沒(méi)滿但系統(tǒng)報(bào) No space left on deviceinode 耗盡df -i統(tǒng)計(jì)小文件數(shù)量遷移或清理大量小文件所在目錄du統(tǒng)計(jì)所有目錄總和比df已用量小很多文件系統(tǒng)保留塊、已刪除未釋放空間、隱藏文件被遺漏tune2fs -l /dev/sdaX、du -sh /.*根據(jù)情況處理刪除隱藏目錄或檢查保留塊ncdu顯示某目錄非常大但du -sh顯示不大稀疏文件或符號(hào)鏈接循環(huán)ls -lh、ls -l檢查 inode根據(jù)文件類型對(duì)應(yīng)處理/proc、/sys目錄不能直接 du虛擬文件系統(tǒng)排除這兩個(gè)目錄正常現(xiàn)象不要嘗試清理6.2 我踩過(guò)的一些坑和總結(jié)的經(jīng)驗(yàn)踩坑經(jīng)歷先說(shuō)說(shuō)。有次幫同事排查一臺(tái)編譯機(jī)磁盤 100% 滿所有常規(guī)命令都查不出哪里大。我du --max-depth1逐層看每個(gè)目錄都 正常但加起來(lái)才用了不到 60%。最后用lsof L1才發(fā)現(xiàn)是一個(gè)被刪除的編譯臨時(shí)文件被某個(gè)還開著的進(jìn)程一直占住足足 40G。從那以后我排查磁盤問(wèn)題一定會(huì)把lsof L1納入標(biāo)準(zhǔn)流程而不是最后實(shí)在查不出來(lái)才想到。還有一次是磁盤沒(méi)滿但某個(gè)服務(wù)頻繁宕機(jī)查了半天才發(fā)現(xiàn)是/var目錄下有一個(gè)隱藏的.cache目錄被程序無(wú)限寫入小文件把 inode 耗盡了。所以我現(xiàn)在df -i也基本是必查項(xiàng)。給幾點(diǎn)個(gè)人的實(shí)操建議第一沒(méi)有把握不要?jiǎng)h文件。寧可先du確認(rèn)內(nèi)容看到路徑名里帶tmp、cache、log等明顯標(biāo)識(shí)再根據(jù)自己對(duì)業(yè)務(wù)的了解決定是否清理。第二清理大日志時(shí)推薦truncate而不是rm。對(duì)正在寫入的日志文件執(zhí)行truncate -s 0 文件名能把文件清空但不改變文件路徑和打開的文件句柄相比rm后重新創(chuàng)建要優(yōu)雅得多尤其是服務(wù)進(jìn)程并不支持動(dòng)態(tài)重新打開日志文件的情況。第三謹(jǐn)慎使用rm -rf。每次敲rm -rf之前我都強(qiáng)制自己先cd到絕對(duì)路徑再操作不要用相對(duì)路徑不要帶通配符的模糊匹配去刪。磁盤滿了很急但越急越要冷靜。第四如果你的服務(wù)器有監(jiān)控系統(tǒng)建議對(duì)根分區(qū)和幾個(gè)常用分區(qū)設(shè)置空間使用率告警例如 85% 警告、92% 緊急避免每次都是被動(dòng)的“磁盤滿了才發(fā)現(xiàn)”。這個(gè)話題說(shuō)到底就是把du、df、lsof這三板斧用好再配合一層層下鉆的排查思路。我不太習(xí)慣寫那種華麗的技術(shù)總結(jié)只分享一個(gè)最樸素的心得——遇到磁盤問(wèn)題別慌先看分區(qū)再看目錄最后看文件句柄按這個(gè)順序走大多數(shù)問(wèn)題都能很快定位。下一次你再看到磁盤告警的時(shí)候直接按這篇文章的流程操作就行。