Oracle
 sql >> Base de données >  >> RDS >> Oracle

HikariCP :quels délais d'attente au niveau de la base de données doivent être pris en compte pour définir maxLifetime pour Oracle 11g

Réponse courte :aucune (par défaut).

Pour mémoire (pour inclure des détails ici au cas où le lien changerait), nous parlons de la propriété maxLifetime de HikariCP :

Cette propriété contrôle la durée de vie maximale d'une connexion dans le pool. Une connexion en cours d'utilisation ne sera jamais retirée, ce n'est qu'une fois fermée qu'elle sera supprimée. Nous vous recommandons vivement de définir cette valeur, et elle doit être inférieure d'au moins 30 secondes à toute limite de temps de connexion imposée par une base de données ou une infrastructure. Une valeur de 0 indique qu'il n'y a pas de durée de vie maximale (durée de vie infinie), sous réserve bien sûr du paramètre idleTimeout. Par défaut :1800000 (30 minutes)

D'après mon expérience, c'est une bonne chose que HikariCP fasse cela. Autant que je sache, par défaut, Oracle n'impose pas de durée de vie maximale pour les connexions (ni côté pilote JDBC (1), ni côté serveur (2)). Ainsi, à cet égard, la "limite de temps de connexion imposée par l'infrastructure " est +infinity -- et c'était un problème pour nous, car nous avons observé des problèmes avec les connexions de longue durée. Cela signifie également que toute valeur est "au moins 30 secondes de moins ", y compris la valeur par défaut :)

Je suppose la couche de connexion ne fait rien à ce sujet car elle compte sur la couche de pool au-dessus pour gérer de telles choses. Ce n'était pas possible avec le pool de connexions implicites (maintenant obsolète), et je ne sais pas si UCP (le remplaçant) le fait, mais si vous utilisez HikariCP, vous ne les utilisez pas.

Maintenant, après 30 minutes (généralement après de nombreuses réutilisations à des fins diverses) pour une connexion donnée, HikariCP la ferme et en crée une nouvelle. Cela a un coût très mineur et a résolu nos problèmes avec les connexions de longue durée. Nous sommes satisfaits de cette valeur par défaut, mais nous la rendons toujours configurable au cas où (voir 2 ci-dessous).

(1) OracleDataSource n'offre aucun point de configuration (propriété ou propriété système) pour contrôler cela, et j'ai observé durée de vie infinie.

(2) Pour les limites côté serveur, voir le paramètre de profil IDLE_TIME . Citant cette réponse :

Par défaut, Oracle ne fermera pas une connexion en raison d'une inactivité. Vous pouvez configurer un profil avec un IDLE_TIME pour qu'Oracle ferme les connexions inactives.

Pour vérifier quelle est la valeur de IDLE_TIME pour votre utilisateur, en combinant les réponses de ce Q&R :

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

La valeur par défaut est UNLIMITED .

Veuillez noter qu'il peut y avoir d'autres limites appliquées ailleurs (pare-feu... ) qui pourraient interférer. Vous feriez donc mieux de le rendre configurable , au cas où de tels problèmes seraient découverts lors du déploiement de votre produit.

Sous Linux, vous pouvez vérifier la durée de vie maximale des connexions physiques en surveillant les sockets TCP connectés à votre base de données. J'ai exécuté le script ci-dessous sur mon serveur (du point de vue de la base de données, c'est le client host), il prend 1 argument, le ip:port de votre nœud oracle, tel qu'il apparaît dans la sortie de netstat -tan (ou un motif si vous avez plusieurs nœuds).

#!/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"

Si vous l'exécutez et l'arrêtez avec ctrl-c pendant la sleep temps, il devrait quitter la boucle et nettoyer le répertoire temporaire, mais ce n'est pas infaillible à 100 %

Dans les résultats, aucun des ports ne doit afficher une valeur supérieure à 1 800 secondes (c'est-à-dire 30 minutes), donner ou prendre une minute. Voir l'exemple de sortie ci-dessous, le premier échantillon montre 2 sockets au-dessus de 1800s, ils sont partis 10s plus tard.

------------ 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

Vous devrez exécuter le script pendant plus de 30 minutes pour voir cela, car il ne connaît pas l'âge des sockets qui existaient auparavant