Per prima cosa capiamo le proprietà di mysql.
interactive_timeout
:timeout interattivo per sessioni di shell di MySQL in secondi come mysqldump o strumenti da riga di comando mysql. le connessioni sono in stato di sospensione. Il più delle volte questo è impostato su un valore più alto perché non vuoi che venga disconnesso mentre stai facendo qualcosa su mysql cli.wait_timeout
:la quantità di secondi durante l'inattività che MySQL attenderà prima di chiudere una connessione su una connessione non interattiva in secondi. esempio:connesso da java. le connessioni sono in stato di sospensione.
Ora capiamo le proprietà di c3po e la sua relazione con gli oggetti di scena DB. (Copierò solo dalla tua domanda)
Si riferisce alla durata di un oggetto di connessione utilizzabile e disponibile nel pool. Una volta scaduto il timeout, c3po lo distruggerà o lo riciclerà.
Ora il problema arriva quando hai maxIdleTime
superiore a wait_timeout
.diciamo se il mxIdleTime : 50
secondi e wait_timeout : 40 s
poi c'è una possibilità che otterrai Connection time out exception: Broken Pipe
se si tenta di eseguire qualsiasi operazione negli ultimi 10 secondi. Quindi maxIdelTime
dovrebbe essere sempre inferiore a wait_timeout
.
Invece di maxIdleTime puoi utilizzare le seguenti proprietà.
idleConnectionTestPeriod
imposta un limite per quanto tempo una connessione rimarrà inattiva prima di testarla. SenzapreferredTestQuery
, il valore predefinito èDatabaseMetaData.getTables()
- che è indipendente dal database e, sebbene sia una chiamata relativamente costosa, probabilmente va bene per database relativamente piccoli. Se sei paranoico riguardo alle prestazioni, usa l'aquery specifica per il tuo database(i.e. preferredTestQuery="SELECT 1")
maxIdleTimeExcessConnections
riporterà il connectionCount a minPoolSize dopo un picco di attività.
Tieni presente che qualsiasi proprietà del pool (ad es. maxIdleTime
) interessa solo le connessione che sono in pool ad esempio, se hibernate ha acquisito una connessione e la mantiene inattiva per più di maxIdleTime e quindi tenta di eseguire qualsiasi operazione, otterrai "Broken Pipe"
È bene avere un wait_timeout
inferiore su mysql ma non è sempre giusto quando hai un'applicazione già creata. Devi assicurarti prima di ridurla che nella tua applicazione non stai mantenendo la connessione aperta per più di wait_time
fuori.
Devi anche considerare che l'acquisizione di una connessione è un'attività costosa e se il tempo di attesa è troppo basso, supera l'intero scopo di avere un pool di connessioni, poiché cercherà spesso di acquisire connessioni.
Ciò è particolarmente importante quando non si esegue la gestione della connessione manualmente, ad esempio quando si utilizza l'API transnazionale Spring. La primavera avvia la transazione quando inserisci un @Transaction
metodo annotato in modo che acquisisca una connessione dal pool. Se stai effettuando una chiamata al servizio Web o leggendo un file che richiederà più tempo di wait_time out, otterrai un'eccezione.
Ho affrontato questo problema una volta.
In uno dei miei progetti avevo un cron che eseguiva l'elaborazione degli ordini per i clienti. Per renderlo più veloce ho usato l'elaborazione batch. Ora una volta recupero un batch di clienti ed eseguo alcune elaborazioni (nessuna chiamata db). Quando provo a salvare tutti gli ordini che ho usato per ottenere l'eccezione del tubo rotto. Il problema era che il mio wait_timeout era di 1 minuto e l'elaborazione dell'ordine richiedeva più tempo. Quindi abbiamo dovuto aumentarlo a 2 minuti. Avrei potuto ridurre le dimensioni del batch, ma ciò stava rallentando l'elaborazione complessiva.