web-dev-qa-db-ja.com

ATAが応答を停止すると、mdRAIDでデバイスに障害が発生する

5つの1TB HDDパーティション/dev/sda1/dev/sdb1/dev/sdc1/dev/sde1、および/dev/sdf1)を-で作成しましたRAID 6 Ubuntu 14.04 LTS TrustyTahrでmdadmを使用して/dev/md0と呼ばれる配列。

コマンドSudomdadm --detail /dev/md0は、active sync内のすべてのドライブを表示するために使用されます。

次に、テストのために、/dev/sdbがアレイでまだアクティブなときに次のコマンドを実行して、/dev/sdb1での長いI/Oブロッキングをシミュレートしました。

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

[〜#〜]警告[〜#〜]

気になるデータでこれを試さないでください!
このATA操作の結果として、455681iノードが破損することになりました。私は自分の過失を認めます。

安全な消去のための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日): I/Oブロックがクリアされるのを188分待った後、mdが完全に空白になっているのを見て、驚きが恐怖に変わりました。 /dev/sdbまるで完全に無傷であるかのように。

mdは、少なくともパリティが一致していないことを確認してから、/dev/sdb1を削除すると思いました。

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

入出力エラーが発生したため、ファイルシステムの破損はすでに発生していました。まだパニックに陥っていますが、RAIDアレイのデータパーティションを怠惰にアンマウントし、それが悪化することはないと考えたため、reboot -nfを実行しました。

パーティションにe2fsckを釘付けにした後、455681iノードが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. mdがATAコマンドに応答しないドライブに自動的に障害を起こすようにタイムアウトを構成できますか?
  4. mdが無効なデータを持つデバイスを引き続き使用するのはなぜですか?
4
Deltik

Deltik 、LinuxソフトウェアRAID(md)がどのように機能するかを誤解しました。

mdは、複数のデバイスまたはパーティションから仮想ブロックデバイスを作成し、仮想デバイスとの間で転送するデータを認識しません。
設計されていないことを実行できることを望んでいました。


回答

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

これは、md

  • ドライブは、md自体が要求したものからのI/Oでビジーです。
  • ドライブ自体のエラー回復や、場合によってはATAセキュア消去などの外部環境が原因で、ドライブがブロックされました。

したがって、mdは、ドライブが何を返すかを確認するために待機します。ドライブは最終的に読み取りまたは書き込みエラーを返しませんでした。読み取りエラーが発生した場合、mdは自動的にパリティから修正し、書き込みエラーが発生した場合、mdはデバイスに障害を起こします(-の「回復」セクションを参照) md manページ )。

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

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

いいえ。_/dev/md0_ RAIDデバイスはブロックされており、ブロックがクリアされるまで変更できません。

_-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 Secure Eraseが終了したとき、ドライブはコマンドの中止などの問題を報告しなかったため、mdは問題があったと疑う理由がありませんでした。

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

これは md manページ からです:

スクラブとミスマッチ

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

md配列は、checkまたはrepairのいずれかをファイルmd/sync_actionsysfsディレクトリに書き込むことでスクラブできます。デバイス。

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

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

通常の操作では、mdは、読み取っているデータが有効であると想定しているため、 サイレントデータ破損 に対して脆弱なままです。あなたの場合、ドライブをワイプしたため、サイレントに破損したデータのドライブ全体がありました。

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

サイレントデータの破損を回避するために、まず、二度と行ったことを行わないでください。次に、 [〜#〜] zfs [〜#〜] を使用することを検討してください。これは、データの整合性に重点を置き、サイレントデータの破損を検出して修正するファイルシステムです。

2
Deltik