當 ATA 停止回應時,md RAID 中的裝置發生故障

當 ATA 停止回應時,md RAID 中的裝置發生故障

我已經創建了5個1TB硬碟分割區( /dev/sda1/dev/sdb1/dev/sdc1/dev/sde1/dev/sdf1) 中磁碟陣列6在 Ubuntu 14.04 LTS Trusty Tahr 上/dev/md0呼叫的陣列。mdadm

sudo 指令mdadm --detail /dev/md0用於顯示所有磁碟機主動同步

然後,為了進行測試,我透過在陣列中仍處於活動狀態/dev/sdb時執行這些命令來模擬長 I/O 阻塞:/dev/sdb1

hdparm --user-master u --security-set-pass deltik /dev/sdb
hdparm --user-master u --security-erase-enhanced deltik /dev/sdb

警告

不要在您關心的數據上嘗試此操作!
由於此 ATA 操作,我最終損壞了 455681 個 inode。我承認我的疏忽。

用於安全擦除的 ATA 命令預計將運行 188 分鐘,從而阻止所有其他命令至少在這段時間內運行。

我原本希望md像正常的 RAID 控制器一樣丟棄無響應的驅動器,但令我驚訝的是,它/dev/md0也被阻止了。

mdadm --detail /dev/md0查詢被阻止的設備,因此它凍結並且不會輸出。

/proc/mdstat這是我無法使用時的佈局mdadm --detail /dev/md0

root@node51 [~]# cat /proc/mdstat 
Personalities : [raid6] [raid5] [raid4] [linear] [multipath] [raid0] [raid1] [raid10] 
md0 : active raid6 sdf1[5] sda1[0] sdb1[4] sdc1[2] sde1[1]
      2929887744 blocks super 1.2 level 6, 512k chunk, algorithm 2 [5/5] [UUUUU]

unused devices: <none>

我試圖mdadm /dev/md0 -f /dev/sdb1強行失敗/dev/sdb1,但也被阻止了:

root@node51 [~]# ps aux | awk '{if($8~"D"||$8=="STAT"){print $0}}' 
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root      3334  1.2  0.0  42564  1800 ?        D    03:21   3:37 parted -l
root      4957  0.0  0.0  13272   900 ?        D    06:19   0:00 mdadm /dev/md0 -f /dev/sdb1
root      5706  0.0  0.0  13388  1028 ?        D    06:19   0:00 mdadm --detail /dev/md0
root      7541  0.5  0.0      0     0 ?        D    Jul19   6:12 [kworker/u16:2]
root     22420  0.0  0.0  11480   808 ?        D    07:48   0:00 lsblk
root     22796  0.0  0.0   4424   360 pts/13   D+   05:51   0:00 hdparm --user-master u --security-erase-enhanced deltik /dev/sdb
root     23312  0.0  0.0   4292   360 ?        D    05:51   0:00 hdparm -I /dev/sdb
root     23594  0.1  0.0      0     0 ?        D    06:11   0:07 [kworker/u16:1]
root     25205  0.0  0.0  17980   556 ?        D    05:52   0:00 ls --color=auto
root     26008  0.0  0.0  13388  1032 pts/23   D+   06:32   0:00 mdadm --detail /dev/md0
dtkms    29271  0.0  0.2  58336 10412 ?        DN   05:55   0:00 python /usr/share/backintime/common/backintime.py --backup-job
root     32303  0.0  0.0      0     0 ?        D    06:16   0:00 [kworker/u16:0]

更新(2015 年 7 月 21 日):在我等待了整整 188 分鐘以清除 I/O 區塊後,當我看到將md完全空白的資料/dev/sdb視為完全完好無損時,驚訝變成了恐懼。

我認為這md至少會看到奇偶校驗不匹配,然後就會下降/dev/sdb1

我慌了,mdadm /dev/md0 -f /dev/sdb1又跑了,由於I/O塊已經解除,命令很快就完成了。

隨著輸入/輸出錯誤的出現,檔案系統損壞已經發生。仍然驚慌失措,我懶惰地卸載了 RAID 陣列中的資料分區,因為reboot -nf我認為情況不會變得更糟。

在對分區進行了一番艱苦的努力之後e2fsck,455681 個 inode 進入了lost+found.

我已經重新組裝了數組,數組本身現在看起來很好:

root@node51 [~]# mdadm --detail /dev/md0
/dev/md0:
        Version : 1.2
  Creation Time : Mon Feb 16 14:34:26 2015
     Raid Level : raid6
     Array Size : 2929887744 (2794.16 GiB 3000.21 GB)
  Used Dev Size : 976629248 (931.39 GiB 1000.07 GB)
   Raid Devices : 5
  Total Devices : 5
    Persistence : Superblock is persistent

    Update Time : Tue Jul 21 00:00:30 2015
          State : active 
 Active Devices : 5
Working Devices : 5
 Failed Devices : 0
  Spare Devices : 0

         Layout : left-symmetric
     Chunk Size : 512K

           Name : box51:0
           UUID : 6b8a654d:59deede9:c66bd472:0ceffc61
         Events : 643541

    Number   Major   Minor   RaidDevice State
       0       8        1        0      active sync   /dev/sda1
       1       8       97        1      active sync   /dev/sdg1
       2       8       33        2      active sync   /dev/sdc1
       6       8       17        3      active sync   /dev/sdb1
       5       8      113        4      active sync   /dev/sdh1

md沒有我期望的兩道保護線,這仍然讓我感到相當震驚:

  • 設備鎖定時發生故障
  • 當設備回傳的資料是垃圾時,設備會發生故障

問題

  1. md為什麼沒有回應的磁碟機/分割區不會發生故障?
  2. 當磁碟機被封鎖時,我可以從陣列中刪除該磁碟機/分割區嗎?
  3. 是否可以設定逾時,以便md自動使不回應 ATA 命令的磁碟機發生故障?
  4. 為什麼md繼續使用資料無效的設備?

答案1

德爾蒂克,您誤解了 Linux 軟體 RAID ( md) 的工作原理。

md從多個設備或分割區建立虛擬區塊設備,並且不知道您正在向虛擬設備傳輸什麼資料或從虛擬設備傳輸什麼資料。
你希望它可以做一些它沒有設計要做的事情。


答案

md1. 為什麼沒有回應的磁碟機/分割區不會故障?

這是因為md不知道是否

  • 驅動器正忙於處理md自身請求的 I/O 或
  • 由於某些外部情況(例如驅動器本身的錯誤恢復或在您的情況下是 ATA 安全擦除),因此驅動器被阻止,

因此md將等待查看驅動器返回的內容。驅動器最終沒有傳回任何讀取或寫入錯誤。如果存在讀取錯誤,md則會自動從奇偶校驗中修復它,如果存在寫入錯誤,md則會導致裝置故障(請參閱「復原」部分)md手冊頁)。

由於既沒有讀取錯誤也沒有寫入錯誤,因此md在核心等待設備回應後繼續使用該設備。

2. 當磁碟機被封鎖時,我可以從陣列中刪除該磁碟機/分割區嗎?

不可以/dev/md0

您將-f--fail標誌傳遞給mdadm“管理”模式。
以下是其實際作用的演練:

這是該標誌如何運作的源代碼:

case 'f': /* set faulty */
    /* FIXME check current member */
    if ((sysfd >= 0 && write(sysfd, "faulty", 6) != 6) ||
        (sysfd < 0 && ioctl(fd, SET_DISK_FAULTY,
                rdev))) {
        if (errno == EBUSY)
            busy = 1;
        pr_err("set device faulty failed for %s:  %s\n",
            dv->devname, strerror(errno));
        if (sysfd >= 0)
            close(sysfd);
        goto abort;
    }
    if (sysfd >= 0)
        close(sysfd);
    sysfd = -1;
    count++;
    if (verbose >= 0)
        pr_err("set %s faulty in %s\n",
            dv->devname, devname);
    break;

注意來電write(sysfd, "faulty", 6)sysfd是檔案前面設定的變數:
sysfd = sysfs_open(fd2devnm(fd), dname, "block/dev");

sysfs_open()是一個函數這個文件:

int sysfs_open(char *devnm, char *devname, char *attr)
{
    char fname[50];
    int fd;

    sprintf(fname, "/sys/block/%s/md/", devnm);
    if (devname) {
        strcat(fname, devname);
        strcat(fname, "/");
    }
    strcat(fname, attr);
    fd = open(fname, O_RDWR);
    if (fd < 0 && errno == EACCES)
        fd = open(fname, O_RDONLY);
    return fd;
}

如果您遵循這些函數,您會發現它mdadm /dev/md0 -f /dev/sdb1基本上是這樣做的:

echo "faulty" > /sys/block/md0/md/dev-sdb1/block/dev

該請求將等待,不會立即通過,因為/dev/md0被封鎖。

3. 是否可以設定逾時,以便md自動使不回應 ATA 指令的磁碟機發生故障?

是的。實際上,預設情況下,超時時間為 30 秒:

root@node51 [~]# cat /sys/block/sdb/device/timeout
30

您的假設的問題在於您的驅動器實際上正忙於運行 ATA 命令(持續 188 分鐘),因此它沒有超時。

有關這方面的詳細信息,請參閱Linux 核心 SCSI 錯誤處理文檔

4. 為什麼md繼續使用資料無效的設備?

當 ATA 安全性擦除完成時,磁碟機沒有報告任何問題,例如中止的命令,因此md沒有理由懷疑有問題。

此外,在您使用分割區作為 RAID 裝置而不是整個磁碟的情況下,核心的記憶體分割表不會被告知已擦除磁碟機上的分割區已消失,因此md將繼續存取您的分割區,/dev/sdb1就像沒有任何問題一樣。

這是來自md手冊頁:

擦洗和不匹配

由於儲存裝置隨時可能產生壞區塊,因此定期讀取陣列中所有裝置上的所有區塊以儘早捕獲此類壞區塊非常有價值。這個過程稱為擦洗

md 陣列可以透過寫入來擦除查看或者維修到文件md/sync_action在裡面系統檔案系統設備的目錄。

請求清理將導致 md 讀取陣列中每個裝置上的每個區塊,並檢查資料是否一致。對於 RAID1 和 RAID10,這表示檢查副本是否相同。對於 RAID4、RAID5、RAID6,這表示檢查奇偶校驗區塊(或多個區塊)是否正確。

我們可以由此推斷,奇偶校驗通常不會在每次磁碟讀取時進行檢查。 (此外,每次讀取時檢查奇偶校驗都會增加完成讀取所需的事務並執行奇偶校驗與資料讀取的比較,從而對效能造成很大的負擔。)

在正常操作下,md只是假設它正在讀取的資料是有效的,使其容易受到無聲資料損壞。就您而言,由於您擦除了驅動器,整個驅動器中的資料都已悄然損壞。

您的檔案系統不知道損壞。您在檔案系統層級看到輸入/輸出錯誤,因為檔案系統無法理解為什麼它有錯誤的資料。

為了避免靜默資料損壞,首先,永遠不要再做你做過的事。其次,考慮使用ZFS,一個專注於資料完整性並檢測和糾正靜默資料損壞的檔案系統。

相關內容