Mysql
 sql >> Datenbank >  >> RDS >> Mysql

MySQL ALTER TABLE dauert in kleinen Tabellen lange

Ich würde vermuten, dass ALTER TABLE auf eine Metadatensperre wartet und nicht wirklich damit begonnen hat, etwas zu ändern.

Was ist eine Metadatensperre?

Wenn Sie eine Abfrage wie SELECT/INSERT/UPDATE/DELETE für eine Tabelle ausführen, muss diese eine Metadatensperre erwerben. Diese Abfragen blockieren sich nicht gegenseitig. Eine beliebige Anzahl von Abfragen dieses Typs kann eine Metadatensperre haben.

Aber eine DDL-Anweisung wie CREATE/ALTER/DROP/TRUNCATE/RENAME oder ein Ereignis CREATE TRIGGER oder LOCK TABLES muss ein exclusive erhalten Metadatensperre. Wenn eine Transaktion immer noch eine Metadatensperre hält, wartet die DDL-Anweisung.

Das können Sie demonstrieren. Öffnen Sie zwei Terminalfenster und öffnen Sie in jedem Fenster den mysql-Client.

  • Fenster 1:CREATE TABLE foo ( id int primary key );
  • Fenster 1:START TRANSACTION;
  • Fenster 1:SELECT * FROM foo; -- es spielt keine Rolle, dass die Tabelle keine Daten enthält

  • Fenster 2:DROP TABLE foo; - Beachten Sie, dass es wartet

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

Sie können sehen, dass die Drop-Tabelle auf die Tabellen-Metadatensperre wartet. Einfach warten. Wie lange wird es warten? Bis die Transaktion in Fenster 1 abgeschlossen ist. Schließlich wird es nach lock_wait_timeout ablaufen Sekunden (standardmäßig ist dies auf 1 Jahr eingestellt ).

  • Fenster 1:COMMIT;

  • Fenster 2:Beachten Sie, dass das Warten aufhört und die Tabelle sofort gelöscht wird.

Also, was kannst du machen? Stellen Sie sicher, dass keine lang andauernden Transaktionen Ihre ALTER TABLE blockieren. Sogar eine Transaktion, die zuvor ein schnelles SELECT gegen Ihre Tabelle ausgeführt hat, behält ihre Metadatensperre bei, bis die Transaktion festgeschrieben wird.