Eu procurei por soluções para bloquear um banco de dados inteiro, e o único que encontrei até agora é FLUSH TABLES WITH READ LOCK .
Isso é bom para backups, mas infelizmente não posso usar isso para impedir outros acessos ao banco de dados enquanto estou corrigindo meu banco de dados com alterações de esquema. Se eu executar um ALTER TABLE
after FLUSH TABLES WITH READ LOCK
, recebo a seguinte mensagem:
Não é possível executar a consulta porque você tem um bloqueio de leitura conflitante
Existe uma maneira de impedir que outras conexões de banco de dados acessem o banco de dados temporariamente enquanto estou corrigindo o banco de dados?
Não quero recusar ativamente as outras conexões, gostaria apenas de colocá-las "em espera" até que o patch seja concluído (uma questão de segundos).
Como eu posso fazer isso?
Você deve ser capaz de bloquear todas as tabelas que pretende alterar (ou de outra forma deseja isolar, a fim de modificar os gatilhos) com uma instrução, e sua sessão manterá o bloqueio enquanto você fizer as alterações, até que você libere o bloqueio.
Exemplo, tenho 3 tabelas aqui, t1, t2 e t3. Farei alterações em t2 e t3 e usarei t1 para ilustrar se ainda estou mantendo bloqueios em t2 e t3.
Obtenha bloqueios de gravação em t2 e t3. Sempre que
lock table
você liberar implicitamente quaisquer outros bloqueios de tabela, será necessário bloqueá-los todos juntos. Sua sessão será bloqueada até que você obtenha todos os bloqueios e, em seguida, seu prompt retornará.A tabela t2 está bloqueada e posso alterá-la.
Também tenho acesso a t3 (que por acaso está vazio):
No entanto, não bloqueei t1, então não posso nem selecionar a partir dele. Quando você mantém um ou mais bloqueios de mesa, você só pode acessar as tabelas para as quais possui bloqueios.
Agora, para testar a criação de uma trigger simples em t2, que ainda está travada.
Ha! Isso é um erro de digitação: eu disse incorretamente "após inserir em t1" em vez de "t2" e o servidor me impediu de tocar em uma mesa que não bloqueei, enquanto mantenho outros bloqueios. Posso, no entanto, modificar os gatilhos em uma tabela que realmente bloqueei, se digitar isso corretamente.
Depois de tudo isso, posso confirmar que ainda tenho bloqueios em t2 e t3 selecionando-os, e também posso confirmar que tenho bloqueios em "alguma coisa" tentando tocar em uma mesa que sei que não bloqueei, ( t1 novamente):
Alterações concluídas, libere todos os bloqueios que você adquiriu originalmente.
A única ressalva que vem à mente é que, se algo bastante sério der errado (não um erro de sintaxe, mas um erro de baixo nível, como erros de E/S, corrupção de dados e permissões do sistema operacional) durante a alteração de uma tabela, a tabela pode ser desbloqueada implicitamente. .e o fato de que, como mencionei, você tem que obter todos os bloqueios da tabela em uma única instrução, porque a próxima
LOCK TABLE
irá desbloquear qualquer coisa que você já tenha bloqueado.Outros encadeamentos tentando acessar as tabelas que você bloqueou devem bloquear até que você termine ou perca sua conexão, o que liberaria implicitamente os bloqueios, pois eles estão associados à sua conexão/sessão.