Question

Dans notre configuration serveur / client, nous avons un comportement étrange. Le client est une application C / C ++ qui utilise OCI pour se connecter à un serveur Oracle (à l'aide de la bibliothèque OTL ). .

De temps en temps, le serveur de base de données meurt d'une manière (oui, il s'agit du problème principal, mais du côté de l'application, nous ne sommes pas en mesure de le résoudre, mais nous devons quand même le résoudre), la machine ne répond plus. aux nouvelles demandes / connexions, mais les requêtes existantes, comme les connexions Oracle, ne sont ni abandonnées ni expirées. Les requêtes envoyées à la base de données ne retournent plus jamais avec succès.

Quelles sont les possibilités (le cas échéant) fournies par Oracle pour détecter ces connexions bloquées du côté de l'application client et récupérer de manière plus ou moins sûre?

Était-ce utile?

La solution

Il s’agit d’un bogue dans Oracle (ou appelez-le une fonctionnalité) jusqu’au 11.1.0.6 et ils ont dit le correctif pour Oracle 11g version 1 (correctif 11.1.0.7) qui contient le correctif. Besoin de voir ça. Si cela se produit, vous devrez annuler (tuer) le thread effectuant cette action. Pas bonne approche cependant

Autres conseils

Dans tout mon schéma de base de données, j'ai une table avec un enregistrement constant. Il suffit d’interroger cette table périodiquement par simple requête SQL. Toutes les autres méthodes peu fiables.

Il existe une API set_timeout dans OTL qui pourrait être utile à cet effet.

Modifier: En fait, ignorez cela. set_timeout ne fonctionne pas avec OCI. Consultez la description de set_timeout dans ici , où il décrit technique pouvant être utilisée avec OCI

On dirait que vous devez lancer une requête sur la base de données (par exemple, SELECT * FROM dual; ), puis si la base de données n'a pas répondu dans le délai spécifié, supposez que le serveur a décédé et réagit en conséquence. J'ai bien peur de ne pas connaître le C / C ++, mais pouvez-vous utiliser le multi-threading pour déclencher l'instruction, puis attendre la réponse sans suspendre l'application?

Cela fonctionne - j'ai fait exactement ce que vous recherchez. Avoir un processus parent (A) créer un processus enfant (B). Le processus enfant (B) se connecte à la base de données, effectue une requête (par exemple, "Sélectionnez 1 dans a_table" - vous obtiendrez de meilleures performances si vous évitez d'utiliser "dual" pour cela et créez votre propre table). Si (B) réussit, il écrit qu’il a réussi et se termine. (A) attend pendant un laps de temps déterminé. J'ai utilisé 15 secondes. Si (A) détecte que (B) est toujours en cours d'exécution - il peut alors supposer que la base de données est bloquée - il tue (B) et effectue les actions nécessaires (comme m'appeler au téléphone avec un SMS).

Si vous configurez SQL * NET pour utiliser un délai d'attente, vous remarquerez probablement que les requêtes volumineuses échouent à cause de cela. La configuration OCI set_timeout en sera également la cause.

Il existe un moyen manuel d'éviter cela. Vous pouvez ouvrir un pare-feu et faire quelque chose comme une base de données ping après chaque durée spécifiée. De cette façon, la connexion à la base de données ne sera pas perdue.

idée

If (current_time - lastPingTime > configuredPingTime)
{
     //Dummy query
     select 1 from dual;
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top