MDADM RAID Utilites

MD (multi disk)

mdadm — утилита для управления программными RAID массивами в GNU/Linux (Linux Software Raid), ранее известная, как mdctl. MD — сокращение от multi disk.
В Linux можно использовать следующие разновидности RAID:
  • LINEAR (JBOD) — расширение размера логического диска за счет нескольких физических дисков;
  • RAID0 (striping) — распределение блоков на нескольких физических дисках без обеспечения отказоустойчивости;
  • RAID1 (mirroring) — зеркалирование, запись одних и тех же данных одновременно на два диска, что обеспечивает отказоустойчивость при отказе одного из дисков;
  • RAID4;
  • RAID5 — массив с обеспечением отказоустойчивости за счет минимальной избыточности (требуется минимум три диска);
  • RAID6;
  • MULTIPATH — не RAID-массив, позволяющий создавать разные псевдо-дисковые устройства для одного физического диска;
  • FAULTY — псевдо RAID-массив.
Не все разновидности RAID-массивов доступны в ядре Linux в начальной конфигурации. Например, чтобы использовать RAID5 необходимо внести изменения в конфигурацию ядра и скомпилировать его заново. Для уже скомпилированных ядер из дистрибутивов, возможно потребуется явная загрузка соответствующего модуля. Пример: modprobe raid5.
При создании RAID1 (зеркала) с целью повышения отказоустойчивости системы рекомендуется разделы swap также объединять в массив. При использовании swap-разделов вне RAID при отказе одного диска может случиться крах системы (если на поломавшийся диск была выгружена часть страниц памяти). При объединении в RAID- массив разделов swap такого не произойдет, т.к. выгружаемая страница будет присутствовать на обоих дисках.

Восстановление функционирования ([_U])

Если вместо [UU] видим [_U], то целостность одного из дисков нарушена.
Ниже описана процедура восстановления диска после незначительного сбоя. В моем случае было выключено некорректно питание сервера и развалился md5.
  • Восстановление функционирования (rebuild) разделов диска по одному после однократного "несмертельного" сбоя:
    # mdadm -a /dev/md<0-6> /dev/sd<a-b><1-10>
    например:
    # mdadm -a /dev/md0 /dev/sdb1
Нужно быть аккуратным с номерами разделов.
  • В случае ошибки, удалить компонент из RAID командой:
    # mdadm -r /dev/md0 /dev/sdb1
    получается не всегда - устройство может быть занято, тогда устройство нужно пометить как сбойное, а потом удалить
    mdadm --manage /dev/md0 --fail /dev/sdb1
  • Пример восстановления:
[root@vm ~]# cat /proc/mdstat
Personalities : [raid1] 
md5 : active raid1 sdb2[1]
      860160192 blocks [2/1] [_U]
      
md3 : active raid1 sdb3[1] sda3[0]
      30716160 blocks [2/2] [UU]
      
md4 : active raid1 sdb5[1] sda5[0]
      20482752 blocks [2/2] [UU]
      
md1 : active raid1 sdb6[1] sda6[0]
      16386176 blocks [2/2] [UU]
      
md2 : active raid1 sdb7[1] sda7[0]
      10241280 blocks [2/2] [UU]
      
md0 : active raid1 sdb1[1] sda1[0]
      20482752 blocks [2/2] [UU]
      
unused devices: <none>
Видим, что проблема с md5. Смотрим более подробную информацию о ошибке.
[root@vm ~]# mdadm --query --detail /dev/md5
/dev/md5:
        Version : 0.90
  Creation Time : Mon Jan 31 13:29:01 2011
     Raid Level : raid1
     Array Size : 860160192 (820.31 GiB 880.80 GB)
  Used Dev Size : 860160192 (820.31 GiB 880.80 GB)
   Raid Devices : 2
  Total Devices : 1
Preferred Minor : 5
    Persistence : Superblock is persistent

    Update Time : Mon Feb 28 13:08:42 2011
          State : clean, degraded
 Active Devices : 1
Working Devices : 1
 Failed Devices : 0
  Spare Devices : 0

           UUID : bba1242e:c9f75ce4:7872b1fa:7a320018
         Events : 0.89396

    Number   Major   Minor   RaidDevice State
       0       0        0        0      removed
       1       8       18        1      active sync   /dev/sdb2
Видим что не хватает /dev/sda2. Пробуем его добавить обратно в RAID md5.
[root@vm ~]# mdadm -a /dev/md5 /dev/sda2
 mdadm: added /dev/sda2
Если все ок. Наблюдаем состояние синхронизации RAID md5.
[root@vm ~]# cat /proc/mdstat
Personalities : [raid1] 
md5 : active raid1 sda2[0] sdb2[1]
      860160192 blocks [2/1] [_U]
      [===>.................]  recovery = 18.0% (154891584/860160192) finish=108.7min speed=108091K/sec

Замена неисправного диска

  • Постановка задачи: Окружение: CentOS release 5.5 (Final), RAID1 (два винчестера /dev/sda и /dev/sdb). Нужно заменить сбойный винчестер /dev/sda.
Пришли уведомления от Logwatch:
 --------------------- Raid Begin ------------------------ 

 Apr  3 08:46:21 raid1: Disk failure on sda7, disabling device.  
 
 ---------------------- Raid End ------------------------- 
и от mdadm monitoring:
This is an automatically generated mail message from mdadm
running

A Fail event had been detected on md device /dev/md2.

It could be related to component device /dev/sda7.

Faithfully yours, etc.
  • Решение:
  1. Проверим(уточним) поступившую информацию
    [root@vm ~]# cat /proc/mdstat 
    Personalities : [raid1] 
    md5 : active raid1 sdb2[1] sda2[0]
          860160192 blocks [2/2] [UU]
          
    md3 : active raid1 sdb3[1] sda3[0]
          30716160 blocks [2/2] [UU]
          
    md4 : active raid1 sdb5[1] sda5[0]
          20482752 blocks [2/2] [UU]
          
    md1 : active raid1 sdb6[1] sda6[0]
          16386176 blocks [2/2] [UU]
          
    md2 : active raid1 sdb7[1] sda7[2](F)
          10241280 blocks [2/1] [_U]
          
    md0 : active raid1 sdb1[1] sda1[0]
          20482752 blocks [2/2] [UU]
          
    unused devices: <none>
  2. Проблема с md2. Уточним информацию.
    [root@vm ~]# mdadm --query --detail /dev/md2
    /dev/md2:
            Version : 0.90
      Creation Time : Mon Jan 31 13:35:55 2011
         Raid Level : raid1
         Array Size : 10241280 (9.77 GiB 10.49 GB)
      Used Dev Size : 10241280 (9.77 GiB 10.49 GB)
       Raid Devices : 2
      Total Devices : 2
    Preferred Minor : 2
        Persistence : Superblock is persistent
    
        Update Time : Mon Apr  4 16:10:47 2011
              State : clean, degraded
     Active Devices : 1
    Working Devices : 1
     Failed Devices : 1
      Spare Devices : 0
    
               UUID : d37240a0:95da8141:7aa4d888:5d41f52f
             Events : 0.30558
    
        Number   Major   Minor   RaidDevice State
           0       0        0        0      removed
           1       8       23        1      active sync   /dev/sdb7
    
           2       8        7        -      faulty spare   /dev/sda7
  3. Проблема с /dev/sda. Нужно это винчестер заменить на аналогичный по размеру. Выключаем компьютер. Заменяем винчестер. Проверяем:
    [root@vm ~]# fdisk -l | less
    Disk /dev/sda: 1000.2 GB, 1000204886016 bytes
    255 heads, 63 sectors/track, 121601 cylinders
    Units = cylinders of 16065 * 512 = 8225280 bytes
    
    
    Disk /dev/sdb: 1000.2 GB, 1000204886016 bytes
    255 heads, 63 sectors/track, 121601 cylinders
    Units = cylinders of 16065 * 512 = 8225280 bytes
    
       Device Boot      Start         End      Blocks   Id  System
    /dev/sdb1   *           1        2550    20482843+  fd  Linux raid autodetect
    /dev/sdb2            2551      109635   860160262+  fd  Linux raid autodetect
    /dev/sdb3          109636      113459    30716280   fd  Linux raid autodetect
    /dev/sdb4          113460      121601    65400615    5  Extended
    /dev/sdb5          113460      116009    20482843+  fd  Linux raid autodetect
    /dev/sdb6          116010      118049    16386268+  fd  Linux raid autodetect
    /dev/sdb7          118050      119324    10241406   fd  Linux raid autodetect
  4. Новый неразмеченный винчестер добавлен как sda. Утилитой sfdisk скопируем структуру разделов с рабочего HDD (sdb) на новый HDD (sda).
    [root@vm ~]# sfdisk -d /dev/sdb | sfdisk /dev/sda
  5. Проверяем разбивку. Видим что новый HDD разбит идентично старому:
    [root@vm ~]# fdisk -l | less
    Disk /dev/sda: 1000.2 GB, 1000204886016 bytes
    255 heads, 63 sectors/track, 121601 cylinders
    Units = cylinders of 16065 * 512 = 8225280 bytes
    
       Device Boot      Start         End      Blocks   Id  System
    /dev/sda1   *           1        2550    20482843+  fd  Linux raid autodetect
    /dev/sda2            2551      109635   860160262+  fd  Linux raid autodetect
    /dev/sda3          109636      113459    30716280   fd  Linux raid autodetect
    /dev/sda4          113460      121601    65400615    5  Extended
    /dev/sda5          113460      116009    20482843+  fd  Linux raid autodetect
    /dev/sda6          116010      118049    16386268+  fd  Linux raid autodetect
    /dev/sda7          118050      119324    10241406   fd  Linux raid autodetect
    
    Disk /dev/sdb: 1000.2 GB, 1000204886016 bytes
    255 heads, 63 sectors/track, 121601 cylinders
    Units = cylinders of 16065 * 512 = 8225280 bytes
    
       Device Boot      Start         End      Blocks   Id  System
    /dev/sdb1   *           1        2550    20482843+  fd  Linux raid autodetect
    /dev/sdb2            2551      109635   860160262+  fd  Linux raid autodetect
    /dev/sdb3          109636      113459    30716280   fd  Linux raid autodetect
    /dev/sdb4          113460      121601    65400615    5  Extended
    /dev/sdb5          113460      116009    20482843+  fd  Linux raid autodetect
    /dev/sdb6          116010      118049    16386268+  fd  Linux raid autodetect
    /dev/sdb7          118050      119324    10241406   fd  Linux raid autodetect
  6. Добавляем каждый раздел в предназначенный ему RAID. Чтобы не ошибиться при добавлении, лучше предварительно используя команду mdadm –query –detail /dev/md? узнать какая по номеру партиция диска sdb добавлена и подставить аналогичную с нового диска sda.
    [root@vm ~]# mdadm --add /dev/md0 /dev/sda1
    mdadm: added /dev/sda1
    [root@vm ~]# mdadm --add /dev/md1 /dev/sda6
    mdadm: added /dev/sda6
    [root@vm ~]# mdadm --add /dev/md2 /dev/sda7
    mdadm: added /dev/sda7
    ...
  7. Проверить синхронизацию, после добавления в RAID можно командой
    [root@vm ~]# cat /proc/mdstat 
    Personalities : [raid1] 
    md5 : active raid1 sda2[2] sdb2[1]
          860160192 blocks [2/1] [_U]
           resync=DELAYED
          
    md3 : active raid1 sda3[2] sdb3[1]
          30716160 blocks [2/1] [_U]
           resync=DELAYED
          
    md4 : active raid1 sda5[2] sdb5[1]
          20482752 blocks [2/1] [_U]
           resync=DELAYED
          
    md1 : active raid1 sda6[0] sdb6[1]
          16386176 blocks [2/2] [UU]
          
    md2 : active raid1 sda7[2] sdb7[1]
          10241280 blocks [2/1] [_U]
          [=====>...............]  recovery = 28.4% (2914880/10241280) finish=2.3min speed=51682K/sec
          
    md0 : active raid1 sda1[0] sdb1[1]
          20482752 blocks [2/2] [UU]
          
    unused devices: <none>
После замены вылетевшего диска нужно обязательно установить на новый диск grub.
В этом случае используется первый grub. Установим grub на /dev/sda:
# cat /boot/grub/device.map
# this device map was generated by anaconda
(hd0)     /dev/sda
(hd1)     /dev/sdb
[root@vm ~]# grub
Probing devices to guess BIOS drives. This may take a long time.

    GNU GRUB  version 0.97  (640K lower / 3072K upper memory
...
grub> root (hd0,0)     

root (hd0,0)
 Filesystem type is ext2fs, partition type 0xfd

grub> setup (hd0)
setup (hd0)
 Checking if "/boot/grub/stage1" exists... yes
 Checking if "/boot/grub/stage2" exists... yes
 Checking if "/boot/grub/e2fs_stage1_5" exists... yes
 Running "embed /boot/grub/e2fs_stage1_5 (hd0)"...  15 sectors are embedded.
succeeded
 Running "install /boot/grub/stage1 (hd0) (hd0)1+15 p (hd0,0)/boot/grub/stage2 /boot/grub/grub.conf"... succeeded
Done.

Мониторинг состояния. Настройка оповещения.

  • Информация о всех RAID-массивах:
# more /proc/mdstat или # cat /proc/mdstat
  • Настроим проверку состояния RAID каждый час. В папке /etc/cron.hourly создадим файл mdraidstate:
# cd /etc/cron.hourly/
# touch mdraidstate
# chmod +x mdraidstate
# nano mdraidstate

#!/bin/sh

/sbin/mdadm --monitor --scan -1 --mail=test@your.domen
# mdadm --monitor --mail=your_mail@here --delay=600 /dev/md*
<code>
Для проверки рассылки сообщения добавляется ключ --test:
<code>
/sbin/mdadm --monitor --scan -1 --mail=test@your.domen --test
Если нужно чаще, самое простое решение, добавить в /etc/crontab строку, используя нотацию с "/", например:
*/5 * * * * root run-parts /etc/cron.my5min
предварительно нужно создать папку /etc/cron.my5min и поместить туда файл (файлы), которые нужно запускать раз в 5 минут.
  • Скрипт для принудительной проверки mdadm. Скрипт должен запускать единоразово при загрузке ОС.
  • в Fedora существует скрипт /etc/cron.weekly/99-raid-check. Для работы скрипта нужно изменить несколько параметров в конфигурационном файле
    # nano /etc/sysconfig/raid-check
    ENABLED=yes
    CHECK=check
    # To check devs /dev/md0 and /dev/md3, use "md0 md3"
    #CHECK_DEVS=""
    CHECK_DEVS="md0 md3 md4 md5"
    REPAIR_DEVS=""
    SKIP_DEVS=""
  • Скрипт checkarray
    # nano /etc/cron.d/mdadm
    #
    # cron.d/mdadm -- schedules periodic redundancy checks of MD devices
    #
    # Copyright © martin f. krafft <madduck@madduck.net>
    # distributed under the terms of the Artistic Licence 2.0
    #
    
    # By default, run at 00:57 on every Sunday, but do nothing unless the day of
    # the month is less than or equal to 7. Thus, only run on the first Sunday of
    # each month. crontab(5) sucks, unfortunately, in this regard; therefore this
    # hack (see #380425).
    57 0 * * 0 root [ -x /usr/share/mdadm/checkarray ] && [ $(date +\%d) -le 7 ] && /usr/share/mdadm/checkarray --cron --all --quiet --status

Работа с утилитой mdadm. Изменение типа массива, chunk size, расширение 

Введение


К написанию данной статьи меня побудило отсутствие внятной информации на русском языке по работе с утилитой mdadm, реализующей RAID различных типов в ОС linux. В принципе, основные положения работы данной утилиты освещаются достаточно подробно. Почитать об этом можно, например, раздватри.

Преобразование RAID1 в RAID5


Основным посылом было преобразование RAID1, созданного при установке Ubuntu массива из двух дисков к RAID5. Начал я, как водится с гугления, и набрел на более раннюю статью на Хабре К сожалению, протестированный на виртуальных машинах, этот способ гарантировано убивал возможность загрузки с корневого раздела. С чем это связано, с более новой версией mdadm, или со спецификой тестирования (корневой раздел на массиве, требуется работа с live CD) выявить не удалось.

Версия системы
root@u1:/home/alf# uname -a
Linux u1 3.2.0-23-generic #36-Ubuntu SMP Tue Apr 10 20:39:51 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux


Разметка диска в моем случае была проще некуда, я смоделировал ее на тестовой виртуальной машине, выделив для дисков по 20 гигов:


Корневой раздел находится на собранных в массив устройствах /dev/sda2 /dev/sdb2 и имеет имя /dev/md0 в базовой системе. Загрузочный раздел находится на обоих дисках, /boot в отдельный диск не выделен.
В версии mdadm v3.2.5, которая устанавливается по умолчанию в Ubuntu, процедура конвертации RAID возможна в направлении 1->5, и невозможна обратно. Выполняется она командой изменения массива –grow, -G. Перед конвертацией вставьте в устройство флешку и примонтируйте ее для сохранения резервного суперблока. В случае сбоев с нее мы будем восстанавливать массив. Монтируем ее в /mnt/sdd1
mkdir /mnt/sdd1
mount /dev/sdd1 /mnt/sdd1
mdadm --grow /dev/md0 --level=5 --backup-file=/mnt/sdd1/backup1

Операция обычно проходит очень быстро и безболезненно. Тут нужно отметить, что получившийся массив типа RAID5 на двух дисках является фактически массивом RAID1, с возможностью расширения. Полноценным RAID5 он станет только при добавлении еще хотя бы одного диска.
Чрезвычайно важно то, что наш загрузочный раздел находится на этом массиве и после перезагрузки GRUB автоматически не подгрузит модули для запуска. Для этого мы делаем обновление загрузчика
update-grub

Если же вы все-таки забыли сделать обновление, и после перезагрузки получили
cannot load raid5rec
grub rescue>

то не отчаивайтесь, вам достаточно загрузится с LiveCD, скопировать на флешку каталог /boot, перегрузиться снова с основного раздела в grub rescue> и подгрузить модуль RAID5 c флешки согласно распространенным инструкциям, например так.
Добавляете строчку insmod /boot/grub/raid5rec.mod 
После загрузки с основного раздела не забываем сделать update-grub

Расширение массива RAID5


Расширения измененного массива описано во всех источниках и проблем не представляет. Питание не выключаем.
  1. Клонируем структуру существующего диска
    sfdisk –d /dev/sda | sfdisk /dev/sdc
  2. Добавляем диск к массиву
    mdadm /dev/md0 --add /dev/sdc2
  3. Расширяем массив
    mdadm --grow /dev/md0 --raid-device=3 --backup-file=/mnt/sdd1/backup2
  4. Ждем окончания переконфигурации и наблюдаем за процессом
    watch cat /proc/mdstat
  5. Устанавливаем загрузочный сектор на новый диск
    grub-install /dev/sdc
  6. Обновляем загрузчик
    update-grub
  7. Расширяем свободное место до максимального, работает на живом и смонтированном разделе.
    resize2fs /dev/md0
  8. Смотрим на получившийся массив
    mdadm --detail /dev/md0
  9. Смотрим на свободное место
    df -h


Изменение Chunk Size существующего массива RAID5


В массиве RAID1 понятие Chunk Size отсутствует, т.к. это размер блока, который по очереди пишется на разные диски. При конвертации типа массива к RAID5 этот параметр появляется в выводе детализированной информации о массиве:
Mdadm –detail /dev/md0
/dev/md0:
        Version : 1.2
  Creation Time : Tue Oct 29 03:57:36 2013
     Raid Level : raid5
     Array Size : 20967352 (20.00 GiB 21.47 GB)
  Used Dev Size : 20967352 (20.00 GiB 21.47 GB)
   Raid Devices : 2
  Total Devices : 2
    Persistence : Superblock is persistent

    Update Time : Tue Oct 29 04:35:16 2013
          State : clean
 Active Devices : 2
Working Devices : 2
 Failed Devices : 0
  Spare Devices : 0

         Layout : left-symmetric
     Chunk Size : 8K

           Name : u1:0  (local to host u1)
           UUID : cec71fb8:3c944fe9:3fb795f9:0c5077b1
         Events : 20

    Number   Major   Minor   RaidDevice State
       0       8        2        0      active sync   /dev/sda2
       1       8       18        1      active sync   /dev/sdb2


При этом размер chunk выбирается согласно правилу: Наибольший общий делитель размера массива (в нашем случае 20967352К) и максимального автоматически выставляемого размера chunk(который составляет 64К). В моем случае максимально возможный размер chunk составляет 8K (20967352/8=2620919 дальше на 2 не делится).

Если вы в дальнейшем планируете добавлять диски, увеличивая размер массива, то вам желательно в определенный момент сменить размер chunk. Про производительность можно почитать достаточно интересную статью.
Для изменения параметра chunk в массиве необходимо привести его размер в соответствие с мультипликатором. Перед этим важно изменить размер раздела, т.к. если вы будете резать по живому максимальному разделу, то скорее всего затрете суперблок раздела, и гарантированно испортите файловую систему.

Как вычислить необходимый размер раздела для нужного вам размера chunk? Берем максимальный текущий размер раздела в килобайтах
mdadm --detail /dev/md0 | grep Array
Делим нацело на требуемый нам размер chunk и на (количество дисков в массиве-1, для RAID5). Полученное число снова умножаем на размер chunk и на (количество дисков в массиве -1), и итогом будет нужный нам размер раздела.
(41934704/256)/2=81903; 81903*256*2=41934336

Изменить размер раздела в сторону уменьшения невозможно на рабочем, смонтированном разделе, и, поскольку он у нас корневой, мы перезагружаемся с любого LiveCD (мне нравится RescueCD, у него mdadm загружается автоматически)
  1. Проверяем запущенные массивы
    Cat /proc/mdstat
    Обнаруживаем, что наш массив в режиме RO
  2. Пересобираем его в обычном режиме
    Mdadm --stop /dev/md127
    Mdadm --assemble --scan
  3. Выполняем проверку массива на ошибки с автоисправлением
    e2fsck -f /dev/md127
  4. Меняем размер активного раздела, указывая в качестве параметра -S 256, чтобы утилита понимала, что данный раздел будет находится на RAID-массиве и добавляя в конец нового размера массива буковку K, чтобы утилита не посчитала данное число — числом блоков
    resize2fs -p S 256 /dev/md127 41934336K
  5. Для изменения размеров массива используем снова параметр --grow в утилите mdadm. Нужно учитывать, изменение массива происходит на каждом диске, а потому в параметрах указываем не общий требуемый размер массива, а размер массива на каждом диске, соответственно делить нужно на (количество дисков в массиве -1). Операция проходит мгновенно
    41934336/2=20967168
    mdadm --grow /dev/md127 --size=20967168
  6. Перезагружаемся в обычный режим, изменяем размер chunk, не забывая предварительно смонтировать флешку для бэкапа суперблока, и ждем окончания пересинхронизации массива.
    mdadm --grow /dev/md0 --chunk=256 --backup-file=/mnt/sdd1/backup3
    watch cat /proc/mdstat

Операция долгая, гораздо дольше, чем добавление диска, приготовьтесь ждать. Питание, как водится, отключать нельзя.

Восстановление массива


Если на каком-то этапе работы с массивом через mdadm у вас произошел сбой, то для восстановления массива из бэкапа (вы же не забыли указать файл для бэкапа?) вам необходимо загрузится с liveCD и пересобрать массив заново с указанием правильной последовательности дисков, входящих в массив и указанием суперблока для загрузки
mdadm --assemble /dev/md0 /dev/sda2 /dev/sdb2 /dev/sdc2 --backup-file=/mnt/sdd1/backup3
В моем случае последняя операция по изменению chunk массива перевела его в состояние *reshape, однако сам процесс пересборки не начинался длительное время. Пришлось перезагружаться с liveCD и восстанавливать массив. После этого пошел процесс пересборки массива, и по окончанию оного размер Chunk Size был уже новый, 256K.


Комментарии

Популярные сообщения из этого блога

Права на папки и файлы (unix/chmod)

Автоматическое монтирование дисков и разделов в Linux или что такое fstab? Проблема Debian

Подключение USB флешки к Debian