VACUUM dan ANALYZE adalah dua operasi pemeliharaan database PostgreSQL yang paling penting.
Vakum digunakan untuk memulihkan ruang yang ditempati oleh "tupel mati" dalam sebuah tabel. Tuple mati dibuat ketika catatan dihapus atau diperbarui (penghapusan diikuti oleh penyisipan). PostgreSQL tidak secara fisik menghapus baris lama dari tabel tetapi menempatkan "penanda" di atasnya sehingga kueri tidak mengembalikan baris itu. Ketika proses vakum berjalan, ruang yang ditempati oleh tupel mati ini ditandai dapat digunakan kembali oleh tupel lain.
Operasi "analisis" melakukan apa yang dikatakan namanya - itu menganalisis isi tabel database dan mengumpulkan statistik tentang distribusi nilai di setiap kolom dari setiap tabel. Mesin kueri PostgreSQL menggunakan statistik ini untuk menemukan paket kueri terbaik. Saat baris dimasukkan, dihapus, dan diperbarui dalam database, statistik kolom juga berubah. ANALISIS – dijalankan secara manual oleh DBA atau secara otomatis oleh PostgreSQL setelah autovacuum – memastikan statistik selalu mutakhir.
Meskipun terdengar relatif mudah, di balik layar, menyedot debu, dan menganalisis adalah dua proses yang kompleks. Untungnya, DBA tidak perlu terlalu khawatir tentang internal mereka. Namun, mereka sering bingung menjalankan proses ini secara manual atau menyetel nilai optimal untuk parameter konfigurasi.
Dalam artikel ini, kami akan membagikan beberapa praktik terbaik untuk VAKUM dan ANALISIS.
Tips 1:Jangan Jalankan VACUUM atau ANALISIS Manual Tanpa Alasan
Penyedot debu PostgreSQL (penyedot debu otomatis atau vakum manual) meminimalkan kembung tabel dan mencegah penyelesaian ID transaksi. Autovacuum tidak memulihkan ruang disk yang diambil oleh tupel mati. Namun, menjalankan VACUUM FULL perintah akan melakukannya. VACUUM FULL memiliki implikasi kinerjanya. Tabel target dikunci secara eksklusif selama operasi, mencegah pembacaan yang merata di atas meja. Proses ini juga membuat salinan lengkap dari tabel, yang membutuhkan ruang disk ekstra saat dijalankan. Kami menyarankan untuk tidak menjalankan VACUUM FULL kecuali ada persentase kembung yang sangat tinggi, dan kueri sangat menderita. Kami juga menyarankan untuk menggunakan periode aktivitas basis data terendah untuknya.
Ini juga merupakan praktik terbaik untuk tidak menjalankan penyedot debu manual terlalu sering di seluruh database; database target dapat disedot secara optimal oleh proses autovacuum. Akibatnya, vakum manual mungkin tidak menghapus tupel mati tetapi menyebabkan beban I/O yang tidak perlu atau lonjakan CPU. Jika perlu, penyedot debu manual hanya boleh dijalankan berdasarkan tabel per tabel saat dibutuhkan, seperti rasio baris hidup dan baris mati yang rendah, atau celah besar antara vakum otomatis. Selain itu, penyedot debu manual harus dijalankan saat aktivitas pengguna minimal.
Autovacuum juga membuat statistik distribusi data tabel tetap mutakhir (tidak membangunnya kembali). Saat dijalankan secara manual, ANALISIS perintah sebenarnya membangun kembali statistik ini alih-alih memperbaruinya. Sekali lagi, membangun kembali statistik ketika sudah diperbarui secara optimal oleh autovacuum reguler dapat menyebabkan tekanan yang tidak perlu pada sumber daya sistem.
Waktu ketika Anda harus menjalankan ANALYZE secara manual segera setelah memuat data secara massal ke tabel target. Sejumlah besar (bahkan beberapa ratus) baris baru dalam tabel yang ada akan secara signifikan mengubah distribusi data kolomnya. Baris baru akan menyebabkan statistik kolom yang ada menjadi usang. Saat pengoptimal kueri menggunakan statistik seperti itu, kinerja kueri bisa sangat lambat. Dalam kasus ini, menjalankan perintah ANALYZE segera setelah memuat data untuk sepenuhnya membangun kembali statistik adalah pilihan yang lebih baik daripada menunggu autovacuum bekerja.
Kiat 2:Sempurnakan Ambang Autovacuum
Sangat penting untuk memeriksa atau menyetel autovacuum dan menganalisis parameter konfigurasi di postgresql.conf file atau di properti tabel individual untuk mencapai keseimbangan antara autovacuum dan peningkatan kinerja.
PostgreSQL menggunakan dua parameter konfigurasi untuk memutuskan kapan memulai autovacuum:
- autovacuum_vacuum_threshold :ini memiliki nilai default 50
- autovacuum_vacuum_scale_factor :ini memiliki nilai default 0,2
Bersama-sama, parameter ini memberi tahu PostgreSQL untuk memulai autovacuum ketika jumlah baris mati dalam tabel melebihi jumlah baris dalam tabel tersebut dikalikan dengan faktor skala, ditambah ambang batas vakum. Dengan kata lain, PostgreSQL akan memulai autovacuum di atas meja ketika:
pg_stat_user_tables.n_dead_tup > (pg_class.reltuples x autovacuum_vacuum_scale_factor) + autovacuum_vacuum_threshold
Untuk meja berukuran kecil hingga menengah, ini mungkin sudah cukup. Misalnya, tabel dengan 10.000 baris, jumlah baris mati harus lebih dari 2.050 ((10.000 x 0,2) + 50) sebelum autovacuum dimulai.
Tidak setiap tabel dalam database mengalami tingkat modifikasi data yang sama. Biasanya, beberapa tabel besar akan sering mengalami modifikasi data, dan akibatnya, akan memiliki jumlah baris mati yang lebih banyak. Nilai default mungkin tidak berfungsi untuk tabel tersebut. Misalnya, dengan nilai default, tabel dengan 1 juta baris harus memiliki lebih dari 200.050 baris mati sebelum autovacuum dimulai ((1000.000 x 0,2) + 50). Ini bisa berarti kesenjangan yang lebih panjang antara autovacuum, waktu autovacuum yang semakin lama, dan lebih buruk lagi, autovacuum tidak berjalan sama sekali jika transaksi aktif di meja menguncinya.
Oleh karena itu, sasarannya adalah menyetel ambang batas ini ke nilai optimal sehingga autovacuum dapat terjadi secara berkala dan tidak memakan waktu lama (dan memengaruhi sesi pengguna) sambil menjaga jumlah baris mati relatif rendah.
Salah satu pendekatan adalah dengan menggunakan satu atau parameter lainnya. Jadi, jika kita menyetel autovacuum_vacuum_scale_factor ke 0 dan sebagai gantinya menyetel autovacuum_vacuum_threshold ke, katakanlah, 5.000, sebuah tabel akan diautovacuum ketika jumlah baris matinya lebih dari 5.000.
Kiat 3:Sempurnakan Ambang Analisis Otomatis
Mirip dengan autovacuum, autoanalyze juga menggunakan dua parameter yang memutuskan kapan autovacuum juga akan memicu autoanalyze:
- autovacuum_analyze_threshold :ini memiliki nilai default 50
- autovacuum_analyze_scale_factor :ini memiliki nilai default 0,1
Seperti autovacuum, parameter autovacuum_analyze_threshold dapat diatur ke nilai yang menentukan jumlah tupel yang dimasukkan, dihapus, atau diperbarui dalam tabel sebelum analisis otomatis dimulai. Kami merekomendasikan pengaturan parameter ini secara terpisah pada tabel transaksi besar dan tinggi. Konfigurasi tabel akan menimpa nilai postgresql.conf.
Cuplikan kode di bawah ini menunjukkan sintaks SQL untuk mengubah setelan autovacuum_analyze_threshold untuk sebuah tabel.
ALTER TABLE <table_name> SET (autovacuum_analyze_threshold = <threshold rows>)
Kiat 4:Sempurnakan Autovacuum Worker
Parameter lain yang sering diabaikan oleh DBA adalah autovacuum_max_workers , yang memiliki nilai default 3. Autovacuum bukanlah proses tunggal, tetapi sejumlah utas vakum individu yang berjalan secara paralel. Alasan untuk menentukan beberapa pekerja adalah untuk memastikan bahwa menyedot debu meja besar tidak menahan penyedotan meja yang lebih kecil dan sesi pengguna. Parameter autovacuum_max_workers memberitahu PostgreSQL untuk menambah jumlah thread pekerja autovacuum untuk melakukan pembersihan.
Praktik umum oleh DBA PostgreSQL adalah meningkatkan jumlah utas pekerja maksimum dengan harapan akan mempercepat autovacuum. Ini tidak berfungsi karena semua utas berbagi autovacuum_vacuum_cost_limit yang sama , yang memiliki nilai default 200. Setiap utas autovacuum diberi batas biaya menggunakan rumus yang ditunjukkan di bawah ini:
individual thread’s cost_limit = autovacuum_vacuum_cost_limit / autovacuum_max_workers
Biaya pekerjaan yang dilakukan oleh utas vakum otomatis dihitung menggunakan tiga parameter:
- vacuum_cost_page_hit :ini memiliki nilai default 1
- vacuum_cost_page_miss :ini memiliki nilai default 10
- vacuum_cost_page_dirty :ini memiliki nilai default 20
Apa yang dimaksud dengan parameter ini adalah:
- Saat utas vakum menemukan halaman data yang seharusnya dibersihkan di buffer bersama, biayanya adalah 1.
- Jika halaman data tidak ada di buffer bersama, tetapi di cache OS, biayanya adalah 10.
- Jika halaman harus ditandai kotor karena utas vakum harus menghapus baris mati, biayanya menjadi 20.
Peningkatan jumlah utas pekerja akan menurunkan batas biaya untuk setiap utas. Karena setiap utas diberi batas biaya yang lebih rendah, utas akan tidur lebih sering karena ambang biaya mudah dicapai, yang pada akhirnya menyebabkan seluruh proses vakum berjalan lambat. Sebaiknya tingkatkan autovacuum_vacuum_cost_limit ke nilai yang lebih tinggi, seperti 2000, lalu sesuaikan jumlah maksimum utas pekerja.
Cara yang lebih baik adalah menyetel parameter ini untuk tabel individual hanya jika diperlukan. Misalnya, jika autovacuum dari tabel transaksional yang besar memakan waktu terlalu lama, tabel tersebut dapat dikonfigurasi untuk sementara untuk menggunakan batas biaya vakumnya sendiri dan penundaan biaya. Batas biaya dan penundaan akan menggantikan nilai seluruh sistem yang ditetapkan di postgresql.conf.
Cuplikan kode di bawah ini menunjukkan cara mengonfigurasi tabel individual.
ALTER TABLE <table_name> SET (autovacuum_vacuum_cost_limit = <large_value>) ALTER TABLE <table_name> SET (autovacuum_vacuum_cost_delay = <lower_cost_delay>)
Menggunakan parameter pertama akan memastikan utas vakum otomatis yang ditetapkan ke tabel akan melakukan lebih banyak pekerjaan sebelum tidur. Menurunkan autovacuum_vacuum_cost_delay juga akan berarti utas memiliki waktu tidur yang lebih sedikit.
Pemikiran Terakhir
Seperti yang Anda lihat, mengubah parameter konfigurasi untuk vakum dan analisis sangatlah mudah, tetapi perlu pengamatan yang cermat terlebih dahulu. Setiap database berbeda dalam hal ukuran, pola lalu lintas, dan tingkat transaksi. Kami merekomendasikan DBA memulai dengan mengumpulkan informasi yang cukup tentang database mereka sebelum mengubah parameter atau meluncurkan rezim vakum/analisis manual. Informasi tersebut dapat berupa:
- Jumlah baris di setiap tabel
- Jumlah tupel mati di setiap tabel
- Waktu vakum terakhir untuk setiap tabel
- Waktu analisis terakhir untuk setiap tabel
- Kecepatan penyisipan/pembaruan/penghapusan data di setiap tabel
- Waktu yang dibutuhkan oleh autovacuum untuk setiap tabel
- Peringatan tentang tabel yang tidak dikosongkan
- Kinerja kueri paling penting saat ini dan tabel yang mereka akses
- Kinerja kueri yang sama setelah vakum/analisis manual
Dari sini, DBA dapat memilih beberapa tabel "percontohan" untuk mulai mengoptimalkan. Mereka dapat mulai mengubah properti vakum/analisis untuk tabel dan memeriksa kinerjanya. PostgreSQL adalah mesin basis data yang cerdas – DBA akan sering merasa bahwa mungkin yang terbaik adalah membiarkan PostgreSQL melakukan penyedotan debu dan analisis daripada melakukannya secara manual.