Pull to refresh

Comments 20

RAID5 на двух дисках никоим образои не может быть RAID1, т.к. у RAID1 нет parity.
Да и сама возможность создания RAID5 на двух дисках какая-то странная, мне на ум приходит только RAID5EE.
В выводе утилиты mdadm --detail он отображается как RAID5, и количество дисков равняется UU, то есть двум. При этом если не добавляя диск мы удалим из конфигурации один mdadm --fail /dev/sdb2 --remove /dev/sdb2, то система продолжит свою работу, массив перейдет в состояние degraded, однако данные будут по прежнему доступны. Значит ведет он себя как классический RAID1.
Логика подсказывает, что в данном случае все остается по прежнему, конфигурация RAID1, меняется только наименование.
При этом добавив диск до трех и выполнив reshape вы получите уже стандартную конфигурацию RAID5 с последовательной записью и блоком checksum.
На двух дисках может быть деградированный RAID5. Который ресинкается при подключении третьего.
именно в случае RAID5 на утилите mdadm у вас есть возможность указать при создании тип массива RAID5, а количество дисков — два. И в этом случае вам удастся создать массив, и он не будет в статусе degrade. Я согласен, что он будет не классическим RAID5, а простейшим RAID1, и тут кроется подвох терминологии. Создатель утилиты так ее сделал, что тип массива отображается в виде RAID5, а фактический тип массива будет RAID1.
А-а, вот вы про что. Да, это будет почти что RAID1, но в отличие от последнего на дисках будут не копии данных, а первый будет содержать негатив второго. Не забываем также про страйпинг: половина блоков первого диска будет содержать данные, половина — негативы, а на втором диске — данные где на первом негатив, и наоборот.
очень странно, ведь для подобных изменений нужно время. А смена типа массива с RAID1 на RAID5 происходит мгновенно даже на виртуальной машине, без всяческих reshape.
Как такое может быть в случае, если оба диска наполовину преобразуются в негативы? На это же нужно время reshape?
Смена массива с точки зрения cat /proc/mdstat происходит мгновенно (точнее, за очень короткий критический период, во время которого переписываются метаданные на всех участвующих устройствах). Но если вы посмотрите на формат метаданных, то увидите, что там есть особые поля:
— Какой был раньше формат массива
— На каком этапе преобразование (сколько блоков уже преобразовано, номер первого непреобразованного блока).
И вот это самое преобразование происходит в фоне и далеко не мгновенно — а как минимум, за время, необходимое, чтобы записать новый диск целиком (и эта нижняя временнАя граница, по-моему, совершенно очевидна).
Наврал: хранится не «какой был раньше», а «какой будет в итоге» формат массива.
И при этом он не показывает статистику и прогресс данного преобразования, делая его скрытым от пользователя, а так же во время этого преобразования можно выполнять прочие операции с массивом, я правильно понимаю?
Ну тогда наиболее вероятно, что я вас не понял. Можете конкретно описать, что именно вы делали, я повторю (как время будет) и разберусь, что именно он делает? (Ну если это отличается от статьи, разумеется. Так-то я что только не делал, экспериментируя с softraid в линуксах...)
Возможно это я вас не понял, т.к. я изменял тип RAID так, как описал это в статье, и при смене типа он не выполняет reshape для двух дисков, а так же прекрасно дает сразу же добавлять еще диск в массив, или удалять диск из массива, не теряя информации.
В какой момент он должен производить преобразование блоков при изменении типа массива?
Вообще сразу после grow.

А что покажет
mdadm --detail /dev/md0

сразу после вашего mdadm --grow /dev/md0 --level=5 --backup-file=/mnt/sdd1/backup1 (третья команда, в самом начале, до добавления третьего диска)?
root@u1:/home/alf# mdadm --detail /dev/md0
/dev/md0:
        Version : 1.2
  Creation Time : Fri Nov  1 05:44:00 2013
     Raid Level : raid1
     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 : Fri Nov  1 06:08:30 2013
          State : clean
 Active Devices : 2
Working Devices : 2
 Failed Devices : 0
  Spare Devices : 0

           Name : u1:0  (local to host u1)
           UUID : 63e24f74:2a1b03c1:4151c2a0:eb8ac91f
         Events : 19

    Number   Major   Minor   RaidDevice State
       0       8        2        0      active sync   /dev/sda2
       1       8       18        1      active sync   /dev/sdb2
root@u1:/home/alf# mdadm --grow /dev/md0 --level=5 --backup-file=/mnt/sdd1/backup1
mdadm: level of /dev/md0 changed to raid5
mdadm: failed to set chunk size
root@u1:/home/alf# cat /proc/mdstat
Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
md0 : active raid5 sdb2[1] sda2[0]
      20967352 blocks super 1.2 level 5, 8k chunk, algorithm 2 [2/2] [UU]

unused devices: <none>

времени не затрачено на reshape
Так я просил --detail сразу после --grow --level 5. Как он выглядит на работающем raid1 я и так знаю, интересно, как он выглядит сразу после конверсии.
root@u1:/home/alf# mdadm --detail /dev/md0
/dev/md0:
        Version : 1.2
  Creation Time : Fri Nov  1 12:23:49 2013
     Raid Level : raid1
     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 : Fri Nov  1 13:46:27 2013
          State : clean
 Active Devices : 2
Working Devices : 2
 Failed Devices : 0
  Spare Devices : 0

           Name : u1:0  (local to host u1)
           UUID : 0138d79c:6a9bb1ab:c732b3ea:21f036c3
         Events : 21

    Number   Major   Minor   RaidDevice State
       0       8        2        0      active sync   /dev/sda2
       1       8       18        1      active sync   /dev/sdb2
root@u1:/home/alf# mdadm --grow /dev/md0 --level=5 --backup-file=/mnt/sdd1/backup1
mdadm: level of /dev/md0 changed to raid5
mdadm: failed to set chunk size
root@u1:/home/alf# mdadm --detail /dev/md0
/dev/md0:
        Version : 1.2
  Creation Time : Fri Nov  1 12:23:49 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 : Fri Nov  1 13:47:03 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 : 0138d79c:6a9bb1ab:c732b3ea:21f036c3
         Events : 22

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

Вот теперь я отчётливо вижу, что чего-то не понимаю :)

Ну что же. Я залез в исходники, нашёл там интересующий меня момент. Для «raid5 из двух дисков» действительно в ядре есть special case, и в комментарии habrahabr.ru/post/200194/#comment_6930036 я заблуждаюсь сам и ввожу в заблуждение других.

Файл linux-3.10.7-gentoo-r1/drivers/md/raid5.c, функция ops_run_compute5. Я выкинул всё, что не относится к рассчёту count, по остаткам можно понять, как count меняется:
        //...
        int count = 0;
        //...
        for (i = disks; i--; )
                if (i != target)
                        xor_srcs[count++] = sh->dev[i].page;
        //...
        if (unlikely(count == 1))
                tx = async_memcpy(xor_dest, xor_srcs[0], 0, 0, STRIPE_SIZE, &submit);
        else
                tx = async_xor(xor_dest, xor_srcs, 0, count, STRIPE_SIZE, &submit);
        //...

Для случая 2-х дисков будет вызван вариант memcpy, для остальных — xor. unlikely() здесь — это фишка ядра для ускорения работы, optimize very likely/unlikely branches, логика этого кода полностью совпадает со случаем когда никакого unlikely нет в помине и написано просто if (count==1).

Так что я ошибся, «linux software RAID5 из двух дисков» устроен так же, как RAID1. (Как приятно, что это можно проверить, прочитав исходники.) Прошу прощения за то, что ввёл в заблуждение и заставил проверять.

Но видно другое :) он поставил chunk size 8k. Это, кажется, неприлично мало. На raid1 этот размер не имеет значения и поэтому не был заполнен в метаданных, на raid5 он важен, но не был указан и поэтому при конверсии mdadm взял его с потолка. Как-то надо при изменении типа указывать размер чанка.

не совсем с потолка. Данный размер chunk size вычисляется
/* chunk size is meaningful, must divide component_size
 * evenly
*/
        if (info->component_size % (info->new_chunk/512)) {
              unsigned long long shrink = info->component_size;
              shrink &= ~(unsigned long long)(info->new_chunk/512-1);
              pr_err("New chunk size (%dK) does not evenly divide device size (%lluk)\n",
              info->new_chunk/1024, info->component_size/2);
              pr_err("After shrinking any filesystem, \"mdadm --grow %s --size %llu\"\n",
              devname, shrink/2);
              pr_err("will shrink the array so the given chunk size would work.\n");
              return "";
              }

не уверен, что исходники в генту не отличаются от этих, т.к. источник странный. fossies.org/dox/mdadm-3.3/Grow_8c_source.html

Конкретно для моей тестовой ситуации я написал, что больше чем на 8 размер массива не делится.
Нет, исходники в этой части в генту не отличаются, я гарантирую это. Больше того, скорее всего этот файл (raid5.c) несколько нет не менялся и он такой вообще во всех современных дистрибутивах.
это участок из файла, отвечающего за операцию расширения массива --grow, и сверху над сорцами написано, что он для mdadm 3.3, а у меня стоит 3.2.5. Правда скорее всего именно этот кусок не менялся :)

Ну и по поводу chunk size — на домашнем массиве в 2928180032К прекрасно выставился 64K автоматически, что подтверждает запись в сорцах о поиске наибольшего общего делителя.
Sign up to leave a comment.

Articles