В пуле необратимо повреждены данные файловых данных, которые являются частью моментального снимка. Если бы данные файла были частью файловой системы (а не частью какого-либо моментального снимка), я мог бы просто восстановить файл из подходящей резервной копии. Как я могу восстановить или исправить (и устранить ошибки, о которых сообщает ZFS) файл в снимке состояния из копии снимка или (частичного1) копия пула?
1 Если частичная копия содержит по крайней мере затронутый моментальный снимок, а предыдущий моментальный снимок также в затронутом пуле.
Вот чрезвычайно надуманный пример, который легко воспроизвести:
Из приглашения оболочки (bash):
cd
mkdir zfs-test
for i in {1..2}; do dd if=/dev/zero of=zfs-test/tank-file$i bs=1G count=1 &> /dev/null; done
sudo zpool create tank1 ~/zfs-test/tank-file1
sudo zpool create tank2 ~/zfs-test/tank-file2
sudo zfs snapshot tank1@snapshot1
sudo sh -c 'zfs send tank1@snapshot1 | zfs receive -F tank2'
Создать текстовый файл / tank1 / test-text-файл с контентом, который можно легко найти в шестнадцатеричном редакторе. Вот что я использовал:
Lorem ipsum dolor sit amet, conctetuer adipiscing elit. Aeneanmodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis disparturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla conquat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Целочисленный tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consquat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Энеанский непердиет. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui.
Опять же из приглашения оболочки:
sudo zfs snapshot tank1@snapshot2
sudo sh -c 'zfs send -i tank1@snapshot1 tank1@snapshot2 | zfs receive -F tank2'
Теперь вам нужно испортить данные файла. я использовал ht и я искал "дуи" и изменил его на "да".
Вы можете подтвердить, что данные повреждены:
sudo zpool scrub tank1; sudo zpool status -v tank1
pool: tank1
state: ONLINE
status: One or more devices has experienced an error resulting in data
corruption. Applications may be affected.
action: Restore the file in question if possible. Otherwise restore the
entire pool from backup.
see: http://zfsonlinux.org/msg/ZFS-8000-8A
scan: scrub repaired 0 in 0h0m with 1 errors on Sun Jan 11 20:16:30 2015
config:
NAME STATE READ WRITE CKSUM
tank1 ONLINE 0 0 1
/home/kenny/zfs-test/tank-file1 ONLINE 0 0 2
errors: Permanent errors have been detected in the following files:
tank1@snapshot2:/test-text-file
Всегда лучше использовать резервные пулы вместо неизбыточных (хотя это не всегда возможно). Приведенная выше проблема вряд ли возникнет в резервном пуле. И быстрее клонировать снимок (чтобы получить из него файл), чем где-то воссоздавать (если у вас, конечно, нет претензий к неисправному оборудованию).
Вот мое слегка обобщенное решение:
sudo cp /tank2/test-text-file /tank1/test-text-file
sudo zfs snapshot tank1@snapshot3
sudo sh -c 'zfs send -i tank1@snapshot2 tank1@snapshot3 | zfs receive -F tank2'
sudo zfs rollback -r tank1@snapshot1
sudo sh -c 'zfs send -i tank2@snapshot1 tank2@snapshot3 | zfs receive -F tank1'
sudo zpool scrub tank1; sudo zpool status -v tank1
И при условии, что других ошибок нет:
sudo zpool clear tank1
Причина, по которой я создал snapshot3
не потому, что это было необходимо для моего (чрезвычайно надуманного) примера, а потому, что это, вероятно, хорошая привычка для развития (и изначально я хотел проверить, будет ли она работать, как я надеялся). Если здесь мы любые другие изменения на tank1
поскольку snapshot2
, Я бы в идеале не потерял их, чтобы восстановить test-text-file
.