VAKUM disk alanını işletim sistemine döndürüyor


21

VACUUMbazı özel durumlar dışında genellikle disk alanını işletim sistemine geri döndürmez.
Dokümanlardan:

Standart form, VACUUMtablo ve dizinlerdeki ölü satır sürümlerini kaldırır ve ileride yeniden kullanılmak üzere kullanılabilir alanı işaretler. Ancak, tablonun sonundaki bir veya daha fazla sayfanın tamamen ücretsiz hale gelebildiği ve özel bir tablo kilidinin kolayca elde edilebileceği özel durumlar haricinde, alanı işletim sistemine geri döndürmez. Buna karşılık, VACUUM FULLölü bir boşluk olmadan tablo dosyasının yeni bir sürümünü yazarak tabloları etkin bir şekilde sıkıştırır. Bu tablonun boyutunu en aza indirir, ancak uzun zaman alabilir. İşlem tamamlanıncaya kadar tablonun yeni kopyası için ek disk alanı gerektirir.

Soru şudur: Bu veritabanı ne one or more pages at the end of a table become entirely freezaman elde edilebilir? Bu, üzerinden yapılabilir VACUUM FULL, ancak bunu uygulamak için yeterli alanım yok. Başka olasılıklar var mı?

Yanıtlar:


29

OS'ye geri dönmek için tuşunu kullanın VACUUM FULL. Sanırım o sırada koştun VACUUM FULL ANALYZE. Ben kılavuzu alıntı :

FULL

Daha fazla yer kaplayabilen , ancak çok daha uzun süren ve yalnızca masayı kilitleyen "tam" vakumu seçer . Bu yöntem ayrıca tablonun yeni bir kopyasını yazdığı ve işlem tamamlanana kadar eski kopyayı serbest bırakmadığı için fazladan disk alanı gerektirir. Genellikle bu yalnızca tablonun içinden önemli miktarda alan geri kazanılması gerektiğinde kullanılmalıdır.

Cesur vurgu benim.

CLUSTER bunu da teminat etkisi olarak başarır.

Plain VACUUMnormalde hedefinize ulaşmaz ( "tablonun sonunda bir veya daha fazla sayfa tamamen ücretsiz" ). Satırları yeniden sıralamaz ve fırsat ortaya çıktığında yalnızca boş sayfaların bu dosyanın fiziksel sonundan budamasını sağlar - manuel talimatlardaki alıntı gibi.

INSERTBir grup satır ve DELETEdiğer gruplara eklenmeden önce fiziksel dosyanın sonunda boş sayfalar alabilirsiniz. Ya da yeterince satır silinirse tesadüf olabilir.

VACUUM FULLAlan geri kazanılmasını engelleyebilecek özel ayarlar da vardır . Görmek:

Test için tablonun sonunda boş sayfalar hazırlayın

Sistem sütunu ctid, bir satırın fiziksel konumunu temsil eder. Bu sütunu anlamalısınız:

Bununla çalışabilir ve son sayfadaki tüm satırları silerek bir tablo hazırlayabiliriz:

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;

Şimdi son sayfa boş. Bu, eşzamanlı yazma işlemlerini yoksayar. Ya bu tabloya yazacak tek kişi sizsiniz ya da paraziti önlemek için yazma kilidi almanız gerekir.

Sorgu, uygun satırları hızlı bir şekilde tanımlamak için optimize edilmiştir. tidA'nın ikinci sayısı, imzasız olarak depolanan tuple indeksidir int2ve 65535bu tip ( 2^16 - 1) için maksimum değerdir , bu nedenle güvenli üst sınır budur.

SQL Fiddle (basit bir tabloyu farklı bir durumdan tekrar kullanmak.)

Satır / tablo boyutunu ölçmek için araçlar:

Disk dolu

Bu işlemlerden herhangi biri için diskte kıpır kıpır boşluk gerekir. / pg_repackİçin topluluk aracı da vardır . Özel kilitleri önler, ancak çalışmak için de boş alana ihtiyaç duyar. Kullanım kılavuzu:VACUUM FULLCLUSTER

Hedef tablo (lar) ve dizinlerden iki kat daha büyük boş disk alanı gerektirir.

Son çare olarak, bir döküm / geri yükleme döngüsü çalıştırabilirsiniz. Bu, tüm şişkinliği tablolardan ve dizinlerden de kaldırır. Yakından ilgili soru:

Oradaki cevap oldukça radikal. Durumunuz buna izin veriyorsa (yabancı anahtarlar veya satır silme işlemlerini önleyen başka referanslar yok) ve tabloya eşzamanlı erişim yoksa, şunları yapabilirsiniz:

Bir bağlanırken diske tabloyu dökümü uzak bilgisayara sahip disk alanı bol ( -aiçin --data-only):

Uzak kabuktan tablo verilerini dökümü:

pg_dump -h <host_name> -p <port> -t mytbl -a mydb > db_mytbl.sql

Bir pg oturumunda TRUNCATEtablo:

-- drop all indexes and constraints here for best performance
TRUNCATE mytbl;

Uzak kabuktan aynı tabloya geri yükleme:

psql -h <host_name> -p <port> mydb -f db_mytbl.sql
-- recreate all indexes and constraints here

Artık herhangi bir ölü sıra veya şişkinlik içermiyor.

Ama belki bu kadar basit olabilir mi?

  • İlişkisiz dosyaları silerek (taşıyarak) diskte yeterli alan açabilir misiniz?

  • Eğer Can VACUUM FULL, ilk önce küçük masalar birer birer suretle yeterli disk alanı boşaltarak?

  • Şişirilmiş dizinlerden çalışabilir REINDEX TABLEveya REINDEX INDEXdisk alanını boşaltabilir misiniz?

Ne yaparsan yap, döküntü olma . Şüpheniz varsa, önce her şeyi güvenli bir yere yedekleyin.


Erwin, özür dilerim, vakum için yeterli alanım olmadığını söylemeyi unuttum. Soru güncellendi.
her şeyle ilgili yanlış

@Zapadlo: Güncellenmiş soru için bir bölüm ekledim.
Erwin Brandstetter

Kapsamlı cevap için teşekkürler. Aslında sahte güncellemelerle db sayfalarının sonuna ölü satırlar yerleştirebileceğimi düşündüm, yani update table set field_1 = field_1, ama bu işlemden sonra bu tabloyu vakumlamak boş alan, herhangi bir fikir döndüremedi?
her şey hakkında yanlış

@Zapadlo: Sahip olduğum fikirler zaten cevapta. :) Ölü kaplumbağaları diskte önemli bir kıpır kıpır odasına ihtiyaç duymadan yeniden sıralayabilen bir araç bilmiyorum. (Orada bir tane olamayacağı anlamına gelmez.)
Erwin Brandstetter

Bu aracın hile yaptığını söylüyorlar, ancak henüz denemediler: code.google.com/p/pgtoolkit/source/browse/trunk/bin/…
yanlış olan her şey
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.