Blog Details

Linux 作業系統 cutexyz > Blog > 伺服器管理 > 伺服器管理必學 100 招|Part 2:磁碟、空間與檔案系統

伺服器管理必學 100 招|Part 2:磁碟、空間與檔案系統

前言
「磁碟空間已滿(Disk Full)」與「檔案節點耗盡(No Space Left on Device – Inodes)」是伺服器維運中最常見的突發災難之一。本篇精選 10 個核心磁碟與檔案系統管理技巧,從快速定位爆量大檔、清空未釋放的幽靈日誌,到 LVM 動態擴容與檔案權限防坑,協助你建立健全的儲存維運機制。

技巧 011:終端視覺化神隊友!用 ncdu 快速揪出吃容量怪獸

  • 痛點場景:
    傳統 du -sh * 指令層次繁瑣,一層層點進去找大檔案耗時費力,且容易遇到權限問題或輸出過多難以閱讀。
  • 解決方案:
    安裝並使用具備文字圖形介面的 ncdu(NCurses Disk Usage):
    sudo apt install ncdu -y
    # 掃描根目錄並排除其他掛載點(如外部硬碟或 NFS)
    sudo ncdu -x /

    在介面中可用方向鍵進入子目錄,按 n 依檔名排序、按 s 依大小排序,按 d 可直接刪除無用檔案。
  • 專家提醒:
    掃描大規模目錄時,可先將掃描結果導出存檔(ncdu -o scan.json /),後續重複分析無需重新讀取硬碟 I/O。

技巧 012:磁碟滿了卻找不到檔案?處理「已刪除但未釋放」的幽靈 Lo

  • 痛點場景:
    df -h 顯示使用率 100%,但用 du -sh 掃遍全硬碟卻只佔用了 40%。通常是因為執行中的程序(如 Nginx、Java 或 Python)依然抓著已刪除檔案的 File Descriptor,導致空間無法歸還。
  • 解決方案:
    使用 lsof 列出被刪除但仍被進程咬住的檔案,並清空該檔案描述符:
    # 找出持有 deleted 檔案的程序與 PID
    sudo lsof +L1 | grep deleted

    # 不必重啟服務,直接對該進程的檔案描述符進行 truncate 清空
    sudo truncate -s 0 /proc/<PID>/fd/<FD_NUM>

  • 專家提醒:
    千萬不要直接 rm 正在寫入的 Log 檔案;日常清空請用 > access.log 或 truncate -s 0 access.log。

技巧 013:空間還有幾十 GB 卻報「Disk Full」?排查 Inode 耗盡

  • 痛點場景:
    磁碟明明還有很多空間,建立新檔案時系統卻跳出 No space left on device。這是因為小檔案過多,將檔案系統的 Inode 編號用光了。
  • 解決方案:
    檢查 Inode 使用百分比,並統計哪一個目錄的小檔案最多:
    # 1. 查看 Inodes 使用率
    df -i

    # 2. 統計當前目錄下各子目錄的檔案數量
    find . -xdev -type d -exec sh -c 'echo "$(find "$1" -maxdepth 1 | wc -l) $1"' _ {} \; | sort -nr | head -n 10
    常見凶手包括:/var/spool/postfix/maildrop(大量失敗信件)、PHP Session 目錄或快取縮圖目錄。批次刪除大量檔案時,使用 find . -type f -delete 比 rm -rf * 更快且不會引發 Argument list too long 錯誤。

  • 專家提醒:
    若你的應用程式天然會產生數百萬個小檔案,格式化硬碟時需指定較高 Inode 比例(如 mkfs.ext4 -i 4096),或是改用 XFS 檔案系統。

技巧 014:Systemd Journal 日誌暴增?設定日誌容量上限

  • 痛點場景:
    許多 Linux 發行版預設允許 systemd-journald 占用最多 10% 的磁碟空間,運作一兩年後 /var/log/journal 常默默吃掉數十 GB。
  • 解決方案:
    立即清理舊日誌,並永久限制最大容量:
    # 1. 立即清除保留超過 7 天以前的日誌
    sudo journalctl --vacuum-time=7d
    # 2. 或立即壓縮日誌至指定大小以下
    sudo journalctl --vacuum-size=1G

    修改 /etc/systemd/journald.conf 永久生效:
    [Journal]
    SystemMaxUse=2G
    SystemMaxFileSize=200M

    重新載入配置:sudo systemctl restart systemd-journald。
  • 專家提醒:
    生產環境建議維持在 1G 到 2G 之間,太小會導致故障發生時找不到昨天的日誌,太大則浪費寶貴磁碟。

技巧 015:多人協作共享資料夾:配置 SetGID 與預設群組繼承

  • 痛點場景:
    在 /var/www/html 或內部共用區中,使用者 A 上傳的檔案群組是 user_a,導致同專案的 user_b 沒有寫入權限,每天都在手動下 chmod 777。
  • 解決方案:
    使用 SetGID(Set Group ID)讓目錄下新建的所有子檔案與目錄,自動繼承父目錄的群組歸屬:
    # 建立專案群組並加入成員
    sudo groupadd webapps
    sudo usermod -aG webapps alice
    sudo usermod -aG webapps bob
    # 設定目錄群組並啟用 SetGID
    sudo chown -R :webapps /var/www/project
    sudo chmod -R 2775 /var/www/project
  • 專家提醒:
    數字 2 代表 SetGID(目錄顯示為 drwxrwsr-x)。配合適當的 umask,日後群組內的任何人上傳檔案,其他人皆能共同讀寫,完全杜絕權限衝突。

技巧 016:防手殘與防止他人刪除:善用 Sticky Bit 與不可變屬性(chattr)

  • 痛點場景:
    公用上傳區如果開了 777 權限,惡意或手殘的使用者可以直接刪除別人上傳的檔案;或是關鍵設定檔(如 /etc/resolv.conf)老是被系統程式暗中洗掉。
  • 解決方案:
    防止非作者刪除(Sticky Bit):
    # 任何人都可寫入,但只有檔案擁有者與 root 能刪除該檔案
    sudo chmod +t /var/shared_uploads
    徹底鎖死不可修改(Immutable 屬性):
    # 加上 +i 屬性,連 root 執行 rm -f 都不允許修改或刪除
    sudo chattr +i /etc/resolv.conf
    # 解鎖時使用 -i
    sudo chattr -i /etc/resolv.conf
  • 專家提醒:
    如果哪天用 root 執行 rm -f 卻回報 Operation not permitted,八成就是檔案被標記了 +i,可用 lsattr <filename> 查看。

技巧 017:避免重開機開天窗!安全編輯 /etc/fstab 與 UUID 掛載

  • 痛點場景:
    使用 /dev/sdb1 寫入 /etc/fstab,伺服器重開機時硬碟代號亂掉變成 /dev/sdc1,或是語法打錯一個字,導致伺服器開機失敗卡在 Emergency Mode(緊急救援模式)。
  • 解決方案:
    永遠使用磁碟的唯一標識符(UUID)進行掛載:
    # 查詢目標分割區的 UUID 與檔案系統型態
    sudo blkid /dev/sdb1
    # 輸出範例:
    UUID="5fa7...-4a12" TYPE="ext4"

    在 /etc/fstab 寫入掛載設定:
    UUID=5fa7...-4a12 /data ext4 defaults,nofail 0 2

    重開機前必測驗證指令:
    sudo mount -a

  • 專家提醒:
    加入 nofail 參數是關鍵防線!若該外接硬碟暫時斷線,伺服器仍能正常開機,不會整台卡死在啟動流程。若 mount -a 出現任何錯誤,絕不要重開機,立刻修正。

技巧 018:磁碟不夠用了?LVM 線上動態擴容實戰(零停機擴充)

  • 痛點場景:
    雲端硬碟掛載點滿了,雖然在雲端控制台(AWS / GCP)將 EBS/硬碟擴充了 50GB,但進入 Linux 系統查看,容量依然沒有變大。
  • 解決方案:
    利用 LVM 與檔案系統線上動態擴容,完全不用停機重啟:
    # 1. 讓核心重新辨識物理磁碟新大小
    sudo growpart /dev/vda 1

    # 2. 若為 LVM 架構,擴展物理卷(PV)與邏輯卷(LV)
    sudo pvresize /dev/vda1
    sudo lvextend -l +100%FREE /dev/ubuntu-vg/ubuntu-lv

    # 3. 線上擴展檔案系統(ext4 專用)
    sudo resize2fs /dev/ubuntu-vg/ubuntu-lv

    # 若為 XFS 檔案系統則改用:
    # sudo xfs_growfs /

  • 專家提醒:
    XFS 只能線上擴大不能縮小;ext4 支援擴大與縮小,但縮小必須離線操作。生產環境擴容永遠只建議「往上加」。

技巧 019:實用應急解法!在磁碟上快速建立 Swap 虛擬記憶體

  • 痛點場景:
    在 1GB RAM 的低配主機編譯程式(如 npm run build)或啟動大型資料庫時,頻繁觸發 OOM Killer(Out of Memory)導致行程直接被殺。
  • 解決方案:
    在沒有專用 Swap 分割區的情況下,直接用檔案建立 2GB 的 Swap Space:
    # 1. 建立一個 2GB 的連續空檔案(fallocate 極快)
    sudo fallocate -l 2G /swapfile

    # 2. 嚴格鎖定權限,僅允許 root 存取
    sudo chmod 600 /swapfile

    # 3. 格式化為 Swap 並啟用
    sudo mkswap /swapfile
    sudo swapon /swapfile

    寫入 /etc/fstab 確保開機持續生效:
    /swapfile none swap sw 0 0

  • 專家提醒:
    透過 cat /proc/sys/vm/swappiness 可以查看 Swap 活躍度(預設通常為 60)。生產環境建議設為 10 到 20(sysctl vm.swappiness=15),僅在記憶體真正吃緊時才借用硬碟,避免硬碟 I/O 拖垮整體速度。

技巧 020:善用 rsync 增量同步與斷點續傳(優於 scp)

  • 痛點場景:
    用 scp 複製數十 GB 的資料夾,網路中斷後必須整包重傳;或是搬家時不知道如何保持檔案的原始權限與時間戳記。
  • 解決方案:
    使用 rsync 進行高效增量傳輸:
    # -a: 歸檔模式(保留權限、擁有者、時間戳與軟連結)
    # -v: 顯示詳細歷程
    # -z: 傳輸時壓縮
    # -P: 顯示進度條(Progress)並支援斷點續傳(Partial)
    rsync -avzP -e "ssh -p 22222" /local/backup/ user@remote:/remote/backup/

    若要讓兩端完全同步並鏡像一致(遠端若有多出的檔案自動刪除):
    rsync -avzP --delete /source/ /destination/

  • 專家提醒:
    來源目錄尾端的斜線非常重要!/source/ 代表「同步該目錄下的所有內容」;/source(無斜線)代表「把 source 資料夾本身複製過去」。先加上 --dry-run 模擬測試可以防範路徑寫錯的悲劇。

Leave A Comment

All fields marked with an asterisk (*) are required