2009-07-28 9 views
5

Ho provato con Perl fork manager e DBI. Ma ho ricevuto l'errore DBD :: mysql :: st execute failed: connessione persa al server MySQL durante la query.Perché non riesco a interrogare un database da un figlio biforcuto in Perl?

Ecco il codice di esempio: Voglio fare domanda tra basso ad alto valore (ho sputato record int 10k)

use Parallel::ForkManager; 
my $pm = new Parallel::ForkManager(50); 
my $db = krish::DB->new or die $!; # its has all connection details 
while ($low < $high ) { 
    # Some value manipulation 

    my $pid = $pm->start and next; 
    #db_execution returns execution 
    while (my $sth = db_execution ($db, $low , $high)) { 
     ... 
     #fetch row operation 
     ... 
    } 
    $pm->finish; 
} 

sub db_execution { 
    ... 
    my $dbh = $db->connect('students') or die $!; 
    my $sth = $dbh->prepare($sql) or die "$!:" . $dbh->errstr; 
    $sth->execute or die "$!:" . $sth->errstr; 
    ... 
} 

Lo stesso codice viene eseguito con l'elaborazione in parallelo fuori. Qual'è il problema? Come risolvere è questo?

+0

Siamo spiacenti. Ho erroneamente convertito in wiki della comunità – joe

risposta

9

Quando si condividono connessioni di database tra processi (che è ciò che si sta facendo con un fork) è necessario assicurarsi che un processo non lo chiuda da sotto l'altro. Poiché le connessioni sono anche variabili, quando l'interprete Perl si arresta chiamerà il metodo DESTROY di quell'oggetto che in questo caso chiuderà la connessione.

Quindi, se qualcuno dei bambini chiude la connessione db (cosa che accadrà quando finirà e si spegnerà) lo ucciderà da sotto il processo genitore. Il modo per evitare ciò è impostare InactiveDestroy su true nel processo padre prima del fork e quindi chiudere esplicitamente la connessione nel parent quando viene eseguito.

https://metacpan.org/pod/DBI#InactiveDestroy

+3

Un altro modo per farlo è semplicemente aprire la connessione al database dopo 'fork()'. In questo modo ogni bambino ha una propria connessione e non può interferire l'uno con l'altro. La condivisione di una singola connessione tra più processi non è generalmente una buona idea. –

+1

Sì, funziona anche. Soprattutto perché alcuni sistemi (come Oracle) non supportano la condivisione della connessione tra i processi. – mpeters

0

Si cerca di guai, utilizzando lo stesso handle db simultaneamente in tutti i processi figli. Dovresti creare una nuova connessione in ogni bambino.

Non importa ... Ho letto il resto del codice.

Problemi correlati