Начав googlить наткнулся на:
http://forums.freebsd.org/showthread.php?t=12088
http://forums.freebsd.org/showthread.php?t=11337
http://blogs.freebsdish.org/
http://lulf.geeknest.org/blog/freebsd/Using_4k_sector_drives/
Проблема в том, что диски, сообщают что их размер сектора будет 512 вместо 4096, для того, чтобы они хорошо работали с существующими операционными системами.
Обсуждали здесь и здесь.
В итоге, это приводит к двум основным проблемам:
Partitioning tools operate on 512 bytes "logical" sectors, which may result in a partition starting at a non-aligned (compared to 4096 bytes) physical sector. If using partitioning tools that are not updated to align partitions to 4k, a request may cause a write to more than one sector.
File systems/disk consumers think the underlying device has a 512 byte sector size, and issues requests that are below 4096 bytes. For a write request, this is catastrophic, because in order to write only parts of a block, the disk will have to read the block and modify the part that changed, before writing it back to disk (Read-modify-write)
Итак нам повезло т.к. имеется два зеркальных HDD, один из них мы разобьем как положено, а потом снова объеденим в рейд.
То что есть:
#gmirror list
Geom name: gm0
State: DEGRADED
Components: 2
Balance: round-robin
Slice: 4096
Flags: NONE
GenID: 0
SyncID: 3
ID: 1592264940
Providers:
1. Name: mirror/gm0
Mediasize: 640135028224 (596G)
Sectorsize: 512
Mode: r8w7e20
Consumers:
1. Name: ad6
Mediasize: 640135028736 (596G)
Sectorsize: 512
Mode: r1w1e1
State: ACTIVE
Priority: 0
Flags: DIRTY
GenID: 0
SyncID: 3
ID: 130311893
2. Name: ad8
Mediasize: 640135028736 (596G)
Sectorsize: 512
Mode: r1w1e1
State: ACTIVE
Priority: 0
Flags: DIRTY
GenID: 0
SyncID: 3
ID: 183839521
тест мирора с нагрузкой
I/O command overhead:
time to read 10MB block 6.008214 sec = 0.293 msec/sector
time to read 20480 sectors 181.905846 sec = 8.882 msec/sector
calculated command overhead = 8.589 msec/sector
тест мирора без нагрузки
I/O command overhead:
time to read 10MB block 0.455914 sec = 0.022 msec/sector
time to read 20480 sectors 2.929690 sec = 0.143 msec/sector
calculated command overhead = 0.121 msec/sector
тест винта с нагрузкой
I/O command overhead:
time to read 10MB block 1.502570 sec = 0.073 msec/sector
time to read 20480 sectors 16.512993 sec = 0.806 msec/sector
calculated command overhead = 0.733 msec/sector
тест самого винта без нагрузки
I/O command overhead:
time to read 10MB block 0.163781 sec = 0.008 msec/sector
time to read 20480 sectors 2.209027 sec = 0.108 msec/sector
calculated command overhead = 0.100 msec/sector
Разбраем зеркало:
gmirror remove gm0 ad8
dd if=/dev/zero of=/dev/ad8 bs=1M count=100
Далее всплывает тоже интересный момент. Поскольку Gmirror записывает данные о своей разметке в конец раздела или диска который в него включен то он затирает второй GPT header самого gpart (см. http://en.wikipedia.org/wiki/GUID_Partition_Table) и после перезагрузки gpart ругается на то что этот самый хеадер поврежден.
kernel: GEOM: ad8: the secondary GPT table is corrupt or invalid.
kernel: GEOM: ad8: using the primary only -- recovery suggested
Поэтому мы будем миррорить не весь диск а раздел gpart.
Создаем новые разделы и записываем в них загрузчик. Обращаем внимание на то что все разделы должны начинаться с сектора кратного 8 (8 * 512 = 4096).
gpart create -s GPT /dev/ad8
gpart bootcode -b /boot/pmbr ad8
/sbin/gpart add -b 40 -s 128 -t freebsd-boot ad8
/sbin/gpart bootcode -p /boot/gptboot -i 1 ad8
/sbin/gpart add -b 168 -t freebsd-ufs ad8
Создаем зеркало на раздел:
gmirror label -v -b round-robin gm1 ad8p2
Создаем на зеркале раздел под слайсы:
gpart create -s bsd mirror/gm1
Создаем слайсы:
/sbin/gpart add -s 2G -t freebsd-ufs mirror/gm1
/sbin/gpart add -s 4G -t freebsd-swap mirror/gm1
/sbin/gpart add -s 3G -t freebsd-ufs mirror/gm1
/sbin/gpart add -s 20G -t freebsd-ufs mirror/gm1
/sbin/gpart add -s 5G -t freebsd-ufs mirror/gm1
/sbin/gpart add -s 80G -t freebsd-ufs mirror/gm1
/sbin/gpart add -t freebsd-ufs mirror/gm1
Получили на выходе:
# gpart show
=> 34 1250263661 ad8 GPT (596G)
34 6 - free - (3.0K)
40 128 1 freebsd-boot (64K)
168 1250263527 2 freebsd-ufs (596G)
=> 0 1250263526 mirror/gm1 BSD (596G)
0 4194304 1 freebsd-ufs (2.0G)
4194304 8388608 2 freebsd-swap (4.0G)
12582912 6291456 4 freebsd-ufs (3.0G)
18874368 41943040 5 freebsd-ufs (20G)
60817408 10485760 6 freebsd-ufs (5.0G)
71303168 167772160 7 freebsd-ufs (80G)
239075328 1011188198 8 freebsd-ufs (482G)
# cd /dev/mirror; ls
gm1 gm1a gm1b gm1d gm1e gm1f gm1g gm1h
Форматируем слайсы:
newfs -S 4096 -b 32768 -f 4096 -O 2 -U -m 8 -o space /dev/mirror/gm1a
newfs -S 4096 -b 32768 -f 4096 -O 2 -U -m 8 -o space /dev/mirror/gm1d
newfs -S 4096 -b 32768 -f 4096 -O 2 -U -m 8 -o space /dev/mirror/gm1e
newfs -S 4096 -b 32768 -f 4096 -O 2 -U -m 8 -o space /dev/mirror/gm1f
newfs -S 4096 -b 32768 -f 4096 -O 2 -U -m 8 -o space /dev/mirror/gm1g
newfs -S 4096 -b 32768 -f 4096 -O 2 -U -m 8 -o space /dev/mirror/gm1h
Монтируем слайсы:
cd /mnt; mkdir data; mkdir root; mkdir var; mkdir usr; mkdir log
mount /dev/mirror/gm1a /mnt/root
mount /dev/mirror/gm1d /mnt/tmp
mount /dev/mirror/gm1e /mnt/var
mount /dev/mirror/gm1f /mnt/log
mount /dev/mirror/gm1g /mnt/usr
mount /dev/mirror/gm1h /mnt/data
Дампим систему с первого винта следующим скриптом:
#!/bin/sh
# резервное копирование основных разделов за исключением home
echo 'Начал копирование корневого раздела'
dump -0 -L -f - / | (cd /mnt/root; restore -v -r -f-)
echo 'Корневой раздел скопирован, жду 4 секунды'
sleep 4
echo 'Начал копирование usr раздела'
dump -0 -L -f - /usr | (cd /mnt/usr; restore -v -r -f-)
echo 'Раздел usr скопирован, жду 4 секунды'
sleep 4
echo 'Начал копирование var раздела'
dump -0 -L -f - /var | (cd /mnt/var; restore -v -r -f-)
echo 'Раздел var скопирован. Все задачи резервного копирования выполнены.'
sleep 4
echo 'Начал копирование log раздела'
dump -0 -L -f - /var/log | (cd /mnt/log; restore -v -r -f-)
echo 'Раздел var/log скопирован. Все задачи резервного копирования выполнены.'
sleep 4
echo 'Начал копирование data раздела'
dump -0 -L -f - /data | (cd /mnt/data; restore -v -r -f-)
echo 'Раздел data скопирован. Все задачи резервного копирования выполнены.'
Правим /mnt/root/etc/fstab
# Device Mountpoint FStype Options Dump Pass#
/dev/mirror/gm1b none swap sw 0 0
/dev/mirror/gm1a / ufs rw 1 1
/dev/mirror/gm1h /data ufs rw 2 2
/dev/mirror/gm1d /tmp ufs rw 2 2
/dev/mirror/gm1g /usr ufs rw 2 2
/dev/mirror/gm1e /var ufs rw 2 2
/dev/mirror/gm1f /var/log ufs rw 2 2
/dev/acd0 /cdrom cd9660 ro,noauto 0 0
После дампа перезагружаемся, проверяем чтоб все работало, тестируем скорость, убеждаемся что все в порядке и разбираем старое зеркало:
gmirror remove gm0 ad6
dd if=/dev/zero of=/dev/ad6 bs=1M count=100
Создаем boot раздел на первом HDD, копируем соответствующие микро коды и включаем его в зеркало:
gpart create -s GPT /dev/ad6
gpart bootcode -b /boot/pmbr ad6
/sbin/gpart add -b 40 -s 128 -t freebsd-boot ad6
/sbin/gpart bootcode -p /boot/gptboot -i 1 ad6
/sbin/gpart add -b 168 -t freebsd-ufs ad6
gmirror insert gm1 ad6p2
Что получили:
Миррор с нагрузкой:
# diskinfo -ctv /dev/mirror/gm1
/dev/mirror/gm1
512 # sectorsize
640134925312 # mediasize in bytes (596G)
1250263526 # mediasize in sectors
0 # stripesize
0 # stripeoffset
I/O command overhead:
time to read 10MB block 1.185152 sec = 0.058 msec/sector
time to read 20480 sectors 12.080955 sec = 0.590 msec/sector
calculated command overhead = 0.532 msec/sector
Seek times:
Full stroke: 250 iter in 5.224140 sec = 20.897 msec
Half stroke: 250 iter in 3.751464 sec = 15.006 msec
Quarter stroke: 500 iter in 7.027832 sec = 14.056 msec
Short forward: 400 iter in 4.914474 sec = 12.286 msec
Short backward: 400 iter in 5.262984 sec = 13.157 msec
Seq outer: 2048 iter in 1.491297 sec = 0.728 msec
Seq inner: 2048 iter in 1.189439 sec = 0.581 msec
Transfer rates:
outside: 102400 kbytes in 2.311209 sec = 44306 kbytes/sec
middle: 102400 kbytes in 5.421454 sec = 18888 kbytes/sec
inside: 102400 kbytes in 8.315827 sec = 12314 kbytes/sec
Миррор без нагрузки:
# diskinfo -ctv /dev/mirror/gm1
/dev/mirror/gm1
512 # sectorsize
640134925312 # mediasize in bytes (596G)
1250263526 # mediasize in sectors
0 # stripesize
0 # stripeoffset
I/O command overhead:
time to read 10MB block 0.298718 sec = 0.015 msec/sector
time to read 20480 sectors 2.559015 sec = 0.125 msec/sector
calculated command overhead = 0.110 msec/sector
Seek times:
Full stroke: 250 iter in 1.731325 sec = 6.925 msec
Half stroke: 250 iter in 1.701972 sec = 6.808 msec
Quarter stroke: 500 iter in 2.621019 sec = 5.242 msec
Short forward: 400 iter in 2.509421 sec = 6.274 msec
Short backward: 400 iter in 2.740263 sec = 6.851 msec
Seq outer: 2048 iter in 0.303295 sec = 0.148 msec
Seq inner: 2048 iter in 0.277656 sec = 0.136 msec
Transfer rates:
outside: 102400 kbytes in 1.011548 sec = 101231 kbytes/sec
middle: 102400 kbytes in 1.158101 sec = 88421 kbytes/sec
inside: 102400 kbytes in 1.590811 sec = 64370 kbytes/sec
Диск без нагрузки:
# diskinfo -ctv /dev/ad6
/dev/ad6
512 # sectorsize
640135028736 # mediasize in bytes (596G)
1250263728 # mediasize in sectors
0 # stripesize
0 # stripeoffset
1240341 # Cylinders according to firmware.
16 # Heads according to firmware.
63 # Sectors according to firmware.
WD-WCAV5A988981 # Disk ident.
I/O command overhead:
time to read 10MB block 0.114118 sec = 0.006 msec/sector
time to read 20480 sectors 1.900506 sec = 0.093 msec/sector
calculated command overhead = 0.087 msec/sector
Seek times:
Full stroke: 250 iter in 4.827589 sec = 19.310 msec
Half stroke: 250 iter in 3.712057 sec = 14.848 msec
Quarter stroke: 500 iter in 6.753247 sec = 13.506 msec
Short forward: 400 iter in 2.887075 sec = 7.218 msec
Short backward: 400 iter in 3.495591 sec = 8.739 msec
Seq outer: 2048 iter in 0.299966 sec = 0.146 msec
Seq inner: 2048 iter in 0.233651 sec = 0.114 msec
Transfer rates:
outside: 102400 kbytes in 0.969479 sec = 105624 kbytes/sec
middle: 102400 kbytes in 1.090684 sec = 93886 kbytes/sec
inside: 102400 kbytes in 1.519195 sec = 67404 kbytes/sec
Как видим время чтения сократилось:
Стандартная разбивка 512
time to read 10MB block 6.008214 sec = 0.293 msec/sector
time to read 20480 sectors 181.905846 sec = 8.882 msec/sector
ADF разбивка
time to read 10MB block 1.185152 sec = 0.058 msec/sector
time to read 20480 sectors 12.080955 sec = 0.590 msec/sector
С gpart интересно все выходит. Спасибо за статью. Вмемориз.
ОтветитьУдалитьСпасибо, познавательно.
ОтветитьУдалитьХотя есть подозрение, что если сделать с gnop -S 4096, то всё будет ещё более шоколадно.
Не сочтите за некропостинг, но всё же.
ОтветитьУдалитьПометочка, прежде чем gm1 со вторым винтом создавать, проверьте велика ли разница между винтами. Есть вариант что первый винт меньше окажется и в зеркало с большим размером не вставится.