2013-02-07 3 views
3

Au travail, nous avons un DBA qui a dit que son RAC fonctionne très bien, mais la vérité est que ce n'est pas le cas. Les IDEs SQL comme Toad ou SQL Developer abandonnant leurs connexions de façon aléatoire (ma suspicion est due aux paramètres réseau incorrects du RAC). Je voudrais prouver ma théorie avec un test. Je suppose un script Perl serait à l'astuce:Perl DBI connecter et exécuter le délai

étape 1. ping la db de l'IP

étape 2. si IP est en tentative de connexion à la DB

étape 3. Si connecté sélectionnez sysdate de double et le lien étroit

étape 4. attendre un certain temps et commencer encore

J'ai réussi à écrire ce en Perl DBI mais je ne sais pas comment puis-je Délai d'attente de connexion et de l'exécution de la requête. Y a-t-il une solution pour temporiser ces choses?

Répondre

2

Il semble dépendre du backend DB auquel vous vous connectez. Par exemple, DBD::mysql ne documente une telle valeur de délai d'attente:

mysql_connect_timeout

If your DSN contains the option "mysql_connect_timeout=##", the connect request to the server will timeout if it has not been 

réussie après le nombre de secondes.

Cependant, je ne vois pas la même chose documentée pour Oracle.

J'ai trouvé une discussion de faire cela avec la gestion du signal in the DBI documentation.

5

Vous pouvez utiliser des signaux relatifs à DBI pour implémenter un délai d'attente à l'aide de alarm() et de $SIG{ALRM}.

du module DBI sur CPAN et cpan pod

Délai d'attente

La manière traditionnelle de mettre en œuvre un délai d'attente est de définir SIG {ALRM} $ à font référence à un code qui sera exécuté quand ALRM le signal arrive puis d'appeler l'alarme ($ secondes) pour programmer un signal ALRM à livré $ secondes dans le futur.

Par exemple:

my $ dbh = DBI-> connect ("DBI: sqlrelay: host = nom d'hôte $; port = port $; socket =", $ user, mot de passe de $) ou mourir DBI > errstr;

mon $ sth = $ dbh-> préparer ($ query) ou mourir $ dbh-> errstr;

eval { 
    local $SIG{ALRM} = sub { die "TIMEOUT\n" }; # \n is required 
    eval { 
     alarm($seconds); 
     if(! $sth->execute()) { # execute query 
       print "Error executing query!\n" 
     } 
    }; 
    # outer eval catches alarm that might fire JUST before this alarm(0) 
    alarm(0); # cancel alarm (if code ran fast) 
    die "[email protected]" if [email protected]; 
    }; 
    if ([email protected] eq "TIMEOUT\n") { ... } 
    elsif ([email protected]) { ... } # some other error 

La première (externe) eval est utilisé pour éviter l'improbable mais possible chance que le « code à exécuter » meurt et les feux d'alarme avant qu'il ne est annulée. Sans l'évaluation externe, si cela s'est produit, votre programme mourra si vous n'avez pas de gestionnaire ALRM ou si un gestionnaire d'alarmes non local sera appelé .