web-dev-qa-db-fra.com

Comment Wordpress gère-t-il les erreurs de verrouillage de ligne MySQL?

Si un plugin WordPress met à jour les lignes d'une table personnalisée, mais que cette mise à jour rencontre un verrou de ligne, que se passe-t-il? Par exemple. Deux utilisateurs lancent simultanément une mise à jour sur la TABLE1, un paramètre AGE = 1 et l'autre paramètre AGE = 2:

  • Y aura-t-il un verrou de ligne?
  • MySQL gèrera-t-il cela "gracieusement" et l'une des 2 mises à jour sera-t-elle simplement "perdue"?
  • Est-ce que Wordpress le gère gracieusement?
  • Dois-je m'en occuper dans le plugin?

Les données ne sont pas très importantes, car je n’ai pas besoin de suivre chaque changement. Mais je dois gérer toutes les erreurs qui pourraient survenir.

5
Samudra

Strictement du point de vue MySQL

VERSION COURTE

MyISAM Storage Engine

  • Serrures de table
  • Les écritures sont premier arrivé, premier servi
  • Les lectures ralentissent l’initiation des écritures

InnoDB Storage Engine

  • Serrures de rangée
  • Transactions (non bloquantes)
  • Un blocage peut survenir lors de la mise à jour des index

LONG VERSION

Si les tables sous-jacentes utilisent le MyISAM Storage Engine , les verrous de ligne ne sont pas possibles. Chaque instruction DML (INSERT, UPDATE et DELETE) provoque un verrouillage complet de la table.

Si 50 connexions DB tentent de mettre à jour une ligne inw dans mydb.mytable

  • 1 verrou de table, 1 mise à jour, 49 connexions DB en attente
  • 1 verrou de table, 1 mise à jour, 48 connexions DB en attente
  • 1 verrou de table, 1 mise à jour, 47 connexions de base de données en attente
  • ...
  • 1 verrou de table, 1 mise à jour, 02 connexions DB attendent
  • 1 verrou de table, 1 mise à jour, 01 attente de connexion à la base de données

Obtenez la photo? Vous pouvez voir où un goulot d'étranglement peut se produire sur une seule table. Maintenant, imaginez un site WordPress à trafic intense. Les SELECT ont la priorité sur les instructions DML (l'exception concerne les INSERT simultanés sur les tables MyISAM, à condition que la table MyISAM ne contienne que des SELECT et des INSERT, sans espace entre eux). Des centaines, voire des dizaines, de SELECT entre deux instructions DML peuvent ralentir encore davantage le goulot d'étranglement mentionné précédemment.

Grâce à MyISAM sur un site WordPress à trafic intense, les blocages ne peuvent jamais se produire.

Si les tables sous-jacentes utilisent le InnoDB Storage Engine , les verrous de ligne (même sur la même ligne) ne peuvent jamais bloquer les lectures, mais des blocages sont toujours possibles pendant les écritures. Avec AUTOCOMMIT=0 défini dans /etc/my.cnf, chaque instruction DML (INSERT, UPDATE et DELETE) sera exécutée sous la forme d'une transaction à une seule ligne. Des verrous de rangée individuels sont émis. Ainsi, 50 connexions DB peuvent aller après 50 lignes différentes et il ne se passe rien de tragique.

Où les impasses peuvent-elles entrer?

Étant donné que la clé PRIMARY KEY des tables InnoDB est contenue dans le Clustered Index (appelé en interne gen_clust_index) , les données de la ligne sont étroitement associées aux entrées de l'index. Tous les index créés avec des colonnes ne faisant pas partie de PRIMARY KEY sont catalogués avec deux éléments de base, 1) la valeur de la colonne et 2) la clé gen_clust_index. Parfois, la mise à jour de colonnes indexées dans InnoDB peut provoquer ce que j'appelle en plaisantant la constipation d'index. Cela se produit lorsque deux verrous ou plus sont générés sur des entrées d'index stockées proches les unes des autres. Cela est possible dans un site Web à forte trafic.

Une fois, j'ai aidé un développeur à comprendre pourquoi cela peut se produire dans DBA StackExchange. Ce développeur a ensuite modifié le code. Voici ces messages:

VOTRE QUESTION

Une des mises à jour sera perdue quel que soit le moteur de stockage. Seul le dernier UPDATE d'une colonne définit la valeur finale.

CONCLUSION

Ce message ne favorise pas non plus Storage Engine. Ce sont simplement les faits sur ce qui peut et va se passer lorsque vous écrivez aux tables.

9
RolandoMySQLDBA