/ect/lvm/lvm.conf, похоже, указывает на то, что 'thin_pool_zero' включен по умолчанию. Запуск 'lvs' показывает атрибут 'z' для логических томов с тонкой подачей, но, например, 'cat /sys/block/dm-34/queue/discard_zeroes_data' указывает на то, что ядро не учитывает это или не знает об этом. Я не могу найти никаких сообщений по этому поводу. Это задумано (возможно, из-за того, что LVM-thin не обнуляет данные атомарно) или еще не написан необходимый код ядра? Мы используем следующий относительно простой bash-скрипт для обновления блочных устройств (дисков VM) на серверах в резервном центре. Скрипт в основном считывает и сравнивает 1КБ хэши MD5 и затем либо пропускает следующий блок, либо передает этот блок. Работает очень хорошо как со снимками на исходе (консистентный исходный образ), так и на месте назначения (последний снимок является консистентным образом, пока оригинал патчится). Мы надеялись найти способ заставить LVM-thin игнорировать блоки нулей, чтобы сэкономить место на DR-сайте, хотя, похоже, такого пока нет. Гостевые системы используют параметры монтирования discard или запускают дефрагментацию диска с TRIM (Windows) на сервере-источнике, но наша схема репликации в результате записывает нули в пункт назначения, если этот блок ранее содержал данные, поэтому образы назначения медленно растут со временем. Было бы идеально, если бы LVM-thin мог обнаруживать участки, содержащие только нули, и автоматически освобождать их, или если бы мы могли периодически обрабатывать блочные устройства для достижения этого. В настоящее время мы периодически запускаем VM в среде DR и вручную выполняем fstrim или дефрагментацию диска, но хотели бы, чтобы это было автоматизировано. P.S.: Чтение нулей из невыделенного пространства с LVM-thin также происходит очень быстро, так как на самом деле не нужно считывать никаких данных. Вот скрипт, который мы запускаем каждую ночь на системе Proxmox в удаленном офисе, надеюсь, он будет полезен кому-то (использует 'lzop' для сжатия хэшей и данных в пути): P.S.: Скрипт ниже взят из другого устаревшего хоста, который все еще использует стандартный LVM (без тонких томов). Изменить его несложно, так как требуется лишь небольшая настройка команды lvcreate. Код: #!/bin/sh
network_kvm_backup () {
src_vg=$1;
src_lvm=$2;
snapsize=$3;
dst_host=$4;
dst_vg=$5;
export dev1="/dev/$src_vg/$src_lvm-snap1";
export dev2="/dev/$dst_vg/$src_lvm-backup";
export remote="root@$dst_host";
logger "Начинаем обновлять $dev1 на $dst_host как $dev2";
[ "$src_vg" = "vg_kvm" ] && stripes=2 || stripes=1;
lvcreate -i $stripes -L $snapsize /dev/$src_vg/$src_lvm -s -n $dev1 > /dev/null;
ssh -i /root/.ssh/rsync_rsa $remote "
perl -'MDigest::MD5 md5' -ne 'BEGIN{\$/=\1024};print md5(\$_)' $dev2 | lzop -c" |
lzop -dc | perl -'MDigest::MD5 md5' -ne 'BEGIN{$/=\1024};$b=md5($_);
read STDIN,$a,16;if ($a eq $b) {print "s"} else {print "c" . $_}' $dev1 | lzop -c |
ssh -i /root/.ssh/rsync_rsa $remote "lzop -dc |
perl -ne 'BEGIN{\$/=\1} if (\$_ eq\"s\") {\$s++} else {if (\$s) {
seek STDOUT,\$s*1024,1; \$s=0}; read ARGV,\$buf,1024; print \$buf}' 1<> $dev2"
logger "Завершили обновление $dev1 на $dst_host как $dev2";
lvremove -f $dev1 > /dev/null;
}
# src_vg src_lvm snapsize dst_host dst_vg
network_kvm_backup vg_kvm lair-nt01 50G dr2.lair.co.za lvm0
network_kvm_backup vg_kvm lair-eppdns 5G dr2.lair.co.za lvm0
network_kvm_backup vg_kvm lair-webapp 5G dr3.lair.co.za lvm0