Предисловие Ссылка на заголовок
Вот и пришла пора увеличить место на своём домашнем сервере, для этого было куплено 2 диска разных производителей, но одинакового объёма.
Захотелось сделать soft RAID1, но мне не очень подходит mdadm, так как я хочу иметь более гибкое зеркало, которое можно будет легко расширить в будущем, а не выделять сразу большой объём.
Решил попытать счастья с LVM RAID, но информации по нему, в сжатом виде, мало, в основном всё заканчивает на том, как его создать. Попробую исправить этот пробел.

Мои диски
LVM Ссылка на заголовок
Нам понадобится 2 диска, если вы собираетесь настраивать RAID, если нет, то просто пропускайте части с настройкой второго диска.
Для тестирования необязательно иметь настоящие диски, можно использовать обычные файлы: How to create virtual block device (loop device/filesystem) in Linux
sdX, sdY, sdZ, во избежание потери данных на реальных носителях.Инициализация Ссылка на заголовок
Казалось бы, сделал pvcreate над диском и готово, но не тут то было…
Согласно рекомендациям1 2, стоит всегда создавать разделы на диске, во избежание проблем с софтом, который не знает об LVM и будет считать диск пустым.
Для разбивки диска я буду использовать gdisk, обычно уже установлен, но если что, устанавливается командой:
apt install gdiskgdisk /dev/sdX# Смотрим разделы и проверяем, тот ли мы диск выбрали.
p
# Создаём пустую GUID partition table.
o # жмём `y`, чтобы удалить все разделы и создать GPT запись.
# Создаём первый и единственный раздел на весь диск.
n
1
<enter>
<enter>
8e00 # Указываем, что данный раздел относится к LVM.
# Теперь можно просмотреть то, что получилось.
p
# Если всё устраивает, то осталось записать изменения на диск.
w # жмём `y`, чтобы подтвердить запись.проделываем то же самое со вторым диском.
Добавляем диски в LVM
pvcreate /dev/sdX1 /dev/sdY1
# или коротко
pvcreate /dev/sd[XY]1Создаём группу vgdata из двух дисков
vgcreate vgdata /dev/sdX1 /dev/sdY1
# или коротко
vgcreate vgdata /dev/sd[XY]1Простой логический диск Ссылка на заголовок
Создаём простой логический диск с именем lv0 на 3ГБ:
lvcreate --size 3G --name lv0 vgdata
# или коротко
lvcreate -L 3G -n lv0 vgdataRAID 1 (mirror) Ссылка на заголовок
Создаём логический диск с RAID 1 под именем lvmirror на 3ГБ:
lvcreate --size 3G --name lvmirror --mirrors 1 vgdata
# или коротко
lvcreate -L 3G -n lvmirror -m1 vgdataможно указать флаг --nosync, чтобы пропустить синхронизацию пустого зеркала.
Смотрим что получилось Ссылка на заголовок
lvs -a -o +devicesКолонка Cpy%Sync показывает, процент синхронизации, а Devices, устройства, на которых находятся данные логического диска.
FS Ссылка на заголовок
Осталось создать файловую систему:
mkfs.ext4 /dev/vgdata/lvmirrorИ можно примонтировать и пользоваться
mount /dev/vgdata/lvmirror /mnt/Тестируем LVM RAID 1 и учимся чинить Ссылка на заголовок
Как можно доверять свои данные технологии, когда ты не знаешь, что произойдёт в случае нештатной ситуации и как всё починить без потери данных.
Для начала, посмотрим, как у нас всё выглядит до начала тестов:
lvs -a -o +devices,lv_health_statusLV VG Attr LSize Cpy%Sync Devices Health
lvmirror vgdata rwi-aor--- 3.00g 100.00 lvmirror_rimage_0(0),lvmirror_rimage_1(0)
[lvmirror_rimage_0] vgdata iwi-aor--- 3.00g /dev/sdX1(1)
[lvmirror_rimage_1] vgdata iwi-aor--- 3.00g /dev/sdY1(1)
[lvmirror_rmeta_0] vgdata ewi-aor--- 4.00m /dev/sdX1(0)
[lvmirror_rmeta_1] vgdata ewi-aor--- 4.00m /dev/sdY1(0)Теперь мы можем приступать к тестированию, но сначала:
Отвал диска (ресинхронизация) и его замена Ссылка на заголовок
В данном случае, мы будем симулировать отвал диска, через изменение его состояния 3
Отключаем диск sdX:
echo offline > /sys/block/sdX/device/stateТеперь, чтобы LVM понял, что с диском что-то не то, нужно записать на диск данные.
Если FS есть:
echo test > /mnt/test.txt Если FS нет(эта команда уничтожит FS, если она есть!):
dd if=/dev/zero of=/dev/vgdata/lvmirror count=10Смотрим результат:
lvs -a -o +devices,lv_health_status/dev/sdX: open failed: No such device or address
/dev/sdX: open failed: No such device or address
/dev/sdX: open failed: No such device or address
WARNING: Couldn't find device with uuid VkIceg-2ZVd-tTuZ-HgHz-EblT-5GwQ-oH3gKM.
WARNING: VG vgdata is missing PV VkIceg-2ZVd-tTuZ-HgHz-EblT-5GwQ-oH3gKM (last written to /dev/sdX1).
WARNING: Couldn't find all devices for LV vgdata/lvmirror_rmeta_0 while checking used and assumed devices.
WARNING: Couldn't find all devices for LV vgdata/lvmirror_rimage_0 while checking used and assumed devices.
LV VG Attr LSize Cpy%Sync Devices Health
lvmirror vgdata rwi-aor-p- 3.00g 100.00 lvmirror_rimage_0(0),lvmirror_rimage_1(0) partial
[lvmirror_rimage_0] vgdata iwi-aor-p- 3.00g [unknown](1) partial
[lvmirror_rimage_1] vgdata iwi-aor--- 3.00g /dev/sdY1(1)
[lvmirror_rmeta_0] vgdata ewi-aor-p- 4.00m [unknown](0) partial
[lvmirror_rmeta_1] vgdata ewi-aor--- 4.00m /dev/sdY1(0)Обратите внимание, статус Health стал partial
Теперь запишем рандомные данные на диск, чтобы можно было увидеть рассинхронизацию:
FS есть, пишем в файл /mnt/random.file:
dd if=/dev/urandom of=/mnt/random.file bs=10M count=10 FS нет(эта команда уничтожит FS, если она есть!):
dd if=/dev/urandom of=/dev/vgdata/lvmirror bs=10M count=10Включаем диск sdX обратно:
echo running > /sys/block/sdX/device/stateСмотрим результат:
lvs -a -o +devices,lv_health_statusLV VG Attr LSize Cpy%Sync Devices Health
lvmirror vgdata rwi-aor-r- 3.00g 100.00 lvmirror_rimage_0(0),lvmirror_rimage_1(0) refresh needed
[lvmirror_rimage_0] vgdata Iwi-aor-r- 3.00g /dev/sdX1(1) refresh needed
[lvmirror_rimage_1] vgdata iwi-aor--- 3.00g /dev/sdY1(1)
[lvmirror_rmeta_0] vgdata ewi-aor-r- 4.00m /dev/sdX1(0) refresh needed
[lvmirror_rmeta_1] vgdata ewi-aor--- 4.00m /dev/sdY1(0)Ошибки и предупреждения об отсутствии диска пропали, но статус Health изменился на refresh needed
Чиним Ссылка на заголовок
Запускаем синхронизацию командой:
lvchange --refresh /dev/vgdata/lvmirrorНо если диск выпал, я бы рекомендовал его заменить на новый, проинициализировав его как в начале статьи и добавив в PV и VG:
pvcreate /dev/sdZ1
vgextend vgdata /dev/sdZ1И заменив диск у зеркала:
lvconvert --replace /dev/sdX1 /dev/vgdata/lvmirror /dev/sdZ1Замена мёртвого диска Ссылка на заголовок
Теперь давайте просимулируем замену мёртвого диска, для этого нам придётся стереть заголовок нашего диска, чтобы он выглядел как новый:
Эта команда уничтожит данные на диске!
dd if=/dev/zero of=/dev/sdX bs=10M count=1При вызове
lvs -a -o +devices,lv_health_statusМы увидим тот же результат, что и при отвале диска, статус Health стал partial, но чинится это по другому.
Чиним Ссылка на заголовок
Удалим старый диск из VG
vgreduce --removemissing --force vgdataТак как мы стёрли заголовки диска, нам придётся проинициализировать диск заново и добавить его в PV и VG:
pvcreate /dev/sdX1
vgextend vgdata /dev/sdX1И нужно починить наше зеркало
lvconvert --repair /dev/vgdata/lvmirrorАвтоматически запуститься ресинхронизация.
Конвертируем логический диск из RAID 1 в обычный Ссылка на заголовок
lvconvert -m0 /dev/vgdata/lvmirrorКонвертируем логический диск из обычного в RAID 1 Ссылка на заголовок
lvconvert -m1 /dev/vgdata/lvmirrorУвеличиваем размер диска с зеркалом Ссылка на заголовок
umount /dev/vgdata/lvmirror
# Добавляем 5GB к диску
lvresize --resizefs --size +5G /dev/vgdata/lvmirror
# Смотрим результат
lvsУменьшаем размер диска с зеркалом Ссылка на заголовок
umount /dev/vgdata/lvmirror
# Делаем диск равным 4GB
lvresize --resizefs --size 4G /dev/vgdata/lvmirror
# Смотрим результат
lvsМониторинг Ссылка на заголовок
Для мониторинга состояния LVM я написал exporter для prometheus
lvm_exporter
Как я всё сломал Ссылка на заголовок
Пока писал статью, успел сломать тестовый LVM
Inconsistent metadata Ссылка на заголовок
Когда отключил диск, я решил удалить лишнее зеркало (у меня было 2 LV зеркальных), после подключения диска обратно, у меня появилась ошибка при любой команде LVM:
WARNING: ignoring metadata seqno 20 on /dev/sdX1 for seqno 21 on /dev/sdY1 for VG vgdata.
WARNING: Inconsistent metadata found for VG vgdata
WARNING: outdated PV /dev/sdX1 seqno 20 has been removed in current VG vgdata seqno 21.После долгих поисков, нашёл нужную мне команду в багтрекере 4, которая мне помогла:
vgck --updatemetadata vgdata