Untuk mengembalikan ruang ke OS, gunakan VACUUM FULL
. Sementara berada di sana, saya kira Anda lari VACUUM FULL ANALYZE
. Saya mengutip manual :
FULL
Memilih vakum "penuh", yang dapat memperoleh kembali lebih banyak ruang , tetapi membutuhkan waktu lebih lama dan secara eksklusif mengunci tabel. Metode ini juga membutuhkan ruang disk tambahan, karena ia menulis salinan tabel baru dan tidak merilis salinan lama sampai operasi selesai. Biasanya ini hanya boleh digunakan ketika sejumlah besar ruang perlu direklamasi dari dalam tabel.
Penekanan berani saya.
CLUSTER
mencapai itu juga, sebagai efek jaminan.
Plain VACUUM
biasanya tidak mencapai tujuan Anda ( "satu atau lebih halaman di ujung tabel sepenuhnya gratis" ). Itu tidak menyusun ulang baris dan hanya memangkas halaman kosong dari ujung fisik file ketika kesempatan muncul - seperti kutipan Anda dari instruksi manual.
Anda bisa mendapatkan halaman kosong di akhir file fisik saat Anda INSERT
menambahkan banyak baris dan DELETE
sebelum tupel lainnya ditambahkan. Atau itu bisa terjadi secara kebetulan jika cukup banyak baris dihapus.
Ada juga pengaturan khusus yang mungkin mencegah VACUUM FULL
dari reklamasi ruang. Lihat:
Persiapkan halaman kosong di akhir tabel untuk pengujian
Kolom sistem ctid
mewakili posisi fisik suatu baris. Anda perlu memahami kolom itu:
Kita bisa bekerja dengan itu dan menyiapkan tabel dengan menghapus semua baris dari halaman terakhir:
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;
Sekarang, halaman terakhir kosong. Ini mengabaikan menulis bersamaan. Entah Anda satu-satunya yang menulis ke meja itu atau Anda perlu mengambil kunci tulis untuk menghindari gangguan.
Kueri dioptimalkan untuk mengidentifikasi baris yang memenuhi syarat dengan cepat. Angka kedua a tid
adalah indeks tuple yang disimpan sebagai tidak bertanda int2
, dan 65535
merupakan maksimum untuk tipe itu ( 2^16 - 1
), jadi itulah batas atas yang aman.
SQL Fiddle (menggunakan kembali tabel sederhana dari kasus yang berbeda.)
Alat untuk mengukur ukuran baris / tabel:
Disk penuh
Anda perlu ruang gerak pada disk untuk semua operasi ini. Ada juga alat komunitas pg_repack
sebagai pengganti VACUUM FULL
/ CLUSTER
. Itu menghindari kunci eksklusif tetapi membutuhkan ruang bebas untuk bekerja dengan juga. Manual:
Membutuhkan ruang disk kosong dua kali lebih besar dari tabel target dan indeks.
Sebagai upaya terakhir, Anda dapat menjalankan siklus dump / restore. Itu menghapus semua mengasapi dari tabel dan indeks juga. Pertanyaan yang terkait erat:
Jawabannya cukup radikal. Jika situasi Anda memungkinkan (tidak ada kunci asing atau referensi lain yang mencegah penghapusan baris), dan tidak ada akses bersamaan ke tabel), Anda dapat:
Membuang meja ke disk yang terhubung dari komputer jarak jauh dengan banyak ruang disk ( -a
untuk --data-only
):
Dari shell jauh, buang data tabel:
pg_dump -h <host_name> -p <port> -t mytbl -a mydb > db_mytbl.sql
Dalam sesi pg, TRUNCATE
tabel:
-- drop all indexes and constraints here for best performance
TRUNCATE mytbl;
Dari shell jarak jauh, pulihkan ke tabel yang sama:
psql -h <host_name> -p <port> mydb -f db_mytbl.sql
-- recreate all indexes and constraints here
Sekarang bebas dari baris mati atau kembung.
Tapi mungkin Anda bisa memiliki yang lebih sederhana?
Bisakah Anda membuat cukup ruang pada disk dengan menghapus (memindahkan) file yang tidak terkait?
Bisakah Anda VACUUM FULL
mengecilkan tabel lebih dulu, satu per satu, sehingga membebaskan ruang disk yang cukup?
Bisakah Anda menjalankan REINDEX TABLE
atau REINDEX INDEX
membebaskan ruang disk dari indeks yang membengkak?
Apa pun yang Anda lakukan, jangan terburu-buru . Jika ragu, cadangkan semuanya ke lokasi yang aman terlebih dahulu.