sql >> Databáze >  >> RDS >> Mysql

Jak mohu uzamknout tabulku InnoDB, abych zabránil aktualizacím během kopírování tabulky?

Omlouvám se za dlouhou odpověď, ale bude potřeba odpovědět v několika částech.

1. Na zamykání tabulek InnoDB pomocí LOCK TABLES obecně

Pomocí LOCK TABLES s InnoDB ve skutečnosti funguje a lze to demonstrovat na dvou instancích MySQL CLI připojených ke stejnému serveru (označeno mysql-1 a mysql-2 ) v níže uvedeném příkladu. Obecně je třeba se mu vyhnout v jakémkoli produkčním kontextu kvůli dopadu na klienty, ale někdy to může být jediná možnost.

Vytvořte tabulku a naplňte ji daty:

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

Zamkněte stůl:

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

Zkuste vložit z mysql-2 , který bude viset čekat na zámku:

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

Nyní odemkněte tabulku z mysql-1 :

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

A nakonec mysql-2 odblokuje a vrátí:

Query OK, 1 row affected (6.30 sec)

2. Použití phpMyAdmin pro testování

Vaše testovací metoda pomocí phpMyAdmin je neplatná, protože phpMyAdmin neudržuje trvalé spojení se serverem mezi dotazy ze svého webového rozhraní. Chcete-li použít jakýkoli druh zamykání, LOCK TABLES , START TRANSACTION , atd., musíte udržovat spojení, dokud jsou zámky drženy.

3. Uzamčení všech stolů potřebných při práci

Způsob, jakým MySQL zamyká tabulky, jakmile použijete LOCK TABLES chcete-li cokoli explicitně uzamknout, nebudete mít přístup k žádným dalším tabulkám, které nebyly explicitně uzamčeny během LOCK ... UNLOCK zasedání. Ve výše uvedeném příkladu musíte použít:

LOCK TABLES my_table WRITE, new_table WRITE, table2 READ;

(Předpokládám table2 použitý v dílčím výběru nebyl překlep.)

4. Atomic table swap pomocí RENAME TABLE

Dále bych měl poznamenat, že nahrazení stávající tabulky pomocí DROP TABLE následuje RENAME TABLE způsobí krátký okamžik, kdy tabulka neexistuje, a to může zmást klienty, kteří její existenci očekávají. Obecně je mnohem lepší udělat:

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

Tím dojde k atomickému prohození dvou tabulek.




  1. Testy přijetí kódů v rámci databázových transakcí na MySQL

  2. Oracle Connection String pro prostředí RAC?

  3. MySQL převodní tabulka z Latin1 na utf8

  4. Jak používat více databází v Laravelu