Travail autour d'erreur MySQL “Blocage trouvé lorsque vous essayez d'obtenir le verrou; essayez de redémarrer transaction”

J'ai une table MySQL avec environ 5 000 000 de lignes qui sont constamment mis à jour dans de petits moyens en parallèle Perl processus de connexion via DBI. La table a environ 10 colonnes et plusieurs index.

Un assez commune de l'opération donne lieu à l'erreur suivante parfois:

DBD::mysql::st execute failed: Deadlock found when trying to get lock; try restarting transaction at Db.pm line 276.

L'instruction SQL qui déclenche l'erreur est quelque chose comme ceci:

UPDATE file_table SET a_lock = 'process-1234' WHERE param1 = 'X' AND param2 = 'Y' AND param3 = 'Z' LIMIT 47

L'erreur est déclenchée seulement parfois. J'avais estimation de 1% des appels ou moins. Cependant, il n'est jamais arrivé avec une petite table et il est devenu plus commun que la base de données a augmenté.

Noter que je suis en utilisant le a_lock champ dans file_table pour s'assurer que les quatre quasi-identiques processus, je suis en cours d'exécution n'essayez pas de travailler sur la même ligne. La limite est conçu pour briser leur travail en petits morceaux.

Je n'ai pas fait beaucoup de tuning sur MySQL ou DBD::mysql. MySQL est un standard Solaris déploiement, et la connexion de base de données est défini comme suit:

my $dsn = "DBI:mysql:database=" . $DbConfig::database . ";host=${DbConfig::hostname};port=${DbConfig::port}";
my $dbh = DBI->connect($dsn, $DbConfig::username, $DbConfig::password, { RaiseError => 1, AutoCommit => 1 }) or die $DBI::errstr;

J'ai vu en ligne que plusieurs autres personnes ont signalé des erreurs similaires et que cela peut être un véritable situation de blocage.

J'ai deux questions:

  1. Ce qu'est exactement à ma situation est à l'origine de l'erreur ci-dessus?

  2. Est-il un moyen simple de le contourner ou de diminuer sa fréquence? Par exemple, comment dois-je faire à propos de "redémarrage de la transaction à la Db.pm de la ligne 276"?

Merci d'avance.

  • Pour voir ce que la table est verrouillée et certaines des données qui en est la cause, exécuter SHOW ENGINE INNODB STATUS.
InformationsquelleAutor Anon Gordon | 2010-04-07