Alokacja przestrzeni w Firebird 2.1 i nowszych wersjach
Vlad Khorsun, 20-PAZ-2010
Od samego początku Firebird nie miał zasad dotyczących alokacji miejsca na dysku dla plików bazy danych. Po prostu zapisuje nowo przydzielone strony w nieokreślonej kolejności (ze względu na zależności między stronami, aby realizować strategię „ostrożnego zapisu”).
To podejście jest bardzo proste, ale ma pewne wady:
• z powodu nieokreślonej kolejności zapisów może wystąpić sytuacja, gdy bufor stron zawiera wiele brudnych stron w momencie, gdy nowo przydzielona strona musi zostać zapisana, ale nie może, ponieważ brakuje miejsca na dysku. W takich przypadkach często wszystkie inne brudne strony są tracone, ponieważ administratorzy wolą zamknąć bazę danych, zanim zwolnią miejsce na dysku. Prowadzi to do poważnych uszkodzeń.
• alokacja miejsca na dysku w stosunkowo małych fragmentach może prowadzić do znacznej fragmentacji plików na poziomie systemu plików i zmniejszać wydajność dużych skanów (na przykład podczas tworzenia kopii zapasowej).
Używając nowego ODS 11.1, Firebird zmienia swój algorytm alokacji miejsca na dysku, aby uniknąć uszkodzeń w warunkach braku miejsca na dysku oraz dać systemowi plików szansę na uniknięcie fragmentacji. Zmiany te opisano poniżej.
a) Każda nowo przydzielona strona jest natychmiast zapisywana na dysku przed powrotem do silnika. Jeśli strona nie może zostać zapisana, alokacja nie następuje, bit PIP nie jest czyszczony i zgłaszany jest odpowiedni błąd wejścia/wyjścia. Ten błąd nie może prowadzić do uszkodzeń, ponieważ mamy gwarancję, że wszystkie brudne strony w buforze mają przydzielone miejsce na dysku i mogą być bezpiecznie zapisane.
Ta zmiana powoduje jeden dodatkowy zapis każdej nowo przydzielonej strony w porównaniu ze starym zachowaniem. Dlatego oczekiwany jest spadek wydajności podczas wzrostu pliku bazy danych. Aby zmniejszyć ten spadek, Firebird grupuje zapisy nowo przydzielonych stron do 128 KB na raz i śledzi liczbę „zainicjalizowanych” stron w nagłówku PIP.
Uwaga: nowo przydzielona strona zostanie zapisana na dysku dwukrotnie tylko wtedy, gdy strona jest przydzielana po raz pierwszy. To znaczy, jeśli strona została przydzielona, zwolniona i przydzielona ponownie, nie zostanie zapisana dwukrotnie przy drugiej alokacji.
b) Aby uniknąć fragmentacji plików, Firebird używa odpowiedniego API systemu plików do prealokacji miejsca na dysku w stosunkowo dużych fragmentach. Obecnie takie API istnieje tylko w systemie Windows, ale zostało niedawno dodane do API Linuksa i może zostać zaimplementowane w tak popularnych systemach plików, jak ext2 itp. w przyszłości. Dlatego ta funkcja jest obecnie zaimplementowana tylko w wersjach Firebird dla systemu Windows i może zostać zaimplementowana w wersjach dla Linuksa w przyszłości.
Dla lepszej kontroli prealokacji miejsca na dysku wprowadzono nowe ustawienie w Firebird.conf: DatabaseGrowthIncrement. Jest to górna granica rozmiaru fragmentu prealokacji w bajtach. Wartość domyślna to 128 MB. Gdy silnik potrzebuje więcej miejsca na dysku, alokuje 1/16 już przydzielonego miejsca, ale nie mniej niż 128 KB i nie więcej niż wartość DatabaseGrowthIncrement. Jeśli DatabaseGrowthIncrement jest ustawione na zero, prealokacja jest wyłączona. Miejsce dla plików cieni bazy danych nie jest prealokowane.
Prealokacja jest również wyłączona, jeśli dla bazy danych ustawiona jest opcja „No reserve”.
Uwaga: prealokacja pozwala również uniknąć uszkodzeń w warunkach braku miejsca na dysku - w takim przypadku istnieje duża szansa, że baza danych ma wystarczająco dużo prealokowanego miejsca, aby działać, dopóki administrator nie zwolni miejsca na dysku.
Autor: Vlad Khorsun,