Jak odzyskać miejsce zajęte przez indeks, który został częściowo zbudowany i został przerwany z powodu awarii zasilania

9

Używam postgres (postgis) 9.4.2 na komputerze Mac (10.10.4).

Mam kilka dużych stołów (kilka TB).

Podczas budowania indeksu na jednym z nich, który zajmuje około tygodnia, obserwowałem spadek dostępnej przestrzeni HD, ponieważ można oczekiwać prawie tego momentu, w którym indeks zostałby ukończony, gdy przerwa w zasilaniu trwałaby dłużej niż akumulator i system zszedł. Miałem wyłączone bufory i fillfactor=100podczas kompilacji, ponieważ jest to statyczne źródło danych. Po ponownym uruchomieniu dostępne miejsce na dysku znajduje się dokładnie tam, gdzie było prawie na końcu kompilacji indeksu. Analiza próżniowa nie zwalnia przestrzeni.

Próbowałem upuścić stół i ponownie spożywać, ale to nie upuściło miejsca. Teraz jestem w miejscu, w którym nie mam wystarczająco dużo miejsca, aby zbudować indeks.

Czy pliki generowane podczas kompilacji indeksu utknęły w zawieszeniu, w którym system nie może ich usunąć z powodu awarii komputera podczas awarii zasilania?

Kiedy patrzę na rozmiary tabel + indeksy w db (które są jedynymi danymi na tym dysku), sumują się do około 6 TB . Dysk ma pojemność 8 TB , a na dysku pozostało mniej niż 500 GB , więc wydaje się, że gdzieś utracono około 1,5 TB , co odpowiada rozmiarowi indeksu.

Jakieś pomysły?

dkitchel
źródło
Czy indeks nadal znajduje się na liście z takim zapytaniem? SELECT r.relname, r.relkind, n.nspname FROM pg_class r INNER JOIN pg_namespace n ON r.relnamespace = n.oid WHERE relkind = 'i';
Kassandry,
Nie, nie pojawia się w wynikach tego zapytania.
dkitchel,
1
Czy masz coś na liście, co SELECT indexrelid::regclass, indrelid::regclass FROM pg_catalog.pg_index WHERE NOT indisvalid;Ci daje?
dezso,
Nie, to wychodzi puste.
dkitchel,

Odpowiedzi:

5

Zwykle spodziewalibyśmy się, że po ponownym uruchomieniu Postgres proces odzyskiwania po awarii usunąłby pliki związane z indeksem przywracania z katalogu danych.

Załóżmy, że to nie działało, a przynajmniej trzeba to sprawdzić ręcznie.

Lista plików, które powinny znajdować się w katalogu danych, można ustalić za pomocą następującego zapytania:

select pg_relation_filenode(oid)
   from pg_class
  where relkind in ('i','r','t','S','m')
    and reltablespace=0
  order by 1;

reltablespace=0jest dla domyślnego obszaru tabel. Jeśli problematyczny indeks został utworzony w innym niż domyślny obszarze tabel, 0należy go zastąpić jego OID w pg_tablespace.

i, r, t, S, mw relkindodpowiadają odpowiednio indeksom, tabelom, przestrzeni tostowej, sekwencjom, widokom zmaterializowanym. Wszystkie te obiekty mają swoje dane w plikach, których nazwy pasują do siebie pg_relation_filenode(oid).

Na dysku pliki danych znajdują się poniżej, w $PGDATA/base/oid/której oidznajduje oidsię baza danych uzyskana przez select oid,datname from pg_database. Jeśli nie mówimy o domyślnym obszarze tabel, zamiast niego basejest zastępowany PG_version_somelabel.

Wyświetl i posortuj pliki pasujące do relfilenodes w tym katalogu:

ls | grep -E '^[0-9]+$' | sort -n > /tmp/list-of-relations.txt

(w rzeczywistości zachowuje tylko pierwszy segment dla relacji, które są większe niż 1 Gb. Jeśli istnieją trwałe segmenty niepowiązane z niczym, należy je rozpatrywać osobno)

i różnicuj ten plik z wynikiem powyższego zapytania.

Jeśli istnieją pliki danych trwałych, które nie odpowiadają żadnemu obiektowi znanemu przez bazę danych, powinny pojawić się w tym pliku różnicowym.

Daniel Vérité
źródło
Niesamowite! Znalazłem 1 plik w katalogu danych, który nie pojawił się na liście wyboru. Czy mogę bezpiecznie usunąć ten plik?
dkitchel,
W rzeczywistości odpowiada to około 800 plikom z iteracjami po kropce - wszystko jak 499807.484 itd. Czy mogę bezpiecznie usunąć te pliki?
dkitchel,
@dkitchel: byłyby to segmenty 1 Gb każdy dla ogromnego indeksu. Być może sprawdź, czy ich znaczniki czasu pokrywają się z uruchomionym indeksem tworzenia. Jeśli chodzi o ich usunięcie, mam nadzieję, że moje powyższe uzasadnienie jest prawidłowe, ale to twoje dane, więc ostatecznie to twoja decyzja!
Daniel Vérité,
Tak, znaczniki czasu są zgodne z momentem budowania indeksu, a suma rozmiarów plików odpowiada wielkości indeksu. Twoje rozumowanie wydaje się solidne. Spróbuję z dużą pewnością. Wielkie dzięki.
dkitchel,
Wystarczy śledzić, aby inni, którzy znaleźli się w tej samej sytuacji, mogli z pewnością korzystać z rozwiązania @ DanielVerite. Jego rozwiązanie rzeczywiście działało dla mnie idealnie.
dkitchel,