====== Работа с виртуальными RAID массивами mdadm ======

===== Установка =====
 
<code bash>apt-get install mdadm</code>

===== Сборка RAID =====

==== Подготовка носителей ====

Сначала необходимо занулить суперблоки на дисках, которые мы будем использовать для построения RAID (если диски ранее использовались, их суперблоки могут содержать служебную информацию о других RAID): <code bash>mdadm --zero-superblock --force /dev/sd{b,c}</code> * в данном примере мы зануляем суперблоки для дисков sdb и sdc.

Если мы получили ответ: 
<code bash>mdadm: Unrecognised md component device - /dev/sdb
mdadm: Unrecognised md component device - /dev/sdc</code>
... то значит, что диски не использовались ранее для RAID. Просто продолжаем настройку.

Далее нужно удалить старые метаданные и подпись на дисках:
<code bash>wipefs --all --force /dev/sd{b,c}</code>

==== Создание рейда ====

Для сборки избыточного массива применяем следующую команду: <code bash>mdadm --create --verbose /dev/md0 -l 1 -n 2 /dev/sd{b,c}</code>
* где:

  * **/dev/md0** — устройство RAID, которое появится после сборки; 
  * **-l 1** — уровень RAID; 
  * **-n 2** — количество дисков, из которых собирается массив; 
  * /**dev/sd{b,c}** — сборка выполняется из дисков sdb и sdc.

Мы должны увидеть что-то на подобие:
<code bash>mdadm: Note: this array has metadata at the start and
    may not be suitable as a boot device.  If you plan to
    store '/boot' on this device please ensure that
    your boot-loader understands md/v1.x metadata, or use
    --metadata=0.90
mdadm: size set to 1046528K</code>
Также система задаст контрольный вопрос, хотим ли мы продолжить и создать RAID — нужно ответить **y**:
<code bash>Continue creating array? y</code>
Мы увидим что-то на подобие:
<code bash>mdadm: Defaulting to version 1.2 metadata
mdadm: array /dev/md0 started.</code>
Вводим команду:
<code bash>lsblk</code>
... и находим информацию о том, что у наших дисков sdb и sdc появился раздел md0, например:
<code bash>...
sdb                     8:16   0    2G  0 disk  
??md0                   9:0    0    2G  0 raid1 
sdc                     8:32   0    2G  0 disk  
??md0                   9:0    0    2G  0 raid1 
...</code>
* в примере мы видим собранный raid1 из дисков sdb и sdc.

===== Создание файла mdadm.conf =====

В файле mdadm.conf находится информация о RAID-массивах и компонентах, которые в них входят. Для его создания выполняем следующие команды: 

<code bash>mkdir /etc/mdadm
echo "DEVICE partitions" > /etc/mdadm/mdadm.conf
mdadm --detail --scan --verbose | awk '/ARRAY/ {print}' >> /etc/mdadm/mdadm.conf</code>

Пример содержимого:
<code bash>DEVICE partitions
ARRAY /dev/md0 level=raid1 num-devices=2 metadata=1.2 name=proxy.dmosk.local:0 UUID=411f9848:0fae25f9:85736344:ff18e41d</code>
* в данном примере хранится информация о массиве /dev/md0 — его уровень 1, он собирается из 2-х дисков.

===== Создание файловой системы и монтирование массива =====

Создание файловой системы для массива выполняется также, как для раздела, например:
<code bash>mkfs.ext4 /dev/md0</code>
* данной командой мы создаем на md0 файловую систему ext4.

или:
<code bash>mkfs.xfs /dev/md0</code>
* для файловой системы xfs.

Примонтировать раздел можно командой:
<code bash>mount /dev/md0 /mnt</code>
* в данном случае мы примонтировали наш массив в каталог /mnt.

Чтобы данный раздел также монтировался при загрузке системы, добавляем в fstab.

Сначала смотрим идентификатор раздела:
<code bash>blkid</code>
Мы увидим что-то на подобие:
<code bash>/dev/md0: UUID="ffa7c082-7613-4dbc-ae62-3f5508652cf6" TYPE="ext4"</code>
* в моем примере мы будем использовать идентификатор ffa7c082-7613-4dbc-ae62-3f5508652cf6.

Открываем теперь fstab и добавляем строку:
<code bash>nano /etc/fstab</code>
<code bash>UUID="ffa7c082-7613-4dbc-ae62-3f5508652cf6"    /mnt    ext4    defaults    0 0</code>
Если ранее мы монтировали раздел в каталог /mnt, вводим:
<code bash>umount /mnt</code>
И после: 
<code bash>mount -a</code>
Мы должны увидеть примонтированный раздел md, например:
<code bash>df -h</code>
<code bash>/dev/md0               990M         2,6M  921M            1% /mnt</code>

===== Информация о RAID =====

Посмотреть состояние всех RAID можно командой: <code bash>cat /proc/mdstat</code> В ответ мы получим что-то на подобие: <code bash>md0 : active raid1 sdc[1] sdb[0]
      1046528 blocks super 1.2 [2/2] [UU]</code>
* где 
  * **md0** — имя RAID устройства; 
  * **raid1 sdc[1] sdb[0]** — уровень избыточности и из каких дисков собран;
  * **1046528 blocks** — размер массива;
  * **[2/2] [UU]** — количество юнитов, которые на данный момент используются.

* мы можем увидеть строку **md0 : active(auto-read-only)** — это означает, что после монтирования массива, он не использовался для записи.\\
Подробную информацию о конкретном массиве можно посмотреть командой: <code bash>mdadm -D /dev/md0</code> * где **/dev/md0** — имя RAID устройства.\\

Пример ответа:
<code bash>   Version : 1.2
     Creation Time : Wed Mar  6 09:41:06 2019
        Raid Level : raid1
        Array Size : 1046528 (1022.00 MiB 1071.64 MB)
     Used Dev Size : 1046528 (1022.00 MiB 1071.64 MB)
      Raid Devices : 2
     Total Devices : 2
       Persistence : Superblock is persistent

       Update Time : Wed Mar  6 09:41:26 2019
             State : clean 
    Active Devices : 2
   Working Devices : 2
    Failed Devices : 0
     Spare Devices : 0

Consistency Policy : resync

              Name : proxy.dmosk.local:0  (local to host proxy.dmosk.local)
              UUID : 304ad447:a04cda4a:90457d04:d9a4e884
            Events : 17

    Number   Major   Minor   RaidDevice State
       0       8       16        0      active sync   /dev/sdb
       1       8       32        1      active sync   /dev/sdc
</code>
* где:

  * **Version** — версия метаданных.
  * **Creation Time** — дата в время создания массива.
  * **Raid Level** — уровень RAID.
  * Array Size — объем дискового пространства для RAID.
  * **Used Dev Size** — используемый объем для устройств. Для каждого уровня будет индивидуальный расчет: RAID1 — равен половине общего размера дисков, RAID5 — равен размеру, используемому для контроля четности.
  * **Raid Devices** — количество используемых устройств для RAID.
  * **Total Devices** — количество добавленных в RAID устройств.
  * **Update Time** — дата и время последнего изменения массива.
  * **State** — текущее состояние. clean — все в порядке.
  * **Active Devices** — количество работающих в массиве устройств.
  * **Working Devices** — количество добавленных в массив устройств в рабочем состоянии.
  * **Failed Devices** — количество сбойных устройств.
  * **Spare Devices** — количество запасных устройств.
  * **Consistency Policy** — политика согласованности активного массива (при неожиданном сбое). По умолчанию используется resync — полная ресинхронизация после восстановления. Также могут быть bitmap, journal, ppl.
  * **Name** — имя компьютера.
  * **UUID** — идентификатор для массива.
  * **Events** — количество событий обновления.
  * **Chunk Size** (для RAID5) — размер блока в килобайтах, который пишется на разные диски.
Подробнее про каждый параметр можно прочитать в мануале для mdadm: <code bash>man mdadm</code> Также, информацию о разделах и дисковом пространстве массива можно посмотреть командой fdisk: <code bash>fdisk -l /dev/md0</code>

===== Проверка целостности =====

Для проверки целостности вводим:
<code bash>echo 'check' > /sys/block/md0/md/sync_action</code>
Результат проверки смотрим командой:
<code bash>cat /sys/block/md0/md/mismatch_cnt</code>
* если команда возвращает **0**, то с массивом все в порядке.

Остановка проверки:
<code bash>echo 'idle' > /sys/block/md0/md/sync_action</code>

===== Восстановление RAID =====

Рассмотрим два варианта восстановлении массива.

==== Замена диска ====

В случае выхода из строя одного из дисков массива, команда cat /proc/mdstat покажет следующее: <code bash>cat /proc/mdstat</code>
<code bash>Personalities : [raid1] 
md0 : active raid1 sdb[0]
      1046528 blocks super 1.2 [2/1] [U_]</code>
* о наличии проблемы нам говорит нижнее подчеркивание вместо U — **[U_]** вместо **[UU]**.

Или:
<code bash>mdadm -D /dev/md0</code>
<code bash>...
       Update Time : Thu Mar  7 20:20:40 2019
             State : clean, degraded
...</code>
* статус **degraded** говорит о проблемах с RAID.

Для восстановления, сначала удалим сбойный диск, например:
<code bash>mdadm /dev/md0 --remove /dev/sdc</code>
Теперь добавим новый:
<code bash>mdadm /dev/md0 --add /dev/sde</code>
Смотрим состояние массива:
<code bash>mdadm -D /dev/md0</code>
<code bash>...
       Update Time : Thu Mar  7 20:57:13 2019
             State : clean, degraded, recovering
...
    Rebuild Status : 40% complete
...</code>
* **recovering** говорит, что RAID восстанавливается; **Rebuild Status** — текущее состояние восстановления массива (в данном примере он восстановлен на 40%).

Если синхронизация выполняется слишком медленно, можно увеличить ее скорость. Для изменения скорости синхронизации вводим:
<code bash>echo '10000' > /proc/sys/dev/raid/speed_limit_min</code>
* по умолчанию скорость **speed_limit_min** = 1000 Кб, **speed_limit_max** — 200000 Кб. Для изменения скорости, можно поменять только минимальную.

==== Пересборка массива ====

Если нам нужно вернуть ранее разобранный или развалившийся массив из дисков, которые уже входили в состав RAID, вводим:
<code bash>mdadm --assemble --scan</code>
* данная команда сама найдет необходимую конфигурацию и восстановит RAID.

Также, мы можем указать, из каких дисков пересобрать массив:
<code bash>mdadm --assemble /dev/md0 /dev/sdb /dev/sdc</code>

===== Запасной диск (Hot Spare) =====

Если в массиве будет запасной диск для горячей замены, при выходе из строя одного из основных дисков, его место займет запасной.

Диском Hot Spare станет тот, который просто будет добавлен к массиву:
<code bash>mdadm /dev/md0 --add /dev/sdd</code>
Информация о массиве изменится, например:
<code bash>mdadm -D /dev/md0</code>
<code bash>...
    Number   Major   Minor   RaidDevice State
       0       8       16        0      active sync   /dev/sdb
       2       8       48        1      active sync   /dev/sdc

       3       8       32        -      spare   /dev/sdd</code>

Проверить работоспособность резерва можно вручную, симулировав выход из строя одного из дисков:
<code bash>mdadm /dev/md0 --fail /dev/sdb</code>
И смотрим состояние:
<code bash>mdadm -D /dev/md0</code>
<code bash>...
    Rebuild Status : 37% complete
...
    Number   Major   Minor   RaidDevice State
       3       8       32        0      spare rebuilding   /dev/sdd
       2       8       48        1      active sync   /dev/sdc

       0       8       16        -      faulty   /dev/sdb
...</code>
* как видим, начинается ребилд. На замену вышедшему из строя sdb встал hot-spare sdd.

===== Добавить диск к массиву =====

В данном примере рассмотрим вариант добавления активного диска к RAID, который будет использоваться для работы, а не в качестве запасного.

Добавляем диск к массиву:
<code bash>mdadm /dev/md0 --add /dev/sde</code>
Новый диск мы увидим в качестве spare:
<code bash>4       8       16        -      spare   /dev/sde</code>
Теперь расширяем RAID:
<code bash>mdadm -G /dev/md0 --raid-devices=3</code>
* в данном примере подразумевается, что у нас RAID 1 и мы добавили к нему 3-й диск.

===== Удаление массива =====
<WRAP center round important 60%>
При удалении массива внимателнее смотрите на имена массива и дисков и подставляйте свои значения.
</WRAP>
Если нам нужно полностью разобрать RAID, сначала размонтируем и остановим его:
<code bash>umount /mnt</code>
* где **/mnt** — каталог монтирования нашего RAID.
<code bash>mdadm -S /dev/md0</code>
* где **/dev/md0** — массив, который мы хотим разобрать.
<WRAP center round alert 60%>
Если мы получим ошибку mdadm: fail to stop array /dev/md0: Device or resource busy, с помощью команды
<code bash>lsof -f -- /dev/md0</code>
</WRAP>
Затем очищаем суперблоки на всех дисках, из которых он был собран:
<code bash>
mdadm --zero-superblock /dev/sdb
mdadm --zero-superblock /dev/sdc
mdadm --zero-superblock /dev/sdd
</code>
* где диски **/dev/sdb**, **/dev/sdc**, **/dev/sdd** были частью массива md0.

А также удаляем метаданные и подпись:
<code bash>wipefs --all --force /dev/sd{b,c,d}</code>