PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Ikhtisar Pemrosesan VACUUM di PostgreSQL

PostgreSQL tidak menggunakan mekanisme pembaruan IN-PLACE, jadi sesuai dengan cara perintah DELETE dan UPDATE dirancang,

  • Setiap kali operasi DELETE dilakukan, itu menandai tupel yang ada sebagai MATI, bukan menghapus tupel tersebut secara fisik.
  • Demikian pula, setiap kali operasi UPDATE dilakukan, itu menandai tupel yang ada yang sesuai sebagai MATI dan menyisipkan tupel baru (yaitu operasi UPDATE =DELETE + INSERT).

Jadi setiap perintah DELETE dan UPDATE akan menghasilkan satu tuple MATI, yang tidak akan pernah digunakan (kecuali ada transaksi paralel). Tupel mati ini akan menyebabkan penggunaan ruang ekstra yang tidak perlu meskipun jumlah catatan efektif yang sama atau kurang. Ini juga disebut kembung ruang di PostgreSQL. Karena PostgreSQL banyak digunakan sebagai sistem basis data relasional jenis OLTP, di mana sering dilakukan operasi INSERT, UPDATE dan DELETE, akan ada banyak tupel MATI dan karenanya konsekuensi yang sesuai. Jadi PostgreSQL membutuhkan mekanisme pemeliharaan yang kuat untuk menangani tupel MATI ini. VACUUM adalah proses pemeliharaan yang menangani tupel DEAD bersama dengan beberapa aktivitas lain yang berguna untuk mengoptimalkan operasi VACUUM. Mari kita pahami beberapa terminologi yang akan digunakan nanti di blog ini.

Peta Visibilitas

Seperti namanya, ini mempertahankan info visibilitas tentang halaman yang hanya berisi tupel yang diketahui dapat dilihat oleh semua transaksi aktif. Untuk setiap halaman, satu bit digunakan. Jika bit diset ke 1 berarti semua tupel dari halaman yang sesuai terlihat. Bit yang disetel ke 0 berarti tidak ada ruang kosong pada halaman yang diberikan dan tupel dapat dilihat oleh semua transaksi.

Peta visibilitas dipertahankan untuk setiap relasi (tabel dan indeks) dan diasosiasikan bersama relasi utama yaitu jika nama node file relasi adalah 12345, maka file visibilitas akan disimpan dalam file paralel 12345_vm.

Peta Ruang Kosong

Ini mempertahankan info ruang kosong yang berisi detail tentang ruang yang tersedia dalam relasi. Ini juga disimpan dalam file paralel dengan file utama relasi yaitu jika nama node file relasi adalah 12345, maka file peta ruang kosong akan disimpan dalam file paralel 12345_fsm.

Bekukan Tuple

PostgreSQL menggunakan 4 byte untuk menyimpan id transaksi, yang berarti maksimum 2 miliar transaksi dapat dihasilkan sebelum dibungkus. Sekarang pertimbangkan masih saat ini beberapa Tuple berisi id transaksi awal katakanlah 100, kemudian untuk transaksi baru (yang menggunakan transaksi yang dibungkus) katakanlah 5, id transaksi 100 akan melihat ke masa depan dan tidak akan dapat melihat data yang ditambahkan /dimodifikasi olehnya meskipun itu sebenarnya di masa lalu. Untuk menghindari id transaksi khusus ini, FrozenTransactionId (sama dengan 2) ditetapkan. Id transaksi khusus ini selalu dianggap di masa lalu dan akan terlihat oleh semua transaksi.

VACUUM

Tugas utama VAKUM adalah merebut kembali ruang penyimpanan yang ditempati oleh tupel MATI. Ruang penyimpanan yang direklamasi tidak dikembalikan ke sistem operasi melainkan hanya didefragmentasi dalam halaman yang sama, sehingga hanya tersedia untuk digunakan kembali oleh penyisipan data di masa mendatang dalam tabel yang sama. Sementara operasi VACUUM terjadi pada tabel tertentu, secara bersamaan operasi READ/WRITE lainnya dapat dilakukan pada tabel yang sama karena kunci eksklusif tidak diambil pada tabel tertentu. Dalam kasus nama tabel tidak ditentukan, VACUUM akan dilakukan pada semua tabel database. Operasi VACUUM bekerja di bawah serangkaian operasi dalam kunci ShareUpdateExclusive:

  • Pindai semua halaman dari semua tabel (atau tabel tertentu) database untuk mendapatkan semua tupel mati.
  • Bekukan tupel lama jika diperlukan.
  • Hapus tupel indeks yang menunjuk ke tupel MATI masing-masing.
  • Hapus tupel MATI dari halaman yang sesuai dengan tabel tertentu dan alokasikan ulang tupel aktif di halaman.
  • Perbarui Peta Ruang Kosong (FSM) dan Peta Visibilitas (VM).
  • Potong halaman terakhir jika memungkinkan (jika ada tupel MATI yang dibebaskan).
  • Perbarui semua tabel sistem yang sesuai.

Seperti yang dapat kita lihat dari langkah kerja VACUUM di atas, jelas bahwa ini adalah operasi yang sangat mahal karena perlu memproses semua halaman relasi. Jadi sangat diperlukan untuk melewati kemungkinan halaman yang tidak perlu disedot. Karena Visibility map (VM) memberikan informasi halaman di mana jika tidak ada ruang kosong, dapat diasumsikan bahwa kekosongan halaman yang sesuai tidak diperlukan dan karenanya halaman ini dapat dilewati dengan aman.

Karena VACUUM tetap melintasi semua halaman dan semua tupelnya, maka dibutuhkan kesempatan untuk melakukan tugas penting lainnya untuk membekukan tupel yang memenuhi syarat.

VACUUM Penuh

Seperti yang dibahas di bagian sebelumnya, meskipun VACUUM menghapus semua tupel MATI dan mendefrag halaman untuk penggunaan di masa mendatang, itu tidak membantu dalam mengurangi keseluruhan penyimpanan tabel karena ruang sebenarnya tidak dilepaskan ke sistem operasi. Misalkan tabel tbl1 bahwa total penyimpanan telah mencapai 1,5GB dan dari 1GB ini ditempati oleh tupel mati, maka setelah VAKUM lain sekitar 1GB akan tersedia untuk penyisipan tupel lebih lanjut tapi tetap saja, penyimpanan total akan tetap sebagai 1,5GB.

VAKUM Penuh memecahkan masalah ini dengan benar-benar mengosongkan ruang dan mengembalikannya kembali ke sistem operasi. Tapi ini datang dengan biaya. Tidak seperti VACUUM, FULL VACUUM tidak mengizinkan operasi paralel karena dibutuhkan kunci eksklusif pada relasi untuk mendapatkan FULL VACUUM. Berikut langkah-langkahnya:

  • Mengambil kunci eksklusif pada relasi.
  • Buat file penyimpanan kosong paralel.
  • Salin semua tupel aktif dari penyimpanan saat ini ke penyimpanan yang baru dialokasikan.
  • Kemudian kosongkan penyimpanan asli.
  • Kosongkan kuncinya.

Jadi seperti yang jelas dari langkah-langkahnya juga, itu akan memiliki penyimpanan yang hanya diperlukan untuk data yang tersisa.

VACUUM Otomatis

Daripada melakukan VACUUM secara manual, PostgreSQL mendukung demon yang secara otomatis memicu VACUUM secara berkala. Setiap kali VACUUM bangun (secara default 1 menit) itu memanggil banyak pekerjaan (tergantung pada proses konfigurasi autovacuum_worker).

Pekerja vakum otomatis melakukan proses VAKUM secara bersamaan untuk masing-masing tabel yang ditentukan. Karena VACUUM tidak mengambil kunci eksklusif apa pun pada tabel, itu tidak (atau minimal) memengaruhi pekerjaan basis data lainnya.

Konfigurasi Auto-VACUUM harus dilakukan berdasarkan pola penggunaan database. Seharusnya tidak terlalu sering (karena akan menyia-nyiakan pekerja yang bangun karena mungkin tidak ada atau terlalu sedikit tupel mati) atau terlalu banyak tertunda (itu akan menyebabkan banyak tupel mati bersama-sama dan karenanya tabel mengasapi).

VACUUM atau VAKUM Penuh

Idealnya, aplikasi database harus dirancang sedemikian rupa sehingga tidak memerlukan VAKUM PENUH. Seperti dijelaskan di atas, FULL VACUUM membuat ulang ruang penyimpanan dan mengembalikan data, jadi jika tupel yang mati hanya sedikit, maka segera ruang penyimpanan akan dibuat ulang untuk mengembalikan semua data asli. Juga karena VAKUM PENUH mengambil kunci eksklusif di atas meja, itu memblokir semua operasi di meja yang sesuai. Jadi melakukan FULL VACUUM terkadang dapat memperlambat keseluruhan database.

Singkatnya VAKUM Penuh harus dihindari kecuali jika diketahui bahwa sebagian besar ruang penyimpanan adalah karena tupel mati. Ekstensi PostgreSQL pg_freespacemap dapat digunakan untuk mendapatkan petunjuk yang adil tentang ruang kosong.

Mari kita lihat contoh proses VACUUM yang dijelaskan.

Pertama, mari kita buat tabel demo1:

postgres=# create table demo1(id int, id2 int);

CREATE TABLE

Dan masukkan beberapa data di sana:

postgres=# insert into demo1 values(generate_series(1,10000), generate_series(1,

10000));

INSERT 0 10000

postgres=# SELECT count(*) as npages, round(100 * avg(avail)/8192 ,2) as average_freespace_ratio FROM pg_freespace('demo1');

 npages | average_freespace_ratio

--------+-------------------------

  45 |                0.00

(1 row)

Sekarang, mari kita hapus data:

postgres=# delete from demo1 where id%2=0;

DELETE 5000

Dan jalankan vakum manual:

postgres=# vacuum demo1;

VACUUM

postgres=# SELECT count(*) as npages, round(100 * avg(avail)/8192 ,2) as average_freespace_ratio FROM pg_freespace('demo1');

 npages | average_freespace_ratio

--------+-------------------------

  45 |               45.07

(1 row)

Ruang kosong ini sekarang tersedia untuk digunakan kembali oleh PostgreSQL, tetapi jika Anda ingin melepaskan ruang tersebut ke sistem operasi, jalankan:

postgres=# vacuum full demo1;

VACUUM

postgres=# SELECT count(*) as npages, round(100 * avg(avail)/8192 ,2) as average_freespace_ratio FROM pg_freespace('demo1');

 npages | average_freespace_ratio

--------+-------------------------

  23 |                0.00

(1 row)

Kesimpulan

Dan ini adalah contoh singkat bagaimana proses VACUUM bekerja. Untungnya, berkat proses vakum otomatis, sebagian besar waktu dan dalam lingkungan PostgreSQL yang umum, Anda tidak perlu memikirkan hal ini karena ini dikelola oleh mesin itu sendiri.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cara Menampilkan Nilai Null Saat Menjalankan Kueri di psql (PostgreSQL)

  2. Bagaimana cara menangani membuka/menutup koneksi Db di aplikasi Go?

  3. Cara mengganti basis data menggunakan PostgreSQL

  4. Sisipkan beberapa baris dalam satu tabel berdasarkan nomor di tabel lain

  5. Berhenti (lama) menjalankan kueri SQL di PostgreSQL saat sesi atau permintaan tidak ada lagi?