2010-11-12 32 views
0

J'ai une requête que je cours une fois par jour qui prend certaines tables de ma base de données et les met dans une seule table afin que je puisse rapidement exporter l'information dans n'importe quel format dont j'ai besoin.Y at-il un moyen de ne pas avoir un verrou dans MySQL?

Je courais un problème mais qui me donne l'erreur suivante: « SQLSTATE [40001]: échec de sérialisation: 1213 Deadlock trouvé en essayant d'obtenir verrouillage, essayez transaction redémarrer »

D'après ce que je comprends les sons comme ma requête essaie d'obtenir un verrou sur la table quand il y a déjà un verrou en place. Cependant j'avoue que je ne sais rien sur le verrouillage de table ou comment cela fonctionne.

Vraiment j'essaie juste de lire les autres tables et de ne pas leur écrire, est-ce qu'il y a une manière que je peux créer la requête mais ne pas demander un verrou?

Ma requête est ridiculement longue, c'est pourquoi je ne l'ai pas posté. S'il y a certaines parties dont vous avez besoin faites le moi savoir et je peux les poster.

+0

Types de tableaux? InnoDB ou MyISAM? – razzed

+0

Les tables sont toutes InnoDB. –

Répondre

2

Vous pouvez essayer d'utiliser INSERT DELAYED, voici ce qu'il fait:

When a client uses INSERT DELAYED, it gets an okay from the server at once, and the row is queued to be inserted when the table is not in use by any other thread.

Si vous êtes prêt à voir les données dans un état mixte, vous pouvez modifier le niveau d'isolation des transactions

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; 
-- Problematic SELECT query goes here -- 
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; 

I appris que l'un de l'autre SO réponse by Jon Erickson

+0

Cela ne fonctionnerait pas avec les tables InnoDB car elles ne prennent pas en charge INSERT DELAYED. –

2

Si vous êtes en mode d'isolation de transaction REPEATABLE_READ (qui est la valeur par défaut), les sélections ne doivent pas créer de verrous. C'est normal. Toutefois, si vous utilisez insert ... sélectionnez bien sûr des verrous dans la table de destination. Donc, à condition que personne d'autre n'écrive dans la table de destination, ET qu'il y ait au plus une copie de votre programme s'exécutant en même temps, vous ne pouvez jamais obtenir un interblocage.

Les blocages se produisent lorsque deux processus (ou plus) essaient de faire des choses en conflit qui ne pourraient jamais se terminer. Normalement, cela implique de mettre à jour la même paire de lignes dans un ordre différent, mais cela peut dépendre de la structure de votre table.

idées à considérer:

  • Utilisez un verrou externe (InnoDB) à serialise le processus contre plusieurs copies
  • Changer le mode d'isolation des transactions à READ_COMMITTED pour cette opération - si vous comprenez ce que cela signifie et peut tolère-le.
  • moins travailler dans une transaction (commit plus fréquemment)

Vous pouvez voir ce que les transactions en cause dans une impasse ont fait, en utilisant SHOW ENGINE ETAT INNODB, immédiatement après l'impasse.

Vous devriez être capable de voir ce que les autres processus étaient et ce qu'ils faisaient. Pensez à activer le journal général ou à utiliser d'autres techniques de débogage.

Assurez-vous de faire des tests dans un système hors production!