Comment puis-je résoudre ce problème MySQL / InnoDB interblocage dans un environnement non-bloquant?

StackOverflow https://stackoverflow.com/questions/870097

  •  22-08-2019
  •  | 
  •  

Question

Nous utilisons MySQL avec InnoDB Engine. Nous avons un environnement « evented » qui envoie plusieurs requêtes simultanées sur une table. En gros, cela fonctionne comme ceci: Nous avons une fonction find_or_insert qui fait que: - trouver() -> sur le résultat, si elle est vide -> insert -> sur find résultat ()

Nous utilisons un pilote MySQL non-bloquant, donc en gros, quand on commence ce petit algorithme plus d'une fois en même temps, il exécute toutes les trouvailles avant d'insérer le premier résultat ... etc.

Malheureusement, nous obtenons ces erreurs: « Deadlock trouvé en essayant d'obtenir verrouillage, essayez de redémarrer la transaction »

Tout le monde peut aider?

[EDIT]: De plus, je ne comprends pas vraiment pourquoi MySQL besoin de verrouiller la table juste pour insérer un nouvel élément. Dans un premier temps je si l'auto-incrément était le coupable ici, donc je l'ai enlevé ... bu je reçois toujours l'erreur. Y at-il un moyen d'empêcher MySQL pour verrouiller la table sur des inserts?

Était-ce utile?

La solution

Essayez mysql manuel de référence pour le diagnostic et la résolution. On dirait que vous faites un cache. Une raison probable pourrait être que beaucoup de clients a frappé simultanément la table en essayant de créer la « première version » (i.e. a frappé le « si insert vide »). Peut-être que vous pouvez ajouter un délai pseudo-aléatoire ou coordonner les créateurs afin que vous ne recevez pas beaucoup de concurrents créer des appels à la db?

EDIT: Avez-vous vu cette page ? On dirait que vous devez définir un my.cnf paramètre pour désactiver les verrous par table avec InnoDB. Ce que je voulais dire, surtout si, était que votre test pourrait ne pas être représentable car il peut contenir un des écrivains de pourcentage beaucoup plus élevé que dans une situation réaliste. Si vous commencez à 100 threads avec une table vide, ils bloqueraient tout instantanément sur créer (même pour la même valeur peut-être). Ceci est bien pire que dans une situation moyenne où vous avez une meilleure répartition des clés, moins misses et un pourcentage beaucoup plus élevé de lectures. Si ce comportement est normal (i.e. vous auriez ce live comportement), je suggère d'ajouter une stratégie de réduction de puissance dans les déclarations de créer.

Autres conseils

Vous avez besoin de ces demandes se produise un à la fois, alors arrêtez peut-être en utilisant ce pilote non-bloquant. Ou mettre en œuvre votre propre mécanisme de blocage. Attendre une à terminer avant de passer à la suivante.

Vous havent dit que cela est déraisonnable, ou que pour une raison quelconque besoin de ces choses à se déplacer le long si rapidement.

Je change ma réponse à réfléchir que la question est révisée. Il semble maintenant que ce n'est un problème avec les insertions concurrentes, et non une dépendance sur le comportement de recherche.

Je crois comprendre que InnoDB le verrouillage de ligne sur des inserts et vous ne pouvez pas le désactiver. Cependant, vous [modifier] ne sont pas en mesure d'utiliser INSERT DELAYED. Je viens de lire ce n'est pas disponible sur InnoDB.

http://dev.mysql.com/doc /refman/5.0/en/insert-delayed.html

Peut-être un LOCK TABLES explicite autour de toutes vos écritures seront collectivement remplacer le comportement de verrouillage par défaut. S'il n'y a pas d'autres opérations sur la table pendant l'intervalle lorsque les événements d'écriture se produisent, cela pourrait fonctionner.

http://dev.mysql.com/doc /refman/5.0/en/lock-tables.html

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top