Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Wie kann ich eine InnoDB-Tabelle sperren, um Aktualisierungen zu verhindern, während diese Tabelle kopiert wird?

Entschuldigen Sie die lange Antwort, aber dies muss in mehreren Teilen beantwortet werden.

1. Beim Sperren von InnoDB-Tabellen mit LOCK TABLES allgemein

Verwendung von LOCK TABLES mit InnoDB funktioniert tatsächlich und kann mit zwei Instanzen der MySQL-CLI demonstriert werden, die mit demselben Server verbunden sind (gekennzeichnet durch mysql-1 und mysql-2 ) im folgenden Beispiel. Aufgrund der Auswirkungen auf die Kunden sollte dies im Allgemeinen in jedem Produktionskontext vermieden werden, aber manchmal kann es die einzige Option sein.

Erstellen Sie eine Tabelle und füllen Sie sie mit einigen Daten:

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

Tabelle sperren:

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

Versuchen Sie, von mysql-2 einzufügen , die am Schloss warten wird:

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

Entsperren Sie nun die Tabelle von mysql-1 :

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

Und schließlich mysql-2 entsperrt und gibt zurück:

Query OK, 1 row affected (6.30 sec)

2. Verwendung von phpMyAdmin zum Testen

Ihre Testmethode mit phpMyAdmin ist ungültig, da phpMyAdmin zwischen Abfragen von seiner Webschnittstelle keine dauerhafte Verbindung zum Server aufrechterhält. Um irgendeine Art von Sperren zu verwenden LOCK TABLES , START TRANSACTION usw. müssen Sie eine Verbindung aufrechterhalten, während die Sperren gehalten werden.

3. Sperren aller Tische, die während der Arbeit benötigt werden

Die Art und Weise, wie MySQL Tabellen sperrt, nachdem Sie LOCK TABLES verwendet haben irgendetwas explizit zu sperren, können Sie nicht auf andere Tabellen zugreifen, die während des LOCK nicht explizit gesperrt wurden ... UNLOCK Sitzung. In Ihrem obigen Beispiel müssen Sie Folgendes verwenden:

LOCK TABLES my_table WRITE, new_table WRITE, table2 READ;

(Ich gehe davon aus, dass table2 in der Unterauswahl verwendet wurde, war kein Tippfehler.)

4. Atomarer Tabellenaustausch mit RENAME TABLE

Außerdem sollte ich beachten, dass das Ersetzen der vorhandenen Tabelle mit DROP TABLE gefolgt von RENAME TABLE führt zu einem kurzen Moment, in dem die Tabelle nicht existiert, und dies kann Clients verwirren, die erwarten, dass sie existiert. Es ist im Allgemeinen viel besser zu tun:

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

Dadurch wird ein atomarer Austausch der beiden Tabellen durchgeführt.