LWLock: SubTrans SLRU - Amazon Relational Database Service

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

LWLock: SubTrans SLRU

Gli eventi LWLock:SubtransSLRU and LWLock:SubtransBuffer wait indicano che una sessione è in attesa di accedere alla cache SLRU (Simple Least-Recently Used) per le informazioni sulle sottotransazioni. Ciò si verifica quando si determina la visibilità delle transazioni e le relazioni padre-figlio.

  • LWLock:SubtransSLRU: Un processo è in attesa di accedere alla cache SLRU (Simple Least-Recently Used) per una sottotransazione. In e versioni precedenti, viene chiamato questo evento di attesa. SubtransControlLock

  • LWLock:SubtransBuffer: Un processo è in attesa di una sottotransazione I/O su un buffer SLRU (Simple Least-Recently Used). In e versioni precedenti, viene chiamato questo evento di attesa. subtrans

Versioni del motore supportate

Queste informazioni sugli eventi di attesa sono supportate per tutte le versioni di .

Contesto

Comprendere le sottotransazioni: una sottotransazione è una transazione all'interno di una transazione in PostgreSQL. È anche nota come transazione annidata.

Le sottotransazioni vengono in genere create quando si utilizza:

  • Comandi SAVEPOINT

  • Blocchi di eccezioni () BEGIN/EXCEPTION/END

Le sottotransazioni consentono di ripristinare parti di una transazione senza influire sull'intera transazione. Questo ti offre un controllo granulare sulla gestione delle transazioni.

Dettagli di implementazione: PostgreSQL implementa le sottotransazioni come strutture annidate all'interno delle transazioni principali. Ogni sottotransazione ottiene il proprio ID di transazione.

Aspetti chiave dell'implementazione:

  • IDs Le transazioni vengono tracciate pg_xact

  • Le relazioni padre-figlio sono archiviate nella sottodirectory in pg_subtrans PGDATA

  • Ogni sessione del database può mantenere fino a sottotransazioni attive 64

  • Il superamento di questo limite causa un overflow delle sottotransazioni, che richiede l'accesso alla cache SLRU (Simple Least-Recently Used) per le informazioni sulle sottotransazioni

Probabili cause di aumento delle attese

Le cause più comuni di contesa SLRU per le sottotransazioni includono:

  • Uso eccessivo della gestione di SAVEPOINT e EXCEPTION: PL/pgSQL le procedure con EXCEPTION gestori creano automaticamente punti di salvataggio impliciti, indipendentemente dal fatto che si verifichino eccezioni. Ciascuno avvia una nuova sottotransazione. SAVEPOINT Quando una singola transazione accumula più di 64 sottotransazioni, attiva un overflow SLRU di sottotransazione.

  • Configurazioni di driver e ORM: l'SAVEPOINTutilizzo può essere esplicito nel codice dell'applicazione o implicito nelle configurazioni dei driver. Molti strumenti ORM e framework applicativi di uso comune supportano le transazioni annidate in modo nativo. Ecco alcuni esempi comuni:

    • Il parametro del driver JDBCautosave, se impostato su always oconservative, genera punti di salvataggio prima di ogni query.

    • Definizioni delle transazioni Spring Framework quando impostato su. propagation_nested

    • Rails quando requires_new: true è impostato.

    • SQLAlchemy quando session.begin_nested viene usato.

    • Django quando vengono utilizzati atomic() blocchi annidati.

    • GORM quando viene usatoSavepoint.

    • pSQLodbc quando l'impostazione del livello di rollback è impostata sul rollback a livello di istruzione (ad esempio,). PROTOCOL=7.4-2

  • Carichi di lavoro simultanei elevati con transazioni e sottotransazioni di lunga durata — Quando si verifica un overflow SLRU di sottotransazioni durante carichi di lavoro simultanei elevati e transazioni e sottotransazioni di lunga durata, PostgreSQL sperimenta un aumento della contesa. Ciò si manifesta con eventi di attesa e blocchi elevati. LWLock:SubtransBuffer LWLock:SubtransSLRU

Azioni

Consigliamo azioni diverse a seconda delle cause dell’evento di attesa. Alcune azioni forniscono un sollievo immediato, mentre altre richiedono indagini e correzioni a lungo termine.

Monitoraggio dell'utilizzo delle sottotransazioni

Per le versioni 16.1 e successive di PostgreSQL, usa la seguente query per monitorare il conteggio delle sottotransazioni e lo stato di overflow per backend. Questa query unisce le statistiche di backend con le informazioni sulle attività per mostrare quali processi utilizzano sottotransazioni:

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;

Per le versioni 13.3 e successive di PostgreSQL, monitora pg_stat_slru la visualizzazione per verificare la pressione della cache delle sottotransazioni. La seguente query SQL recupera le statistiche della cache SLRU per il componente Subtrans:

SELECT * FROM pg_stat_slru WHERE name = 'Subtrans';

Un blks_read valore in costante aumento indica un accesso frequente al disco per le sottotransazioni non memorizzate nella cache, segnalando una potenziale pressione sulla cache SLRU.

Configurazione dei parametri di memoria

Per PostgreSQL 17.1 e versioni successive, è possibile configurare la dimensione della cache SLRU della sottotransazione utilizzando il parametro. subtransaction_buffers L'esempio di configurazione seguente mostra come impostare il parametro del buffer delle sottotransazioni:

subtransaction_buffers = 128

Questo parametro specifica la quantità di memoria condivisa utilizzata per memorizzare nella cache i contenuti delle sottotransazioni (). pg_subtrans Se specificato senza unità, il valore rappresenta blocchi di BLCKSZ byte, in genere 8 KB ciascuno. Ad esempio, l'impostazione del valore su 128 alloca 1 MB (128 * 8 kB) di memoria per la cache delle sottotransazioni.

Nota

È possibile impostare questo parametro a livello di cluster in modo che tutte le istanze rimangano coerenti. Verifica e modifica il valore in base ai requisiti specifici del carico di lavoro e alla classe di istanza. È necessario riavviare l'istanza di writer per rendere effettive le modifiche ai parametri.

Azioni a lungo termine

  • Esamina il codice e le configurazioni dell'applicazione: esamina le configurazioni del codice dell'applicazione e dei driver del database per l'utilizzo esplicito e implicito e SAVEPOINT l'utilizzo delle sottotransazioni in generale. Identifica le transazioni che potrebbero generare più di 64 sottotransazioni.

  • Riduci l'utilizzo dei savepoint: riduci al minimo l'uso dei savepoint nelle transazioni:

    • Rivedi PL/pgSQL le procedure e le funzioni con i blocchi EXCEPTION. I blocchi EXCEPTION creano automaticamente punti di salvataggio impliciti, che possono contribuire all'overflow delle sottotransazioni. Ogni clausola EXCEPTION crea una sottotransazione, indipendentemente dal fatto che si verifichi effettivamente un'eccezione durante l'esecuzione.

      Esempio 1: utilizzo problematico del blocco EXCEPTION

      Il seguente esempio di codice mostra l'utilizzo problematico del blocco EXCEPTION che crea più sottotransazioni:

      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;

      Il seguente esempio di codice migliorato riduce l'utilizzo delle sottotransazioni utilizzando UPSERT anziché la gestione delle eccezioni:

      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;

      Esempio 2: gestore di eccezioni STRICT

      Il seguente esempio di codice mostra la gestione problematica delle ECCEZIONI con 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;

      Il seguente esempio di codice migliorato evita le sottotransazioni utilizzando IF NOT FOUND anziché la gestione delle eccezioni:

      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: il autosave parametro, se impostato su always oconservative, genera punti di salvataggio prima di ogni query. Valuta se l'neverimpostazione è accettabile per la tua applicazione.

    • Driver ODBC PostgreSQL (pSQLOdBC): l'impostazione del livello di rollback (per il rollback a livello di istruzione) crea punti di salvataggio impliciti per abilitare la funzionalità di rollback delle istruzioni. Valuta se il rollback a livello di transazione o nessun rollback è accettabile per la tua applicazione.

    • Esamina le configurazioni delle transazioni ORM

    • Prendi in considerazione strategie alternative di gestione degli errori che non richiedono punti di salvataggio

  • Ottimizza la progettazione delle transazioni: ristruttura le transazioni per evitare un annidamento eccessivo e ridurre la probabilità che si verifichino condizioni di overflow delle sottotransazioni.

  • Riduzione delle transazioni di lunga durata: le transazioni di lunga durata possono aggravare i problemi relativi alle sottotransazioni conservando più a lungo le informazioni relative alle sottotransazioni. Monitora le metriche di Performance Insights e configura il idle_in_transaction_session_timeout parametro per terminare automaticamente le transazioni inattive.

  • Monitora le metriche di Performance Insights: monitora le metriche tra cui idle_in_transaction_count (numero di sessioni inattive nello stato della transazione) e idle_in_transaction_max_time (durata della transazione inattiva più lunga) per rilevare le transazioni di lunga durata.

  • Configuraidle_in_transaction_session_timeout: imposta questo parametro nel tuo gruppo di parametri per terminare automaticamente le transazioni inattive dopo una durata specificata.

  • Monitoraggio proattivo: monitora gli eventi più ricorrenti LWLock:SubtransBuffer e LWLock:SubtransSLRU attendi gli eventi per rilevare le controversie relative alle sottotransazioni prima che diventino critiche.