Mysql
 sql >> Base de données >  >> RDS >> Mysql

MySQL ALTER TABLE prend beaucoup de temps dans une petite table

Je suppose que ALTER TABLE attend un verrou de métadonnées et qu'il n'a pas réellement commencé à modifier quoi que ce soit.

Qu'est-ce qu'un verrou de métadonnées ?

Lorsque vous exécutez une requête telle que SELECT/INSERT/UPDATE/DELETE sur une table, elle doit acquérir un verrou de métadonnées. Ces requêtes ne se bloquent pas. N'importe quel nombre de requêtes de ce type peut avoir un verrou de métadonnées.

Mais une instruction DDL comme CREATE/ALTER/DROP/TRUNCATE/RENAME ou un événement CREATE TRIGGER ou LOCK TABLES, doit acquérir un exclusif verrouillage des métadonnées. Si une transaction détient toujours un verrou de métadonnées, l'instruction DDL attend.

Vous pouvez le démontrer. Ouvrez deux fenêtres de terminal et ouvrez le client mysql dans chaque fenêtre.

  • Fenêtre 1 :CREATE TABLE foo ( id int primary key );
  • Fenêtre 1 :START TRANSACTION;
  • Fenêtre 1 :SELECT * FROM foo; -- peu importe que la table n'ait pas de données

  • Fenêtre 2 :DROP TABLE foo; -- notez qu'il attend

  • Fenêtre 1 :SHOW PROCESSLIST;

    +-----+------+-----------+------+---------+------+---------------------------------+------------------+-----------+---------------+
    | Id  | User | Host      | db   | Command | Time | State                           | Info             | Rows_sent | Rows_examined |
    +-----+------+-----------+------+---------+------+---------------------------------+------------------+-----------+---------------+
    | 679 | root | localhost | test | Query   |    0 | starting                        | show processlist |         0 |             0 |
    | 680 | root | localhost | test | Query   |    4 | Waiting for table metadata lock | drop table foo   |         0 |             0 |
    +-----+------+-----------+------+---------+------+---------------------------------+------------------+-----------+---------------+
    

Vous pouvez voir la table de dépôt en attente du verrouillage des métadonnées de la table. J'attends juste. Combien de temps attendra-t-il ? Jusqu'à ce que la transaction dans la fenêtre 1 soit terminée. Finalement, il expirera après lock_wait_timeout secondes (par défaut, il est défini sur 1 an ).

  • Fenêtre 1 :COMMIT;

  • Fenêtre 2 :notez qu'il cesse d'attendre et qu'il supprime immédiatement la table.

Alors, qu'est-ce que tu peux faire? Assurez-vous qu'aucune transaction de longue durée ne bloque votre ALTER TABLE. Même une transaction qui a exécuté un SELECT rapide sur votre table plus tôt conservera son verrou de métadonnées jusqu'à ce que la transaction soit validée.