Eu tenho uma tabela grande com uma coluna VARCHAR (20) e preciso modificá-la para se tornar uma coluna VARCHAR (50). Normalmente, a execução de uma ALTER TABLE (adicionando um TINYINT) nessa tabela em particular leva cerca de 90 a 120 minutos para ser concluída. Por isso, só posso fazer isso no sábado ou domingo à noite para evitar afetar os usuários do banco de dados. Se possível, eu gostaria de fazer essa modificação antes de então.
A coluna também é indexada, o que eu presumo que tornará o ALTER TABLE mais lento, porque ele deve reconstruir o índice depois de modificar o comprimento da coluna.
O aplicativo da web é configurado em um ambiente de replicação do MySQL (26 escravos e um mestre). Lembro-me de ler uma vez em algum lugar que um método é primeiro executar a ALTER TABLE em cada escravo (minimizando o impacto sobre os usuários), depois fazer isso no mestre, mas isso não tentará replicar o comando ALTER TABLE para os escravos?
Portanto, minha pergunta é: qual é a melhor maneira de modificar essa tabela com o mínimo de interrupção para meus usuários?
Edit: a tabela é InnoDB.
fonte
Respostas:
Se você é um pouco aventureiro, pode resolver o problema executando a ALTER TABLE nos estágios que pode ver. Suponha que a tabela que você deseja alterar seja chamada WorkingTable. Você pode executar as alterações em estágios como este:
Você pode fazer isso em todos os escravos. E o mestre ??? Como você evita que isso seja replicado para os escravos. Simples: não envie o SQL para os logs binários do mestre. Simplesmente desligue o log binário na sessão antes de executar o procedimento ALTER TABLE:
Mas espere !!! E quanto a novos dados que chegam ao processar esses comandos ??? Renomear a tabela no início da operação deve funcionar. Vamos alterar um pouco esse código para evitar a inserção de novos dados a esse respeito:
De uma chance !!!
fonte
Meu palpite na documentação seria que apenas aumentar a restrição de comprimento em um
varchar
não causaria o mesmo problema que adicionar uma coluna:Mas isso parece ser contradito nos comentários sobre essa questão do SO .
EDITAR
Pelo menos no 5.0, acho que posso confirmar que o aumento do comprimento realmente exige uma tabela temporária (ou alguma outra operação igualmente cara):
testbed:
resultado:
fonte
Eu pensei, eu mencionaria que desde o
ENGINE=INNODB
Se você tiver restrições de chave estrangeira, não poderá alterar e renomear as restrições que apontam para a tabela antiga (agora renomeada). Você precisará alterar posteriormente ou eliminar as restrições durante o período.
fonte