2010-07-10 11 views
1

J'écris un programme pour extraire des données d'un tas de fichiers texte et le bourrer dans DB. Toutes mes commandes ont actuellement la forme similaire à ce (avec différentes requêtes):Perl/MySQL "Requête était vide" erreur, probablement liée au multithreading

$query = "INSERT INTO relations (relation_type_id, confidence) VALUES ($reltypeid, $conf)"; 
print "$query\n"; 
$result = $conn->query($query); 
$relid = $result->insertid(); 
... 

Cependant, je l'ai remarqué des erreurs aléatoires pop-up lors de l'exécution, comme ceci:

INSERT INTO relations (relatiDBD::mysql::st execute failed: Query was empty at /usr/lib64/perl5/vendor_perl/5.8.5/x86_64-linux-thread-multi/Mysql.pm line 175. 
DBD::mysql::st execute failed: Query was empty at /usr/lib64/perl5/vendor_perl/5.8.5/x86_64-linux-thread-multi/Mysql.pm line 175. 
on_type_id, confidence) VALUES (12, 0.709310711263845) 

Si je cours avec perl -w, je reçois ceci:

INSERT INTO relations (relatiUse of uninitialized value in subroutine entry at /usr/lib64/perl5/vendor_perl/5.8.5/x86_64-linux-thread-multi/DBD/mysql.pm line 211. 
Use of uninitialized value in subroutine entry at /usr/lib64/perl5/vendor_perl/5.8.5/x86_64-linux-thread-multi/Mysql.pm line 175. 
DBD::mysql::st execute failed: Query was empty at /usr/lib64/perl5/vendor_perl/5.8.5/x86_64-linux-thread-multi/Mysql.pm line 175. 
Use of uninitialized value in subroutine entry at /usr/lib64/perl5/vendor_perl/5.8.5/x86_64-linux-thread-multi/DBD/mysql.pm line 211. 
Use of uninitialized value in subroutine entry at /usr/lib64/perl5/vendor_perl/5.8.5/x86_64-linux-thread-multi/Mysql.pm line 175. 
DBD::mysql::st execute failed: Query was empty at /usr/lib64/perl5/vendor_perl/5.8.5/x86_64-linux-thread-multi/Mysql.pm line 175. 
on_type_id, confidence) VALUES (12, 0.709310711263845) 

maintenant, ce qui me préoccupe est que clairement quelques conneries multithreading se passe - le programme ne meurt pas, et l'erreur est insérée au milieu d'un imprimer - et je n'ai aucune idée de comment le déboguer. Pour mémoire, je me suis pas bifurquent ou enfiler partout sauf backticking zcat, et ce sont tous les paquets qui sont inclus:

use Switch; 
use File::Basename; 

et dans un inclus pm:

use Mysql; 
use Exporter qw(import); 

Aussi, je » J'ai googlé le message d'erreur, et je ne peux pas obtenir le hit complet (nom & emplacement). Juste le nom de l'erreur ("Query was empty") a frappé un article où l'affiche accédait à une connexion à partir de deux processus par la suite.

Encore une chose importante: le phénomène est déterministe. Les erreurs apparaissent toujours au même endroit, tant que le code est intact. Si je change la sortie (par exemple, insérer des lignes de marqueur comme print "---"; pour séparer mes blocs d'enregistrement), les erreurs se produisent plus tôt (on ne peut pas vraiment dire si c'est sur le même octet de sortie ou non).

Existe-t-il un moyen de désactiver le multithreading dans perl? Comment puis-je attraper le bugger? De quoi parle ce message d'erreur?

MISE À JOUR: Le problème résidait dans la combinaison de la mise en mémoire tampon stdout, des résultats Google trompeurs, du nom de répertoire perl et d'un cas majeur de problème de cerveau.

+0

Orthogonal: vous vous exposez à des attaques par injection SQL. S'il vous plaît envisager de passer à l'aide de paramètres de liaison. – Ether

+0

Je me demandais si je devrais ajouter une phrase à l'effet de "Toutes les variables ont été citées, aucun SQL n'a été blessé dans cet article" ou pas ... (et, pas que ce soit une excuse, la source de données est sous notre contrôle). Cependant, 'perl' n'est pas ma langue maternelle, et je ne connaissais pas' $ conn-> do' quand j'ai commencé. Ce serait probablement un peu plus facile. – Amadan

Répondre

1

Veuillez poster tout le programme Perl. Rien de ce que je vois ici ne me fait penser qu'il s'agit d'un problème de multithread. À moins que vous ne demandiez des threads quelque part, vous n'obtenez pas plusieurs threads dans Perl5. Comme une conjecture, en raison des instructions d'impression supplémentaires modifiant les résultats, il se sent comme un problème de mise en mémoire tampon. Essayez de marquer votre STDOUT avec $|=1;

+0

Merci beaucoup pour le '$ |' - c'était vraiment un problème de mise en mémoire tampon (j'ai été trompé par le résultat de Google et le 'x86_64-linux-thread-multi'). – Amadan

+0

Cette convention de dénomination s'applique aux bibliothèques Perl optimisées spécifiques à la machine. Cela ne signifie pas qu'ils sont multithread, cela signifie simplement qu'ils se réservent le droit de multithread.Les meilleures bibliothèques sont thread safe, ce qui signifie que vous ne sauriez jamais qu'ils le font. Pour plus d'informations sur la mise en mémoire tampon, consultez la section Suffering From Buffering ?: http://perl.plover.com/FAQs/Buffering.html – masonk

+0

Oui, je comprends. Je commençais à devenir paranoïaque et je pensais que la bibliothèque MySQL faisait de la merde dans mon dos :) Tellement soulagé que ce n'était pas le cas. J'ai compris le point tampon dès que j'ai regardé 'perlvar' pour voir ce que' $ | 'voulait dire, mais merci pour le lien. – Amadan

Questions connexes