Oracle
 sql >> Database >  >> RDS >> Oracle

HikariCP:quali timeout a livello di database dovrebbero essere considerati per impostare maxLifetime per Oracle 11g

Risposta breve:nessuna (per impostazione predefinita).

Per la cronaca (per includere i dettagli qui nel caso in cui il collegamento cambi), stiamo parlando della proprietà maxLifetime di HikariCP:

Questa proprietà controlla la durata massima di una connessione nel pool. Una connessione in uso non verrà mai ritirata, solo quando viene chiusa verrà rimossa. Consigliamo vivamente di impostare questo valore e dovrebbe essere almeno 30 secondi in meno rispetto a qualsiasi limite di tempo di connessione imposto dal database o dall'infrastruttura. Un valore di 0 indica nessuna durata massima (durata infinita), ovviamente soggetta all'impostazione idleTimeout. Predefinito:1800000 (30 minuti)

Nella mia esperienza, è una buona cosa che HikariCP lo faccia. Per quanto posso dire per impostazione predefinita Oracle non impone una durata massima per le connessioni (né sul lato driver JDBC (1), né sul lato server (2)). Quindi, a questo proposito, il "limite di tempo di connessione imposto dall'infrastruttura " è +infinito -- e questo è stato un problema per noi, poiché abbiamo osservato problemi con connessioni di lunga durata. Significa anche che qualsiasi valore è "almeno 30 secondi in meno ", incluso quello predefinito :)

suppongo il livello di connessione non fa nulla al riguardo perché conta sul livello del pool sopra per gestire tali cose. Non era possibile con il pool di connessioni implicite (ora deprecato) e non so se UCP (il sostituto) lo fa, ma se usi HikariCP non li usi.

Ora, dopo 30 minuti (di solito dopo molti riutilizzi per vari scopi) per una determinata connessione, HikariCP la chiude e ne crea una nuova. Ciò ha un costo molto contenuto e ha risolto i nostri problemi con le connessioni di lunga durata. Siamo contenti di tale impostazione predefinita, ma la rendiamo comunque configurabile per ogni evenienza (vedi 2 di seguito).

(1) OracleDataSource non offre alcun punto di configurazione (proprietà o proprietà di sistema) per controllarlo, e io osservato vita infinita.

(2) Per i limiti lato server, vedere il parametro del profilo IDLE_TIME . Citando questa risposta:

Oracle per impostazione predefinita non chiuderà una connessione a causa di inattività. Puoi configurare un profilo con IDLE_TIME per far sì che Oracle chiuda le connessioni inattive.

Per verificare qual è il valore di IDLE_TIME per il tuo utente, combinando le risposte di queste domande e risposte:

select p.limit
from dba_profiles p, dba_users u
where p.resource_name = 'IDLE_TIME' and p.profile = u.profile and u.username = '...'
;

Il valore predefinito è UNLIMITED .

Tieni presente che potrebbero esserci altri limiti applicati altrove (firewall... ) che potrebbero interferire. Quindi faresti meglio a renderlo configurabile , nel caso in cui tali problemi vengano rilevati durante la distribuzione del prodotto.

Su Linux, puoi verificare la durata massima delle connessioni fisiche monitorando i socket TCP collegati al tuo database. Ho eseguito lo script di seguito sul mio server (dal punto di vista del DB è il client host), richiede 1 argomento, ip:port del tuo nodo Oracle, come appare nell'output di netstat -tan (o un pattern se hai più nodi).

#!/bin/bash
target="$1"
dir=$(mktemp -d)
while sleep 10
do
    echo "------------ "$(date)
    now=$(date +%s)
    netstat -tan | grep " $target " | awk '{print $4}' | cut -f2 -d: | while read port
    do
        file="p_$port"
        [ ! -e $file ] && touch $file
        ftime=$(stat -c %Z "$file")
        echo -e "$port :\t "$(( now - ftime))
    done
done
\rm "$dir"/p_*
\rmdir "$dir"

Se lo esegui e lo interrompi con ctrl-c durante sleep volta, dovrebbe uscire dal ciclo e ripulire la directory temporanea, ma questo non è infallibile al 100%

Nei risultati nessuna delle porte deve mostrare un valore superiore a 1800 secondi (cioè 30 minuti), dare o prendere un minuto. Vedi l'output di esempio di seguito, il primo esempio mostra 2 socket sopra 1800, sono andati 10 secondi dopo.

------------ Thu Jul 6 16:09:00 CEST 2017
49806 :  1197
49701 :  1569
49772 :  1348
49782 :  1317
49897 :  835
49731 :  1448
49620 :  1830
49700 :  1569
49986 :  523
49722 :  1498
49715 :  1509
49711 :  1539
49629 :  1820
49732 :  1448
50026 :  332
49849 :  1036
49858 :  1016
------------ Thu Jul 6 16:09:10 CEST 2017
49806 :  1207
49701 :  1579
49772 :  1358
49782 :  1327
49897 :  845
49731 :  1458
49700 :  1579
49986 :  533
49722 :  1508
49715 :  1519
49711 :  1549
49732 :  1458
50026 :  342
49849 :  1046
49858 :  1026

Dovrai eseguire lo script per più di 30 minuti per vederlo, perché non conosce l'età dei socket che esistevano prima