Mały suplement do artykułów o linuksowym RAID.
Po padzie komputera softwareowe macierze potrafią się rozpiąć. Żaden z dysków nie jest uszkodzony ale jeden zostaje uznany za nieaktualny i rozpoczyna się powolny proces odbudowy macierzy.
Potrafi to wyglądać np. tak (obrazek krótko po resecie zawieszonego komputera):
$ cat /proc/mdstat
Personalities : [raid1] [linear] [multipath] [raid0] [raid6] [raid5] [raid4] [raid10]
md2 : active raid1 sda4[1] sdb4[0]
171630336 blocks [2/2] [UU]
resync=DELAYED
md3 : active raid1 sda3[1] sdb3[0]
311516288 blocks [2/2] [UU]
[>....................] resync = 0.7% (2410240/311516288) finish=1993.9min speed=2583K/sec
md0 : active raid1 sda6[0] sdc1[1]
488254272 blocks super 1.2 [2/2] [UU]
resync=DELAYED
unused devices: <none>
1993 minut to ponad doba. A to tylko pierwsza część…
Środki doraźne
Gdy do rozpięcia już doszło, macierz musi się odbudować, ale można to nieco przyspieszyć. Domyślnie MD znacząco ogranicza wykorzystywane I/O gdy na maszynie coś się dzieje:
$ cat /proc/sys/dev/raid/speed_limit_min
1000
$ cat /proc/sys/dev/raid/speed_limit_max
200000
Następujące polecenie każe mu zachowywać się agresywniej:
sudo sysctl -w dev.raid.speed_limit_min=50000
To 50000 (50MB/s) jest wartością popularną w rozmaitych dokumentacjach i raczej sensowną. Można próbować podbić to wyżej, można ustawić trochę niżej, efekty zależą od używanego sprzętu. Ewentualne negatywne konsekwencje zbyt dużej wartości to gorsza responsywność komputera po zdominowaniu jego I/O przez rebuild macierzy.
Efekty są widoczne już po paru minutach
$ cat /proc/mdstat
Personalities : [raid1] [linear] [multipath] [raid0] [raid6] [raid5] [raid4] [raid10]
md2 : active raid1 sda4[1] sdb4[0]
171630336 blocks [2/2] [UU]
resync=DELAYED
md3 : active raid1 sda3[1] sdb3[0]
311516288 blocks [2/2] [UU]
[>....................] resync = 1.0% (3249152/311516288) finish=264.4min speed=19428K/sec
md0 : active raid1 sda6[0] sdc1[1]
488254272 blocks super 1.2 [2/2] [UU]
resync=DELAYED
unused devices: <none>
a po godzinie widać dopasowanie do podanego parametru:
$ cat /proc/mdstat
Personalities : [raid1] [linear] [multipath] [raid0] [raid6] [raid5] [raid4] [raid10]
md2 : active raid1 sda4[1] sdb4[0]
171630336 blocks [2/2] [UU]
resync=DELAYED
md3 : active raid1 sda3[1] sdb3[0]
311516288 blocks [2/2] [UU]
[=>...................] resync = 8.0% (24932416/311516288) finish=94.1min speed=50702K/sec
md0 : active raid1 sda6[0] sdc1[1]
488254272 blocks super 1.2 [2/2] [UU]
resync=DELAYED
unused devices: <none>
Poprawki na przyszłość
Jako że mój nowy komputer zawisł już trzeci raz w ciągu około dwudziestu dni używania, poza planowaniem rozmaitych memtestów i zapuszczeniem SMARTów, zdecydowałem się przygotować na kolejny taki wypadek.
Mniej ważną poprawką jest zapisanie na stałe zachęty do szybszego odbudowywania macierzy.
Stworzyłem plik /etc/sysctl.d/60-szybszy-rebuild-raid.conf
o treści::
dev.raid.speed_limit_min = 100000
dev.raid.speed_limit_max = 200000
100000 ustawiłem jako wartość „nie ograniczaj” (po ustawieniu limitu na tyle czy więcej i tak osiągam tempo synchronizacji maksymalnie ok. 60000K/s).
Ważniejszą sprawą jest uniknięcie przepisywania całego dysku w razie ponownego rozpięcia. MDADM ma mechanizm bitmap, polegający na zapisywaniu dodatkowej informacji które obszary dysków były modyfikowane. Gdy informacja ta jest dostępna, ewentualny resync nie musi kopiować wszystkiego a jedynie potencjalnie zmienione części i trwa drastycznie krócej.
Mechanizm włączamy następująco:
# mdadm --grow --bitmap=internal /dev/md0
(należy powtórzyć to dla innych macierzy w komputerze, jeśli jest ich kilka)
Fakt włączenia bitmapy można zweryfikować, w mdstat pojawia się nowy wiersz (bitmap
):
$ cat /proc/mdstat
(…)
md0 : active raid1 sda1[1] sdb1[0]
10482304 blocks [2/2] [UU]
bitmap: 2/3 pages [8KB], 65536KB chunk
(…)
Nie jestem pewien czemu opcja ta nie jest włączona domyślnie – dodatkowy koszt aktualizowania bitmapy nie wygląda na znaczący.
Bitmapy nie można włączyć w trakcie resynchronizacji::$ mdadm --grow --bitmap=internal /dev/md2
mdadm: Cannot add bitmap while array is resyncing or reshaping etc.
mdadm: failed to set internal bitmap.