2010-05-27 6 views
1

J'ai une situation dans laquelle nous avons deux bases de données de production qui se synchronisent les unes avec les autres. Le serveur un est considéré comme le principal. Parfois, en raison d'une maintenance ou d'un sinistre, le serveur deux deviendra primaire.Pourquoi oci_connect de PHP ne retourne-t-il pas faux?

Dans certains de nos codes, cela signifie que nous devons entrer manuellement et modifier le nom du serveur pour les connexions à la base de données. Je trouve cela ennuyeux, donc la dernière chose que j'ai écrite, j'ai mis les informations du serveur pour les deux et mettre en place une boucle. Si oci_connect a échoué sur le Serveur Un 3 fois, il passera au Serveur Deux. Si le serveur deux a échoué 3 fois, il signale à l'utilisateur qu'une connexion n'a pas pu être établie.

Cela a fonctionné très bien la plupart du temps, nous avons eu la situation de la commutation des serveurs. Hier, par exemple, cela a bien fonctionné. Aujourd'hui, ce n'est pas le cas. Il s'est juste assis et filé à l'infini. Aucune erreur dans le journal des erreurs PHP. Pas d'échec à partir de. Pas de sortie d'erreur à l'écran. Rien pendant 5 minutes. Alors j'ai dû éditer manuellement le stupide fichier de configuration. J'ai demandé ce qui pourrait être différent et on m'a dit "hier, la base de données était en panne, mais pas le serveur, aujourd'hui le serveur est en panne". D'accord...? Mais je ne vois pas de distinction. Je m'attendrais à ce que oci_connect renvoie false s'il ne peut établir aucune sorte de communication avec le serveur. Je m'attendrais à ce que le temps d'attente et d'erreur. Pas seulement le transmettre quand il reçoit un code d'erreur du serveur. Que faire s'il y a un problème de réseau, par exemple?

Est-ce un bug dans oci_connect ou est-il possible que quelque chose dans notre configuration PHP donne oci_connect un délai d'attente follement long?

S'il s'agit d'une sorte de "bogue", est-il possible de vérifier si le serveur est en place en premier? Comme un ping? (Bien sûr, quand j'ai fait un ping via l'invite de commande, j'ai reçu une réponse de Server One et on m'a dit: "C'est de retour maintenant", mais je suis sceptique quant au timing.)

un peu de lumière sur pourquoi oci_connect pourrait fonctionner indéfiniment sans défaillance et comment l'empêcher de le faire, je serais reconnaissant.

- Éditer: Mon code ressemble aux exemples sur PHP.net seulement dans certaines boucles.

$count = count($servers); 
for($i = 0; $i < $count; $i++){ 
     if((!isset($connection)) || ($connection == false)){ 
      // Attempt to connect to the oracle database 
      $connection = @oci_connect($servers[$i]["user"], $servers[$i]["pass"], $servers[$i]["conid"]) or ($conn_error = oracle_error()); 
      // Try again if there was a failure 
      if(($connection == false) || (isset($con_error))){ 
       // Three (two more) tries per alternative 
       for($j = $st; $j < $fn; $j++){ 
        // Try again to connect 
        $connection = @oci_connect($servers[$i]["user"], $servers[$i]["pass"], $servers[$i]["conid"]) or ($conn_error = oracle_error()); 
       } // for($j = 2; $j < 4; $j++) 
      } // if($connection == false) 
     } // if(!isset($connection) || ($connection == false)) 
} // for($i = 0; $i < $count; $i++) 
+0

À quoi ressemble votre script de connexion? – thetaiko

+0

Je suis d'accord. Et il retourne parfois faux en cas d'échec. Le code a fonctionné plusieurs fois comme prévu jusqu'à ce que je rencontre ce problème un jour. On m'a dit: "Hier, la base de données était en panne, mais pas le serveur, aujourd'hui le serveur est en panne". était la différence entre la journée de travail et la journée de non-travail. – morewry

Répondre

3

Pouvez-vous vérifier qu'il ne retourne pas faux? Est-ce que c'est peut-être juste de bloquer en attendant une connexion? (Ce qui se passe si vous var_dump(oci_connect(...))

droit de ce php.net documentation:

Si vous souhaitez spécifier un délai d'attente de connexion en cas il y a un problème réseau , vous pouvez modifier le côté client (par exemple côté PHP) fichier sqlnet.ora et ensemble SQLNET.OUTBOUND_CONNECT_TIMEOUT. Ceci définit la limite supérieure de temps pour établir une connexion droit par le biais de la base de données, y compris le temps pour tente de se connecter à d'autres services. Il est disponible à partir de Oracle 10.2.0.3 et versions ultérieures.

Dans Oracle 11.1, une solution légèrement plus légère TCP.CONNECT_TIMEOUT a été introduite. Il s'agit également d'un paramètre sqlnet.ora.Il limite simplement la connexion TCP temps d'établissement, qui est la plupart du temps où le problème de connexion sont vus. Le fichier client sqlnet.ora doit être placé dans le même répertoire que le fichier tnsnames.ora .

De plus, vous pouvez consulter FAN on this page ... On dirait qu'il peut faire exactement ce que vous voulez (mais je n'ai aucune expérience avec elle, donc je ne suis pas sûr que ce soit vraiment bon pour vous) . Oci_connect devrait renvoyer false en cas d'erreur

+0

Merci. Je l'avais lu et je regarde dans les deux cas. – morewry

Questions connexes