Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.
LWLock:SubtransSLRU (LWLock:SubtransControlLock)
Per LWLock:SubtransSLRU istiwa dan LWLock:SubtransBuffer tunggu menunjukkan bahwa sesi sedang menunggu untuk mengakses cache sederhana yang paling jarang digunakan (SLRU) untuk informasi subtransaksi. Ini terjadi ketika menentukan visibilitas transaksi dan hubungan orangtua-anak.
-
LWLock:SubtransSLRU: Sebuah proses sedang menunggu untuk mengakses cache sederhana yang paling jarang digunakan (SLRU) untuk subtransaksi. Di RDS untuk PostgreSQL sebelum versi 13, acara tunggu ini dipanggil.SubtransControlLock -
LWLock:SubtransBuffer: Sebuah proses sedang menunggu I/O pada buffer sederhana yang paling jarang digunakan (SLRU) untuk subtransaksi. Di RDS untuk PostgreSQL sebelum versi 13, acara tunggu ini dipanggil.subtrans
Versi mesin yang didukung
Informasi peristiwa tunggu ini didukung untuk semua versi RDS for PostgreSQL.
Konteks
Memahami subtransaksi — Sub-transaksi adalah transaksi dalam transaksi di PostgreSQL. Ini juga dikenal sebagai transaksi bersarang.
Subtransaksi biasanya dibuat saat Anda menggunakan:
-
SAVEPOINTperintah -
Blok pengecualian (
BEGIN/EXCEPTION/END)
Subtransaksi memungkinkan Anda memutar kembali bagian dari transaksi tanpa mempengaruhi keseluruhan transaksi. Ini memberi Anda kontrol halus atas manajemen transaksi.
Detail implementasi — PostgreSQL mengimplementasikan subtransaksi sebagai struktur bersarang dalam transaksi utama. Setiap subtransaksi mendapatkan ID transaksinya sendiri.
Aspek implementasi utama:
-
ID transaksi dilacak di
pg_xact -
Parent-child hubungan disimpan dalam
pg_subtranssubdirektori di bawahPGDATA -
Setiap sesi database dapat mempertahankan hingga sub
64transaksi aktif -
Melebihi batas ini menyebabkan luapan subtransaksi, yang memerlukan akses ke cache sederhana yang paling jarang digunakan (SLRU) untuk informasi subtransaksi
Kemungkinan penyebab peningkatan peristiwa tunggu
Penyebab umum perselisihan SLRU subtransaksi meliputi:
-
Penggunaan berlebihan penanganan SAVEPOINT dan EXCEPTION — PL/pgSQL prosedur dengan penangan secara otomatis membuat titik
EXCEPTIONpenyimpanan implisit, terlepas dari apakah pengecualian terjadi. MasSAVEPOINTing-masing memulai subtransaksi baru. Ketika satu transaksi mengakumulasi lebih dari 64 subtransaksi, itu memicu overflow SLRU subtransaksi. -
Konfigurasi driver dan ORM —
SAVEPOINTpenggunaan dapat eksplisit dalam kode aplikasi atau implisit melalui konfigurasi driver. Banyak alat ORM yang umum digunakan dan kerangka kerja aplikasi mendukung transaksi bersarang secara native. Berikut adalah beberapa contoh umum:-
Parameter driver JDBC
autosave, jika disetel kealwaysatauconservative, menghasilkan titik penyimpanan sebelum setiap kueri. -
Definisi transaksi Spring Framework saat disetel ke
propagation_nested. -
Rel saat
requires_new: truediatur. -
SQLAlchemy saat
session.begin_nesteddigunakan. -
Django saat
atomic()blok bersarang digunakan. -
GORM saat
Savepointdigunakan. -
psqloDBC saat pengaturan level rollback disetel ke rollback tingkat pernyataan (misalnya,).
PROTOCOL=7.4-2
-
-
Beban kerja bersamaan yang tinggi dengan transaksi dan subtransaksi yang berjalan lama — Ketika overflow SLRU subtransaksi terjadi selama beban kerja bersamaan yang tinggi dan transaksi dan subtransaksi yang berjalan lama, PostgreSQL mengalami peningkatan pertikaian. Ini bermanifestasi sebagai peristiwa tunggu yang ditingg
LWLock:SubtransBufferikan danLWLock:SubtransSLRUkunci.
Tindakan
Kami merekomendasikan berbagai tindakan, tergantung pada penyebab peristiwa tunggu Anda. Beberapa tindakan memberikan bantuan segera, sementara yang lain memerlukan penyelidikan dan koreksi jangka panjang.
Memantau penggunaan subtransaksi
Untuk PostgreSQL versi 16.1 dan yang lebih baru, gunakan kueri berikut untuk memantau jumlah subtransaksi dan status overflow per backend. Kueri ini menggabungkan statistik backend dengan informasi aktivitas untuk menunjukkan proses mana yang menggunakan subtransaksi:
SELECT a.pid, usename, query, state, wait_event_type, wait_event, subxact_count, subxact_overflowed FROM (SELECT id, pg_stat_get_backend_pid(id) pid, subxact_count, subxact_overflowed FROM pg_stat_get_backend_idset() id JOIN LATERAL pg_stat_get_backend_subxact(id) AS s ON true ) a JOIN pg_stat_activity b ON a.pid = b.pid;
Untuk PostgreSQL versi 13.3 dan yang lebih baru, pantau pg_stat_slru tampilan untuk tekanan cache subtransaksi. Query SQL berikut mengambil statistik cache SLRU untuk komponen Subtrans:
SELECT * FROM pg_stat_slru WHERE name = 'Subtrans';
Nilai yang meningkat blks_read secara konsisten menunjukkan akses disk yang sering untuk subtransaksi yang tidak di-cache, menandakan potensi tekanan cache SLRU.
Mengkonfigurasi parameter memori
Untuk PostgreSQL 17.1 dan yang lebih baru, Anda dapat mengonfigurasi ukuran cache SLRU subtransaksi menggunakan parameter. subtransaction_buffers Contoh konfigurasi berikut menunjukkan cara mengatur parameter buffer subtransaksi:
subtransaction_buffers = 128
Parameter ini menentukan jumlah memori bersama yang digunakan untuk menyimpan konten subtransaksi (pg_subtrans). Ketika ditentukan tanpa unit, nilainya mewakili blok BLCKSZ byte, biasanya 8KB masing-masing. Misalnya, menyetel nilai ke 128 mengalokasikan 1MB (128 * 8kB) memori untuk cache subtransaksi.
catatan
Anda dapat mengatur parameter ini di tingkat cluster sehingga semua instance tetap konsisten. Uji dan sesuaikan nilai agar sesuai dengan persyaratan beban kerja spesifik dan kelas instance Anda. Anda harus me-reboot instance writer agar perubahan parameter berlaku.
Long-term tindakan
-
Periksa kode aplikasi dan konfigurasi — Tinjau kode aplikasi dan konfigurasi driver database untuk penggunaan eksplisit dan implisit serta
SAVEPOINTpenggunaan subtransaksi secara umum. Identifikasi transaksi yang berpotensi menghasilkan lebih dari 64 subtransaksi. -
Kurangi penggunaan savepoint — Minimalkan penggunaan savepoints dalam transaksi Anda:
-
Tinjau PL/pgSQL prosedur dan fungsi dengan blok PENGECUALIAN. Blok PENGECUALIAN secara otomatis membuat titik penyimpanan implisit, yang dapat berkontribusi pada luapan subtransaksi. Setiap klausa PENGECUALIAN menciptakan subtransaksi, terlepas dari apakah pengecualian benar-benar terjadi selama eksekusi.
contoh
Contoh 1: Penggunaan blok PENGECUALIAN yang bermasalah
Contoh kode berikut menunjukkan penggunaan blok PENGECUALIAN bermasalah yang membuat beberapa subtransaksi:
CREATE OR REPLACE FUNCTION process_user_data() RETURNS void AS $$ DECLARE user_record RECORD; BEGIN FOR user_record IN SELECT * FROM users LOOP BEGIN -- This creates a subtransaction for each iteration INSERT INTO user_audit (user_id, action, timestamp) VALUES (user_record.id, 'processed', NOW()); UPDATE users SET last_processed = NOW() WHERE id = user_record.id; EXCEPTION WHEN unique_violation THEN -- Handle duplicate audit entries UPDATE user_audit SET timestamp = NOW() WHERE user_id = user_record.id AND action = 'processed'; END; END LOOP; END; $$ LANGUAGE plpgsql;Contoh kode yang ditingkatkan berikut mengurangi penggunaan subtransaksi dengan menggunakan UPSERT alih-alih penanganan pengecualian:
CREATE OR REPLACE FUNCTION process_user_data() RETURNS void AS $$ DECLARE user_record RECORD; BEGIN FOR user_record IN SELECT * FROM users LOOP -- Use UPSERT to avoid exception handling INSERT INTO user_audit (user_id, action, timestamp) VALUES (user_record.id, 'processed', NOW()) ON CONFLICT (user_id, action) DO UPDATE SET timestamp = NOW(); UPDATE users SET last_processed = NOW() WHERE id = user_record.id; END LOOP; END; $$ LANGUAGE plpgsql;contoh
Contoh 2: Penangan pengecualian STRICT
Contoh kode berikut menunjukkan penanganan EXCEPTION yang bermasalah dengan NO_DATA_FOUND:
CREATE OR REPLACE FUNCTION get_user_email(p_user_id INTEGER) RETURNS TEXT AS $$ DECLARE user_email TEXT; BEGIN BEGIN -- STRICT causes an exception if no rows or multiple rows found SELECT email INTO STRICT user_email FROM users WHERE id = p_user_id; RETURN user_email; EXCEPTION WHEN NO_DATA_FOUND THEN RETURN 'Email not found'; END; END; $$ LANGUAGE plpgsql;Contoh kode yang ditingkatkan berikut menghindari subtransaksi dengan menggunakan IF NOT FOUND alih-alih penanganan pengecualian:
CREATE OR REPLACE FUNCTION get_user_email(p_user_id INTEGER) RETURNS TEXT AS $$ DECLARE user_email TEXT; BEGIN SELECT email INTO user_email FROM users WHERE id = p_user_id; IF NOT FOUND THEN RETURN 'Email not found'; ELSE RETURN user_email; END IF; END; $$ LANGUAGE plpgsql; -
Driver JDBC —
autosaveParameter, jika disetel kealwaysatauconservative, menghasilkan titik penyimpanan sebelum setiap kueri. Evaluasi apakahneverpengaturan akan dapat diterima untuk aplikasi Anda. -
Driver ODBC PostgreSQL (PsqloDBC) — Pengaturan tingkat rollback (untuk rollback tingkat pernyataan) membuat titik penyimpanan implisit untuk mengaktifkan fungsionalitas rollback pernyataan. Evaluasi apakah tingkat transaksi atau tidak ada rollback akan dapat diterima untuk aplikasi Anda.
-
Periksa konfigurasi transaksi ORM
-
Pertimbangkan strategi penanganan kesalahan alternatif yang tidak memerlukan titik penyimpanan
-
-
Optimalkan desain transaksi — Merestrukturisasi transaksi untuk menghindari sarang yang berlebihan dan mengurangi kemungkinan kondisi luapan subtransaksi.
-
Mengurangi transaksi yang berjalan lama — Long-running transaksi dapat memperburuk masalah subtransaksi dengan menyimpan informasi subtransaksi lebih lama. Pantau metrik penghitung per kueri dan basis data terperinci dan konfigurasikan
idle_in_transaction_session_timeoutparameter untuk secara otomatis menghentikan transaksi idle. -
Pantau metrik penghitung per kueri dan basis data terperinci — Lacak metrik termasuk
idle_in_transaction_count(jumlah sesi dalam keadaan idle dalam keadaan transaksi) danidle_in_transaction_max_time(durasi transaksi idle yang berjalan terlama) untuk mendeteksi transaksi yang berjalan lama. -
Konfigurasi
idle_in_transaction_session_timeout— Tetapkan parameter ini di grup parameter Anda untuk secara otomatis menghentikan transaksi idle setelah durasi yang ditentukan. -
Pemantauan proaktif — Pantau kejadian tinggi
LWLock:SubtransBufferdanLWLock:SubtransSLRUtunggu peristiwa untuk mendeteksi perselisihan terkait subtransaksi sebelum menjadi kritis.