Mysql
 sql >> Database >  >> RDS >> Mysql

Come posso bloccare una tabella InnoDB per impedire gli aggiornamenti durante la copia di quella tabella?

Ci scusiamo per la lunga risposta, ma sarà necessario rispondere in più parti.

1. Sul blocco delle tabelle InnoDB con LOCK TABLES in generale

Usando LOCK TABLES con InnoDB funziona infatti e può essere dimostrato con due istanze della CLI MySQL collegate allo stesso server (indicato da mysql-1 e mysql-2 ) nell'esempio seguente. In genere dovrebbe essere evitato in qualsiasi tipo di contesto di produzione a causa dell'impatto sui clienti, ma a volte può essere l'unica opzione.

Crea una tabella e popolala con alcuni dati:

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

Blocca il tavolo:

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

Prova a inserire da mysql-2 , che si bloccherà in attesa sul lucchetto:

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

Ora sblocca la tabella da mysql-1 :

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

E infine mysql-2 sblocca e restituisce:

Query OK, 1 row affected (6.30 sec)

2. Utilizzo di phpMyAdmin per i test

Il tuo metodo di test che utilizza phpMyAdmin non è valido perché phpMyAdmin non mantiene una connessione persistente al server tra le query dalla sua interfaccia web. Per utilizzare qualsiasi tipo di blocco LOCK TABLES , START TRANSACTION , ecc., è necessario mantenere una connessione mentre i blocchi sono mantenuti.

3. Blocco di tutti i tavoli necessari durante il lavoro

Il modo in cui MySQL blocca le tabelle, una volta che hai usato LOCK TABLES per bloccare qualcosa in modo esplicito, non sarai in grado di accedere ad altre tabelle che non sono state bloccate esplicitamente durante il LOCK ... UNLOCK sessione. Nel tuo esempio sopra, devi usare:

LOCK TABLES my_table WRITE, new_table WRITE, table2 READ;

(Sto assumendo table2 utilizzato nella sottoselezione non era un errore di battitura.)

4. Scambia la tabella atomica usando RENAME TABLE

Inoltre, dovrei notare che la sostituzione della tabella esistente utilizzando DROP TABLE seguito da RENAME TABLE causerà un breve momento in cui la tabella non esiste e ciò potrebbe confondere i client che si aspettano che esista. In genere è molto meglio fare:

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

Questo eseguirà uno scambio atomico delle due tabelle.