Jak odzyskać miejsce na dysku na PostgreSQL?

25

Mam lokalną instalację bazy danych 9.1 z kilkoma tabelami, które zawierały cca. 300 milionów rekordów, a baza danych wzrosła do około 20 GB. Następnie wydałem delete frompolecenie usunięcia z niego wszystkich rekordów (powinienem był użyć truncate, ale nie wiedziałem o tym). Więc zrobiłem pełną próżnię na mojej db, aby odzyskać miejsce na dysku, ale to po prostu nie pomaga. Mój problem wygląda identycznie jak ten , ale nie ma rozwiązania. Sprawdziłem już ten wątek i dokumentację dotyczącą „odzyskiwania miejsca na dysku” , ale nadal nie mogę znaleźć rozwiązania. Używam tego kodu, aby uzyskać rozmiar wszystkich tabel

 SELECT nspname || '.' || relname AS "relation",
 pg_size_pretty(pg_total_relation_size(C.oid)) AS "total_size"
 FROM pg_class C
 LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
 WHERE nspname NOT IN ('pg_catalog', 'information_schema')
 AND C.relkind <> 'i'
 AND nspname !~ '^pg_toast'
 ORDER BY pg_total_relation_size(C.oid) DESC
 LIMIT 15;

Jednak w sumie mniej niż 1 GB

SELECT pg_database.datname, pg_size_pretty(pg_database_size(pg_database.datname)) AS size FROM pg_database 

nadal pokazuje około 20 GB. Wszelkie porady bardzo mile widziane.

Społeczność
źródło
Twoje zapytanie o rozmiar wyklucza: indeksy, tabele pg_catalogi tabele w information_schema. Spróbuj więc sprawdzić, czy to którykolwiek z nich, usuwając ograniczenia w WHEREklauzuli. Pokaż dokładnie swoją wersję PostgreSQL ( SELECT version()) i co dokładnie robisz, aby „odkurzyć pełną bazę danych”, tj. Dokładne polecenie. Jeśli to możliwe, uruchom VACUUM FULL VERBOSE;(bez argumentów) i wklej gdzieś wynik, a następnie link do niego tutaj.
Craig Ringer
Spróbuj usunąć bazę danych. Możesz także spróbować zrzucić bazę danych, a przywrócenie spowoduje usunięcie śmieci.
jb.
1
@jb To działałoby, ale nie powinno być konieczne. Lepiej dowiedzieć się, na czym polega problem.
Craig Ringer

Odpowiedzi:

22

Chociaż tego nie podałeś, z twoich odniesień do dokumentów, które obserwowałeś, zakładam, że zrobiłeś VACUUM FULL w bazie danych i / lub tabelach, których dotyczy problem. Nie określiłeś również, jakiej wersji postgresql używasz - założę, że jest to> 9.0 (VACUUM FULL zachowywał się wcześniej inaczej).

VACUUM FULL przepisuje zmienione tabele na nowe pliki, a następnie usuwa stare pliki. Jeśli jednak jakiś proces nadal ma otwarty stary plik, system operacyjny faktycznie go nie usunie - dopóki ostatni proces go nie zamknie.

Jeśli to praktyczne, ponowne uruchomienie bazy danych zapewni zamknięcie wszystkich otwartych plików.

Jeśli to nie jest praktyczne, możesz sprawdzić, czy to jest twój problem i dowiedzieć się, który proces ma otwarte pliki.

Jeśli używasz Linuksa (lub większości innych systemów uniksowych), możesz użyć polecenia „lsof”, aby uzyskać listę wszystkich plików otwartych we wszystkich procesach. Pliki, które są otwarte, ale które zostały później usunięte, będą miały „(usunięte)” dołączone do nazwy pliku. Więc możesz grepować wyjście lsof, szukając usuniętych plików, jak poniżej:

sudo lsof -u postgres | grep 'deleted'

Jeśli identyfikuje to procesy, w których nadal są otwarte stare pliki, możesz użyć pg_terminate_backend, aby zakończyć ten proces:

SELECT pg_terminate_backend(xxx);

gdzie xxx jest PID procesu, znalezionym w wyjściu lsof.

Jeśli używasz systemu Windows, ta sama zasada może mieć zastosowanie, ponieważ postgres otwiera pliki przy użyciu flagi FILE_SHARE_DELETE, co pozwala mu usuwać pliki otwarte w innym procesie. Polecenie „ uchwyt ” jest z grubsza odpowiednikiem lsof, chociaż nie jestem pewien, czy możesz stwierdzić, czy pliki zostały usunięte, czy nie, więc może być wymagana dodatkowa praca.

To kolejne pytanie, dlaczego takie procesy będą się zawieszały na starych uchwytach plików. Jednak w wątku, który zacytowałeś w swoim pytaniu, Tom Lane wydaje się sugerować, że tak się może stać.

harmoniczny
źródło
Musiałem pilnie odzyskać miejsce na dysku, więc usunąłem bazę danych i przywróciłem ją z kopii zapasowej. Jednak „jak” rozwiązać ten problem jest nadal bardzo cenny w przyszłych przypadkach. Moja baza danych to 9.1, Windows 8 64-bitowy, czy nazywanie plików (w przypadku plików otwartych) obowiązuje tak samo, jak w Linuksie?
@arcull OK, nie wiedziałem, że używasz systemu Windows. Dodałem kilka informacji do odpowiedzi na temat tego, jak to dotyczy systemu Windows. Jeśli uważasz, że może to być przydatna odpowiedź, rozważ wzięcie udziału w głosowaniu, ponieważ ułatwia to innym osobom znalezienie go.
harmic