sql >> Databasteknik >  >> RDS >> Mysql

Hur kan jag låsa en InnoDB-tabell för att förhindra uppdateringar medan den tabellen kopieras?

Ursäkta det långa svaret, men detta måste besvaras i flera delar.

1. Om att låsa InnoDB-tabeller med LOCK TABLES i allmänhet

Använder LOCK TABLES med InnoDB fungerar faktiskt, och kan demonstreras med två instanser av MySQL CLI ansluten till samma server (betecknad med mysql-1 och mysql-2 ) i exemplet nedan. Det bör i allmänhet undvikas i alla slags produktionssammanhang på grund av påverkan på kunderna, men ibland kan det vara det enda alternativet.

Skapa en tabell och fyll i den med lite data:

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

Lås bordet:

mysql-1> lock tables a write;
Query OK, 0 rows affected (0.00 sec)

Försök att infoga från mysql-2 , som kommer att hänga och vänta på låset:

mysql-2> insert into a (id) values (4);

Lås nu upp tabellen från mysql-1 :

mysql-1> unlock tables;
Query OK, 0 rows affected (0.00 sec)

Och slutligen mysql-2 låser upp och returnerar:

Query OK, 1 row affected (6.30 sec)

2. Använda phpMyAdmin för testning

Din testmetod som använder phpMyAdmin är ogiltig eftersom phpMyAdmin inte upprätthåller en beständig anslutning till servern mellan frågor från dess webbgränssnitt. För att använda någon form av låsning LOCK TABLES , START TRANSACTION , etc., måste du upprätthålla en anslutning medan låsen hålls.

3. Låsning av alla bord som behövs under arbetet

Sättet som MySQL låser tabeller när du har använt LOCK TABLES för att explicit låsa någonting kommer du inte att kunna komma åt några andra tabeller som inte var explicit låsta under LOCK ... UNLOCK session. I ditt exempel ovan måste du använda:

LOCK TABLES my_table WRITE, new_table WRITE, table2 READ;

(Jag antar table2 som användes i undervalet var inte ett stavfel.)

4. Byte av atomtabell med RENAME TABLE

Dessutom bör jag notera att ersätta den befintliga tabellen med DROP TABLE följt av RENAME TABLE kommer att orsaka ett kort ögonblick där tabellen inte existerar, och detta kan förvirra klienter som förväntar sig att det finns. Det är i allmänhet mycket bättre att göra:

CREATE TABLE t_new (...);
<Populate t_new using some method>
RENAME TABLE t TO t_old, t_new TO t;
DROP TABLE t_old;

Detta kommer att utföra ett atomärt byte av de två tabellerna.




  1. MySQL-fråga med SUM() ger inte de förväntade resultaten

  2. Hur COMPRESS() fungerar i MariaDB

  3. Bästa frågan för att träffa Oracle-index med binds och null-värden

  4. I MySQL fungerar CHAR()-funktionen konstigt