A Linux 6.2 kernel update proposes improvements to Btrfs concerning the 'write hole' issue in RAID 5/6 implementations. The essence of the problem is that if a crash occurs during a write operation, it is initially unclear which block was correctly written on which of the RAID devices and which write was incomplete. Attempting to recover RAID in such a scenario can lead to the corruption of blocks corresponding to the unwritten blocks, as the states of the RAID blocks become unsynchronized. This issue arises in any RAID1/5/6 arrays where no specific measures are taken to combat such effects.
In RAID implementations like RAID1 in btrfs, this issue is solved by using checksums in both copies; in case of a mismatch, the data is simply restored from the second copy. This approach also works if one device starts providing incorrect data instead of completely failing.
However, in the case of RAID5/6, the filesystem does not store checksums for parity blocks: under normal circumstances, the integrity of the blocks is verified by the fact that they all have checksums, and the parity block can be reconstructed from the data. However, in the case of partial writes, this approach may not work in certain situations. In this case, during array recovery, there is a possibility that the blocks subject to incomplete writes may be incorrectly restored.
A btrfs esetében ez a probléma különösen aktuális, ha a létrehozott írás mérete kisebb, mint a stripe. Ekkor a fájlrendszernek el kell végeznie az olvasás-módosítás-írás (read-modify-write, RMW) műveletet. Ha az írás során olyan blokkokba ütközünk, amelyek még nem fejeződtek be, akkor az RMW művelet károsodásokat okozhat, amelyeket nem észlelnek, a checksumok ellenére. A fejlesztők olyan változtatásokat hajtottak végre, amelyek révén az RMW művelet ellenőrzi a blokkok checksumját, mielőtt végrehajtaná ezt a műveletet, és szükség esetén az írás után is elvégzi a checksum ellenőrzését. Sajnos az RMW esetében a nem teljes stripe írása (RMW) további overhead-et jelent a checksumok kiszámításában, azonban jelentősen növeli a megbízhatóságot. A RAID6 esetében ez a logika még nem készült el, de egy RAID6 esetén ehhez arra van szükség, hogy az írás két eszközön egyszerre ne sikerüljön, ami kevésbé valószínű.
Továbbá érdemes megjegyezni a RAID5/6 használatára vonatkozó fejlesztői ajánlásokat, melyek lényege az, hogy a Btrfs-ben a metaadatok és az adatok tárolási profilja eltérhet. Ekkor használható RAID1 (tükör) vagy akár RAID1C3 (3 másolat) profil a metaadatokhoz, míg az adatokhoz RAID5 vagy RAID6. Ezzel megbízható védelmet biztosítunk a metaadatok számára, és megszüntetjük az „írási lyukat” egyik oldalon, míg a RAID5/6-ra jellemző hatékonyabb helyhasználatot biztosítunk a másikon. Ez lehetővé teszi a metaadatokban bekövetkező károsodások elkerülését, míg az adatok sérülése javítható.
Továbbá meg kell említeni, hogy az SSD-k esetében a Btrfs 6.2-es verziójában alapértelmezetten aktiválva lesz az aszinkron „discard” művelet végrehajtása (a már nem szükséges blokkok felszabadításának jelölése). Ennek a módnak az előnye a magas teljesítmény, mivel hatékonyan csoportosítja a „discard” műveleteket a sorban, majd ezen lista háttérfeldolgozó általi feldolgozása miatt a fájlrendszer normál műveletei nem lassulnak le, mint a szinkron „discard” esetében a blokkok felszabadítása során, és az SSD kedvezőbb döntéseket hozhat. Másrészt, már nincs szükség olyan segédprogramok használatára, mint az fstrim, mivel az összes elérhető blokk automatikusan törlődik a fájlrendszerben további szkennelés nélkül, és nem lassítja a műveleteket.
Forrás: opennet.ru
