Przepraszamy za długą odpowiedź, ale na to trzeba będzie odpowiedzieć w wielu częściach.
1. O blokowaniu tabel InnoDB za pomocą LOCK TABLES
ogólnie
Korzystanie z LOCK TABLES
z InnoDB faktycznie działa i można to zademonstrować z dwoma instancjami MySQL CLI podłączonymi do tego samego serwera (oznaczonego przez mysql-1
i mysql-2
) w poniższym przykładzie. Zasadniczo należy tego unikać w jakimkolwiek kontekście produkcyjnym ze względu na wpływ na klientów, ale czasami może to być jedyna opcja.
Utwórz tabelę i wypełnij ją danymi:
mysql-1> create table a (id int not null primary key) engine=innodb;
Query OK, 0 rows affected (0.02 sec)
mysql-1> insert into a (id) values (1), (2), (3);
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
Zablokuj stół:
mysql-1> lock tables a write;
Query OK, 0 rows affected (0.00 sec)
Spróbuj wstawić z mysql-2
, który będzie wisiał czekając na zamek:
mysql-2> insert into a (id) values (4);
Teraz odblokuj tabelę z mysql-1
:
mysql-1> unlock tables;
Query OK, 0 rows affected (0.00 sec)
I wreszcie mysql-2
odblokowuje i zwraca:
Query OK, 1 row affected (6.30 sec)
2. Używanie phpMyAdmin do testowania
Twoja metoda testowania przy użyciu phpMyAdmin jest nieprawidłowa, ponieważ phpMyAdmin nie utrzymuje stałego połączenia z serwerem między zapytaniami z jego interfejsu internetowego. Aby użyć dowolnego rodzaju blokowania LOCK TABLES
, START TRANSACTION
itp., musisz utrzymywać połączenie, gdy blokady są utrzymywane.
3. Blokowanie wszystkich stołów potrzebnych podczas pracy
Sposób, w jaki MySQL blokuje tabele po użyciu LOCK TABLES
aby jawnie cokolwiek zablokować, nie będziesz mieć dostępu do żadnych innych tabel, które nie zostały jawnie zablokowane podczas LOCK
... UNLOCK
sesja. W powyższym przykładzie musisz użyć:
LOCK TABLES my_table WRITE, new_table WRITE, table2 READ;
(Zakładam, że table2
użyta w podselekcji nie była literówką).
4. Zamiana tabeli atomowej za pomocą RENAME TABLE
Dodatkowo należy zauważyć, że zastąpienie istniejącej tabeli za pomocą DROP TABLE
po którym następuje RENAME TABLE
spowoduje krótki moment, w którym tabela nie istnieje, co może zmylić klientów, którzy oczekują jej istnienia. Generalnie znacznie lepiej jest zrobić:
CREATE TABLE t_new (...);
<Populate t_new using some method>
RENAME TABLE t TO t_old, t_new TO t;
DROP TABLE t_old;
Spowoduje to atomową zamianę dwóch tabel.