Eu sou desenvolvedor de PHP, então não seja rigoroso. Eu tenho uma grande mesa ~ despejo 5.5gb. Nosso PM decidiu criar uma nova coluna para executar um novo recurso. Tabela é InnoDB então o que eu tentei:
Altere a tabela na tela com o bloqueio da tabela. Tomou ~ 30 horas e nada. Então eu apenas parei. Primeiro cometi um erro porque não encerrei todas as transações, mas a 2ª vez não foi multitoque. O status era
copy to tmp table
.Como também preciso aplicar o particionamento para esta tabela, decidimos fazer dump, renomear e criar tabela com o mesmo nome e nova estrutura. Mas o dump está fazendo uma cópia estrita (pelo menos eu não encontrei outra coisa). Então eu adicionei para despejar uma nova coluna
sed
e consultá-la. Mas alguns erros estranhos começaram. Eu acredito que foi causado por charset. A tabela no utf-8 e o arquivo se tornaram us-ascii depoissed
. Então, eu tenho erros (comando desconhecido '\' ') em 30% dos dados. Portanto, este também é um caminho ruim.
Quais são as outras opções para conseguir isso e acelerar o desempenho (eu posso fazer isso com o script php, mas levará séculos). Qual será o desempenho INSERT SELECT
nesse caso.
Obrigado por qualquer avanço.
SET NAMES utf8
eCOLLATION
.But meh idk porque 30% dos dados corrompidos depoissed
. Eu acho que a carga em massa será a mais rápida, mas talvez exista algo mais do que estou perdendo. Obrigado, MarkSua ideia sed é um método decente, mas sem os erros ou o comando que você executou, não podemos ajudá-lo.
No entanto, um método bem conhecido para fazer alterações online em tabelas grandes é pt-online-schema-change . A negligência simplista do que essa ferramenta faz é copiada da documentação:
Esse método também pode demorar um pouco para ser concluído, mas durante o processo a tabela original será completamente utilizável.
fonte
'D\'agostini'
, causará errounknown command '\''
. Mas nem sempre, como em 30% dos casos. Isso é estranho e com bugs. O mesmo acontece com os dumps hexadecimais. Obrigado Derek.alter table add column, algorithm=inplace, lock=none
irá alterar uma tabela do MySQL 5.6 sem copiar a tabela e sem travar o impacto.Acabei de testar isso ontem, massa inserida 70K linhas em uma tabela de partição de 280K 7 linhas, 10K linhas em cada partição, com 5 segundos de sono entre eles para permitir outra taxa de transferência.
Iniciou as inserções em massa e, em sessão separada, iniciou a
alter
instrução on-line acima no MySQL Workbench,alter
finalizada antes das inserções, duas novas colunas foram adicionadas e nenhuma linha resultou da alteração, o que significa que o MySQL não copiou nenhuma linha.fonte
Atualmente, a melhor opção para alterar tabelas enormes é provavelmente https://github.com/github/gh-ost
O gh-ost é uma solução de migração de esquema on-line sem gatilho para o MySQL. É testável e oferece capacidade de pausa, controle / reconfiguração dinâmica, auditoria e muitas vantagens operacionais.
O gh-ost produz uma carga de trabalho leve no mestre durante toda a migração, desacoplado da carga de trabalho existente na tabela migrada.
Ele foi projetado com base em anos de experiência com soluções existentes e altera o paradigma das migrações de tabelas.
fonte
Eu acho que o Mydumper / Myloader é uma boa ferramenta para operações como esta: está melhorando a cada dia. Você pode utilizar suas CPUs e carregar dados em paralelo: http://www.percona.com/blog/2014/03/10/new-mydumper-0-6-1-release-offers-several-performance-and- recursos de usabilidade /
Consegui carregar centenas de gigabytes de tabelas MySQL em horas.
Agora, quando se trata de adicionar uma nova coluna, é complicado, pois o MySQL copia toda a tabela para a
TMP
área de memória comALTER TABLE...
Embora o MySQL 5.6 diga que pode fazer alterações de esquema on-line, eu não consegui fazê-las on-line para tabelas maciças sem bloqueio contenção ainda.fonte
Eu apenas tive o mesmo problema. Um pouco de solução alternativa:
CREATE TABLE new_table SELECT * FROM tabela antiga;
DELETE FROM new_table
ALTER TABLE new_table ADD COLUMN new_column int (11);
INSERIR EM nova_tabela selecione *, 0 de antiga_tabela
soltar tabela old_table; renomeie a tabela new_table para old_table;
fonte