Quelle est la cause des erreurs en attente de verrouillage de niveau table?

8

Nous avons déjà suspendu la base de données deux fois et essayons de trouver une cause.

show processlist
Waiting for global read lock | INSERT INTO {myisam_table} ...

Ici, l'espace disque était plein, donc nous pensions que le problème était résolu après en avoir donné un peu plus, mais le lendemain à midi, il a de nouveau pendu:

show processlist
Waiting for table level lock | UPDATE {myisam_table} ... 

Qu'est-ce qui pourrait en être la cause?

Moteur par défaut de Mysql: InnoDB.

La base de données a un mélange de tables avec les moteurs MyISAM et InnoDB.

Journal affiché ici:

http://arturito.net/2013/08/28/mysql-waiting-for-table-level-lock-errors/

Artur Kędzior
la source
Les deux événements peuvent ne pas être liés, car vous dites que vous avez eu un problème d'espace disque à un moment donné et que ce sont deux types de verrous différents qui pourraient avoir été causés par des choses indépendantes. Une possibilité qui pourrait avoir causé les deux est une sauvegarde avec mysqldump. Exécutiez-vous une sauvegarde à l'époque?
Michael - sqlbot
Toutes les sauvegardes se terminent à 7h00 et ne s'exécutent jamais pendant les heures de travail. La base de données s'est bloquée à l'heure du déjeuner.
Artur Kędzior
Si une table MyISAM est verrouillée dans une session DB, il doit y avoir une autre session DB qui l'a verrouillée. Veuillez montrer la liste complète des processus la prochaine fois que cela se produit.
RolandoMySQLDBA
@Arturito dont nous avons probablement besoin SHOW FULL PROCESSLISTplutôt que SHOW PROCESSLISTpour que nous puissions voir l'intégralité de la requête pour chaque thread ... mais en l'état, s'il y a des MyISAMtables impliquées, il semble que la SELECTrequête de longue durée de 42686 bloque la UPDATErequête de 43506 , ce qui, à son tour, bloque chaque SELECTrequête qui la suit.
Michael - sqlbot

Réponses:

8

OBSERVATIONS INITIALES

  • L'ID de processus 42686 indique qu'il se prépare à exécuter une requête SELECT
  • Il y a des connexions de sommeil
  • Tous les autres processus ne peuvent pas acquérir un verrou de table
  • Je m'attendais à ce qu'une MISE À JOUR, SUPPRIMER ou INSÉRER fasse le verrouillage. Il n'y a aucune revendication de propriété de la table en question.
  • Impossible de voir la requête complète dans ID de processus 42686, mais je soupçonne que cela implique un JOIN, GROUP BYouORDER BY

THÉORIE DE TRAVAIL

Si vous n'avez plus d'espace disque avec la liste de processus que vous m'avez donnée, nous pouvons blâmer le moteur de stockage MyISAM. Pourquoi?

Dans votre cas particulier, ce n'est pas une de vos tables. Si un JOIN, GROUP BYou ORDER BYest en cours d' exécution et une table temporaire est en cours d' écriture sur le disque (sur les tables temporaires disque utilisent le moteur MyISAM) MySQL se fige simplement quand hors de l' espace. Comment le sais-je?

Selon le guide d'étude de certification MySQL 5.0

entrez la description de l'image ici Page 408 409 La section 29.2 Bulletpoint 11 dit:

Si vous manquez d'espace disque lors de l'ajout de lignes à une table MyISAM, aucune erreur ne se produit. Le serveur suspend l'opération jusqu'à ce que de l'espace soit disponible, puis termine l'opération.

J'ai déjà discuté de cette situation

Quelque chose me dit que vous avez l'une de ces deux situations

  • tables temporaires basées sur disque pour vos SELECT et en concurrence pour l'espace avec vos données régulières
  • Si la table temporaire atterrit dans /tmpla partition racine, cela manque d'espace

SUGGESTIONS

Suggestion # 1: mappez tmpdir à un autre disque

[mysqld]
tmpdir = /another/disk/besides/root/partition

Suggestion # 2: créer un disque RAM

Exécutez ce code pour installer un disque RAM qui sera disponible au redémarrage de Linux.

RAMDISK_SIZE=32g
service mysql stop
mkdir /var/tmpfs
echo "none   /var/tmpfs  tmpfs  defaults,size=${RAMDISK_SIZE} 1 2" >> /etc/fstab
mount -t tmpfs -o size=${RAMDISK_SIZE} none /var/tmpfs
cp -R /var/lib/mysql/* /var/tmpfs
mv /var/lib/mysql /var/lib/mysql_old
ln -s /var/tmpfs /var/lib/mysql
chown -R mysql:mysql /var/tmpfs
chown -R mysql:mysql /var/lib/mysql
service mysql start

Ensuite, mappez tmpdir à/var/tmpfs

ESSAIE !!!

RolandoMySQLDBA
la source
De bons conseils sur le disque RAM - de grands gains de vitesse, vous avez besoin de beaucoup de mémoire pour cela - c'est comme faire un SSD.
Up_One