sql >> Database >  >> RDS >> Mysql

Hoe kan ik een InnoDB-tabel vergrendelen om updates te voorkomen terwijl die tabel wordt gekopieerd?

Sorry voor het lange antwoord, maar dit moet in meerdere delen worden beantwoord.

1. Over het vergrendelen van InnoDB-tabellen met LOCK TABLES in het algemeen

LOCK TABLES gebruiken met InnoDB werkt inderdaad en kan worden gedemonstreerd met twee exemplaren van de MySQL CLI die zijn verbonden met dezelfde server (aangeduid met mysql-1 en mysql-2 ) in het onderstaande voorbeeld. Het moet over het algemeen worden vermeden in elke productiecontext vanwege de impact op klanten, maar soms kan het de enige optie zijn.

Maak een tabel en vul deze met enkele gegevens:

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

Vergrendel de tafel:

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

Probeer in te voegen vanuit mysql-2 , die aan het slot zal wachten:

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

Ontgrendel nu de tabel van mysql-1 :

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

En tot slot mysql-2 deblokkeert en retourneert:

Query OK, 1 row affected (6.30 sec)

2. phpMyAdmin gebruiken voor testen

Uw testmethode met phpMyAdmin is ongeldig omdat phpMyAdmin geen permanente verbinding met de server onderhoudt tussen query's vanuit de webinterface. Om elke vorm van vergrendeling te gebruiken LOCK TABLES , START TRANSACTION , enz., moet u een verbinding behouden terwijl de vergrendelingen worden vastgehouden.

3. Alle tafels vergrendelen die nodig zijn tijdens het werk

De manier waarop MySQL tabellen vergrendelt, als je eenmaal LOCK TABLES hebt gebruikt om iets expliciet te vergrendelen, hebt u geen toegang tot andere tabellen die niet expliciet zijn vergrendeld tijdens de LOCK ... UNLOCK sessie. In je bovenstaande voorbeeld moet je het volgende gebruiken:

LOCK TABLES my_table WRITE, new_table WRITE, table2 READ;

(Ik neem aan table2 gebruikt in de subselectie was geen typfout.)

4. Atomic table swap met behulp van RENAME TABLE

Bovendien moet ik er rekening mee houden dat het vervangen van de bestaande tabel met behulp van DROP TABLE gevolgd door RENAME TABLE zal een kort moment veroorzaken waar de tabel niet bestaat, en dit kan klanten in verwarring brengen die verwachten dat deze wel bestaat. Het is over het algemeen veel beter om:

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

Dit zal een atomaire verwisseling van de twee tabellen uitvoeren.




  1. CREATE TABLE als SELECT - met behulp van MEMORY ENGINE (in RAM-geheugen)

  2. Update primaire sleutel Django MySQL

  3. Hoe geef ik een lijst met ID's door aan de MySQL-opgeslagen procedure?

  4. tel meerdere kolommen in één zoekopdracht