Бывает, что нужно получить полную копию тома в рамках одной системы хранения данных (СХД), не снимок, клон, а именно полноценный том. Но не всегда СХД дает это сделать внутри себя собственными средствами. Вроде единственный вариант копировать через сервер, но при этом весь объем данных будет гоняться через сам сервер, сеть до СХД и порты СХД, нагружая все эти компоненты. Но есть SCSI команды, которые могут позволить сделать все в рамках самой СХД и если ваша система поддерживает VAAI от VMware, то практически 100%, что поддерживается команда XCOPY (EXTENDED COPY), которая и говорит массиву что и куда скопировать, не вовлекая в этот процесс сервер и сеть.
Вроде как все должно быть просто, но так сходу я готовых скриптов не нашел, пришлось изобретать велосипед. Для ОС сервера был выбран Linux, а в качестве средства копирования команда ddpt (http://sg.danny.cz/sg/ddpt.html). Копировать с помощью такой комбинации можно любые тома от любой ОС, поскольку копирование идет поблочно на стороне СХД. Поскольку надо копировать поблочно, а количество блоков надо посчитать, то для подсчета количества таких итераций использовалась команда blockdev. Максимальный размер блока был получен опытным путем, с большим блоком ddpt не работал по факту. В итоге получился следующий довольно простой скрипт:
Давайте сделаем небольшую проверку! Ну как небольшую, 1ТБ файл создавался и проверялся md5sum небыстро :)
Что в этот момент происходило на СХД:
Продолжим с Линуксом.
Все получилось, но тестируйте и используйте на свой страх и риск! Как исходный том лучше брать снепшоты, для начала.
Вроде как все должно быть просто, но так сходу я готовых скриптов не нашел, пришлось изобретать велосипед. Для ОС сервера был выбран Linux, а в качестве средства копирования команда ddpt (http://sg.danny.cz/sg/ddpt.html). Копировать с помощью такой комбинации можно любые тома от любой ОС, поскольку копирование идет поблочно на стороне СХД. Поскольку надо копировать поблочно, а количество блоков надо посчитать, то для подсчета количества таких итераций использовалась команда blockdev. Максимальный размер блока был получен опытным путем, с большим блоком ddpt не работал по факту. В итоге получился следующий довольно простой скрипт:
#!/bin/bash
# first parameter = input device
# second parameter = output device
# device size must be the same
# changing bs variable can reduce speed, max speed should be at bs=32768. 32768 is max setting, lower settings should be calculated dividing by 2
set -o nounset
bs=32768
s=`blockdev --getsz $1`
i=0
while [ $i -le $s ]
do
ddpt of=$2 bs=512 oflag=xcopy,direct if=$1 iflag=xcopy,direct count=$bs verbose=-1 skip=$i seek=$i
i=$(( $i+$bs ))
done
Давайте сделаем небольшую проверку! Ну как небольшую, 1ТБ файл создавался и проверялся md5sum небыстро :)
root@sales-demo-05:/home/vasilyk# blockdev --getsz /dev/mapper/mpathfs
2516582400
root@sales-demo-05:/home/vasilyk# blockdev --getsz /dev/mapper/mpathfr
2516582400
root@sales-demo-05:/home/vasilyk# mount /dev/mapper/mpathfs /xcopy_source/
mount: /xcopy_source: wrong fs type, bad option, bad superblock on /dev/mapper/mpathfs, missing codepage or helper program, or other error.
root@sales-demo-05:/home/vasilyk# mkfs /dev/mapper/mpathfs
mke2fs 1.44.1 (24-Mar-2018)
Discarding device blocks: done
Creating filesystem with 314572800 4k blocks and 78643200 inodes
Filesystem UUID: bed3ea00-c181-4b4e-b52e-d9bb498be756
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
4096000, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968,
102400000, 214990848
Allocating group tables: done
Writing inode tables: done
Writing superblocks and filesystem accounting information: done
root@sales-demo-05:/home/vasilyk# mount /dev/mapper/mpathfs /xcopy_source/
root@sales-demo-05:/home/vasilyk# ls -l /xcopy_source/
total 16
drwx------ 2 root root 16384 Aug 19 15:35 lost+found
root@sales-demo-05:/home/vasilyk# head -c 1T </dev/urandom > /xcopy_source/1TB_file
root@sales-demo-05:/home/vasilyk# ls -l /xcopy_source/
total 1074791444
-rw-r--r-- 1 root root 1099511627776 Aug 19 17:25 1TB_file
drwx------ 2 root root 16384 Aug 19 15:35 lost+found
root@sales-demo-05:/home/vasilyk# umount /xcopy_source
root@sales-demo-05:/home/vasilyk# mount /dev/mapper/mpathfr /xcopy_dest/
mount: /xcopy_dest: wrong fs type, bad option, bad superblock on /dev/mapper/mpathfr, missing codepage or helper program, or other error.
root@sales-demo-05:/home/vasilyk# cat xcopy.sh
#!/bin/bash
# first parameter = input device
# second parameter = output device
# device size must be the same
# changing bs variable can reduce speed, max speed should be at bs=32768. 32768 is max setting, lower settings should be calculated dividing by 2
bs=32768
s=`blockdev --getsz $1`
i=0
while [ $i -le $s ]
do
ddpt of=$2 bs=512 oflag=xcopy,direct if=$1 iflag=xcopy,direct count=$bs verbose=-1 skip=$i seek=$i
i=$(( $i+$bs ))
done
root@sales-demo-05:/home/vasilyk# time ./xcopy.sh /dev/mapper/mpathfs /dev/mapper/mpathfr
real 11m30.878s
user 2m3.000s
sys 1m11.657s
Что в этот момент происходило на СХД:
Продолжим с Линуксом.
root@sales-demo-05:/home/vasilyk# mount /dev/mapper/mpathfr /xcopy_dest/
root@sales-demo-05:/home/vasilyk# ls -l /xcopy_dest/
total 1074791444
-rw-r--r-- 1 root root 1099511627776 Aug 19 17:25 1TB_file
drwx------ 2 root root 16384 Aug 19 15:35 lost+found
root@sales-demo-05:/home/vasilyk# mount /dev/mapper/mpathfs /xcopy_source/
root@sales-demo-05:/home/vasilyk# md5sum /xcopy_source/1TB_file
53dc6dfdfc89f099c0d5177c652b5764 /xcopy_source/1TB_file
root@sales-demo-05:/home/vasilyk# md5sum /xcopy_dest/1TB_file
53dc6dfdfc89f099c0d5177c652b5764 /xcopy_dest/1TB_file
root@sales-demo-05:/home/vasilyk#
Все получилось, но тестируйте и используйте на свой страх и риск! Как исходный том лучше брать снепшоты, для начала.
polar_yogi
Статья о возможностях, которые знать полезно. Но есть несколько вопросов:
1. какая СХД использовалась
2. какова скорость копирования без использования xcopy
3. для копирования используется скрипт который выполняет работу частями — вычисляет размер устройств, вызывает ddpt для копирования 16МБ (32к блоков по 512байт) каждый раз делая seek/skip для уже скопированных данных. Зачем? Почему не убрать count совсем и оставить эту работу ddpt:
Кстати, исходя из написанного, if и of не обязательно должны иметь одинаковый размер.
4. Размер блока установлен в 512 байт, это оптимально?
5. В чем смысл команды tail /xcopy_dest/1TB_file | strings?
vkostr Автор
1 и 2 — это не являлось целью исследований, использовалось то, что под рукой (InfiniBox) и скорость копирования без XCOPY не замерялась (можно замерить, но там много параметров будет влиять)
3 не хотелось отдавать определение количества итераций, а хотелось задать в явном виде, но можно сделать и как вы предлагаете
4 Ну скажем так, все считают размеры таким блоком, так было проще сделать, если скорость копирования не устраивает, то можно попробовать поиграть тут, но это не тот блок, которым происходит копирование, а указание СХД скопировать некоторое количество таких блоков
5 для того чтобы понять что файлы получились одинаковые. По идее надо бы чексумму считать, но на 1ТБ файле было как-то уже лень
Я сейчас может попробую еще поиграться и посмотреть по пунктам 2, 4 и 5
vkostr Автор
Кстати, по пункту 4 глянул статистику на СХД, размер блока был 16МБ, то есть запрос от ddpd в 32768 кусочков по 512 байт был собран в один IO запрос, так что наверное я тут с этим играться не буду, на данной СХД сомнительно что будет лучше.
vkostr Автор
Ну что же, по пункту 2, если убрать ключ xcopy, то около 100 мегабайт в секунду, если взять dd и увеличить блок, то около 400 мегабайт. Подозреваю, что можно делать в несколько потоков и будет быстрее. Что также касается и XCOPY — если разбить по адресам том на несколько кусков и делать XCOPY параллельно, то тоже может быть быстрее.
По пункту 5 сделал через md5sum, так и статья стала покороче :)