Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

MySQL ALTER TABLE demorando muito em pequena tabela


Eu acho que o ALTER TABLE está aguardando um bloqueio de metadados e não está realmente começando a alterar nada.

O que é um bloqueio de metadados?

Quando você executa qualquer consulta como SELECT/INSERT/UPDATE/DELETE em uma tabela, ela deve adquirir um bloqueio de metadados. Essas consultas não bloqueiam umas às outras. Qualquer número de consultas desse tipo pode ter um bloqueio de metadados.

Mas uma instrução DDL como CREATE/ALTER/DROP/TRUNCATE/RENAME ou evento CREATE TRIGGER ou LOCK TABLES, deve adquirir um exclusivo bloqueio de metadados. Se alguma transação ainda mantiver um bloqueio de metadados, a instrução DDL aguardará.

Você pode demonstrar isso. Abra duas janelas de terminal e abra o cliente mysql em cada janela.
  • Janela 1:CREATE TABLE foo ( id int primary key );
  • Janela 1:START TRANSACTION;

  • Janela 1:SELECT * FROM foo; -- não importa que a tabela não tenha dados

  • Janela 2:DROP TABLE foo; -- note que espera

  • Janela 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 |
    +-----+------+-----------+------+---------+------+---------------------------------+------------------+-----------+---------------+
    

Você pode ver a tabela suspensa aguardando o bloqueio de metadados da tabela. Apenas esperando. Quanto tempo vai esperar? Até que a transação na janela 1 seja concluída. Eventualmente, ele expirará após lock_wait_timeout segundos (por padrão, isso é definido como 1 ano ).

  • Janela 1:COMMIT;

  • Janela 2:Observe que ele para de esperar e imediatamente descarta a mesa.

Então o que você pode fazer? Certifique-se de que não haja transações de longa duração bloqueando sua ALTER TABLE. Mesmo uma transação que executou um SELECT rápido em sua tabela anteriormente manterá seu bloqueio de metadados até que a transação seja confirmada.