Em um dos casos de uso do meu aplicativo, eu tenho dois concorrentes MySQL conexões:
- uma ativamente escrevendo para uma tabela chamada
T
(na verdade, continuamente atualizando uma única linha nesta tabela), e - outra execução de um DDL contra a mesma tabela (
ALTER TABLE
, adicionando novas colunas 8 e estendendo-se uma coluna a partir devarchar(80)
avarchar(2000)
). A DDL é esperado para eventualmente completa.
As colunas da UPDATE
DML são não afetados pela DDL.
A tabela contém apenas uma única linha (a um ser UPDATE
'd).
Análise
O que eu observo quando um teste de integração que abrange este caso de uso é de gerência é um tempo de teste para fora (a tabela está sendo escrito de forma activa para, de modo que o DDL nunca completa), mas apenas para o MySQL 5.7. Normalmente, espera-se o teste para completar em menos de 30 segundos sobre o nosso hardware (o que de fato acontece para MySQL 5.6 e 8.0), mas para MySQL 5.7 até 200 segundos não é suficiente. Eu experimentei com diferentes ALGORITHM
e LOCK
valores (ver 13.1.8 ALTER TABLE Syntax ), sem sorte.
Quando eu perfil minha aplicação ( MySQL 5.7 caso), observo que 99% do tempo de CPU é gasto lendo a partir de uma tomada (ou seja, à espera de MySQL para responder que a tabela foi alterada), mas a instância de banco de dados é uma espécie de um preto caixa para mim - claro que tenho performance_schema
ativado e pode executar consultas contra ela, mas não tenho idéia de qual a informação exata que eu estou procurando.
Síntese
Ao mesmo tempo, eu não conseguiu reduzir o problema a um teste de unidade mínima auto-suficiente - a única coisa que eu observo é 3x a 10x aumento no teste de tempo decorrido para MySQL 5.7 em comparação com outros MySQL versões, mas o DDL não jeito para sempre:
Todos os MySQL versões são ou versões de ações para o Windows ou Debian Linux baixado www.mysql.com com alterações mínimas my.cnf
, ou os oficiais Docker imagens.
Questões:
- É de fato tecnicamente possível para MySQL para atrasar a execução de
ALTER TABLE
DDL para sempre? Ou o que estou observando é apenas um exemplo de banco de dados muito ocupado? É possível tanto- pedido que
ALTER TABLE
é executado interruptibly, ou seja, um erro é devolvido pelo banco de dados se um certo tempo limite é excedido, ou - forçar todas as outras conexões que podem potencialmente colocar até mesmo um
SHARED
bloqueio na tabela ou algumas das suas linhas para fazer uma pausa, para que eles não intervir enquanto o DDL está sendo executado?
- pedido que
- Ao lidar com o fora de tempo de teste de integração original, como posso diagnosticar ainda mais a situação do MySQL lado?
TL; DR - comprometer suas transações Para desbloquear o ALTER TABLE.
Sim, ALTER TABLE pode bloquear por um longo tempo. Pode parecer uma eternidade. É realmente o valor de lock_wait_timeout , que é 31536000 segundos, por padrão, ou 365 dias.
No MySQL, instruções DDL como ALTER TABLE exigem um exclusivo bloqueio de metadados sobre a mesa. O objetivo é ter certeza de que você faz TABLE não ALTER de duas sessões simultâneas ao mesmo tempo.
declaração DML como SELECT, INSERT, UPDATE, DELETE também realizar "compartilhada" fechaduras de metadados. bloqueios compartilhados pode ser realizada por várias sessões simultaneamente, mas bloquear bloqueios exclusivos, porque bloqueios exclusivos exigem que ser o único a realizar qualquer tipo de bloqueio na tabela.
estados de documentação:
Esta abordagem de bloqueio tem a implicação de que uma tabela que está sendo usado por uma transação dentro de uma sessão não pode ser usado em DDL declarações de outras sessões até as extremidades da transação.
O objetivo do DML segurando um bloqueio de metadados é para que eles possam preservar sua visão repetível leitura da mesa sem se preocupar que uma outra sessão está fazendo DROP TABLE ou ALTER TABLE para comprometer a sua exibição da tabela. Este bloqueio é necessário porque o MySQL não tem metadados versioned ( eles são gradualmente a trabalhar para esse ).
Isto significa que uma transação que foi executado um simples SELECT e não comete irá bloquear um DROP TABLE ou ALTER TABLE que requer uma mudança de bloqueio.
Há alguma nuance com a introdução de DDL online.
On-line Desempenho DDL e simultaneidade descreve com mais detalhes que um ALTER TABLE começa por adquirir um bloqueio metadados compartilhados, assim que a transação não confirmada não vai bloqueá-lo. Mas a próxima fase pode atualizar o bloqueio de metadados compartilhado para um bloqueio exclusivo de metadados, se a natureza da mudança ALTER TABLE exige. Neste ponto, a aquisição de bloqueio está bloqueado porque a outra transação ainda mantém o seu próprio bloqueio de metadados.
Não em linha DDL não se aplicam a cada tipo de operação ALTER TABLE; alguns ainda exigem bloqueios exclusivos. Alterar um tipo de dados, por exemplo, como você está fazendo, requer um bloqueio exclusivo. Veja online DDL Overview para mais detalhes.