紀錄工作經驗、相關知識,解決技術相關問題。

資訊相關

CrystalDiskInfo Reallocated Sectors Count 磁區重分配過高黃色警告排查與備份

CrystalDiskInfo Reallocated Sectors Count 磁區重分配過高黃色警告排查與備份 特色圖片

工程師與 IT 維運人員在日常巡檢時,最不願意看到的莫過於儲存裝置監控工具突然跳出黃色警示。當 CrystalDiskInfo Reallocated Sectors Count 的原始值不再是 0、健康狀態變成黃色「警告」時,代表硬碟韌體已經把讀寫有問題的磁區換成備用磁區(spare sector)。這時第一件事是評估風險並備份資料,而不是急著修復。想了解基礎硬碟選型差異可前往 〈快速查看 WD 硬碟差異:藍標、黑標、紅標、紫標、金標對照表〉 觀看。本篇拆解 SMART 數值背後的意義,並整理資料搶救與檢測排查流程。

想直接查看生產環境的備份策略與磁區轉移指令可跳至 #examples。


一、 核心速查與常見瓶頸對照

CrystalDiskInfo 的磁碟健康狀態分為「良好」(藍色)、「警告」(黃色)、「不良」(紅色)與「未知」(灰色)。傳統硬碟(HDD)由「良好」轉為黃色「警告」,依官方說明是看 3 個屬性的原始值:05 Reallocated Sectors Count、C5 Current Pending Sector Count、C6 Uncorrectable Sector Count,任一個原始值達到「警告臨界值」就會亮黃燈。

這個臨界值可以在選單「功能 → 進階功能 → 磁碟健康狀態設定」逐顆調整,預設值全部是 1,設為 0 代表忽略該屬性。也就是說,在預設設定下,只要出現 1 個重新配置磁區就會顯示「警告」。

1. 常見錯誤寫法的工程瓶頸

  • 在有讀取錯誤的硬碟上直接跑 CHKDSK 或檔案系統修復:GNU ddrescue 手冊明確提醒,不要在有 I/O 錯誤的硬碟上修復檔案系統,否則很可能損失更多資料。正確順序是先把資料映像到另一顆健康的硬碟,再對複本做修復。
  • 把臨界值調高或設為 0 來消除黃燈:在「磁碟健康狀態設定」把數值改掉,只是讓 CrystalDiskInfo 不再對該屬性發出警告,硬碟回報的原始值不會改變,已經換掉的磁區也不會恢復。
  • 未區分待處理磁區與已重新配置磁區:C5 代表硬碟讀取失敗、等著重新配置的磁區,裡面的資料目前讀不出來;如果直接寫入覆蓋,資料就會遺失。應先備份,再決定後續處理。

2. 核心機制規格對照表

SMART 屬性程式碼與名稱原始數值 (Raw Value) 意義CrystalDiskInfo 判定(HDD)應對處理與風險評估
05 Reallocated Sectors Count(正體中文介面:重新配置磁區數量)已被換成備用磁區的磁區數原始值 ≥ 警告臨界值(預設 1)顯示黃色「警告」磁區已經出現讀寫問題,應立即規劃資料備份與硬碟汰換。
C5 Current Pending Sector Count(等待重新配置的磁區)讀取失敗、等待重新配置的磁區數同上這些磁區上的資料目前讀不出來,先用映像工具搶救其他資料。
C6 Uncorrectable Sector Count(無法修正的磁區)離線掃描或自我檢測時讀不出來的磁區數同上若該磁區存有資料,讀取時會失敗,需依賴備份還原。

另外,任一屬性的正規化目前值(Current)低於廠商設定的臨界值(Threshold)時,CrystalDiskInfo 會判定為紅色「不良」,這和上面以原始值判定的黃色「警告」是兩套不同的規則。


二、 關鍵機制解析:底層規範與注意事項

硬碟的 SMART(Self-Monitoring, Analysis and Reporting Technology)屬性由硬碟韌體維護,CrystalDiskInfo 與 smartctl 這類工具負責讀出並顯示。依 smartmontools 文件的說明,待處理磁區(pending sector)通常是電腦讀取某個磁區時,因資料損毀、錯誤檢查與校正碼(ECC)對不上而讀取失敗,硬碟就把它記為想要標成壞軌並重新配置的磁區。

1. 磁區重新配置與資料遺失的關係

對待處理磁區寫入資料,通常會讓硬碟改用一個好的備用磁區取代它,代價是原本那個磁區裡的資料(512 位元組)就此遺失。換句話說,05 原始值增加代表已有磁區被換掉;C5、C6 不為 0 則代表目前仍有讀不出來的資料。smartmontools 的 smartd 也提醒,部分硬碟在磁區重新配置後並不會把 C5 或 C6 歸零,所以看到這兩個數字沒有下降,不一定代表問題還在擴大,要和 05 一起觀察變化趨勢。

2. 跨世代儲存介質的差異:傳統 HDD 與固態硬碟 (SSD)

CrystalDiskInfo 對 SSD 採用不同的判定方式:官方說明的 SSD 規則是剩餘壽命(Remaining Life)小於等於 10% 顯示「警告」、低於廠商定義的臨界值顯示「不良」。從 CrystalDiskInfo 原始碼也可以看到,05、C5、C6 的原始值警告判定只套用在非 SSD 的磁碟上。因此,同樣看到 05 欄位有數字,HDD 會亮黃燈,SSD 則要回到剩餘壽命與各廠商的屬性定義來判斷,不能直接套用 HDD 的標準。


三、 實作範本:生產環境完整程式碼

面對 Reallocated Sectors Count 異常的硬碟,如果作業系統複製檔案時一直卡住或出現讀取錯誤,應改用會略過壞軌、優先搶救好資料的映像工具。以下提供 Linux 環境下使用 GNU ddrescue 進行映像備份的指令範本,以及用 Python 呼叫 smartctl 定期檢查 SMART 狀態的監控腳本。

範本一:使用 ddrescue 進行兩階段磁區映像備份

GNU ddrescue 的演算法分為複製(copying)、修剪(trimming)、掃掠(sweeping)、刮取(scraping)與重試(retrying)五個階段,並用 mapfile 記錄每個區塊的搶救狀態,中斷後可以接續執行、不會重複複製已完成的部分。下面照官方手冊範例的做法分成兩次執行:第一次加 -n 跳過最耗時的刮取階段,先救出容易讀的資料;第二次再用直接磁碟存取與重試處理困難區域。

# 安裝 GNU ddrescue(Debian / Ubuntu 的套件名稱為 gddrescue)
sudo apt-get update && sudo apt-get install -y gddrescue

# 將損壞硬碟 /dev/sdb 映像到另一顆健康硬碟上的 /mnt/backup,並以 mapfile 記錄進度
# 第一次:-n 跳過刮取(scraping)階段,先搶救容易讀取的區域
sudo ddrescue -n /dev/sdb /mnt/backup/damaged_disk.img /mnt/backup/rescue.map

# 第二次:沿用同一個 mapfile,只處理第一次沒救回的區域
# -d:使用直接磁碟存取(O_DIRECT),繞過核心快取
# -r3:對壞磁區最多再做 3 輪重試
sudo ddrescue -d -r3 /dev/sdb /mnt/backup/damaged_disk.img /mnt/backup/rescue.map

執行前確認來源硬碟沒有被掛載:手冊建議要搶救的裝置或分割區最好完全不要掛載,連唯讀掛載都不要。映像完成後,再對映像檔(不是原硬碟)做檔案系統檢查與檔案救援。

下圖是在 Ubuntu 24.04(WSL 2)的 GNU ddrescue 1.27 上,以 64 MiB 的一般檔案 src.img 取代硬碟,依序執行上面兩段指令的輸出:第一次 -n 把 64 MiB 全數救回並寫入 mapfile,第二次 -d -r3 讀到 mapfile 的「Initial status」,已救回的區塊不再重讀。-d 對一般檔案也能正常執行,最後 cmp 比對來源與映像內容一致。

ddrescue 兩次執行的終端輸出內容

Ubuntu 24.04(WSL 2)、GNU ddrescue 1.27,來源與目的皆為一般檔案,輸出已省略部分進度行。

輸出畫面可以抓三個重點來判讀:

  1. rescued 是已經救回的資料量,pct rescued 是占總量的百分比;兩者隨進度增加,救完時是 100.00%。
  2. bad-sector 與 read errors 是還讀不出來的區域與讀取錯誤次數。來源是健康的一般檔案時兩者都是 0;面對真正有壞磁區的硬碟,這兩欄不為 0 才是需要後續重試的部分。
  3. 第二次執行開頭的 Initial status (read from mapfile) 表示 ddrescue 讀回上次寫入的進度,所以兩次執行必須使用同一個 mapfile 檔名;換了檔名,它就當作全新的救援從頭開始。

mapfile 本身是純文字檔,標頭記錄執行時的指令與起訖時間,狀態欄位的 + 代表該區塊已經救回。上面的範例結束後,mapfile 只剩一行 0x00000000 0x04000000 +,也就是從位移 0 開始的 0x04000000 位元組(64 MiB)全部標為已救回。真正救援壞硬碟時,這個檔案會出現多段不同狀態的區塊,把它和映像檔一起保存,之後才能繼續處理剩下的區域。

另外,圖中第一次執行只出現「Pass 1 (forwards)」的複製階段就結束,因為來源沒有任何讀取錯誤,不需要進入修剪、掃掠這些處理壞區域的階段。

範本二:Python 腳本結合 SMART 狀態檢測與防禦通知

腳本呼叫 smartctl -A -j 取得 JSON 格式的屬性表,讀出 05、C5(ID 197)、C6(ID 198)的原始值,判定方式比照 CrystalDiskInfo 的預設警告臨界值 1。需要先安裝 smartmontools,Linux 上以 root 權限執行;這段只處理 ATA/SATA 硬碟的屬性表,NVMe SSD 沒有這張表。

import json
import subprocess
import sys

# 與 CrystalDiskInfo「磁碟健康狀態設定」的預設警告臨界值相同
CAUTION_THRESHOLD = 1
WATCH_ATTRIBUTES = {
    5: "Reallocated Sectors Count",
    197: "Current Pending Sector Count",
    198: "Uncorrectable Sector Count",
}

def read_raw_counts(device):
    """以 smartctl 讀取指定硬碟的 SMART 屬性原始值"""
    result = subprocess.run(
        ["smartctl", "-A", "-j", device],
        capture_output=True,
        text=True,
    )
    # smartctl 的結束碼是位元遮罩:bit 0、bit 1 代表指令解析或開啟裝置失敗
    # 其他位元(例如錯誤記錄裡有紀錄)仍會輸出屬性表,所以不能用 check=True
    if result.returncode & 0b11:
        raise RuntimeError(f"smartctl 無法讀取 {device}(結束碼 {result.returncode})")

    data = json.loads(result.stdout)
    counts = {}
    for attr in data.get("ata_smart_attributes", {}).get("table", []):
        if attr["id"] in WATCH_ATTRIBUTES:
            # raw.string 可能是 "8" 或 "8 (3 0)",第一段才是磁區數
            counts[attr["id"]] = int(attr["raw"]["string"].split()[0])
    return counts

def check_drive(device):
    counts = read_raw_counts(device)
    caution = False
    for attr_id, name in WATCH_ATTRIBUTES.items():
        if attr_id not in counts:
            continue
        raw = counts[attr_id]
        print(f"[{device}] {attr_id:02X} {name}: {raw}")
        if raw >= CAUTION_THRESHOLD:
            caution = True

    if caution:
        print(f"警告:{device} 已出現重新配置或待處理磁區,請先完成資料備份!")
    return not caution

if __name__ == "__main__":
    target_drive = sys.argv[1] if len(sys.argv) > 1 else "/dev/sda"
    try:
        sys.exit(0 if check_drive(target_drive) else 1)
    except (RuntimeError, FileNotFoundError, json.JSONDecodeError) as e:
        print(f"無法讀取硬碟 SMART 資訊:{e}", file=sys.stderr)
        sys.exit(2)

當 /dev/sda 的 05 原始值為 8、C5 與 C6 為 0 時,輸出如下,結束碼為 1,可以直接接到 cron 或監控系統的告警流程:

[/dev/sda] 05 Reallocated Sectors Count: 8
[/dev/sda] C5 Current Pending Sector Count: 0
[/dev/sda] C6 Uncorrectable Sector Count: 0
警告:/dev/sda 已出現重新配置或待處理磁區,請先完成資料備份!

三項原始值都是 0 的硬碟,輸出沒有警告行、結束碼為 0。下圖是 Windows 11 上以 Python 3.11 執行上述腳本的輸出,輸入是 smartmontools 7.5 對一顆 TOSHIBA DT01ACA200(3.5 吋、7200 rpm、SATA)執行 smartctl --json -a 產生的 JSON:

腳本輸出內容:三項原始值皆為 0

smartmontools 7.5 輸出的 JSON 中,這三個屬性的名稱是 Reallocated_Sector_Ct、Current_Pending_Sector、Offline_Uncorrectable,原始值放在 raw.string。腳本以屬性 ID(5、197、198)比對,所以不受名稱差異影響;輸出裡的中文名稱只是顯示用的標籤。


四、 常見問題與排錯(Q&A)

Q1:當 CrystalDiskInfo 顯示黃色警告且 Reallocated Sectors Count 數值持續上升時,是否代表硬碟即將完全失效?

  • 問題原因:Reallocated Sectors Count 代表已經被換成備用磁區的磁區數。在預設設定下,只要這個原始值大於等於 1,CrystalDiskInfo 就會把 HDD 標成黃色「警告」。
  • 解法:黃色「警告」不等於硬碟馬上故障,SMART 數值也無法告訴你還能撐多久;但數值持續上升,表示硬碟還在不斷遇到讀寫有問題的磁區。比較穩當的做法是停止寫入新資料、先完成完整備份,再安排換新。如果正規化目前值已經低於臨界值、狀態變成紅色「不良」,就更不應該繼續使用。

Q2:Reallocated Sectors Count 與 Current Pending Sector Count 在 SMART 數值上代表什麼不同的硬碟物理損壞階段?

  • 問題原因:兩者代表硬碟面對讀取錯誤時的不同處理階段。
  • 解法:
    • Current Pending Sector Count (C5) 是「等待重新配置的磁區」:硬碟讀取時因 ECC 對不上而失敗,想把它標成壞軌並重新配置。這些磁區之後被寫入時,通常會被換成備用磁區;部分磁區若之後又能讀取成功,也可能從待處理清單移除。
    • Reallocated Sectors Count (05) 則是已經完成重新配置、改由備用磁區取代的磁區數。

Q3:面對 Reallocated Sectors Count 異常的硬碟,應該優先使用哪種工具進行完整磁區備份以避免磁頭損毀?

  • 問題原因:一般的檔案複製遇到讀不出來的磁區時會不斷重試或直接中斷,壞磁區附近的好資料反而救不出來。
  • 解法:優先使用區塊層級、能略過壞軌並記錄進度的映像工具,例如 Linux 下的 GNU ddrescue。官方手冊說明它的設計目標是用盡量不增加額外損傷的方式,從故障硬碟複製資料:先救容易讀的區域,最後才處理壞磁區。映像要寫到另一顆健康的硬碟,之後所有修復與檔案救援都對映像檔操作。

Q4:原廠診斷工具(例如 Seagate SeaTools)對於黃色警示硬碟的測試結果與 CrystalDiskInfo 有何不同?

  • 問題原因:CrystalDiskInfo 是讀取硬碟回報的 SMART 屬性,再依臨界值判定健康狀態;原廠工具則會實際執行測試。以 Seagate 官方說明的 SeaTools for Windows 為例,提供 Short Drive Self Test(約 20~90 秒)、Short Generic 與 Long Generic 等測試,其中 Long Generic 會讀取硬碟上的每一個磁區,可能需要數小時。
  • 解法:先備份,再跑長時間的完整讀取測試。SeaTools 另有「Fix All」修復測試,Seagate 提醒執行前務必先備份所有資料;若 SeaTools 無法修復壞磁區,Seagate 建議查詢裝置的保固狀態。Western Digital 的舊工具 Data Lifeguard Diagnostics for Windows 已自 2021 年 10 月 1 日起終止技術支援,WD 官方說明已由 Western Digital Kitfox 取代。其他品牌的硬碟,請使用該品牌支援網站目前提供的診斷工具。

Linux 環境也可以用 smartctl 觸發硬碟內建的延伸自我檢測,依序執行:

  1. 啟動延伸自我檢測(/dev/sdX 換成實際裝置,指令會顯示預計完成時間):
    sudo smartctl -t long /dev/sdX
  2. 等到預計時間過後,查看自我檢測紀錄:
    sudo smartctl -l selftest /dev/sdX

Q5:硬碟出現 05 Reallocated Sectors Count 警告後,執行低階格式化或零填滿是否能有效修復磁區?

  • 問題原因:部分維護人員以為寫入全零(Zero-fill)可以清空壞軌、讓警告消失。
  • 解法:依 smartmontools 文件,對待處理磁區(C5)寫入資料,通常會強制硬碟把它換成備用磁區,代價是該磁區原本的資料遺失;這只是讓待處理磁區完成重新配置,05 的原始值不會因此減少,已經換掉的磁區也不會「修好」。因此零填滿只適合在資料已經完整備份、且確定要清除整顆硬碟時才考慮,不能當成修復手段。

Q6:在企業級 NAS 或伺服器環境中,RAID 控制器對 Reallocated Sectors Count 異常硬碟的處理機制與單機有何差異?

  • 問題原因:硬碟遇到難以讀取的磁區時,會在內部反覆嘗試錯誤恢復,回應時間可能拉得很長。
  • 解法:SATA 硬碟的 SCT Error Recovery Control 可以限制讀寫錯誤恢復的時間,smartmontools 文件說明它等同 Western Digital 的 TLER、Samsung 與 Hitachi/HGST 的 CCTL,以及 Seagate 的 ERC,RAID 環境通常設為讀寫各 70(單位為 0.1 秒,也就是 7 秒)。查看目前設定的指令如下(/dev/sdX 換成實際裝置):
sudo smartctl -l scterc /dev/sdX

RAID 層級的差異可參考 〈什麼是 RAID 0,1,5,6? RAID 初學者入門介紹〉。


參考資料與延伸閱讀

發佈留言