View a markdown version of this page

LWLock:SubtransSLRU (LWLock:SubtransControlLock) - 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:SubtransSLRU (LWLock:SubtransControlLock)

Gli eventi LWLock:SubtransSLRU e 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 determinano la visibilità delle transazioni e le relazioni padre-figlio.

  • LWLock:SubtransSLRU: un processo è in attesa di accedere alla cache Simple Least-Recentemente Usata (SLRU) per una sottotransazione. In RDS per PostgreSQL precedente alla versione 13, viene chiamato questo evento di attesa. SubtransControlLock

  • LWLock:SubtransBuffer: un processo è in attesa di una sottotransazione I/O su un buffer semplice usato di recente (SLRU). In RDS per PostgreSQL precedente alla versione 13, viene chiamato questo evento di attesa. subtrans

Versioni del motore supportate

Queste informazioni relative all'evento di attesa sono supportate per tutte le versioni di RDS per PostgreSQL.

Contesto

Informazioni sulle 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 utilizzano:

  • Comandi SAVEPOINT

  • Blocchi di eccezioni () BEGIN/EXCEPTION/END

Le sottotransazioni consentono di annullare parti di una transazione senza influire sull'intera transazione. Questo ti offre un controllo dettagliato 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:

  • Gli ID delle transazioni vengono tracciati in pg_xact

  • Parent-child le relazioni sono archiviate nella pg_subtrans sottodirectory in PGDATA

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

  • 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 contenzioso relativo alla SLRU relativa alle subtransazioni includono:

  • Uso eccessivo di SAVEPOINT e gestione delle ECCEZIONI: PL/pgSQL le procedure con EXCEPTION gestori creano automaticamente punti di salvataggio impliciti, indipendentemente dal fatto che si verifichino eccezioni. Ciascuna 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 se impostate su. propagation_nested

    • Rails quando requires_new: true è impostato.

    • SQLAlchemy quando viene utilizzato. session.begin_nested

    • Django quando vengono utilizzati blocchi annidati. atomic()

    • GORM quando viene utilizzatoSavepoint.

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

  • Carichi di lavoro simultanei elevati con transazioni e sottotransazioni di lunga durata: quando l'overflow SLRU delle sottotransazioni si verifica durante carichi di lavoro simultanei elevati e transazioni e sottotransazioni di lunga durata, PostgreSQL presenta un aumento del conflitto. 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 PostgreSQL 16.1 e successive, utilizza la seguente query per monitorare il conteggio delle sottotransazioni e lo stato dell'overflow per backend. Questa query unisce le statistiche del backend alle informazioni sulle attività per mostrare quali processi utilizzano le 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 di PostgreSQL 13.3 e successive, monitora la visualizzazione per verificare la pressione nella cache delle sottotransazioni. pg_stat_slru 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 della 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 Il seguente esempio di configurazione mostra come impostare il parametro del buffer delle subtransazioni:

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, impostando il valore su 128 si 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 affinché le modifiche ai parametri abbiano effetto.

Long-term azioni

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

  • Riduci l'utilizzo dei punti di salvataggio: riduci al minimo l'uso dei punti di salvataggio 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

      Esempio 1: utilizzo problematico del blocco EXCEPTION

      L'esempio di codice seguente 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

      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 sarebbe 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à di condizioni di overflow delle sottotransazioni.

  • Riduci le transazioni di lunga durata: le transazioni possono aggravare i problemi relativi alle Long-running sottotransazioni conservando più a lungo le informazioni sulle sottotransazioni. Monitora le metriche dettagliate per query e contatore del database e configura il parametro per terminare automaticamente le transazioni inattive. idle_in_transaction_session_timeout

  • Monitora le metriche dettagliate per query e contatore del database: tieni traccia delle 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 le numerose occorrenze di eventi LWLock:SubtransBuffer e LWLock:SubtransSLRU attendi per rilevare i conflitti relativi alle subtransazioni prima che diventino critici.