nowości w postgresie 8.2 – … nieblokujące tworzenie indeksów

ta poprawka mnie osobiście ratuje życie, ale mam świadomość, że tyczy się relatywnie niewielkiej ilości osób.

tworzenie indeksu (create index, create unique index) jest operacją blokującą.

w czasie tworzenia wszelkie operacje insert/update/delete na tabeli na której jest robiony indeks są wstrzymane.

zazwyczaj nie jest to problem – create index trwa np. kilka sekund. ale pojawia się problem co z większymi bazami, np. serwisami aukcyjnymi. tabele są spore, ruch jest non stop. jeśli np. zakładałbym indeks na tabeli “aukcje" w której jest kilkadziesiąt milionów rekordów, to tworzenie indeksu może spokojnie potrwać kilkanaście minut.

a w tym czasie wszystkie insert/update/delete by były wstrzymane. co oznacza, że jak ktoś będzie chciał dodać nową aukcję, to będzie czekał, czekał, a po 3 minutach przeglądarka go rozłączy i wyświetli komunikat o time-out'cie. cienko. rzekłbym nawet, że fatalnie.

czy nic nie da się zrobić? wcześniej – nie dawało sie. ale teraz jest lekarstwo:

# CREATE INDEX CONCURRENTLY ble ON tabelka (pole);
# CREATE UNIQUE INDEX CONCURRENTLY ble_u ON tabelka (pole, inne_pole);

indeksy tworzone z klauzulą CONCURRENTLY nie blokują zapisów! czyli wszystko działa tip-top.

haczyki? zawsze są. najważniejszy jest taki, że tworzenie indeksów w ten sposób jest wolniejsze. ale to za bardzo nie przeszkadza.

z innych rzeczy:

  • polecenie reindex nie porafi użyć “concurrently"
  • jeśli create index concurrently się wywali – w systemie zostanie tworzony indeks zawieszony w dziwnym stanie – niby jest, ale system z niego nie korzysta – przed ponowieniem próby założenia tego indeksu trzeba go skasować.
  • jeśli tworzymy indeks typu UNIQUE, to warunki unikalności są sprawdzane w trakcie tworzenia indeksu (dokładniej to w czasie drugiej fazy tworzenia indeksu). dzieje się tak mimo faktu iż nieistniejący jeszcze indeks nie może być użyty do wyszukiwania. jeśli w trakcie tworzenia indeksu polecenie create unique indeks wykryje powtarzające sie wartości – wywali się – i tu trzeba będzie skasować popsuty indeks (vide punkt wyżej)
  • można robić nieblokująco zarówno indeksy zwykłe jak i wielopolowe, funkcyjne czy częściowe.
  • można robić jednocześnie wiele indeksów w sposób nieblokujący, z tym, że nie więcej niż jeden na tabelę.
  • zwykły create index może być użyty w transakcji, ale create index concurrently – już nie.
  • tak samo jak przy zwykłych indeksach, tak samo przy tworzeniu nieblokującym nie są dopuszczone zmiany definicji tabeli na której tworzymy indeks

jak widać jest to funkcjonalność lekko (w/g mnie) jeszcze niewygładzona, ale zakładam, że rzeczy typu – pozostający “cień indeksu" po błędnym indeksowaniu – zostaną wyeliminowane dosyć szybko.

a poza tym – fenomenalna funkcjonalność. od zawsze mi jej brakowało.