Pembengkakan tabel dan indeks terjadi saat operasi vacuum tidak mengimbangi laju Bahasa Pengolahan Data (DML) terhadap tabel. Pembengkakan tabel dan indeks tidak dapat dihindari dan umumnya dapat diterima karena transaksi dapat menggunakan kembali ruang tersebut. Bloat parah menyebabkan masalah performa, seperti waktu kueri yang lebih lambat, peningkatan I/O, penggunaan cache dan buffer bersama yang kurang efisien, serta peningkatan biaya penyimpanan.
Cara terbaik untuk memperkirakan pembengkakan adalah dengan menggunakan modul
pgstattuple. Namun, penggunaan pgstattuple kurang efisien jika ekstensi harus
membaca semua halaman relasi. Jika tidak dapat menggunakan pgstattuple, Anda dapat menggunakan skrip lain untuk memperkirakan pembengkakan, meskipun pendekatan ini memberikan akurasi yang lebih rendah.
Membaca output pgstattuple
Saat Anda menggunakan pgstattuple untuk melaporkan karakteristik penyimpanan fisik tabel atau indeks, outputnya dalam format berikut:
> SELECT * FROM pgstattuple('large_table');
-[ RECORD 1 ]------+-----------
table_len | 7431888896
tuple_count | 66666666
tuple_len | 2796296271
tuple_percent | 37.63
dead_tuple_count | 0
dead_tuple_len | 0
dead_tuple_percent | 0
free_space | 3873153652
free_percent | 52.12
Berikut deskripsi output:
table_len(7431888896)- Total ukuran tabel dalam byte. Bagian ini mencakup semua tuple aktif, tuple tidak aktif, dan ruang kosong. Dalam hal ini,
large_tablemenempati sekitar 7.088 GB. tuple_count(66666666)- Mewakili jumlah tuple aktif—baris yang terlihat dan aktif—yang ada dalam tabel. Tabel ini berisi sekitar 66 juta baris aktif.
tuple_len(2796296271)- Total panjang dalam byte dari semua tuple live yang digabungkan, yang kira-kira 2,6 GB.
tuple_percent(37.63)Persentase
table_lenyang ditempati oleh tuple aktif. Anda menghitungnya sebagai berikut:(
tuple_len/table_len) ∗ 100 = (2796296271/7431888896) ∗ 100 ≈37.63persenOutput ini menunjukkan bahwa data aktif menggunakan kurang dari 40% ruang disk tabel.
dead_tuple_count(0)Jumlah tuple tidak aktif—baris yang belum dihapus oleh operasi pembersihan setelah pembaruan atau penghapusan. Nilai
0berarti tabel bersih dan tidak memiliki tuple tidak aktif yang menunggu untuk diklaim kembali. Hal ini sering menunjukkan bahwaVACUUM, atau autovacuum, berjalan secara efisien di tabel.dead_tuple_len(0)Total panjang dalam byte dari semua tuple yang tidak aktif. Sesuai dengan
dead_tuple_count, nilai0berarti baris yang tidak aktif tidak menggunakan ruang.dead_tuple_percent(0)Persentase
table_lenyang ditempati oleh tuple tidak aktif. Anda menghitungnya sebagai berikut:(
dead_tuple_len/table_len) ∗ 100 = (0/7431888896) ∗ 100 =0persenfree_space(3873153652)Nilai ini menunjukkan jumlah ruang kosong di halaman data tabel. Anda dapat menggunakan kembali ruang ini untuk penyisipan atau pembaruan baru tanpa memerlukan perluasan tabel. Hal ini menunjukkan jumlah ruang kosong yang signifikan, sekitar 3,7 GB.
free_percent(52.12)Nilai ini mewakili persentase
table_lenyang merupakan ruang kosong. Anda menghitungnya sebagai berikut:(
free_space/table_len) ∗ 100 = (3873153652/7431888896) ∗ 100 ≈52.12persen
Memperkirakan pembengkakan menggunakan kueri
Anda dapat memperkirakan pembengkakan menggunakan kueri terhadap tabel katalog sistem, meskipun metode ini kurang akurat dibandingkan menggunakan ekstensi seperti pgstattuple. Jika Anda menggunakan skrip seperti pemeriksaan pembengkakan tabel PostgreSQL, statistik tabel Anda harus terbaru, jika tidak, perkiraan akan tidak akurat.
Saat Anda membandingkan output kueri dengan modul pgstattuple, perkiraan dapat dibandingkan, tetapi bukan pengukuran pasti pembengkakan. Modul ini masih menjadi pengukur pembengkakan yang lebih akurat karena kueri SQL mengandalkan mesin statistik kumulatif PostgreSQL, sedangkan modul membaca halaman data yang sebenarnya.
Contoh berikut membandingkan output dari dua metode berbeda untuk
menganalisis pembengkakan tabel di PostgreSQL untuk tabel bernama large_table.
> SELECT * FROM pgstattuple('large_table');
-[ RECORD 1 ]------+-----------
table_len | 2475892736
tuple_count | 22000000
tuple_len | 922925931
tuple_percent | 37.28
dead_tuple_count | 0
dead_tuple_len | 0
dead_tuple_percent | 0
free_space | 1293696900
free_percent | 52.25
Vs.
-[ RECORD 1 ]+------------
databasename | postgres
schemaname | public
tablename | large_table
can_estimate | t
est_rows | 21965400
pct_bloat | 54
mb_bloat | 1269.24
table_mb | 2361.195
Penggunaan alamat yang berlebihan
Anda dapat mengelola bloat dengan cara berikut, yang masing-masing memiliki kelebihan dan kekurangan, sehingga memerlukan perencanaan yang cermat:
- Lakukan penyedotan debu secara menyeluruh. Operasi ini memerlukan penguncian tabel penuh selama durasi vakum, dan memerlukan periode nonaktif.
- Pindahkan data ke tabel baru. Untuk menggunakan metode ini, Anda harus menghentikan perubahan tabel untuk memastikan bahwa perubahan tidak ditransfer ke relasi baru.
- Gunakan
pg_squeeze. Ekstensi ini mengurangi bloat online. Ekstensi membuat tabel bayangan, memasukkan semua data, lalu mempertahankan perubahan tabel menggunakan slot replikasi hingga langkah terakhir, yaitu mengganti tabel yang membengkak dengan tabel baru yang tidak membengkak. Kemudian, ia meminta penguncian tabel singkat untuk memindahkan tabel yang tidak membengkak guna menggantikan tabel yang membengkak. Metode ini memerlukan dua kali ruang objek selama durasi operasi, tetapi paling tidak mengganggu operasi normal.