PostgreSQL'de UPDATE ve DELETE eski satır sürümünü hemen silmez; satır "ölü" olarak tabloda kalır. VACUUM bu ölü satırların kapladığı alanı yeniden kullanılabilir hâle getirir, planlayıcı istatistiklerini (ANALYZE ile) günceller, görünürlük haritasını işaretler ve transaction kimliği taşmasına (wraparound) karşı eski satırları dondurur. Autovacuum bu işleri arka planda kendiliğinden yapar; temizlik yetişemezse tablo gereksiz yere büyür, buna "bloat" (şişme) denir.

Bu yazıda bloat'ın nasıl oluştuğunu tablo boyutlarıyla gösteriyor, VACUUM, VACUUM FULL ve ANALYZE farkını, autovacuum'un ne zaman tetiklendiğini, uzun açık bir transaction'ın temizliği nasıl engellediğini ve wraparound uyarılarını anlatıyoruz. Genel bakım önerileri ve yapılandırma değerleri için PostgreSQL performans optimizasyonu yazısı kısa bir özet sunar; burada mekanizmanın ayrıntısına iniyoruz.

Neden VACUUM gerekir?

Neden VACUUM gerekir? Güncellenen veya silinen satırların kapladığı disk alanını geri kazanmak ya da..., Sorgu planlayıcısının kullandığı veri istatistiklerini güncellemek...

PostgreSQL'in çok sürümlü eşzamanlılık modelinde (MVCC) bir satır güncellendiğinde yeni bir sürüm yazılır, eskisi ise o satırı hâlâ görebilecek transaction'lar için bir süre saklanır. Bu mekanizma izolasyon seviyeleri yazısında xmin ve ctid sütunlarıyla gösteriliyor. Eski sürüm artık hiçbir transaction'ı ilgilendirmediğinde kapladığı alanın geri kazanılması gerekir. Kılavuz VACUUM'un dört görevini şöyle sıralar:

  • Güncellenen veya silinen satırların kapladığı disk alanını geri kazanmak ya da yeniden kullanılabilir yapmak.
  • Sorgu planlayıcısının kullandığı veri istatistiklerini güncellemek.
  • Index-only taramaları hızlandıran görünürlük haritasını (visibility map) güncellemek.
  • Transaction kimliği veya multixact kimliği taşması (wraparound) nedeniyle çok eski verinin kaybolmasını önlemek.

Bloat'ı gözle görmek

Autovacuum'u yalnızca bu tablo için kapatıp 100.000 satır ekledik, sonra her satırı bir kez güncelledik:

sql
CREATE TABLE sepet (id int PRIMARY KEY, urun text, adet int) WITH (autovacuum_enabled = off);
INSERT INTO sepet SELECT i, 'ürün ' || i, 1 FROM generate_series(1, 100000) i;
SELECT pg_size_pretty(pg_relation_size('sepet')) AS boyut;
UPDATE sepet SET adet = adet + 1;
SELECT pg_size_pretty(pg_relation_size('sepet')) AS boyut;
SELECT n_live_tup, n_dead_tup, last_vacuum, last_autovacuum
FROM pg_stat_user_tables WHERE relname = 'sepet';
text
  boyut
---------
 5096 kB
(1 row)

UPDATE 100000
  boyut
----------
 10192 kB
(1 row)

 n_live_tup | n_dead_tup | last_vacuum | last_autovacuum
------------+------------+-------------+-----------------
     100000 |     100000 |             |
(1 row)

Tek bir UPDATE tablonun boyutunu ikiye katladı: 100.000 canlı satırın yanında 100.000 ölü sürüm duruyor. pg_stat_user_tables görünümündeki n_dead_tup sütunu bu sayıyı tahmini olarak gösterir. (İstatistikler biriktirilerek yayımlandığı için denemede sorgudan önce bir saniye bekledik.) Şimdi VERBOSE seçeneğiyle temizlik yapalım:

sql
VACUUM (VERBOSE) sepet;
text
INFO:  vacuuming "ornek_vacuum.public.sepet"
INFO:  finished vacuuming "ornek_vacuum.public.sepet": index scans: 1
pages: 0 removed, 1274 remain, 1274 scanned (100.00% of total), 0 eagerly scanned
tuples: 100000 removed, 100000 remain, 0 are dead but not yet removable
removable cutoff: 1016, which was 0 XIDs old when operation ended
new relfrozenxid: 1015, which is 2 XIDs ahead of previous value
frozen: 0 pages from table (0.00% of total) had 0 tuples frozen
visibility map: 1274 pages set all-visible, 636 pages set all-frozen (0 were all-visible)
index scan needed: 637 pages from table (50.00% of total) had 100000 dead item identifiers removed
index "sepet_pkey": pages: 551 in total, 0 newly deleted, 0 currently deleted, 0 reusable
avg read rate: 0.000 MB/s, avg write rate: 1.355 MB/s
buffer usage: 3760 hits, 0 reads, 4 dirtied
WAL usage: 3100 records, 4 full page images, 1077433 bytes, 0 buffers full
system usage: CPU: user: 0.00 s, system: 0.01 s, elapsed: 0.02 s
...
VACUUM

Çıktının sonundaki TOAST tablosuna ait bölümü ... ile kısalttık. En önemli satır tuples: 100000 removed: bütün ölü sürümler temizlendi. index scan needed satırı indeksteki ölü kayıtların da silindiğini, visibility map satırı ise sayfaların "herkese görünür" olarak işaretlendiğini söylüyor. Peki tablo küçüldü mü?

sql
SELECT pg_size_pretty(pg_relation_size('sepet')) AS boyut;          -- sonuç: 10192 kB
SELECT n_live_tup, n_dead_tup, vacuum_count FROM pg_stat_user_tables WHERE relname = 'sepet';
UPDATE sepet SET adet = adet + 1;
SELECT pg_size_pretty(pg_relation_size('sepet')) AS boyut;          -- sonuç: 10192 kB
text
 n_live_tup | n_dead_tup | vacuum_count
------------+------------+--------------
     100000 |          0 |            1
(1 row)

Boyut aynı kaldı. Kılavuzun anlattığı gibi standart VACUUM alanı işletim sistemine geri vermez, aynı tablo içinde yeniden kullanıma açar. İkinci UPDATE tabloyu büyütmedi, çünkü yeni sürümler boşalan yerlere yazıldı. Rutin vacuum'un amacı tabloyu en küçük boyutunda tutmak değil, iki temizlik arasında kullanılan alan kadar payla sabit bir boyutta tutmaktır.

VACUUM, VACUUM FULL ve ANALYZE farkı

VACUUM, VACUUM FULL ve ANALYZE farkı: VACUUM, VACUUM FULL, ANALYZE, VACUUM ANALYZE

Standart VACUUM, tablonun sonundaki sayfalar tamamen boşalmışsa ve kısa süreli özel bir kilit kolayca alınabiliyorsa bu sayfaları keserek dosyayı küçültebilir. VACUUM FULL ise tablonun tamamını boşluksuz yeni bir dosyaya yeniden yazar. Satırların %90'ını sildikten sonra ikisini karşılaştırdık:

sql
DELETE FROM sepet WHERE id > 10000;
VACUUM sepet;
SELECT pg_size_pretty(pg_relation_size('sepet')) AS boyut;   -- sonuç: 5096 kB
VACUUM FULL sepet;
SELECT pg_size_pretty(pg_relation_size('sepet')) AS boyut;   -- sonuç: 512 kB

Normal VACUUM dosyanın sonundaki boş sayfaları kesip 10192 kB'tan 5096 kB'a indirdi; VACUUM FULL ise geri kalan boşlukları da atarak tabloyu 512 kB'a sıkıştırdı. Ancak bunun bedeli büyüktür:

KomutNe yaparKilitNe zaman
VACUUMÖlü satırları temizler, alanı tablo içinde yeniden kullanıma açarSHARE UPDATE EXCLUSIVE: okuma ve yazma devam ederRutin bakım; autovacuum bunu yapar
VACUUM FULLTabloyu yeni dosyaya yazar, alanı işletim sistemine geri verirACCESS EXCLUSIVE: tabloya hiçbir erişim olmazSatırların çoğu silindiyse ve alan gerçekten gerekiyorsa
ANALYZESatır örneklemiyle planlayıcı istatistiklerini toplarSHARE UPDATE EXCLUSIVEBüyük veri değişikliklerinden sonra
VACUUM ANALYZEÖnce VACUUM, sonra ANALYZESHARE UPDATE EXCLUSIVEBakım betikleri için pratik birleşim

Kılavuza göre VACUUM FULL çok daha yavaştır ve işlem bitene kadar tablonun yeni kopyası için ek disk alanı gerektirir. Bu yüzden yöneticilerin standart VACUUM kullanması ve VACUUM FULL'dan kaçınması önerilir; autovacuum da hiçbir zaman VACUUM FULL çalıştırmaz. Bir tablonun içeriği düzenli olarak tamamen siliniyorsa DELETE yerine TRUNCATE kullanmak ayrıca vacuum gerektirmez; kılavuz bunun katı MVCC anlamını bozduğunu da not eder. Kilit kiplerinin anlamı kilitler yazısında tablo hâlinde verildi.

VACUUM transaction bloğu içinde çalıştırılamaz, bir tabloyu temizlemek için o tablo üzerinde MAINTAIN yetkisi gerekir (veritabanı sahipleri paylaşılan kataloglar dışındaki tabloları temizleyebilir) ve yetkiniz olmayan tablolar sessizce atlanır. Tablo adı verilmezse geçerli veritabanındaki bütün tablolar işlenir. Diğer yararlı seçenekler şunlardır:

SeçenekAnlamı
FREEZEAgresif dondurma; vacuum_freeze_min_age ve vacuum_freeze_table_age sıfırmış gibi çalışır
SKIP_LOCKEDHemen kilitlenemeyen tabloyu beklemeden atlar
INDEX_CLEANUPAUTO (varsayılan), ON veya OFF; indeks temizliğini zorlar ya da atlar
TRUNCATESondaki boş sayfaları kesme denemesi; false yapılırsa bunun gerektirdiği ACCESS EXCLUSIVE kilidinden kaçınılır
PARALLEL nİndeks temizliği aşamalarını paralel işçilerle yapar; FULL ile kullanılamaz
BUFFER_USAGE_LIMITVACUUM'un kullanacağı halka arabellek boyutu; 128 kB ile 16 GB arası

Uzun açık transaction temizliği engeller

Bloat'ın en sinsi nedeni, vacuum'un çalışıyor görünmesine rağmen hiçbir şeyi temizleyememesidir. Bir satır sürümü, onu görebilecek en eski transaction bitene kadar silinemez. Aşağıda A oturumu bir REPEATABLE READ transaction'ını üç saniye açık tutarken B 5.000 satır silip hemen vacuum çalıştırıyor, sonra A bitince tekrar deniyor:

sql
-- Oturum A
BEGIN ISOLATION LEVEL REPEATABLE READ;
SELECT count(*) FROM sepet;
SELECT pg_sleep(3);
COMMIT;

-- Oturum B (yarım saniye sonra)
DELETE FROM sepet WHERE id <= 5000;
VACUUM (VERBOSE) sepet;
SELECT pid, state, backend_xmin, age(backend_xmin) AS xmin_yasi, left(query, 30) AS sorgu
FROM pg_stat_activity WHERE backend_xmin IS NOT NULL AND pid <> pg_backend_pid();
SELECT pg_sleep(3);
VACUUM (VERBOSE) sepet;
text
-- Oturum B, birinci VACUUM (yalnızca tuples satırı)
tuples: 0 removed, 10000 remain, 5000 are dead but not yet removable

  pid  | state  | backend_xmin | xmin_yasi |        sorgu
-------+--------+--------------+-----------+---------------------
 83636 | active |         1021 |         1 | SELECT pg_sleep(3);
(1 row)

-- Oturum B, A bittikten sonraki ikinci VACUUM (yalnızca tuples satırı)
tuples: 5000 removed, 5000 remain, 0 are dead but not yet removable

Birinci denemede 5.000 ölü satır "dead but not yet removable" olarak kaldı, çünkü A'nın görüntüsü onları hâlâ görebiliyordu. pg_stat_activity görünümündeki backend_xmin sütunu, bu engeli koyan oturumu gösteriyor. A bitince ikinci vacuum bütün satırları temizledi. Gerçek sistemlerde bu A oturumu saatlerce "idle in transaction" kalmış bir uygulama bağlantısı, unutulmuş bir hazırlanmış transaction veya kullanılmayan bir replikasyon slotu olabilir. Kılavuz, idle_in_transaction_session_timeout parametresinin bu amaçla kullanılabileceğini belirtir; ayrıntılar transaction yazısında, uzun oturumları bulma yöntemleri ise pg_stat_activity yazısında.

Autovacuum ne zaman çalışır?

Autovacuum, bir başlatıcı (launcher) süreç ile onun başlattığı işçi (worker) süreçlerinden oluşur. Başlatıcı her veritabanında yaklaşık autovacuum_naptime aralığıyla bir işçi başlatmaya çalışır; aynı anda en fazla autovacuum_max_workers işçi çalışır. İşçiler istatistik sayaçlarına bakarak hangi tablonun temizlik veya analiz gerektirdiğine karar verir, bu yüzden track_counts açık olmalıdır. Kılavuzdaki formüle göre bir tablo, son vacuum'dan bu yana güncellenen veya silinen satır sayısı şu eşiği aştığında temizlenir:

text
vacuum eşiği = en küçük( autovacuum_vacuum_max_threshold,
                         autovacuum_vacuum_threshold + autovacuum_vacuum_scale_factor x reltuples )
analiz eşiği = autovacuum_analyze_threshold + autovacuum_analyze_scale_factor x reltuples

Varsayılan değerleri kendi test kümemizde pg_settings görünümünden okuduk:

sql
SELECT name, setting, unit FROM pg_settings
WHERE name IN ('autovacuum', 'autovacuum_naptime', 'autovacuum_max_workers',
               'autovacuum_vacuum_threshold', 'autovacuum_vacuum_scale_factor',
               'autovacuum_vacuum_max_threshold', 'autovacuum_analyze_scale_factor',
               'autovacuum_freeze_max_age')
ORDER BY name;
text
              name               |  setting  | unit
---------------------------------+-----------+------
 autovacuum                      | on        |
 autovacuum_analyze_scale_factor | 0.1       |
 autovacuum_freeze_max_age       | 200000000 |
 autovacuum_max_workers          | 3         |
 autovacuum_naptime              | 60        | s
 autovacuum_vacuum_max_threshold | 100000000 |
 autovacuum_vacuum_scale_factor  | 0.2       |
 autovacuum_vacuum_threshold     | 50        |
(8 rows)

Bu değerlerle 1.000.000 satırlık bir tablo, 50 + 0,2 x 1.000.000 = 200.050 ölü satırı geçince temizlenir. 1 milyar satırlık bir tabloda formül 200 milyonu verir; PostgreSQL 18 ile gelen autovacuum_vacuum_max_threshold (varsayılan 100 milyon) bu durumda üst sınır olarak devreye girer. Analiz için de benzer bir eşik vardır ve ekleme, güncelleme, silme toplamına bakar. Yalnızca ekleme alan tablolar için ayrıca autovacuum_vacuum_insert_threshold ve autovacuum_vacuum_insert_scale_factor ile tanımlanan bir ekleme eşiği bulunur.

Autovacuum'u iş başında görmek için kendi test kümemizde autovacuum_naptime değerini geçici olarak bir saniyeye indirdik, bir tabloya 1.000 satır ekleyip 600'ünü sildik ve bağlantıyı kapattık. Ayrı bir oturumda beş saniye sonra baktık:

sql
ALTER SYSTEM SET autovacuum_naptime = '1s';
SELECT pg_reload_conf();
CREATE TABLE oturum_log (id int, veri text);
INSERT INTO oturum_log SELECT i, 'x' FROM generate_series(1, 1000) i;
DELETE FROM oturum_log WHERE id <= 600;
-- yeni oturumda, beş saniye sonra:
SELECT n_live_tup, n_dead_tup, last_autovacuum IS NOT NULL AS otomatik_calisti,
       autovacuum_count, autoanalyze_count
FROM pg_stat_user_tables WHERE relname = 'oturum_log';
ALTER SYSTEM RESET autovacuum_naptime;
SELECT pg_reload_conf();
text
 n_live_tup | n_dead_tup | otomatik_calisti | autovacuum_count | autoanalyze_count
------------+------------+------------------+------------------+-------------------
        400 |          0 | t                |                1 |                 1
(1 row)

Autovacuum hem temizliği hem analizi kendiliğinden yaptı. İlk denememizde silme ve kontrol aynı oturumdaydı ve sonuç görünmedi: oturumun istatistik sayaçları sunucunun ortak istatistiklerine o anda henüz aktarılmamıştı. Bu, izleme sorgularında karşılaşabileceğiniz bir gecikmedir. ALTER SYSTEM ve pg_reload_conf kullanımı yapılandırma yazısında ayrıntılı anlatılıyor.

Tablo bazında autovacuum ayarı

Genel eşikler bütün tablolara uyar ama çok sık güncellenen büyük bir tablo için yüzde 20 fazla gelebilir. Kılavuz, eşiklerin ve diğer pek çok autovacuum parametresinin tablo depolama parametreleriyle tek tek değiştirilebildiğini belirtir:

sql
ALTER TABLE sepet SET (autovacuum_enabled = on, autovacuum_vacuum_scale_factor = 0.05);
SELECT relname, reloptions FROM pg_class WHERE relname = 'sepet';
text
 relname |                         reloptions
---------+-------------------------------------------------------------
 sepet   | {autovacuum_enabled=on,autovacuum_vacuum_scale_factor=0.05}
(1 row)

Kılavuz birkaç istisnayı da vurgular: autovacuum geçici tablolara erişemez, yabancı tablolarda ANALYZE çalıştırmaz ve bölümlenmiş (partitioned) üst tabloları işlemez; bölümlerin kendisini ise normal tablo gibi işler. Bölümlenmiş tablonun istatistikleri için zaman zaman elle ANALYZE çalıştırmanız gerekir; bu konu tablo bölümleme yazısında ele alınıyor. Ayrıca autovacuum işçileri genellikle diğer komutları bekletmez: çakışan bir kilit istendiğinde kendisi kesilir. Wraparound'u önlemek için çalışan bir autovacuum ise (pg_stat_activity'de sorgu adı (to prevent wraparound) ile biter) kendiliğinden kesilmez.

Transaction kimliği taşması (wraparound) ve dondurma

MVCC, transaction kimliklerini (XID) karşılaştırarak çalışır ve bu kimlikler 32 bitliktir. Kılavuzun açıklamasıyla, bir küme 4 milyardan fazla transaction çalıştırdığında sayaç başa döner ve geçmişteki transaction'lar birden "gelecekte" görünmeye başlar; bu, verinin görünmez olması demektir. Bunu önlemek için her tablonun her veritabanında en az iki milyar transaction'da bir vacuum görmesi gerekir. VACUUM yeterince eski satırları "donmuş" (frozen) olarak işaretler; donmuş satırlar her normal transaction'a göre geçmişte kabul edilir. Tabloların ve veritabanlarının yaşını kılavuzdaki sorgularla izleyebilirsiniz:

sql
SELECT c.oid::regclass AS tablo, age(c.relfrozenxid) AS yas
FROM pg_class c WHERE c.relname = 'sepet';
SELECT datname, age(datfrozenxid) FROM pg_database ORDER BY datname;
text
 tablo | yas
-------+-----
 sepet |   1
(1 row)

    datname    | age
---------------+-----
 ornek_explain | 276
 ornek_izo     | 276
 ornek_kilit   | 276
 ornek_part    | 276
 ornek_tx      | 276
 ornek_vacuum  | 276
 postgres      | 276
 template0     | 276
 template1     | 276
(9 rows)

Yeni kurulmuş test kümemizde yaşlar çok küçük. autovacuum_freeze_max_age (varsayılan 200 milyon) değerini aşan tablolar için autovacuum, kapalı olsa bile, zorunlu olarak çalıştırılır. Bu da başarısız olursa sistem, wraparound noktasına kırk milyon transaction kaldığında aşağıdaki gibi uyarılar vermeye başlar ve üç milyon kaldığında yeni XID atamayı reddeder (kılavuzdaki örnek çıktılar):

text
WARNING:  database "mydb" must be vacuumed within 39985967 transactions
HINT:  To avoid XID assignment failures, execute a database-wide VACUUM in that database.

ERROR:  database is not accepting commands that assign new transaction IDs to avoid wraparound data loss in database "mydb"
HINT:  Execute a database-wide VACUUM in that database.

Kılavuz bu durumda sunucuyu durdurmanın ya da tek kullanıcı kipine geçmenin gerekli olmadığını, şu adımların izlenmesini önerir: eski hazırlanmış transaction'ları (pg_prepared_xacts) commit veya geri almak, uzun süren açık transaction'ları (pg_stat_activity'de age(backend_xid) veya age(backend_xmin) büyük olanlar) sonlandırmak, eski replikasyon slotlarını kaldırmak ve hedef veritabanında VACUUM çalıştırmak. Bu senaryoda VACUUM FULL ve VACUUM FREEZE kullanılmamalıdır; ilki XID gerektirir, ikincisi gereğinden fazla iş yapar. Replikasyon slotları için streaming replication yazısına bakabilirsiniz.

PostgreSQL 18'de vacuum ile ilgili değişiklikler

PostgreSQL 18 sürüm notlarında bu konuya dokunan çok sayıda madde var:

  • Normal vacuum, dondurma gerekmeden önce de bazı tamamen görünür sayfaları dondurabiliyor ("eager" tarama); bu, sonraki tam dondurma yükünü azaltır ve vacuum_max_eager_freeze_failure_rate ile ayarlanır. VERBOSE çıktısındaki eagerly scanned sayısı bunu gösterir.
  • Dosya sonu kesmeyi kontrol eden vacuum_truncate sunucu parametresi eklendi.
  • Autovacuum tetiklemesi için sabit üst sınır veren autovacuum_vacuum_max_threshold eklendi.
  • autovacuum_worker_slots ile ayrılan yuvalar sayesinde autovacuum_max_workers sunucuyu yeniden başlatmadan bu sınıra kadar değiştirilebiliyor.
  • pg_stat_all_tables ve türevlerine total_vacuum_time, total_autovacuum_time, total_analyze_time ve total_autoanalyze_time sütunları eklendi.
  • VACUUM ve ANALYZE artık kalıtım alt tablolarını da işliyor; eski davranış için yeni ONLY seçeneği kullanılıyor. Bölümlenmiş tabloyu çocukları olmadan işlemek de ONLY ile mümkün.
  • VERBOSE çıktısına ve autovacuum günlüğüne WAL arabelleğinin dolduğu sayısı (buffers full) eklendi; yukarıdaki çıktıda görebilirsiniz.

Bu sürümdeki diğer yenilikler için PostgreSQL 18 yenilikleri yazısına bakabilirsiniz.

Sık yapılan hatalar

Sık yapılan hatalar: Disk dolunca VACUUM FULL'a koşmak, Autovacuum'u kapatmak, Uzun açık transaction'ları gözden kaçırmak, Toplu yüklemeden sonra ANALYZE'ı unutmak
  • Disk dolunca VACUUM FULL'a koşmak: Tablonun yeni kopyası için ek alan gerekir ve tablo işlem boyunca tamamen kilitlenir.
  • Autovacuum'u kapatmak: Kılavuz bunu son derece öngörülebilir iş yükleri dışında önermez; kapalıyken bile wraparound önleme çalışmaları yapılır.
  • Uzun açık transaction'ları gözden kaçırmak: Vacuum çalışır ama hiçbir şey silemez; VERBOSE çıktısındaki "dead but not yet removable" sayısına bakın.
  • Toplu yüklemeden sonra ANALYZE'ı unutmak: Autovacuum yetişene kadar planlayıcı eski istatistiklerle çalışır. Etkisini EXPLAIN yazısında gerçek planlarla gösterdik.
  • Bölümlenmiş üst tabloyu analiz etmemek: Autovacuum üst tablonun istatistiğini toplamaz.
  • Her veritabanını temizlemeyi unutmak: Elle vacuum yapıyorsanız kümedeki her veritabanı ayrı ayrı ele alınmalıdır; kılavuz bunun için vacuumdb programını önerir. Zamanlama için crontab rehberine bakabilirsiniz.

Sık Sorulan Sorular

VACUUM tabloyu kilitler mi?

Standart VACUUM SHARE UPDATE EXCLUSIVE alır; SELECT, INSERT, UPDATE ve DELETE normal çalışmaya devam eder, yalnızca ALTER TABLE gibi şema değişiklikleri bekler. VACUUM FULL ise tabloya her türlü erişimi engeller.

VACUUM sonrası tablo neden küçülmedi?

Standart vacuum alanı tablo içinde yeniden kullanıma açar; yalnızca dosyanın sonundaki tamamen boş sayfaları kesebilir. Alanı işletim sistemine geri vermek için VACUUM FULL gibi tabloyu yeniden yazan bir komut gerekir.

Autovacuum çalışıyor mu, nasıl anlarım?

pg_stat_user_tables görünümündeki last_autovacuum, autovacuum_count, last_autoanalyze ve n_dead_tup sütunlarına bakın. Ayrıntılı günlük için log_autovacuum_min_duration parametresini kullanabilirsiniz; çalışan vacuum'ların ilerlemesi pg_stat_progress_vacuum görünümünde izlenir.

ANALYZE ne kadar sürer?

Kılavuz ANALYZE'ın bütün satırları okumadığını, rastgele bir örneklem kullandığını ve hızlı bir işlem olduğunu belirtir; bu yüzden pratikte genellikle bütün veritabanını analiz etmek önerilir.

Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.

İlgili içerikler: PostgreSQL öğrenme rehberi · PostgreSQL performans optimizasyonu · EXPLAIN ANALYZE ile plan okuma · MVCC ve izolasyon · pg_stat_activity ile izleme