MySQL lubi, gdy podsystem dyskowy jest szybki. MySQL lubi losowe zapisy. Dyski SSD są szybkie w losowych zapisach. Wniosek można z tego wyciągnąć taki, że MySQL lubi dyski SSD. To jest oczywiście prawda. Dyski SSD faktycznie znakomicie się nadają dla MySQL, znacząco przyspieszają dostęp do danych. Pytanie tylko, czy ta wydajność jest niezmienna?

Zrobiłem prosty test. Dwa dyski SSD Intel X25-E 32GB w RAID0, maszyna testowa to serwer oparty o platformę Intel, kontroler to SRCSASJV działający w trybie WriteBack. RAID0 dał łącznie ok. 57GB dostępnego miejsca. Testowałem dyski przy zajętości 20GB, 40GB i 55GB. Skrypt testowy wyglądał następująco:

#!/bin/sh

set -u
set -x
set -e

loop=`seq 1 19`

CURD=`pwd`

for sizei in 20 40 55 ; do
size=${sizei}G

cd /mnt
sysbench --test=fileio --file-num=64 --file-total-size=$size prepare

sysbench --test=fileio --file-total-size=$size --file-test-mode=rndwr   --max-time=600 --max-requests=100000000 --num-threads=16 --init-rng=on   --file-num=64 --file-extra-flags=direct
for i in ${loop} ; do
for mode in rndwr; do
for blksize in 16384 ; do
for threads in 8 16 32 64; do
echo "====== testing $blksize in $threads threads"
echo PARAMS $size $mode $threads $blksize > $CURD/sysbench-size-$size-mode-$mode-threads-$threads-blksz-$blksize
sysbench --test=fileio --file-total-size=$size --file-test-mode=$mode \
--max-time=120 --max-requests=100000000 --num-threads=$threads --init-rng=on \
--file-num=64 --file-extra-flags=direct --file-fsync-freq=0 --file-block-size=$blksize run \
| tee -a $CURD/sysbench-size-$size-mode-$mode-threads-$threads-blksz-$blksize-test${i} 2>&1
done
done
done
done

sysbench --test=fileio --file-total-size=$size cleanup

cd $CURD
done

Wyniki są następujące:

-      8 watkow    16 watkow   32 watkow   64 watkow
20G    6,626.38    6,697.42    6,698.35    6,706.47
40G    4,856.22    4,841.62    4,847.96    4,849.42
55G    3,489.63    3,488.02    3,483.94    3,485.13

Tabela ta zawiera średnie IOPS z 19 pomiarów, poniżej wykres:

IOPS dla różnej ilości danych

-      8 w       16 w       32 w       64 w
20G    264.25    266.53    267.54    267.76
40G    139.16    138.81    139.15    139.15
55G    100.00    100.00    100.00    100.00

Ta z kolei tabelka pokazuje jak wzrasta wydajność wraz z ilością wolnego miejsca na dysku. Wyniki dla 55GB stanowią 100%. I jeszcze wykresik do niej:
Wzrost wydajności w zależności od ilości wolnego miejsca
Jak widać, różnica jest spora – dyski zapełnione w ok. jednej trzeciej były w stanie wykonać 2,6 raza więcej operacji zapisu niż dyski pełne prawie w 100%. Tego typu spadek jest charakterystyczny dla dysków SSD i wynika z zasady ich działania. Nie umieją one nadpisywać danych. Każda operacja nadpisania to operacja skasowania obecnych danych i operacja zapisania nowych. W praktyce są to dwie operacje zamiast jednej. Jeśli na dysku jest wolne miejsce, to nadpisywanie danych można przyspieszyć przez zapisanie modyfikacji w innym, wolnym miejscu. Stare dane są potem, w wolnej chwili usuwane. Jeśli miejsca nie ma, trzeba najpierw skasować a potem zapisać – wydajność siada.

Przeglądając specyfikacje dysków udostępniane przez producentów trzeba tego typu niuanse uwzględniać. Niektórzy z nich podają dla jakiej zajętości dysku osiągnięto daną ilość IOPS. Jeśli takiej informacji nie ma, trzeba przyjąć że testowana została sytuacja najbardziej korzystna dla dysku – dysk był praktycznie pusty. W takiej sytuacji, w praktyce, wydajność okaże się znacznie niższa.

#!/bin/sh 

set -u
set -x
set -e

loop=’1 2 3 4 5 6 7 8 9′

CURD=`pwd`

for sizei in 20; do
size=${sizei}G

cd /mnt
sysbench –test=fileio –file-num=64 –file-total-size=$size prepare

sysbench –test=fileio –file-total-size=$size –file-test-mode=rndwr  –max-time=600 –max-requests=100000000 –num-threads=16 –init-rng=on  –file-num=64 –file-extra-flags=d
for i in ${loop} ; do
for mode in rndwr; do
for blksize in 16384 ; do
for threads in 8 16 32 64; do
echo „====== testing $blksize in $threads threads”
echo PARAMS $size $mode $threads $blksize > $CURD/sysbench-size-$size-mode-$mode-threads-$threads-blksz-$blksize
sysbench –test=fileio –file-total-size=$size –file-test-mode=$mode\
–max-time=120 –max-requests=100000000 –num-threads=$threads –init-rng=on \
–file-num=64 –file-extra-flags=direct –file-fsync-freq=0 –file-block-size=$blksize run \
| tee -a $CURD/sysbench-size-$size-mode-$mode-threads-$threads-blksz-$blksize-test${i} 2>&1
done
done
done
done

sysbench –test=fileio –file-total-size=$size cleanup

cd $CURD
done