Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.
Menyelesaikan masalah kinerja vakum di RDS untuk PostgreSQL
Bagian ini membahas faktor-faktor yang sering berkontribusi pada kinerja vakum yang lebih lambat dan bagaimana mengatasi masalah ini.
Topik
Vakum indeks besar
VACUUM
Prosesnya terdiri dari beberapa tahap: inisialisasi, pemindaian tumpukan, penyedot debu indeks dan tumpukan, membersihkan indeks, memotong tumpukan, dan melakukan pembersihan akhir. Selama pemindaian, halaman dipangkas, didefragmentasi, dan dibekukan. Setelah tumpukan dipindai sepenuhnya, indeks dibersihkan, halaman kosong dikembalikan ke sistem operasi, dan tugas pembersihan akhir, seperti menyedot debu peta ruang kosong dan memperbarui statistik, selesai.
Saat menyedot debu indeks, beberapa lintasan mungkin diperlukan jika tersedia maintenance_work_mem
(atauautovacuum_work_mem
) tidak cukup untuk memproses indeks. Dalam PostgreSQL versi 16 dan sebelumnya, batas 1GB pada alokasi memori untuk menyimpan IDs tupel mati sering memerlukan beberapa lintasan, terutama untuk indeks besar. PostgreSQL versi 17 mengatasi batasan ini dengan TidStore
memperkenalkan, sistem alokasi memori dinamis yang menggantikan array alokasi tunggal. Ini menghilangkan kendala 1GB, meningkatkan efisiensi memori, dan mengurangi kemungkinan beberapa pemindaian per setiap indeks.
Namun, bahkan di PostgreSQL 17, beberapa lintasan mungkin masih diperlukan untuk indeks besar jika memori yang tersedia tidak cukup untuk memproses seluruh indeks sekaligus. Biasanya, indeks besar cenderung mengandung lebih banyak tupel mati yang membutuhkan banyak lintasan.
Mendeteksi operasi vakum yang lambat
postgres_get_av_diag()
Fungsi ini dapat mendeteksi ketika operasi vakum berjalan lambat karena memori yang tidak mencukupi. Untuk informasi lebih lanjut tentang fungsi ini, lihatMenginstal alat pemantauan dan diagnostik autovacuum di RDS untuk PostgreSQL.
postgres_get_av_diag()
Fungsi mengeluarkan pemberitahuan berikut ketika memori yang tersedia tidak cukup untuk menyelesaikan penyedot debu indeks dalam satu lintasan.
rds_tools
1.8
NOTICE: Your database is currently running aggressive vacuum to prevent wraparound and it might be slow.
NOTICE: The current setting of autovacuum_work_mem is "XXX" and might not be sufficient. Consider increasing the setting, and if necessary, scaling up the Amazon RDS instance class for more memory. Additionally, review the possibility of manual vacuum with exclusion of indexes using (VACUUM (INDEX_CLEANUP FALSE, VERBOSE TRUE) table_name;).
rds_tools
1.9
NOTICE: Your database is currently running aggressive vacuum to prevent wraparound and it might be slow.
NOTICE: The current setting of autovacuum_work_mem is XX might not be sufficient. Consider increasing the setting to XXX, and if necessary, scaling up the RDS instance class for more memory. The suggested value is an estimate based on the current number of dead tuples for the table being vacuumed, which might not fully reflect the latest state. Additionally, review the possibility of manual vacuum with exclusion of indexes using (VACUUM (INDEX_CLEANUP FALSE, VERBOSE TRUE) table_name;). For more information, see Working with PostgreSQL autovacuum in the Amazon Amazon RDS User Guide.
catatan
postgres_get_av_diag()
Fungsi ini bergantung pada pg_stat_all_tables.n_dead_tup
untuk memperkirakan jumlah memori yang diperlukan untuk penyedot debu indeks.
Ketika postgres_get_av_diag()
fungsi mengidentifikasi operasi vakum lambat yang memerlukan beberapa pemindaian indeks karena tidak mencukupiautovacuum_work_mem
, itu akan menghasilkan pesan berikut:
NOTICE: Your vacuum is performing multiple index scans due to insufficient autovacuum_work_mem:XXX for index vacuuming. For more information, see Working with PostgreSQL autovacuum in the Amazon Amazon RDS User Guide.
Bimbingan
Anda dapat menerapkan solusi berikut menggunakan manual VACUUM FREEZE
untuk mempercepat pembekuan tabel.
Tingkatkan memori untuk menyedot debu
Seperti yang disarankan oleh postgres_get_av_diag()
fungsi, disarankan untuk meningkatkan autovacuum_work_mem
parameter untuk mengatasi kendala memori potensial pada tingkat instance. Meskipun autovacuum_work_mem
merupakan parameter dinamis, penting untuk dicatat bahwa agar pengaturan memori baru diterapkan, daemon autovacuum perlu me-restart pekerjanya. Untuk mencapai ini:
-
Konfirmasikan bahwa pengaturan baru sudah ada.
-
Hentikan proses yang saat ini menjalankan autovacuum.
Pendekatan ini memastikan bahwa alokasi memori yang disesuaikan diterapkan pada operasi autovacuum baru.
Untuk hasil yang lebih cepat, pertimbangkan untuk melakukan VACUUM FREEZE
operasi secara manual dengan maintenance_work_mem
pengaturan yang ditingkatkan dalam sesi Anda:
SET maintenance_work_mem TO '1GB'; VACUUM FREEZE VERBOSE
table_name
;
Jika Anda menggunakan Amazon RDS dan menemukan bahwa Anda memerlukan memori tambahan untuk mendukung nilai yang lebih tinggi untuk maintenance_work_mem
atauautovacuum_work_mem
, pertimbangkan untuk meningkatkan ke kelas instans dengan lebih banyak memori. Ini dapat menyediakan sumber daya yang diperlukan untuk meningkatkan operasi vakum manual dan otomatis, yang mengarah pada peningkatan kinerja vakum dan basis data secara keseluruhan.
Nonaktifkan INDEX_CLEANUP
Manual VACUUM
di PostgreSQL versi 12 dan yang lebih baru memungkinkan melewatkan fase pembersihan indeks, sementara autovacuum darurat di PostgreSQL versi 14 dan yang lebih baru melakukan ini secara otomatis berdasarkan parameter. vacuum_failsafe_age
Awas
Melewatkan pembersihan indeks dapat menyebabkan indeks kembung dan berdampak negatif pada kinerja kueri. Untuk mengurangi ini, pertimbangkan untuk mengindeks ulang atau menyedot debu indeks yang terpengaruh selama jendela pemeliharaan.
Untuk panduan tambahan tentang penanganan indeks besar, lihat dokumentasi diMengelola autovacuum dengan indeks berukuran besar .
Penyedot debu indeks paralel
Dimulai dengan PostgreSQL 13, indeks dapat disedot dan dibersihkan secara paralel secara default menggunakan VACUUM
manual, dengan satu proses vacuum worker ditetapkan untuk setiap indeks. Namun, untuk PostgreSQL untuk menentukan apakah operasi vakum memenuhi syarat untuk eksekusi paralel, kriteria khusus harus dipenuhi:
-
Setidaknya harus ada dua indeks.
-
max_parallel_maintenance_workers
Parameter harus diatur ke setidaknya 2. -
Ukuran indeks harus melebihi
min_parallel_index_scan_size
batas, yang defaultnya 512KB.
Anda dapat menyesuaikan max_parallel_maintenance_workers
pengaturan berdasarkan jumlah v yang CPUs tersedia di instans Amazon RDS Anda dan jumlah indeks di atas meja untuk mengoptimalkan waktu penyelesaian vakum.
Untuk informasi selengkapnya, lihat Penyedot debu paralel di Amazon RDS untuk PostgreSQL dan Amazon Aurora PostgreSQL
Terlalu banyak tabel atau database untuk vakum
Seperti disebutkan dalam dokumentasi The Autovacuum Daemon PostgreSQL, daemon autovacuumautovacuum_naptime
detik per database.
Dengan database 'N', pekerja baru memulai kira-kira setiap [autovacuum_naptime
/N detik]. Namun, jumlah total pekerja bersamaan dibatasi oleh autovacuum_max_workers
pengaturan. Jika jumlah database atau tabel yang membutuhkan penyedot debu melebihi batas ini, database atau tabel berikutnya akan diproses segera setelah pekerja tersedia.
Ketika banyak tabel besar atau database memerlukan penyedot debu secara bersamaan, semua pekerja autovacuum yang tersedia dapat menjadi sibuk untuk durasi yang lama, menunda pemeliharaan pada tabel dan database lain. Di lingkungan dengan tingkat transaksi tinggi, kemacetan ini dapat dengan cepat meningkat dan berpotensi menyebabkan masalah vakum sampul dalam instans Amazon RDS Anda.
Ketika postgres_get_av_diag()
mendeteksi sejumlah besar tabel atau database, ia memberikan rekomendasi berikut:
NOTICE: Your database is currently running aggressive vacuum to prevent wraparound and it might be slow.
NOTICE: The current setting of autovacuum_max_workers:3 might not be sufficient. Consider increasing the setting and, if necessary, consider scaling up the Amazon RDS instance class for more workers.
Bimbingan
Tingkatkan autovacuum_max_workers
Untuk mempercepat penyedotan debu, kami sarankan untuk menyesuaikan autovacuum_max_workers
parameter untuk memungkinkan lebih banyak pekerja autovacuum bersamaan. Jika kemacetan kinerja tetap ada, pertimbangkan untuk meningkatkan instans Amazon RDS Anda ke kelas dengan lebih banyak v, yang selanjutnya dapat meningkatkan kemampuan pemrosesan CPUs paralel.
Vakum agresif (untuk mencegah pembungkus) sedang berjalan
Usia database (MaximumUsedTransactionIDs) di PostgreSQL hanya berkurang ketika vakum agresif (untuk mencegah sampul) berhasil diselesaikan. Sampai kekosongan ini selesai, usia akan terus meningkat tergantung pada tingkat transaksi.
postgres_get_av_diag()
Fungsi ini menghasilkan yang berikut NOTICE
ketika mendeteksi vakum yang agresif. Namun, itu hanya memicu output ini setelah vakum telah aktif setidaknya selama dua menit.
NOTICE: Your database is currently running aggressive vacuum to prevent wraparound, monitor autovacuum performance.
Untuk informasi lebih lanjut tentang vakum agresif, lihat Saat vakum agresif sudah berjalan.
Anda dapat memverifikasi apakah vakum agresif sedang berlangsung dengan kueri berikut:
SELECT a.xact_start AS start_time, v.datname "database", a.query, a.wait_event, v.pid, v.phase, v.relid::regclass, pg_size_pretty(pg_relation_size(v.relid)) AS heap_size, ( SELECT string_agg(pg_size_pretty(pg_relation_size(i.indexrelid)) || ':' || i.indexrelid::regclass || chr(10), ', ') FROM pg_index i WHERE i.indrelid = v.relid ) AS index_sizes, trunc(v.heap_blks_scanned * 100 / NULLIF(v.heap_blks_total, 0)) AS step1_scan_pct, v.index_vacuum_count || '/' || ( SELECT count(*) FROM pg_index i WHERE i.indrelid = v.relid ) AS step2_vacuum_indexes, trunc(v.heap_blks_vacuumed * 100 / NULLIF(v.heap_blks_total, 0)) AS step3_vacuum_pct, age(CURRENT_TIMESTAMP, a.xact_start) AS total_time_spent_sofar FROM pg_stat_activity a INNER JOIN pg_stat_progress_vacuum v ON v.pid = a.pid;
Anda dapat menentukan apakah itu vakum agresif (untuk mencegah sampul) dengan memeriksa kolom kueri di output. Ungkapan “untuk mencegah sampul” menunjukkan bahwa itu adalah kekosongan yang agresif.
query | autovacuum: VACUUM public.t3 (to prevent wraparound)
Misalnya, Anda memiliki pemblokir pada usia transaksi 1 miliar dan tabel yang membutuhkan vakum agresif untuk mencegah pemblokiran pada usia transaksi yang sama. Selain itu, ada pemblokir lain pada usia transaksi 750 juta. Setelah menyelesaikan pemblokir pada usia transaksi 1 miliar, usia transaksi tidak akan langsung turun menjadi 750 juta. Ini akan tetap tinggi sampai tabel yang membutuhkan vakum agresif atau transaksi apa pun dengan usia di atas 750 juta selesai. Selama periode ini, usia transaksi klaster PostgreSQL Anda akan terus meningkat. Setelah proses vakum selesai, usia transaksi akan turun menjadi 750 juta tetapi akan mulai meningkat lagi hingga penyedotan lebih lanjut selesai. Siklus ini akan berlanjut selama kondisi ini tetap ada, hingga usia transaksi akhirnya turun ke level yang dikonfigurasi untuk instans Amazon RDS Anda, yang ditentukan oleh. autovacuum_freeze_max_age