Hádal bych, že ALTER TABLE čeká na zámek metadat a ve skutečnosti nezačala nic měnit.
Co je to zámek metadat?
Když spustíte jakýkoli dotaz jako SELECT/INSERT/UPDATE/DELETE proti tabulce, musí získat zámek metadat. Tyto dotazy se navzájem neblokují. Libovolný počet dotazů tohoto typu může mít zámek metadat.
Ale příkaz DDL jako CREATE/ALTER/DROP/TRUNCATE/RENAME nebo událost CREATE TRIGGER nebo LOCK TABLES musí získat exkluzivní zámek metadat. Pokud nějaká transakce stále obsahuje zámek metadat, příkaz DDL počká.
Můžete to demonstrovat. Otevřete dvě okna terminálu a v každém z nich otevřete klienta mysql.
- Okno 1:
CREATE TABLE foo ( id int primary key );
- Okno 1:
START TRANSACTION;
-
Okno 1:
SELECT * FROM foo;
-- nezáleží na tom, že tabulka neobsahuje žádná data -
Okno 2:
DROP TABLE foo;
-- všimněte si, že čeká -
Okno 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 | +-----+------+-----------+------+---------+------+---------------------------------+------------------+-----------+---------------+
Můžete vidět, že tabulka přetažení čeká na zámek metadat tabulky. Jen čekám. jak dlouho to bude čekat? Dokud nebude transakce v okně 1 dokončena. Časový limit vyprší po lock_wait_timeout
sekund (ve výchozím nastavení je tato hodnota nastavena na 1 rok ).
-
Okno 1:
COMMIT;
-
Okno 2:Všimněte si, že přestane čekat a okamžitě zahodí stůl.
Co tedy můžete dělat? Ujistěte se, že vaši ALTER TABLE neblokují žádné dlouhotrvající transakce. Dokonce i transakce, která dříve proběhla rychlým SELECT proti vaší tabulce, si podrží svůj zámek metadat, dokud se transakce nepotvrdí.