SSD Nodes Learn 🎉 VPS $5.50/月起
指南 Matt Connor作者: Matt Connor · 已更新 2026-08-13

VPS 磁碟健康監控:SMART 看不到時怎麼辦

多數 VPS 的磁碟是虛擬裝置,SMART 無法傳到 guest。了解可監控的 4 種訊號,以及如何在 I/O 失敗前設定警示。

VPS 上的磁碟健康監控實際能看見什麼

VPS 上的磁碟健康監控,必須先了解多數指南避而不談的事實:磁碟不屬於你。你的 guest 看到的是虛擬區塊裝置。實體磁碟及其儲存的所有計數器都屬於 host。smartctl /dev/vda 失敗不是因為你輸入的 command 錯誤,而是因為該裝置背後沒有任何元件能回答這個問題。

SMART(自我監控、分析與報告技術)是儲存在磁碟本身的計數器表格,包含重新配置的磁區、待處理磁區、通電時數與媒體錯誤。讀取這份表格需要讓 ATA 或 NVMe(非揮發性記憶體 express)command 連線到實體硬體。半虛擬磁碟不提供這條路徑,因此 guest 取得的是已移除遙測資料的儲存裝置。

租戶監控的是影響,而不是硬體。在 guest 內部可以看見 4 種訊號:kernel log 中的 I/O(輸入/輸出)錯誤、重新掛載為唯讀的 filesystem、逐漸上升的延遲,以及耗盡的空間。這 4 種訊號今天都能設定警示,而且都會在使用者提出抱怨前出現。請先設定這些監控。責任分界會在最後說明,因為它會改變你應該投入心力的地方。

確認自己的伺服器實際暴露的內容

不要假設自己屬於哪種情況。先查看結果,再閱讀相符的段落。

sudo apt update && sudo apt install -y smartmontools nvme-cli
lsblk -o NAME,TYPE,SIZE,MODEL,TRAN
sudo smartctl -a /dev/vda

virtio-blk,一般的 KVM (kernel-based virtual machine) 磁碟。 裝置是 /dev/vda,而 smartctl 在送出任何內容前就停止:

/dev/vda: Unable to detect device type
Please specify device type with the -d option.

virtio-blk 是半虛擬化傳輸,後方沒有 ATA 或 SCSI 命令集,因此沒有可傳送 SMART 請求的通道。-d sat-d scsi 也會以相同方式失敗,因為問題出在傳輸方式,而不是旗標。

模擬的 SATA 或 SCSI 磁碟。 裝置是 /dev/sda,而 smartctl 已能執行到識別裝置的階段。模型列顯示 QEMU HARDDISK。這段字串本身就能回答問題:你讀取的是模擬器建立的裝置,而且該裝置回報沒有可用的 SMART 功能。

NVMe namespace。 sudo nvme smart-log /dev/nvme0n1 會回傳完整日誌,這正是容易誤判的地方。先使用 sudo nvme id-ctrl /dev/nvme0 | grep -E '^(mn|sn)' 檢查控制器識別資訊。如果模型編號顯示的是網路儲存產品,表示控制器是軟體實作,因此 percentage_usedmedia_errors 描述的是該模擬層,而不是儲存資料的 flash。若要確認實際使用的儲存裝置,請改為在 Linux 上驗證 NVMe 磁碟,不要只相信方案說明。

容器,例如 LXC (Linux containers) 或 OpenVZ。 你沒有自己的區塊裝置。lsblk 會顯示主機的裝置,或完全不顯示任何內容;smartctl 會被拒絕,因為容器不具備 CAP_SYS_RAWIO

Smartctl open device: /dev/sda failed: Permission denied

另外提醒一種 smartctl 確實能運作的情況。如果 VPS 上的 smartctl 回傳完整的屬性表,請先查看序號,再採取行動。有些主機會暴露直通裝置節點,而其中的計數器屬於該機器上所有租戶共用的硬體。那裡的 Reallocated_Sector_Ct 上升時,應建立支援請求。這不代表你的資料有問題。

核心訊號 1:核心日誌中的 I/O 錯誤

這是租戶能取得的最高價值訊號,而且不需要安裝 agent。

sudo journalctl -k -p err -b
sudo journalctl -k --since "7 days ago" | grep -iE 'i/o error|remount|ext4-fs error|buffer i/o'

虛擬磁碟傳回失敗的請求時,內容如下:

blk_update_request: I/O error, dev vda, sector 2101248 op 0x1:(WRITE) flags 0x800 phys_seg 1 prio class 0

block layer 向主機要求寫入,但主機傳回失敗。在 VPS 上,這很少是即將故障的 flash cell。通常是主機的儲存層,或通往 network attached storage 的網路路徑發生問題,因此屬於 provider 端事件。請將時間戳記、裝置名稱與 sector 複製到 ticket 中,因為 storage team 可用這些資訊比對自己的日誌。

最需要注意的 ext4 序列是以下這一對:

EXT4-fs error (device vda1): ext4_journal_check_start:83: comm cron: Detected aborted journal
EXT4-fs (vda1): Remounting filesystem read-only

第二行才是最嚴重的問題,因為機器仍維持運作。它會回應 ping,也會回應 SSH,但每次寫入都失敗。一般的 HTTP 檢查仍會通過,但應用程式會在每個請求中拋出錯誤。

XFS 則會直接關閉檔案系統:

XFS (vda1): metadata I/O error in "xfs_trans_read_buf_map+0x1c0/0x2e0" at daddr 0x2 len 1 error 5
XFS (vda1): I/O Error Detected. Shutting down filesystem

journalctl -k 只會讀取目前的 boot,除非 journal 已儲存在磁碟上;而許多 image 會使用儲存在 RAM 中的 volatile journal。請啟用 persistence,否則你在疑難排解期間執行重新開機時,證據正好會消失。

sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journald
journalctl --list-boots

下次重新開機後,journalctl --list-boots 應列出不只一個 boot。即使已啟用 persistence,已切換為 read-only 的檔案系統也無法記錄後續發生的事件,因此應將日誌傳送到主機之外。

偵測唯讀重新掛載

在嘗試偵測失敗之前,先讓失敗明確呈現。

findmnt -no SOURCE,FSTYPE,OPTIONS /

查看選項中是否有 errors=remount-ro。Ubuntu 和 Debian 的 cloud image 會在 /etc/fstab 中設定它,因此發生 metadata 錯誤時,檔案系統會切換為唯讀,而不是繼續在損壞狀態下運作。如果缺少此選項,請將它加入 /etc/fstab 的 root 項目,或使用 sudo tune2fs -e remount-ro /dev/vda1 將它寫入 superblock。明確停止比靜默損毀更安全。

mount flag 不是證據。請透過寫入進行測試:

touch /var/tmp/.disk-probe

在唯讀的 root 上,輸出會完全是:

touch: cannot touch '/var/tmp/.disk-probe': Read-only file system

請使用 /var/tmp,不要使用 /tmp。在大多數 image 中,/tmp 是保存在記憶體中的 tmpfs,因此在該位置成功寫入,無法證明磁碟正常。

將寫入測試與空間檢查放在一起,只有所有檢查都通過時才送出 heartbeat:

sudo tee /usr/local/sbin/disk-probe >/dev/null <<'EOF'
#!/bin/sh
set -eu
probe=/var/tmp/.disk-probe
echo ok > "$probe"
test "$(cat "$probe")" = ok
rm -f "$probe"
used=$(df --output=pcent / | tail -n1 | tr -dc '0-9')
test "$used" -lt 90
inodes=$(df --output=ipcent / | tail -n1 | tr -dc '0-9')
test "$inodes" -lt 90
curl -fsS --max-time 10 "https://status.example.com/api/push/REPLACE_TOKEN?status=up&msg=OK" >/dev/null
EOF
sudo chmod 755 /usr/local/sbin/disk-probe
sudo /usr/local/sbin/disk-probe && echo probe-ok

最後一行中的 probe-ok 表示整個鏈結都能正常執行。set -eu 會讓任何失敗的檢查以非零狀態結束,因此不會執行 curl 那一行,也不會送出 heartbeat。這種反轉正是重點:因為沒有收到任何訊號,監控器會變成紅色;而無法寫入的伺服器,無法可靠地描述自己的問題。唯讀檔案系統仍可讀取,因此腳本本身仍會啟動。

透過 systemd timer 執行它。

# /etc/systemd/system/disk-probe.service
[Unit]
Description=Disk writability and space probe

[Service]
Type=oneshot
ExecStart=/usr/local/sbin/disk-probe
# /etc/systemd/system/disk-probe.timer
[Unit]
Description=Run the disk probe every five minutes

[Timer]
OnBootSec=2min
OnUnitActiveSec=5min

[Install]
WantedBy=timers.target
sudo systemctl daemon-reload
sudo systemctl enable --now disk-probe.timer
systemctl list-timers disk-probe.timer
journalctl -u disk-probe.service -n 20 --no-pager

systemctl list-timers 應顯示該 unit,並顯示距離目前不到 5 分鐘的 NEXT 時間。失敗的執行結果會出現在 journalctl -u disk-probe.service,其中包含 shell 自身的錯誤文字,因此不必登入伺服器,也能區分檔案系統唯讀與磁碟已滿。

該 push URL 是 Uptime Kuma 的 push monitor。建立 Push 類型的 monitor,將其 token 複製到腳本中,並將 monitor 的 heartbeat interval 設定得比 timer interval 稍長,避免某次執行較慢而在 03:00 觸發通知。如果你還沒有 status page,自架的 Uptime Kuma instance 是放置這項檢查最經濟的選擇。

有兩項限制需要如實說明。這項測試能確認寫入已被接受,但不能確認位元組已到達持久性儲存,因為讀回結果可能來自 page cache。它也在被監看的機器上執行,因此完全失去回應的伺服器只會停止傳送訊號,不會回報診斷結果。

root 檔案系統已經是唯讀時的處理方式
  1. 確認狀態。findmnt -no OPTIONS / 會以 ro 開頭。
  2. 先將證據保存到 RAM:journalctl -k -b > /dev/shm/kernel.log,然後使用 scp user@server:/dev/shm/kernel.log . 從筆電將資料取回伺服器外部。
  3. 不要直接執行 mount -o remount,rw / 後繼續操作。如果 ext4 已中止 journal,重新掛載會立即再次失敗;即使重新掛載成功,也等於在尚未檢查的損壞區域上繼續寫入。
  4. 重新開機進入 provider 的 rescue mode,並在檔案系統尚未掛載時進行檢查:ext4 使用 e2fsck -fy /dev/vda1,XFS 使用 xfs_repair /dev/vda1
  5. 將含有時間戳記與 sector 的 blk_update_request 那一行提供給 provider。
  6. 從 backup 還原並進行比對,因為需要修復的檔案系統可能已遺失近期寫入內容的尾端。

延遲與吞吐量趨勢

sudo apt install -y sysstat
iostat -xdz 5 3

先查看 r_awaitw_await。這兩項是讀取或寫入所需的平均毫秒數,包含在佇列中等待的時間。接著查看 aqu-sz,即目前處理中的平均請求數。在虛擬磁碟上,請忽略 %util:它只表示佇列不是空的;能平行處理許多請求的裝置,即使遠未達到上限,也可能接近 100%。await 才是反映使用者體感的數值。

絕對值的重要性低於自身的基準值,因此請記錄一段安靜時段的數據並保留。若要自行收集計數器,/proc/diskstats 是原始資料來源。

若要進行刻意測量:

sudo apt install -y fio
fio --name=readlat --filename=/var/tmp/fio.probe --size=512M --rw=randread --bs=4k --iodepth=1 --direct=1 --runtime=30 --time_based --group_reporting
rm -f /var/tmp/fio.probe

查看 clat percentiles 區塊,尤其是第 99 百分位數。--direct=1 會略過頁面快取,但不會略過主機的快取,因此結果反映從程序到平台儲存設備的完整路徑。請在伺服器閒置時執行,因為這項測量會與自身的工作負載競爭。

若核心日誌沒有錯誤,但 await 持續上升,通常不是磁碟故障,而是主機上的資源競爭。這是儲存層面對應於 吵雜鄰居造成的 CPU steal time 的情況。如果它每天都在相同時段恢復,而你的 ticket 檢查結果正常,答案通常是改用 I/O 不以相同方式共用的方案;當工作負載受磁碟限制時,儲存 VPS 相較於一般 VPS 就屬於這種情況。

掛載狀態下可執行的檔案系統檢查

ext4 會在 superblock 中保存錯誤計數器。即使日誌已遺失,這項資訊在重新開機後仍會保留。

sudo dumpe2fs -h /dev/vda1 2>/dev/null | grep -iE 'filesystem state|error count|first error|last error'

狀態正常的檔案系統會輸出 Filesystem state: cleanFS Error count: 0clean with errors 或非零計數表示 kernel 曾發生 metadata 錯誤,即使當時無人察覺,且日誌已輪替移除。這個指令應列入每週檢查。

你無法對已掛載的 root filesystem 執行 fsck,而在運作中的檔案系統上執行 e2fsck -n,只會回報因底層資料持續變更而產生的問題。若要強制執行完整檢查,請從 provider 的主控台,在 kernel command line 加入 fsck.mode=force fsck.repair=yes,讓系統以此參數開機一次。接著,systemd-fsck 會在 root 以 read-write 模式掛載前執行檢查。

XFS 沒有 online check。xfs_repair -n /dev/vda1 拒絕對已掛載的檔案系統執行,因此應在 rescue mode 中使用。XFS 會以明確的方式處理 metadata 錯誤:關閉檔案系統,而不是繼續運作。

Btrfs 內建持久化的計數器。

sudo btrfs device stats /
sudo btrfs scrub start -B /

write_io_errscorruption_errs 大於零表示確實發生過事件。除非重設計數器,否則其數值會在重新開機後保留。scrub 會重新讀取每個 block 並驗證其 checksum,是虛擬磁碟上最接近媒體測試的方式。這項操作會大量使用 I/O,因此請安排在系統負載較低的時段執行。

訊號5:可用空間,包括 df 隱藏的部分

磁碟空間耗盡對伺服器造成的影響,與磁碟故障相同,而且發生頻率高得多。

df -h /
df -i /
sudo du -xh --max-depth=1 / | sort -h | tail -n 20

No space left on device,而 df -h 顯示可用空間時,表示耗盡的是 inode,而不是位元組;df -i 則顯示 IUse% 已達100%。快取目錄或郵件佇列中有數百萬個小檔案時,就會發生這種情況。刪除大型檔案無法解決問題。

刪除檔案後空間沒有釋放,通常是因為執行中的程序仍開啟該檔案。sudo lsof +L1 會列出連結計數已降為0的檔案。重新啟動持有該檔案的程序即可釋放空間。

journal 是常見且不易察覺的空間消耗來源。journalctl --disk-usage 會回報其佔用空間。先在 /etc/systemd/journald.conf 中使用 SystemMaxUse=200M 設定上限,再執行 sudo systemctl restart systemd-journald;若要立即回收空間,請使用 sudo journalctl --vacuum-size=200M

有一種情況看似錯誤,但其實不是。在精簡配置的主機儲存空間上,主機的儲存池可能已滿,但你的 df 仍顯示有數 GB 的可用空間。此時寫入會失敗,核心日誌中會出現 I/O 錯誤,但 guest 內部不會顯示任何空間不足警告。檔案系統未滿卻發生錯誤時,應在同一小時內提報支援案件。

將訊號接入 metrics agent

push probe 只能回答是或否。要觀察趨勢,必須使用 metrics agent;Prometheus node_exporter 已經匯出上述所有資訊,無須額外設定。可使用下列 metric 名稱建立規則:

  • node_filesystem_readonly 在掛載點變成唯讀時會設為 1,可用來觸發重新掛載警報。
  • node_filesystem_avail_bytesnode_filesystem_files_free 分別涵蓋 bytes 與 inodes。
  • node_disk_io_time_seconds_totalnode_disk_read_time_seconds_total 提供 busy time 與 latency 計數器,可繪製圖表。

以下 2 個規則可捕捉真正需要觸發分頁通知的情況:

- alert: FilesystemReadOnly
  expr: node_filesystem_readonly{fstype!~"tmpfs|overlay"} == 1
  for: 2m
- alert: FilesystemFillingUp
  expr: predict_linear(node_filesystem_avail_bytes{mountpoint="/"}[6h], 4*24*3600) < 0
  for: 30m

當前趨勢在 4 天內降至 0 時,第 2 個規則會觸發。如此可提前數天收到警告,不必等到使用率達到 95% 時才處理;屆時可能只剩幾分鐘。

誰負責什麼

您的供應商負責實體磁碟。他們讀取 SMART、管理磁碟陣列,並在磁碟的重新配置磁區持續增加時更換磁碟,通常不會通知您,因為陣列會吸收這項故障。這就是 VPS 下方的 RAID 10 的用途:磁碟故障時進行重建,而不是造成服務中斷。您無法查看這些作業,而租用虛擬伺服器的主要價值之一,就是付費取得這層抽象化管理。

您負責自己的資料,而磁碟遙測本來也無法保護資料。真正會摧毀租戶資料的事件包括錯誤的 rm、有問題的部署、持有您 SSH key 的入侵者,以及連同磁碟陣列一起受影響的平台事故。SMART 屬性無法預測其中任何一項。

因此,租戶真正的防護措施,是將備份存放在伺服器之外,並由您親自執行過還原。供應商快照很方便,而且與受保護的對象位於同一平台;這就是為什麼 快照與備份是不同的防護措施。請在行事曆中安排演練:每季一次,將最新備份還原到新的 VPS,啟動應用程式,並記錄所需時間。這個數字才是您的實際復原時間。第一次演練所需時間一定比任何人預期的更久。

SMART 適用於你的情況

介紹 smartctl 的指南並沒有錯。只要硬體確實由你管理,就適用於下列情況:

  • 專用或 bare metal 伺服器,其中 sudo smartctl -a /dev/sda 會回傳完整的屬性表,而 smartd 可在屬性變更時寄信通知你。
  • 能將實體磁碟直通給 guest 的儲存方案。供應商會明確說明這點,因為它是銷售賣點。
  • 你在家中或租用的機架空間內所擁有的硬體。
  • 位於 RAID controller 後方、可透過 sudo smartctl -a -d megaraid,0 /dev/sda 存取的磁碟,或使用 -d sat 的 USB 外接盒。

在實體 NVMe 上,sudo smartctl -a -d nvme /dev/nvme0sudo nvme smart-log /dev/nvme0n1 會直接從磁碟回報 critical_warningpercentage_used。在實體 SATA 上,最能預測故障的屬性是 Reallocated_Sector_Ct (5)、Current_Pending_Sector (197)、Offline_Uncorrectable (198) 和 Reported_Uncorrect (187)。其中任何一項不再是零,都表示應規劃更換磁碟。大規模磁碟研究一再得到相同的精簡清單,多數其他屬性都只是雜訊。

請執行 daemon,而不是手動檢查。

sudo systemctl enable --now smartd
sudo smartctl -t short /dev/sda
sudo smartctl -l selftest /dev/sda

自我測試日誌應顯示你剛啟動的那次執行結果為 Completed without error。截至 August 2026,Ubuntu 和 Debian 會隨附含有 DEVICESCAN 行的 /etc/smartd.conf,因此 daemon 會處理它能看到的每個磁碟,並在屬性變更時寄信給 root。虛擬磁碟無法使用這些功能,因此本指南的其餘內容才有必要。

FAQ

為什麼 smartctl 在我的 VPS 上無法運作?

因為磁碟是虛擬的。在使用 virtio-blk 的 KVM guest 上,smartctl -a /dev/vda 會輸出 /dev/vda: Unable to detect device type,因為半虛擬化磁碟沒有可供 SMART 請求傳遞的 ATA 或 SCSI 命令通道。在模擬磁碟上,你接觸到的裝置型號會顯示 QEMU HARDDISK,但其背後沒有可用的 SMART 資料。在容器內,smartctl 會因缺少 CAP_SYS_RAWIO 而直接遭拒。這些都不是設定錯誤,也沒有任何 -d 旗標能修正。

如何知道 VPS 的磁碟是否故障?

請監看影響,而不是硬體狀態。檢查 sudo journalctl -k -p err -b 是否有 blk_update_request: I/O error 行,以及是否出現 Remounting filesystem read-only。執行 sudo dumpe2fs -h /dev/vda1 | grep -i 'error count',找出日誌已遺失的錯誤。追蹤 iostat -xdz 5 中的 r_await,並與系統正常時記錄的基準值比較。在 VPS 上,I/O 錯誤通常表示主機儲存設備有問題,而不是磁碟即將故障。因此,應將時間戳記與磁區資訊附在支援工單中一併提供。

VPS 磁碟健康狀態應設定哪些告警?

設定 4 種告警即可涵蓋主要情況。檔案系統以唯讀方式掛載,可能是由 node_filesystem_readonly == 1 觸發,或是寫入探測失敗。可用空間與可用 inode 持續接近 0。最近一個監控區間內出現任何核心 I/O error。伺服器的 heartbeat,讓伺服器停止回應時能透過無回應告警通知你。不要使用任何源自 SMART 的資料,因為在虛擬磁碟上,這些值不是不存在,就是描述 hypervisor 的模擬狀態。

為什麼檔案系統會重新掛載為唯讀?

使用 errors=remount-ro 掛載的 ext4 遇到中繼資料錯誤時,會刻意這樣處理:停止寫入,而不是繼續覆寫損壞內容。觸發原因位於核心日誌中重新掛載訊息的上一段,通常是底層裝置回傳 I/O 錯誤後,日誌出現關於中止日誌的 EXT4-fs error。未檢查檔案系統就重新掛載為讀寫,會掩蓋症狀並保留根本原因。先保存日誌,再從 rescue mode 卸載檔案系統,使用 e2fsck -fy /dev/vda1 進行檢查。

在虛擬伺服器上是否有可能讀取 SMART 資料?

在特定情況下可以。Dedicated server 與 bare metal server 會提供實際的硬體屬性。將實體磁碟直通給 guest 的儲存方案,以及由你自行管理的主機也可以。有些平台會將 NVMe 控制器呈現給 guest,且 nvme smart-log 會回傳日誌,因此請先執行 sudo nvme id-ctrl /dev/nvme0:如果型號名稱指向網路儲存服務,表示這些計數器來自軟體控制器。此外,在共用機器上,即使直通節點確實提供實際計數器,這些資料描述的也是與其他租戶共用的硬體,因此唯一有用的處置是提交支援工單。