web-dev-qa-db-fra.com

Comment puis-je configurer MySQL Innodb pour gérer des milliers d'insertions par heure?

J'ai un site Web très fréquenté où il est possible que des milliers de nouveaux enregistrements soient insérés toutes les heures.

Cette seule erreur paralyse le site:

PDOException: SQLSTATE[40001]: Serialization failure: 1213 
Deadlock found when trying to get lock; 
try restarting transaction: INSERT INTO {location_instance} 
(nid, vid, uid, genid, lid) VALUES (:db_insert_placeholder_0, 
:db_insert_placeholder_1, :db_insert_placeholder_2, 
:db_insert_placeholder_3, :db_insert_placeholder_4); 
Array ( [:db_insert_placeholder_0] => 1059 [:db_insert_placeholder_1] => 
1059 [:db_insert_placeholder_2] => 0 [:db_insert_placeholder_3] => 
cck:field_item_location:1059 [:db_insert_placeholder_4] => 1000 )

Je serais très surpris si MySQL ne pouvait pas gérer ce type de charge. Donc, mes questions sont alors, est-ce un problème de base de données et comment puis-je configurer MySQL pour pouvoir gérer autant de trafic?

J'ai une copie de mon site Web installée sur un serveur de développement avec des scripts qui simulent la charge de contenu ajoutée au site Web. J'utilise Ubuntu, pile LAMP, avec 16 Go de RAM.

Certes, je ne connais pas très bien les bases de données. En fait, je commence avec le fichier my.cnf par défaut qui l'accompagne une fois l'installation d'apt-get terminée. Les tableaux sont tous Innodb. Quels paramètres de configuration et quelle approche recommanderiez-vous pour commencer à résoudre ce problème?

Dites-moi de quelles informations supplémentaires vous pourriez avoir besoin.

Merci

10
user658182

Vous avez affaire à un blocage, pas à un problème de goulot d'étranglement des performances.

Si vous avez un millier de nouveaux enregistrements par heure, vous êtes loin de pouvoir atteindre les limites de MySQL. MySQL peut gérer au moins 50 fois votre charge.

Les interblocages sont dus au code de l'application et ne sont pas la faute du serveur de base de données. Les blocages ne peuvent pas être corrigés côté serveur MySQL, sauf dans certaines situations spécifiques.

InnoDB peut afficher des informations détaillées sur le blocage en exécutant SHOW ENGINE INNODB STATUS à l'invite MySQL, ou avec mysql -uroot -p... -e "SHOW ENGINE INNODB STATUS".

Cependant, cela ne montre que le dernier blocage qui s'est produit, il n'y a pas de journal de blocage.

Heureusement, il existe un outil pt-deadlock-logger qui prend en charge ce problème, il prend en charge l'interrogation de l'état InnoDB et enregistre toutes les informations détaillées sur le blocage avant qu'il ne soit actualisé avec un nouveau blocage. .

11
Valor

Cela peut être aussi simple qu'une partie de votre code exécutant une transaction:

insert into t1...
insert into t2...
commit;

tandis qu'une autre partie de votre code modifie les mêmes tables dans un ordre différent:

delete from t2 where...
delete from t1 where...
commit;

Si ces deux transactions s'exécutent en même temps, une condition de concurrence critique peut se produire: la première transaction ne peut pas modifier t2 car il est verrouillé par la deuxième transaction; tandis que la deuxième transaction est également bloquée car t1 est verrouillé par la première transaction. MySQL choisit une transaction pour être la "victime" où INSERT/UPDATE/DELETE échoue. L'application doit intercepter cette erreur et réessayer l'instruction - peut-être après une pause pour que l'autre transaction ait le temps de se terminer. Rien à voir avec les limites de capacité, juste un timing malheureux qui peut être exacerbé par la façon dont le code est organisé. Basculez entre les DELETEs de la transaction # 2 ou les INSERTs de la transaction # 1, puis il n'y a pas de conflit - chaque transaction attendra l'accès aux tables dont elle a besoin.

Dans MySQL 5.6, vous pouvez exécuter l'option innodb_print_all_deadlocks activée pour collecter des informations sur tous les blocages (pas seulement le plus récent) dans le journal des erreurs MySQL.

[Clause de non-responsabilité obligatoire: je suis un employé d'Oracle. Ce qui précède est mon avis personnel et non une déclaration officielle.]

8
Max Webster