Расширяем RAID10 в mdadm

Решил поиграться с расширением software raid10 на своей машине. Заодно написать статью.

Подготовка

У меня в наличии GPT диск /dev/sdb, два раздела используются под /home (raid1) и swap. Все манипуляции буду делать с ним.
Текущее состояние разделов на диске:

$ sudo fdisk /dev/sdb

Welcome to fdisk (util-linux 2.27.1).
Changes will remain in memory only, until you decide to write them.                                                                        
Be careful before using the write command.                                                                                                 
                                                                                                                                           
Command (m for help): p
Disk /dev/sdb: 465,8 GiB, 500107862016 bytes, 976773168 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 004791FC-E27A-4B7F-890A-96AE57B2420E

Device         Start       End   Sectors   Size Type
/dev/sdb1       2048 765640704 765638657 365,1G Linux RAID
/dev/sdb2  765642752 782223359  16580608   7,9G Linux swap

Подготавливаем раздел — создаем 4 раздела объемом 239МиБ.

Command (m for help): n
Partition number (3-128, default 3): 
First sector (782223360-976773134, default 782223360): 
Last sector, +sectors or +size{K,M,G,T,P} (782223360-976773134, default 976773134): +238,6M

Created a new partition 3 of type 'Linux filesystem' and of size 239 MiB.

Command (m for help): n   
Partition number (4-128, default 4): 
First sector (782712832-976773134, default 782712832): 
Last sector, +sectors or +size{K,M,G,T,P} (782712832-976773134, default 976773134): +238,6M

Created a new partition 4 of type 'Linux filesystem' and of size 239 MiB.

Command (m for help): n
Partition number (5-128, default 5): 
First sector (783202304-976773134, default 783202304): 
Last sector, +sectors or +size{K,M,G,T,P} (783202304-976773134, default 976773134): +238,6M

Created a new partition 5 of type 'Linux filesystem' and of size 239 MiB.

Command (m for help): n
Partition number (6-128, default 6): 
First sector (783691776-976773134, default 783691776): 
Last sector, +sectors or +size{K,M,G,T,P} (783691776-976773134, default 976773134): +238,6M

Created a new partition 6 of type 'Linux filesystem' and of size 239 MiB.

В результате получилось такая картина:

Command (m for help): p
Disk /dev/sdb: 465,8 GiB, 500107862016 bytes, 976773168 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 004791FC-E27A-4B7F-890A-96AE57B2420E

Device         Start       End   Sectors   Size Type
/dev/sdb1       2048 765640704 765638657 365,1G Linux RAID
/dev/sdb2  765642752 782223359  16580608   7,9G Linux swap
/dev/sdb3  782223360 782712831    489472   239M Linux filesystem
/dev/sdb4  782712832 783202303    489472   239M Linux filesystem
/dev/sdb5  783202304 783691775    489472   239M Linux filesystem
/dev/sdb6  783691776 784181247    489472   239M Linux filesystem

Записываем изменения на диск и выходим с утилиты fdisk:

Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Re-reading the partition table failed.: Device or resource busy

Ругнулся — перечитываю карту разделов утилитой partprobe

$ sudo partprobe /dev/sdb

Создаем массив raid10, ext4 на нем и монтируем:

$ sudo mdadm  --create /dev/md10 --level=10 --raid-devices=4 /dev/sdb3 /dev/sdb4 /dev/sdb5 /dev/sdb6
mdadm: Defaulting to version 1.2 metadata
mdadm: array /dev/md10 started.

$ sudo mkfs.ext4 /dev/md10
mke2fs 1.42.13 (17-May-2015)
Creating filesystem with 487424 1k blocks and 121920 inodes
Filesystem UUID: f0be0e7f-d1dc-4ecc-bc3d-29781ca253c8
Superblock backups stored on blocks: 
        8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done 

$ test -d /mnt/test || sudo mkdir /mnt/test
$ sudo mount /dev/md10 /mnt/test
$ sudo  mdadm --detail /dev/md10
/dev/md10:
        Version : 1.2
  Creation Time : Thu Jan  5 12:51:15 2017
     Raid Level : raid10
     Array Size : 487424 (476.08 MiB 499.12 MB)
  Used Dev Size : 243712 (238.04 MiB 249.56 MB)
   Raid Devices : 4
  Total Devices : 4
    Persistence : Superblock is persistent

    Update Time : Thu Jan  5 12:52:28 2017
          State : active 
 Active Devices : 4
Working Devices : 4
 Failed Devices : 0
  Spare Devices : 0

         Layout : near=2
     Chunk Size : 512K

           Name : panaceya:10  (local to host panaceya)
           UUID : b3fb9ea9:5762490b:8755d242:3e36350d
         Events : 20

    Number   Major   Minor   RaidDevice State
       0       8       19        0      active sync set-A   /dev/sdb3
       1       8       20        1      active sync set-B   /dev/sdb4
       2       8       21        2      active sync set-A   /dev/sdb5
       3       8       22        3      active sync set-B   /dev/sdb6

Расширение массива и файловой системы.

Я не стал заморачиваться с расширением существующих разделов — просто создал 4 раздела с большим объемом. Для тестов вполне хватит.
Нужно поочередно каждый раздел:

  1. поставить в статус fail
  2. удалить с массива
  3. произвести расширение блоков (для живого сервера — в этой статье я использую просто другой раздел)
  4. добавить новый раздел в массив
  5. дождаться окончания синхронизации (мета)данных на массиве

Порядок не важен. Я пошел с последнего.

Пример п.п. 1-4 для первого раздела /dev/sdb6 (заменяю на /dev/sdb7):

$ sudo mdadm --manage /dev/md10 --fail /dev/sdb6
mdadm: set /dev/sdb6 faulty in /dev/md10
$ sudo mdadm --manage /dev/md10 --remove /dev/sdb6
mdadm: hot removed /dev/sdb6 from /dev/md10
$ sudo mdadm --manage /dev/md10 --add /dev/sdb7

Ждем окончания синхронизации командой

sudo mdadm --wait /dev/md10

или смотрим watch`ем:

watch -n 1 cat /proc/mdstat

Остальные разделы меняем аналогично, и всегда дожидаемся окончания синхронизации.

Расширяем размер самого массива до максимально возможного.

mdadm --grow /dev/md10 --size=max 

На живом проекте используйте опцию —backup-file, которая ведет на другой диск (неиспользуемый в массиве, NFS-шару или ISCSI)

mdadm --grow --backup-file=/mnt/backup /dev/md1  --size=max 

В итоге у меня получился следующее состояние:

$ sudo cat /proc/mdstat
md10 : active raid10 sdb7[4] sdb10[7] sdb9[6] sdb8[5]
      974848 blocks super 1.2 512K chunks 2 near-copies [4/4] [UUUU]
$ sudo mdadm --detail /dev/md10
/dev/md10:
        Version : 1.2
  Creation Time : Thu Jan  5 12:51:15 2017
     Raid Level : raid10
     Array Size : 974848 (952.16 MiB 998.24 MB)
  Used Dev Size : 487424 (476.08 MiB 499.12 MB)
   Raid Devices : 4
  Total Devices : 4
    Persistence : Superblock is persistent

    Update Time : Thu Jan  5 14:08:37 2017
          State : active 
 Active Devices : 4
Working Devices : 4
 Failed Devices : 0
  Spare Devices : 0

         Layout : near=2
     Chunk Size : 512K

           Name : panaceya-work:10  (local to host panaceya-work)
           UUID : b3fb9ea9:5762490b:8755d242:3e36350d
         Events : 158

    Number   Major   Minor   RaidDevice State
       7       8       26        0      active sync set-A   /dev/sdb10
       6       8       25        1      active sync set-B   /dev/sdb9
       5       8       24        2      active sync set-A   /dev/sdb8
       4       8       23        3      active sync set-B   /dev/sdb7

Размонтируем FS и расширяем:

$ sudo umount /dev/md10
$ sudo resize2fs -f /dev/md10 
resize2fs 1.42.13 (17-May-2015)
Resizing the filesystem on /dev/md10 to 974848 (1k) blocks.
The filesystem on /dev/md10 is now 974848 (1k) blocks long.

Все. Монтируем обратно.

PS: почему-то я находил материалы, в которых сказано что raid10 не расширяется или не расширяется на горячем (online).