VACUUM biasa pada PostgreSQL umumnya membiarkan ruang heap yang telah direklamasi tetap berada di dalam relation agar dapat digunakan kembali. Fase tail truncation yang terpisah dapat memperpendek file relation ketika terdapat rangkaian halaman kosong yang berurutan pada ujung fisiknya. Fase tersebut memerlukan lock ACCESS EXCLUSIVE.

Batas lock ini membuat tail truncation berbeda secara material dari pembersihan vacuum biasa. Pemeliharaan heap dan index rutin dirancang agar dapat berjalan berdampingan dengan operasi baca dan tulis normal, sedangkan memperpendek relation secara fisik memerlukan periode singkat ketika akses tabel secara bersamaan tidak dapat berlangsung.

Ruang yang dapat digunakan kembali dan ruang yang dikembalikan adalah hasil berbeda

Menghapus versi tuple yang sudah mati biasanya tidak langsung mengurangi ukuran file tabel. Vacuum dapat menandai ruang pada halaman heap sebagai tersedia, lalu insert atau update berikutnya dapat menggunakan kembali kapasitas tersebut.

Penggunaan ulang internal ini menghindari penulisan ulang relation dan sudah memadai untuk banyak workload. Karena itu, sebuah tabel dapat memiliki ruang yang cukup besar untuk digunakan kembali sementara ukuran filenya tetap tidak berubah.

Mengembalikan ruang ke sistem operasi memiliki kondisi fisik yang lebih ketat. Halaman kosong harus membentuk suffix berurutan pada ujung relation. Halaman kosong di bagian tengah tidak dapat begitu saja dihapus karena nomor block setelahnya akan bergeser.

Karena itu, posisi fisik ruang kosong sama pentingnya dengan jumlahnya.

Tail truncation mengubah batas relation

Heap relation dialamatkan sebagai block bernomor. Menghapus block dari ujungnya mengubah batas atas yang valid dari rentang block tersebut.

PostgreSQL melindungi perubahan batas itu dengan ACCESS EXCLUSIVE. Lock ini berkonflik dengan setiap mode lock tingkat tabel, termasuk lock ACCESS SHARE yang digunakan oleh operasi baca biasa.

Karena itu, operasi truncation tidak setara dengan menandai halaman individual agar dapat digunakan kembali. Halaman yang dapat digunakan kembali tetap menjadi bagian relation dan mempertahankan nomor block-nya. Tail truncation menghapus block dari cakupan fisik relation.

Halaman kosong harus mencapai ujung fisik

Pertimbangkan relation dengan block kosong yang tersebar di antara block yang masih berisi data:

live | free | live | free | live | free

Block kosong terakhir saja mungkin dapat dihapus jika sepenuhnya kosong dan memenuhi syarat, tetapi block kosong sebelumnya tidak dapat dipotong selama masih ada block berisi data setelahnya.

Susunan berbeda menghasilkan suffix yang lebih besar untuk dihapus:

live | live | free | free | free | free

Di sini, tail kosong yang berurutan berpotensi dipangkas sebagai satu rentang.

Batasan ini berarti delete dalam jumlah besar tidak menjamin penurunan ukuran file yang sebanding. Jika tuple yang masih hidup menempati halaman dekat ujung, relation tidak memiliki suffix kosong panjang untuk dihapus meskipun banyak halaman sebelumnya memiliki ruang kosong.

Lock dapat terlihat dampaknya pada tabel yang sibuk

Permintaan ACCESS EXCLUSIVE berkonflik dengan reader dan writer yang aktif. Pada relation dengan aktivitas tinggi, memperoleh lock ini dapat lebih sulit dibanding menjalankan pekerjaan vacuum biasa.

Dampak praktisnya bergantung pada concurrency dan durasi transaksi. Transaksi singkat dapat menyediakan kesempatan memperoleh lock lebih sering. Operasi yang berjalan lama dapat membuat kesempatan tersebut lebih sulit diprediksi.

Setelah diperoleh, lock juga berkonflik dengan akses tabel baru sampai pekerjaan truncation melepaskannya. Fase truncation dimaksudkan tetap terbatas, bukan mengubah seluruh plain vacuum menjadi operasi dengan lock eksklusif, tetapi keberadaannya tetap dapat berpengaruh pada workload yang sensitif terhadap latency.

Perilaku ini berbeda dari VACUUM FULL. VACUUM FULL menulis ulang relation dan memerlukan ACCESS EXCLUSIVE selama operasinya; tail truncation pada plain vacuum adalah mekanisme yang lebih sempit dan melekat pada pemrosesan vacuum biasa.

Truncation dapat dinonaktifkan secara terpisah

PostgreSQL menyediakan tail truncation sebagai kebijakan vacuum tersendiri. Pengaturan server vacuum_truncate mengendalikan perilaku default, dan sebuah tabel dapat menggantinya melalui storage parameter.

Perintah vacuum juga dapat menentukan opsi TRUNCATE secara eksplisit:

VACUUM (TRUNCATE FALSE) events;

Menonaktifkan truncation tidak menonaktifkan pembersihan dead tuple. Vacuum tetap dapat mereklamasi ruang tuple untuk digunakan kembali di dalam tabel tanpa mencoba memperpendek tail relation.

Pengaturan persisten pada tingkat tabel dapat memisahkan pilihan ini dari perintah individual:

ALTER TABLE events SET (vacuum_truncate = false);

Konsekuensi pilihan ini adalah ruang kosong internal tetap dapat digunakan kembali sambil menghindari kebutuhan lock eksklusif yang terkait dengan pengembalian halaman tail ke sistem operasi.

Ukuran file dapat tetap besar setelah pembersihan berhasil

Ukuran relation yang tetap stabil setelah vacuum bukan, dengan sendirinya, bukti bahwa vacuum gagal mereklamasi ruang dead tuple.

Beberapa keadaan dapat menghasilkan ukuran file yang sama. Kapasitas kosong mungkin tersebar di seluruh heap alih-alih terkonsentrasi pada tail. Sebuah halaman yang masih berisi data dapat menahan rentang block terakhir relation. Tail truncation mungkin dinonaktifkan. Concurrency juga dapat mencegah kesempatan truncation digunakan pada suatu proses vacuum tertentu.

Akuntansi ruang pada tingkat database dan ukuran file pada sistem operasi karena itu menggambarkan aspek storage yang berbeda. Yang pertama dapat menunjukkan kapasitas yang tersedia untuk digunakan kembali meskipun yang kedua tidak berkurang.

Bentuk workload menentukan nilai truncation

Tabel yang berulang kali tumbuh lalu mengalami penghapusan pada wilayah fisik terbaru dapat membentuk tail kosong secara alami. Tail truncation dapat mengembalikan ruang tersebut tanpa menulis ulang seluruh tabel.

Workload yang menghapus row di seluruh key space cenderung menciptakan lubang di berbagai bagian relation. Lubang tersebut tetap berguna untuk penempatan tuple berikutnya, tetapi tidak membentuk suffix yang dapat dihapus.

Penempatan fisik tuple juga berubah dari waktu ke waktu melalui update, penggunaan ulang halaman, bulk load, dan maintenance. Urutan key secara logis saja tidak menjamin row yang dihapus berada pada ujung fisik heap.

Tail truncation karena itu merupakan optimasi batas, bukan mekanisme compaction umum. Mekanisme ini mengubah susunan tertentu dari halaman terminal yang sudah kosong menjadi file relation yang lebih kecil, dengan kebutuhan lock eksklusif pada saat batas fisik tersebut berubah.