Есть ли способ "атомарно" размонтировать FS, сделать снимок LVM и смонтировать его обратно?
Можно сделать моментальный снимок смонтированной файловой системы, даже если файловая система не находится на томе LVM. Если файловая система находится в LVM или имеет встроенные средства моментальных снимков (например, btrfs или ZFS), используйте их вместо этого.
Приведенные ниже инструкции являются довольно низкоуровневыми, но могут быть полезны, если вы хотите иметь возможность снимать файловую систему, которая не находится на томе LVM, и не можете переместить ее на новый том LVM. Тем не менее, они не для слабонервных: если вы допустите ошибку, вы можете испортить свою файловую систему. Обязательно обратитесь к официальной документации и dmsetup
справочной странице, трижды проверьте команды, которые вы выполняете, и имеют резервные копии !
Ядро Linux имеет удивительное средство, называемое Device Mapper, которое может делать полезные вещи, такие как создание блочных устройств, которые являются «представлениями» других блочных устройств, и, конечно, снимки. Это также то, что LVM использует под капотом для выполнения тяжелых работ.
В следующих примерах я предполагаю, что вы хотите сделать снимок /home
, который является файловой системой ext4, расположенной в /dev/sda2
.
Сначала найдите имя устройства сопоставления устройств, на котором смонтирован раздел:
# mount | grep home
/dev/mapper/home on /home type ext4 (rw,relatime,data=ordered)
Здесь имя устройства сопоставления устройств - home
. Если путь к блочному устройству не начинается с /dev/mapper/
, вам необходимо создать устройство сопоставления устройств и перемонтировать файловую систему, чтобы использовать это устройство вместо раздела жесткого диска. Вам нужно будет сделать это только один раз.
# dmsetup create home --table "0 $(blockdev --getsz /dev/sda2) linear /dev/sda2 0"
# umount /home
# mount -t ext4 /dev/mapper/home /home
Далее получите таблицу сопоставления устройств блочного устройства:
# dmsetup table home
home: 0 3864024960 linear 9:2 0
Ваши номера, вероятно, будут другими. Цель устройства должна быть linear
; если у вас нет, вам может потребоваться принять особые меры. Если последнее число (начальное смещение) не равно 0, вам нужно создать промежуточное блочное устройство (с той же таблицей, что и текущее) и использовать его в качестве основы вместо /dev/sda2
.
В приведенном выше примере home
использует таблицу с одним входом с целью linear
. Вам нужно будет заменить эту таблицу на новую, в которой используется цель snapshot
.
Устройство отображения предоставляет три цели для моментального снимка:
Цель snapshot
, которая сохраняет записи на указанное устройство COW. (Обратите внимание, что хотя это и называется снимком, терминология вводит в заблуждение, поскольку снимок будет доступен для записи, но базовое устройство останется без изменений.)
Цель snapshot-origin
, которая отправляет записи на базовое устройство, но также отправляет старые данные, которые были записаны поверх, на указанное устройство COW.
Как правило, вы делаете цель home
snapshot-origin
, а затем создаете несколько целей snapshot
поверх нее. Это то, что делает LVM. Однако более простым способом было бы просто создать цель snapshot
напрямую, что я покажу ниже.
Независимо от выбранного вами метода, вы не должны выполнять запись на базовое устройство (/dev/sda2
), иначе снимки будут отображать искаженное представление файловой системы. Поэтому в качестве меры предосторожности следует пометить базовое блочное устройство только для чтения:
# blockdev --setro /dev/sda2
Это не повлияет на устройства отображения устройств, поддерживаемые им, поэтому, если вы уже перемонтировали /home
на /dev/mapper/home
, это не должно иметь заметного эффекта.
Далее вам необходимо подготовить устройство COW, в котором будут храниться изменения с момента создания снимка. Это должно быть блочное устройство, но оно может быть подкреплено разреженным файлом. Если вы хотите использовать разреженный файл, например, 32GB:
# dd if=/dev/zero bs=1M count=0 seek=32768 of=/home_cow
# losetup --find --show /home_cow
/dev/loop0
Очевидно, что разреженный файл не должен находиться в файловой системе, которую вы снимаете:)
Теперь вы можете перезагрузить таблицу устройства и превратить ее в устройство моментального снимка:
# dmsetup suspend home && \
dmsetup reload home --table \
"0 $(blockdev --getsz /dev/sda2) snapshot /dev/sda2 /dev/loop0 PO 8" && \
dmsetup resume home
Если это удастся, новые записи в /home
теперь должны записываться в файл /home_cow
, а не записываться в /dev/sda2
. Обязательно следите за размером файла COW, а также за свободным пространством в файловой системе, в которой он находится, чтобы избежать исчерпания пространства COW.
Если снимок больше не нужен, вы можете объединить его (чтобы окончательно зафиксировать изменения в файле COW на базовом устройстве) или удалить его.
Чтобы объединить это:
заменить таблицу с целью snapshot-merge
вместо цели snapshot
:
# dmsetup suspend home && \
dmsetup reload home --table \
"0 $(blockdev --getsz /dev/sda2) snapshot-merge /dev/sda2 /dev/loop0 P 8" && \
dmsetup resume home
Далее следите за состоянием объединения, пока не будут объединены все блоки неметаданных:
# watch dmsetup status home
...
0 3864024960 snapshot-merge 281688/2097152 1104
Обратите внимание на 3 цифры в конце (X / Y Z). Слияние завершено, когда X = Z.
Затем снова замените таблицу линейной целью:
# dmsetup suspend home && \
dmsetup reload home --table \
"0 $(blockdev --getsz /dev/sda2) linear /dev/sda2 0" && \
dmsetup resume home
Теперь вы можете разобрать петлевое устройство:
# losetup -d /dev/loop0
Наконец, вы можете удалить файл COW.
# rm /home_cow
Чтобы отменить моментальный снимок, размонтируйте /home
, выполните шаги 3-5 выше и перемонтируйте /home
. Хотя Device Mapper позволит вам сделать это без размонтирования /home
, это не имеет смысла (так как состояние запущенных программ в памяти больше не будет соответствовать состоянию файловой системы), и это, вероятно, повредит вашу файловую систему.