View a markdown version of this page

LWLock:SubtransSLRU (LWLock:SubtransControlLock) - Amazon Relational Database Service

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_subtrans subdirektori di bawah PGDATA

  • Setiap sesi database dapat mempertahankan hingga sub 64 transaksi 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 EXCEPTION penyimpanan implisit, terlepas dari apakah pengecualian terjadi. Mas SAVEPOINT ing-masing memulai subtransaksi baru. Ketika satu transaksi mengakumulasi lebih dari 64 subtransaksi, itu memicu overflow SLRU subtransaksi.

  • Konfigurasi driver dan ORM SAVEPOINT penggunaan 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 JDBCautosave, jika disetel ke always atauconservative, menghasilkan titik penyimpanan sebelum setiap kueri.

    • Definisi transaksi Spring Framework saat disetel kepropagation_nested.

    • Rel saat requires_new: true diatur.

    • SQLAlchemy saat session.begin_nested digunakan.

    • Django saat atomic() blok bersarang digunakan.

    • GORM saat Savepoint digunakan.

    • 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:SubtransBuffer ikan dan LWLock:SubtransSLRU kunci.

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 SAVEPOINT penggunaan 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 — autosave Parameter, jika disetel ke always atauconservative, menghasilkan titik penyimpanan sebelum setiap kueri. Evaluasi apakah never pengaturan 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_timeout parameter 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) dan idle_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:SubtransBuffer dan LWLock:SubtransSLRU tunggu peristiwa untuk mendeteksi perselisihan terkait subtransaksi sebelum menjadi kritis.