Eu tenho um banco de dados MySQL de tamanho moderado com cerca de 30 tabelas, algumas das quais 10 milhões de registros, outras 100 milhões. O mysqldump
de todas as tabelas (em arquivos separados) é bastante rápido, leva talvez 20 minutos. Ele gera cerca de 15 GB de dados. Os maiores arquivos despejados estão na faixa de 2 GB.
Quando carrego os dados no MySQL em outra caixa, uma máquina de 8 GB e seis núcleos, leva uma eternidade. Facilmente 12 horas de relógio ou mais.
Estou apenas executando o cliente mysql para carregar o arquivo, ou seja,
mysql database < footable.sql
diretamente com o arquivo diretamente do mysqldump
mysqldump database foo > footable.sql
Claramente, estou fazendo algo errado. Por onde começo para que possa terminar em um tempo razoável?
Não estou usando nenhuma opção no despejo ou na carga.
Respostas:
Considere esses pontos em consideração: eles podem ajudá-lo no caso de gerar o despejo e restaurá-lo.
Extended inserts
em lixões.--tab
formato para que você possa usarmysqlimport
, o que é mais rápido quemysql < dumpfile
.innodb_flush_log_at_trx_commit = 2
no my.cnf temporariamente enquanto a importação está em execução. você pode voltar para 1 se precisar de ACIDDe uma chance..
fonte
innodb_flush_log_at_trx_commit = 2
salvou meu dia. A importação de um despejo de 600 MB (como uma única transação grande) levaria 6 horas, mas com essa configuração temporária, isso foi feito em 30 minutos!Além da resposta de Abdul , gostaria de enfatizar a importância da
--disable-keys
opção, que desativa as teclas até que todos os dados sejam carregados para uma tabela. Esta opção está ativada como parte da--opt
alternância, que é ativada por padrão, mas considerou importante ressaltar.Se você não pular chaves durante as inserções, cada linha inserida reconstruirá o índice. Um processo extremamente lento.
fonte
--opt
estáThis option is effective only for nonunique indexes of MyISAM tables. It has no effect for other tables
Ultimamente tenho lidado muito com isso. Você pode definitivamente melhorar o desempenho da importação, realizando as importações em paralelo. A maior parte da desaceleração é baseada em E / S, mas você ainda pode obter uma melhoria de 40% despejando tabelas e importando-as, digamos, 4 por vez.
Você pode fazer isso com xargs assim:
ter os arquivos compactados antes de enviá-los para o mysql não diminui nada principalmente por causa da E / S reduzida. Minhas tabelas foram compactadas em até 10: 1, economizando muito espaço em disco.
Descobri que em 4 máquinas principais, o uso de 4 processos é ideal, embora apenas marginalmente melhor do que o uso 3. Se você tiver SSDs ou um RAID rápido, provavelmente escalará melhor.
Algumas outras coisas a serem observadas. Se você possui unidades do setor de 4k, verifique se possui
key_cache_block_size=4096
emyisam_block_size=4K
.Se você estiver usando tabelas MyISAM, defina o
myisam_repair_threads = 2
ou superior. Isso permitirá que seus núcleos extras ajudem a reconstruir índices.Verifique se você não está trocando nada. Se estiver, reduza o tamanho do
innodb_buffer_pool_size
.Eu acho que consegui um pouco de aceleração com o innnodb por essas opções também:
(os três últimos que não testei extensivamente - acho que os encontrei como sugestões nos internets.) Observe que isso
innodb_flush_log_at_commit=0
pode resultar em corrupção com o travamento do mysql ou com a falta de energia.fonte
*_block_size
emyisam_repair_threads
? Além disso, não temos certeza se devemos oferecer conselhos para ajustar as variáveis com base nas 'sugestões dos internets' :) #Se você possui principalmente tabelas MyISAM, deve aumentar o buffer de inserção em massa . Aqui está o que a documentação do MySQL diz sobre a configuração bulk_insert_buffer_size :
Há duas coisas que você precisa fazer
1) Adicione-o ao /etc/my.cnf
2) Defina o valor global para ele
Se você não tiver o privilégio de definir globalmente bulk_insert_buffer_size, faça isso
Obviamente, isso não é para o InnoDB.
De outro ângulo, se as tabelas são InnoDB ou MyISAM, se os índices forem maiores que a tabela, você poderá ter muitos índices. Eu costumo prever que uma recarga de um mysqldump do MyISAM deve levar três vezes o tempo que o mysqldump demorou para ser feito. Também acredito que a recarga de um mysqldump do InnoDB deve levar 4 vezes o tempo que o mysqldump demorou para ser feito.
Se você está excedendo a proporção de 4: 1 para recarregar um mysqldump, você definitivamente tem um dos dois problemas:
Você pode medir o tamanho dos seus dados pelo mecanismo de armazenamento com este:
Veja se os índices são quase tão grandes quanto os dados ou até maiores
Você também pode desabilitar o log binário como este:
antes de recarregar o script
fonte
Se você ignorar completamente o sistema de arquivos e apenas canalizar a saída do mysqldump diretamente para um processo MySQL, deverá ver melhorias visíveis no desempenho. Em última análise, quanto depende do tipo de unidade de disco que você está usando, mas raramente uso mais arquivos de despejo, independentemente do tamanho do banco de dados, apenas por esse motivo.
fonte
De acordo com minhas experiências, o disco rígido é o gargalo. Esqueça os discos giratórios. O SSD é melhor, mas de longe o melhor é fazer isso na RAM - se você tiver o suficiente para armazenar todo o banco de dados por um curto período de tempo. Aproximadamente:
Para mim, um dump de ~ 10G (/ var / lib / mysql consome ~ 20G) pode ser importado em cerca de 35 minutos (mydumper / myloader), 45 minutos (mysqldump --tab / mysqlimport), 50 minutos (mysqldump / mysql) , em um Xeon de 3,2 GHz e 2x6 núcleos.
Se você não tiver RAM suficiente em uma única máquina, mas tiver vários computadores próximos um do outro com rede rápida, seria interessante verificar se as RAMs deles podem ser unidas ao nbd (dispositivo de bloco de rede). Ou, com innodb_file_per_table, você provavelmente pode repetir o processo acima para cada tabela.
fonte