VACUUM
obvykle nevrací diskový prostor operačnímu systému, s výjimkou některých zvláštních případů.
Z dokumentů:
Standardní forma
VACUUM
odstraní verze mrtvých řádků v tabulkách a indexech a označí místo, které je k dispozici pro budoucí opětovné použití. Nevrátí však prostor operačnímu systému, s výjimkou zvláštního případu, kdy se jedna nebo více stránek na konci tabulky zcela uvolní a lze snadno získat exkluzivní zámek stolu. V porovnání,VACUUM FULL
aktivně komprimuje tabulky zápisem kompletní nové verze souboru tabulky bez mrtvého místa. To minimalizuje velikost tabulky, ale může to trvat dlouho. Vyžaduje také další místo na disku pro novou kopii tabulky, dokud nebude operace dokončena.
Otázka zní: jak může tato databáze stát, když one or more pages at the end of a table become entirely free
dosáhnout? To lze provést pomocí VACUUM FULL
, ale nemám dostatek místa k jeho implementaci. Existují tedy i jiné možnosti?
Chcete-li vrátit prostor do operačního systému, použijte VACUUM FULL
. Když jsem v tom, předpokládám, že běžíš VACUUM FULL ANALYZE
. cituji manuál :
FULL
Vybere "plné" vakuum , které může získat zpět více místa , ale trvá mnohem déle a výhradně uzamkne stůl. Tato metoda také vyžaduje další místo na disku, protože zapíše novou kopii tabulky a neuvolní starou kopii, dokud nebude operace dokončena. Obvykle by to mělo být použito pouze tehdy, je-li třeba získat zpět značné množství prostoru z tabulky.
Odvážný důl.
CLUSTER
toho dosahuje také jako kolaterální efekt.
Prostý VACUUM
normálně nedosáhne vašeho cíle ( "jedna nebo více stránek na konci tabulky zcela zdarma"). Když řádek nastane, nebude měnit pořadí řádků a pouze prořezává prázdné stránky z fyzického konce souboru - jako je citace z manuálních pokynů.
Prázdné stránky můžete získat na konci fyzického souboru, když INSERT
dávku řádků a DELETE
je před připojením dalších n-tic. Nebo se to může stát náhodou, pokud bude odstraněno dost řádků.
Existují také speciální nastavení, která mohou zabránit VACUUM FULL
z regenerace prostoru. Vidět:
Sloupec systému ctid
představuje fyzickou polohu řádku. Musíte pochopit tento sloupec:
S tím můžeme pracovat a připravit tabulku odstraněním všech řádků z poslední stránky:
DELETE FROM tbl t
USING (
SELECT (split_part(ctid::text, ',', 1) || ',0)')::tid AS min_tid
, (split_part(ctid::text, ',', 1) || ',65535)')::tid AS max_tid
FROM tbl
ORDER BY ctid DESC
LIMIT 1
) d
WHERE t.ctid BETWEEN d.min_tid AND d.max_tid;
Nyní je poslední stránka prázdná. To ignoruje souběžné zápisy. Buď jste jediný, kdo zapisuje do této tabulky, nebo musíte zamknout zápis, abyste se vyhnuli rušení.
Dotaz je optimalizován pro rychlou identifikaci kvalifikujících řádků. Druhé číslo tid
je Tuple index uložený jako nepodepsaný int2
, a 65535
je maximum pro tento typ (2^16 - 1
), takže to je bezpečná horní mez.
SQL Fiddle (opětovné použití jednoduché tabulky z jiného případu.)
Nástroje pro měření velikosti řádku/tabulky:
Pro některou z těchto operací potřebujete místo na disku kroutit. Existuje také komunitní nástroj pg_repack
jako náhrada za VACUUM FULL
/CLUSTER
. Vyhýbá se exkluzivním zámkům, ale potřebuje také volný prostor pro práci. Manuál:
Vyžaduje volné místo na disku dvakrát tak velké jako cílové tabulky a indexy.
Jako poslední možnost můžete spustit cyklus výpisu/obnovení. To odstraní veškerý nadbytek z tabulek a indexů. Úzce související otázka:
Odpověď je tam docela radikální. Pokud to vaše situace umožňuje (žádné cizí klíče nebo jiné odkazy zabraňující vymazání řádku) a žádný souběžný přístup k tabulce), můžete:
Uložte tabulku na disk připojením ze vzdáleného počítače s dostatkem místa na disku (-a
pro --data-only
):
Ze vzdáleného prostředí Shell data výpisu tabulky:
pg_dump -h <Host_name> -p <port> -t mytbl -a mydb > db_mytbl.sql
V relaci pg TRUNCATE
tabulka:
-- drop all indexes and constraints here for best performance
TRUNCATE mytbl;
Ze vzdáleného prostředí Shell obnovte stejnou tabulku:
psql -h <Host_name> -p <port> mydb -f db_mytbl.sql
-- recreate all indexes and constraints here
Nyní je bez mrtvých řádků nebo nadýmání.
Ale možná to můžete mít jednodušší?
Můžete na disku vytvořit dostatek místa odstraněním (přesunutím) nepříbuzných souborů?
Můžeš VACUUM FULL
nejprve menší tabulky, jedna po druhé, čímž uvolníte dostatek místa na disku?
Můžete spustit REINDEX TABLE
nebo REINDEX INDEX
uvolnit místo na disku od nafouknutých indexů?
Ať už děláte cokoli, nebuďte vyrážka . Pokud máte pochybnosti, nejprve vše zálohujte na zabezpečené místo.