2015-11-19 8 views
6

Ho trovato un bug nel codice dell'applicazione in cui ho avviato una transazione, ma non ho mai eseguito il commit o eseguito un rollback. La connessione viene utilizzata periodicamente, solo leggendo alcuni dati ogni 10 secondi o giù di lì. Nella tabella pg_stat_activity, il suo stato è segnalato come "inattivo nella transazione" e il suo tempo backend_start è più di una settimana fa.Quali sono le conseguenze della mancata conclusione di una transazione di database?

Qual è l'impatto sul database di questo? Causa ulteriore utilizzo di CPU e RAM? Influirà su altre connessioni? Per quanto tempo può persistere in questo stato?

Sto utilizzando postgresql 9.1 e 9.4.

+0

Gli impatti: 1. i tuoi dati non sono visibili ad altre transazioni 2.se alla fine non ti impegni, perdi i tuoi dati. – zerkms

+0

@zerkms Sono più interessato all'impatto dell'elaborazione sul server: mi rendo conto che eventuali modifiche apportate non sarebbero visibili ad altre connessioni (anche se in questo caso, è solo la lettura dei dati, non modifica mai nulla) – wolfcastle

+0

La perdita dei dati non è alla fine una preoccupazione perché puoi sempre usare SAVEPOINTS. – Madthew

risposta

10

Dal momento che solo SELECT, l'impatto è limitato. È più grave per qualsiasi operazione di scrittura, in cui le modifiche non sono visibili a qualsiasi altra transazione fino a quando non viene eseguito il commit, e viene persa se non viene mai eseguita.

Lo fa costo un po 'di RAM e permanente occupa una delle vostre connessioni consentite (che può o non può importa).

Una delle conseguenze più gravi delle transazioni di lunga durata: blocca VACUUM dal suo lavoro, poiché c'è ancora una vecchia transazione che può vedere le vecchie righe. Il sistema inizierà a gonfiarsi.

In particolare, acquisisce un blocco ACCESS SHARE (il minimo blocco di tutti) su tutte le tabelle di riferimento. Questo non interferisce con altri comandi DML come INSERT, UPDATE o DELETE, ma sarà comanda blocco DDL nonché TRUNCATE o VACUUM (compresi i lavori autovacuum). See "Table-level Locks" in the manual.

Si può anche interferire con vari replica soluzioni e portare a transazione ID avvolgente nel lungo periodo se rimane aperta abbastanza a lungo/a bruciare abbastanza XIDs abbastanza veloce. Maggiori informazioni su questo in the manual on "Routine Vacuuming".

Gli effetti di blocco possono fungo se altre transazioni sono bloccate dall'impegno e quelle hanno acquisito blocchi proprio. Ecc

È possibile tenere aperte le transazioni (quasi) a tempo indeterminato - fino a quando la connessione è chiusa (. Che avviene anche quando il server viene riavviato, ovviamente)
Ma non lasciano mai le transazioni aperto più a lungo del necessario.

+0

Blocca VACUUM solo per le tabelle utilizzate nella transazione o tutte le tabelle? – wolfcastle

+0

@wolfcastle: solo quelli a cui si fa riferimento nella transazione (in qualsiasi modo!). Siate consapevoli che l'effetto può essere un fungo ... Ho aggiunto qualcosa in più sopra. –

+2

In realtà, 'VACUUM' può elaborare una tabella bloccata per' ACCESS SHARE' da un xid virtuale. Tuttavia, non può troncarlo per liberare spazio nel sistema operativo. Se la transazione è 'SERIALIZABLE', o ha un'istruzione correntemente in esecuzione, non può rimuovere le righe morte create da aggiornamenti/eliminazioni concorrenti. Prova tu stesso. Crea una tabella con righe fittizie. Inizia un xact e seleziona dalla tabella per bloccarlo. Avvia un altro xact ed elimina metà delle righe ma non eseguire ancora il commit. 'VACUUM VERBOSE' da un'altra sessione. Rimuoverà le righe morte. –

3

Ci sono due principali impatti sul sistema.

Le tabelle che sono stati utilizzati in tali operazioni:

  1. non sono vacuumed che significa che non sono "puliti" e le loro statistiche non vengono aggiornati che potrebbe portare alla cattiva (= lente) i piani di esecuzione
  2. non può essere modificato utilizzando ALTER TABLE
Problemi correlati