Как я образ диска виртуалки восстанавливал

На днях произошло чудо. В плохом смысле этого слова. :( Неведомо по какой причине, внезапно попортился образ виртуальной машины. Причём машина та была с биллингом. Инфа критически важная и как на зло, не имеющая актуального бэкапа на тот момент. Работал себе виртуальный сервер и вдруг начал безбожно тупить без явных причин. После перезагрузки, в консоли всплыло предложение сделать fsck, на что я по глупости повёлся, забив на необходимость предварительно снять копию. Уже через 5 минут я нервно пытался укусить себя за локоть, поскольку эта процедура ушатала раздел так, что он больше не читался и не исправлялся никакими инструментами.

Почему, собственно, не было бэкапа? Да потому, что намедни эту виртуалку я перенёс с другой платформы, которую в свою очередь надо было грохнуть, чтобы сделать там хранилище для бэкапов. Кто бы мог подумать, что именно в этом промежутке возникнет такая проблема? Закон Мёрфи в классическом варианте…

Немного пошевелив мозгом, я решил попробовать для начала восстановить LVM раздел на старом хранилище, которое я уже успел очистить. Иногда лень бывает очень кстати… Хоть я и очистил хранилище, в связи с приходом выходных, я не успел туда ничего записать и по этому шансы восстановить данные были практически стопроцентными.

step-by-step:

И так, мне понадобилось восстановить всю структуру LVM, дабы выковырять оттуда LV раздел, в котором была заветная инфа, хоть уже и не совсем актуальная.

Делается это следующим образом:

cd /etc/lvm/backup/

В этой директории LVM2 аккуратно складывает информацию о pv (физический том) и vg (группа томов), которые были созданы на дисках.

Если там что-либо осталось – это гуд. Пробуем восстановить:

vgcfgrestore -f /etc/lvm/backup/st1 st1

Активируем

lvmdiskscan
lvs -a -o +devices

Смотрим, что получилось

root@st1:~# vgs
VG #PV #LV #SN Attr VSize VFree
VolGroup 1 2 0 wz--n- 9.51g 0
st1 1 16 0 wz--n- 5.46t 5.46t

Замечательно. Группа на месте. Но разделы ещё не восстановлены. Переходим в директорию с архивами, где хранятся все манипуляции с логическими дисками:

root@st1:~# cd /etc/lvm/archive/
root@st1:/etc/lvm/archive# ls
st1_00251-221876201.vg
st1_00290-2082643790.vg
st1_00252-24104864.vg

st1_00291-180822193.vg
....

Если открыть один из них, можно увидеть конфигурацию дисков, которые существовали в группе на тот момент. Выбираем самую жизнеспособную и тестируем:

root@st1:/etc/lvm/archive# vgcfgrestore prim --test -f /etc/lvm/archive/st1_00275-669926956.vg
TEST MODE: Metadata will NOT be updated and volumes will not be (de)activated.
Restored volume group st1

[quads id=2]

Вроде бы всё ок? Тогда делаем то же самое, но уже в боевом режиме:
root@st1:/etc/lvm/archive# vgcfgrestore prim -f /etc/lvm/archive/st1_00275-669926956.vg

После того, как группа будет поднята из архива, нужно просканировать её и активировать найденные логические разделы

root@st1:/etc/lvm/archive# lvscan
inactive '/dev/st1/volume-4b748459-83f2-4b3a-9298-fe02764785b5' [11.00 GiB] inherit
inactive '/dev/st1/shared' [500.00 GiB] inherit
inactive '/dev/st1/volume-41597caa-007a-4880-8c03-f8f6aa59953e' [31.00 GiB] inherit
inactive '/dev/st1/volume-8826f883-42ac-46cf-a90c-2c9407c51a77' [31.00 GiB] inherit
inactive '/dev/st1/volume-a0d819ee-c08f-40c8-a789-7bef1ac14ffb' [300.00 GiB] inherit

Найденные разделы ещё не активны. Активируем нужное и мапим содержимое:

lvchange -a y /dev/st1/volume-8826f883-42ac-46cf-a90c-2c9407c51a77

kpartx -a /dev/st1/volume-8826f883-42ac-46cf-a90c-2c9407c51a77

Теперь переходим в /dev/mapper и видим там разделы, которые есть внутри интересующего нас LVM.

root@st1:/dev/mapper# ls |grep st1-volume--8826f883
st1-volume--8826f883--42ac--46cf--a90c--2c9407c51a77
st1-volume--8826f883--42ac--46cf--a90c--2c9407c51a77p1
st1-volume--8826f883--42ac--46cf--a90c--2c9407c51a77p2
st1-volume--8826f883--42ac--46cf--a90c--2c9407c51a77p5

Теперь можно просто смонтировать нужный раздел. Но я преследовал несколько иные цели. Мне нужно было как то восстановить актуальный диск при помощи старого, поскольку инфа, оставшаяся там была очень важна. Предварительно сделав копии обоих разделов, я начал экспериментировать с восстановлением. Проблема в том, что на новом разделе были раздолбаны все суперблоки и у меня не получилось ничего восстановить даже при помощи резервных. И тут мне в голову пришла совершенно идиотская идея! Я решил скрестить кусочек резервного диска (точнее его раздела) с разделом битого, чтобы воткнуть обратно суперблок, который по идее может дать шанс на восстановление. Поскольку диски по структуре совершенно идентичные, это выглядело вполне обнадёживающе.

Создаём новый lvm раздел и копируем туда битый диск.

lvcreate -L 32G -n billrectest st1
dd if=/root/billpart2.img of=/dev/st1/billrectest

Затем приступаем к операции:

dd if=/dev/mapper/st1-volume--8826f883--42ac--46cf--a90c--2c9407c51a77p1 of=/dev/st1/billrectest bs=51200 count=1

И так, мы выдрали 50 килобайт из начала раздела. (пробовал куски поменьше – не прокатило).

Разумеется, после такой “прививки” смонтировать диск не получится, ведь он всё ещё повреждён. Чиним диск…

fsck.ext4 -y /dev/st1/billrectest

Конечно, тут нет никакой гарантии, но мне повезло. Не смотря на то, что половина файловой системы упала в lost+found а 2.5% было вообще безвозвратно потеряно, каким то чудом база данных уцелела! В конечном итоге я перенёс актуальные данные в резервную копию и запустил сервер. На часах было 6 часов утра… Я с облегчением открыл бутылочку пива и опустошив её до дна, отправился спать. ;)