ATA が応答しなくなったときに md RAID のデバイスが故障する

ATA が応答しなくなったときに md RAID のデバイスが故障する

私が作った5つの1TB HDDパーティション/dev/sda1、、、、および)/dev/sdb1​​/dev/sdc1/dev/sde1/dev/sdf1RAID 6Ubuntu 14.04 LTS Trusty Tahr を/dev/md0使用して呼び出される配列。mdadm

mdadm --detail /dev/md0すべてのドライブを表示するために使用するsudoコマンドアクティブ同期

次に、テストのために、アレイ内で がまだアクティブな/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 分間実行されると予想され、少なくともその間は他のすべてのコマンドがブロックされます。

適切な RAID コントローラーのように、応答しないドライブをドロップできると思っていましたmdが、驚いたことに、/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日):I/O ブロックがクリアされるまで 188 分間待った後、md完全に空白になっているブロックが、あたかも完全に無傷であるかのように扱われているのを見て、驚きは恐怖に変わりました/dev/sdb

md少なくともパリティが一致していないことがわかり、その後ドロップされるだろうと思いました/dev/sdb1

慌ててmdadm /dev/md0 -f /dev/sdb1再度実行したところ、I/O ブロックが解除されていたため、コマンドはすぐに完了しました。

入出力エラーが頻発し、ファイルシステムの破損がすでに発生していました。まだパニック状態でしたが、reboot -nfこれ以上悪化することはないだろうと判断し、RAID アレイのデータ パーティションをアンマウントしました。

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私が期待していた 2 つの保護ラインがないのは、私にとってまだかなりショックです。

  • デバイスがロックしたときに故障する
  • 返されるデータがゴミである場合にデバイスが失敗する

質問

  1. md応答しないドライブ/パーティションが失敗しないのはなぜですか?
  2. ドライブがブロックされている間に、アレイからドライブ/パーティションを削除できますか?
  3. mdATA コマンドに応答しないドライブを自動的に失敗させるようにタイムアウトを設定できますか?
  4. md無効なデータがあるデバイスを使い続けるのはなぜですか?

答え1

デルティック、Linux ソフトウェア RAID ( md) の仕組みを誤解しています。

md複数のデバイスまたはパーティションから仮想ブロック デバイスを作成し、仮想デバイスとの間で転送されるデータについては認識しません。
あなたは、それが本来意図されていないことができることを期待していました。


回答

1.md応答しないドライブ/パーティションが失敗しないのはなぜですか?

これはmd

  • ドライブは、mdそれ自体が要求した何かからのI/Oでビジー状態です。
  • ドライブ自体のエラー回復や、この場合はATA Secure Eraseなどの外部状況によりドライブがブロックされました。

ドライブが何を返すか待つことにしますmd。ドライブは結局、読み取りエラーも書き込みエラーも返しませんでした。読み取りエラーがあった場合は、mdパリティから自動的に修正され、書き込みエラーがあった場合は、mdデバイスが故障します(「リカバリ」セクションを参照してください)。mdマニュアルページ)。

読み取りエラーも書き込みエラーもなかったため、mdカーネルが応答を待った後、デバイスの使用を継続しました。

2. ドライブがブロックされている間に、アレイからドライブ/パーティションを削除できますか?

いいえ。RAID/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

md3. ATA コマンドに応答しないドライブを自動的に失敗させるようにタイムアウトを設定できますか?

はい。実際、デフォルトでは、タイムアウトは30秒です:

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

あなたの仮定の問題は、ドライブが実際には ATA コマンドの実行でビジー状態 (188 分間) だったため、タイムアウトになっていなかったことです。

詳細については、Linux カーネル SCSI エラー処理ドキュメント

md4.無効なデータがあるデバイスを使い続けるのはなぜですか?

ATA Secure Erase が完了したとき、ドライブはコマンドの中止などの問題を報告しなかったため、md問題があると疑う理由はありませんでした。

さらに、ディスク全体ではなくパーティションを RAID デバイスとして使用している場合、カーネルのメモリ内パーティション テーブルには消去されたドライブ上のパーティションがなくなったことが通知されないため、何も問題がないかのようにmdアクセスを続けます/dev/sdb1

これはmdマニュアルページ:

スクラブとミスマッチ

ストレージデバイスはいつでも不良ブロックを発生させる可能性があるため、アレイ内のすべてのデバイスのすべてのブロックを定期的に読み取り、不良ブロックを早期に検出することが重要です。このプロセスはこすり洗い

md配列は、次のいずれかの方法で消去できます。チェックまたは修理ファイルにmd/同期アクションの中にsysfsデバイスのディレクトリ。

スクラブを要求すると、md はアレイ内のすべてのデバイス上のすべてのブロックを読み取り、データの整合性をチェックします。RAID1 および RAID10 の場合、これはコピーが同一であることを確認することを意味します。RAID4、RAID5、RAID6 の場合、これはパリティ ブロック (またはブロック群) が正しいことを確認することを意味します。

このことから、パリティは通常、ディスク読み取りごとにチェックされるわけではないことがわかります。(さらに、読み取りごとにパリティをチェックすると、読み取りを完了するために必要なトランザクションが増加し、パリティと読み取られたデータの比較が実行されるため、パフォーマンスに大きな負担がかかります。)

通常の操作では、md読み込んだデータが有効であると想定し、サイレントデータ破損あなたの場合、ドライブを消去したため、ドライブ全体のデータが気づかないうちに破損していました。

ファイルシステムは破損を認識しませんでした。ファイルシステムが不良データの原因を理解できなかったため、ファイルシステム レベルで入出力エラーが発生しました。

サイレントデータ破損を回避するには、まず、二度と同じことをしないでください次に、ZFSデータの整合性に重点を置き、サイレントなデータ破損を検出して修正するファイルシステムです。

関連情報