TL;DR:Использование параметра -c
, как описано выше, в целом работает. Когда снимки содержат жесткие ссылки, в ядре Linux возникает ошибка, которая вызывает ошибку при отправке снимков — подробности см. в заключении в конце ответа.
Я экспериментирую с параметром -c
, и он выглядит многообещающе:
# for i in {0..3}; do btrfs send testvol_$i $(ls -d testvol_* | head -n$i | sed 's/^/-c /'); done | wc -c
### btrfs send testvol_0
### btrfs send testvol_1 -c testvol_0
### btrfs send testvol_2 -c testvol_0 -c testvol_1
### btrfs send testvol_3 -c testvol_0 -c testvol_1 -c testvol_2
At subvol testvol_0
At subvol testvol_1
At subvol testvol_2
At subvol testvol_3
838778546 # also 800MiB
Я до сих пор не уверен, что это то, что мне нужно. Есть комментарии к этому решению?
Обновление:Чтобы проверить это на моей реальной файловой системе, я написал сценарий Perl для удобной отправки набора подтомов (, создание списков для -c
быстро стало утомительным )и отправил некоторые данные в/dev/null
:
#!/usr/bin/env perl
use strict;
use warnings;
my @subvols = @ARGV
or die "Usage: $0 SUBVOLUME...\n";
for(@subvols) {
-d $_
or die "Not a directory: $_\n";
}
for my $i (0.. $#subvols) {
my $subvol = $subvols[$i];
my @clones = map { ('-c', $_) } @subvols[ 0.. $i-1 ];
print "btrfs send $subvol @clones\n";
}
Результаты:
btrfs send some-subvolme_* | pv > /dev/null
:24 ГБ 0 :04 :17 [95,2 МБ/с] perl btrfs-send-all.pl some-subvolume_* | bash | pv > /dev/null
:12,7 ГБ 0 :03 :58 [54,7 МБ/с] Это незначительное увеличение производительности, но почти 50-процентное уменьшение объема памяти ! Сейчас я пытаюсь запустить это в реале…
Обновление:Я успешно перенес 2 снимка, но для третьего btrfs receive
произошел сбой со следующим сообщением об ошибке:
ERROR: unlink path/to/some/file/in/the/snapshot failed. No such file or directory
Именованный файл присутствует в subvol_2
и subvol_3
, но еще не в subvol_1
.
Я пытался сравнить отправленные и полученные снимки:
# ### sender
# du -s subvol_{1,2,3}
132472304 subvol_1
117069504 subvol_2
126015636 subvol_3
# ### receiver
# du -s subvol_*
132472304 subvol_1
117069504 subvol_2
132472304 subvol_3
Первые два снимка передаются правильно, но subvol_3
является клоном subvol_1
. Это определенно клон, потому что используемое пространство на резервном диске составляет всего 39% от совокупного размера моментальных снимков — чуть больше 1/3, поскольку они совместно используют большинство файлов.
Почему btrfs send subvol_3 -c subvol_1 -c subvol_2 | btrfs receive
неправильно передает снимок, а клонирует subvol_1
, а затем не может удалить файл, который должен храниться в subvol_3
и присутствует только в subvol_2
??
Обновление:Может ли это быть ошибкой?https://patchwork.kernel.org/patch/10073969/
Я использую Debian 9 Stretch с ядром 4.9, которое кажется более старым, чем патч.
Обновление:Поскольку я не смог найти никакого решения, я просто скопировал самый последний моментальный снимок каждого подтома. Затем у меня было примерно 500 ГБ свободного места, и я попытался добавить предыдущий снимок с параметром уже скопированный снимок как -p
. Затем я получил то же сообщение об ошибке для того же снимка, что и выше.
Заключение:Я пришел к выводу, что столкнулся с ошибкой, указанной выше.Мне пришлось перезагрузить эту машину с более новым ядром Linux или получить доступ к файловой системе с другого компьютера, но это невозможно, потому что это производственная система.
До сих пор у меня не было проблем с btrfs, но запуск rsnapshot, который создает много жестких ссылок, и отправка снимков btrfs все еще могут вызывать проблемы в текущей стабильной версии Debian.
Не уверен, что это хорошее решение, но на основанииhttps://stackoverflow.com/questions/4233808/piping-data-to-linux-program-which-expects-a-tty-terminalкажется, что unbuffer
выполняет это.
unbuffer exa | less
покажет цвета.