Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Como posso bloquear uma tabela InnoDB para evitar atualizações enquanto essa tabela está sendo copiada?


Desculpe a resposta longa, mas isso precisará ser respondido em várias partes.

1. Ao bloquear tabelas InnoDB com LOCK TABLES em geral

Usando LOCK TABLES com InnoDB funciona de fato, e pode ser demonstrado com duas instâncias da CLI do MySQL conectadas ao mesmo servidor (indicado por mysql-1 e mysql-2 ) no exemplo abaixo. Geralmente deve ser evitado em qualquer tipo de contexto de produção devido ao impacto para os clientes, mas às vezes pode ser a única opção.

Crie uma tabela e preencha-a com alguns dados:
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

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

Tente inserir de mysql-2 , que ficará travado aguardando o bloqueio:
mysql-2> insert into a (id) values (4);

Agora desbloqueie a tabela de mysql-1 :
mysql-1> unlock tables;
Query OK, 0 rows affected (0.00 sec)

E finalmente mysql-2 desbloqueia e retorna:
Query OK, 1 row affected (6.30 sec)

2. Usando phpMyAdmin para teste

Seu método de teste usando o phpMyAdmin é inválido porque o phpMyAdmin não mantém uma conexão persistente com o servidor entre as consultas de sua interface web. Para usar qualquer tipo de bloqueio LOCK TABLES , START TRANSACTION , etc., você precisa manter uma conexão enquanto os bloqueios são mantidos.

3. Bloqueando todas as tabelas necessárias durante o trabalho

A maneira como o MySQL bloqueia as tabelas, uma vez que você tenha usado LOCK TABLES para bloquear explicitamente qualquer coisa, você não poderá acessar nenhuma outra tabela que não tenha sido bloqueada explicitamente durante o LOCK ... UNLOCK sessão. No seu exemplo acima, você precisa usar:
LOCK TABLES my_table WRITE, new_table WRITE, table2 READ;

(Estou assumindo table2 usado na subseleção não foi um erro de digitação.)

4. Troca de tabela atômica usando RENAME TABLE

Além disso, devo observar que substituir a tabela existente usando DROP TABLE seguido por RENAME TABLE causará um breve momento em que a tabela não existirá, e isso poderá confundir os clientes que esperam que ela exista. Geralmente é muito melhor fazer:
CREATE TABLE t_new (...);
<Populate t_new using some method>
RENAME TABLE t TO t_old, t_new TO t;
DROP TABLE t_old;

Isso executará uma troca atômica das duas tabelas.