MySQL alguma maneira de importar um enorme dump sql (32 GB) mais rápido?

67

Eu tenho esse imenso despejo de SQL de 32 GB que preciso importar para o MySQL. Eu não tive que importar um dump SQL tão grande antes. Eu fiz o de sempre:

mysql -uroot dbname < dbname.sql

Está demorando muito. Há uma tabela com cerca de 300 milhões de linhas, que chegou a 1,5 milhão em cerca de 3 horas. Parece que tudo levaria 600 horas (24 dias) e é impraticável. Então, minha pergunta é: existe uma maneira mais rápida de fazer isso?

Mais informações / descobertas

  1. As tabelas são todas do InnoDB e não há chaves estrangeiras definidas. Existem, no entanto, muitos índices.
  2. Como não tenho acesso ao servidor e ao banco de dados originais, não posso fazer um novo backup nem fazer uma cópia "quente" etc.
  3. Definir innodb_flush_log_at_trx_commit = 2como sugerido aqui parece não melhorar (claramente visível / exponencial).
  4. Estatísticas do servidor durante a importação (do MySQL Workbench): https://imgflip.com/gif/ed0c8 .
  5. A versão do MySQL é a comunidade 5.6.20.
  6. innodb_buffer_pool_size = 16M e innodb_log_buffer_size = 8M. Preciso aumentar isso?
SBhojani
fonte
Você pode adicionar componentes mais rápidos ao servidor, ou seja, mais memória RAM e armazenamento SSD?
@Bert, o servidor possui 8 GB de RAM, a maioria dos quais não é utilizada. Também não é possível adicionar mais armazenamento. Como isso ajudaria? São realmente as operações de gravação que são tão lentas?
Qual é o gargalo? Um núcleo da CPU está vinculado?
Chris S
@ Chris não, o uso da CPU é de 3 a 4%. Não sei ao certo qual é o gargalo. Eu estou pensando que são os índices. Como encontrar / confirmar o gargalo?
11
Se você tiver o sql, poderá editar as instruções create index e ver se ele vai mais rápido? depois de importar os dados, você precisará recriá-los.

Respostas:

84

Vadim Tkachenko, da Percona, fez esta bela representação pictórica do InnoDB

Arquitetura InnoDB

Você definitivamente precisa alterar o seguinte

innodb_buffer_pool_size = 4G
innodb_log_buffer_size = 256M
innodb_log_file_size = 1G
innodb_write_io_threads = 16
innodb_flush_log_at_trx_commit = 0

Por que essas configurações?

Reinicie o mysql assim

service mysql restart --innodb-doublewrite=0

Isso desativa o buffer de gravação dupla do InnoDB

Importe seus dados. Quando terminar, reinicie o mysql normalmente

service mysql restart

Isso reativa o buffer de gravação dupla do InnoDB

De uma chance !!!

NOTA LATERAL: Você deve atualizar para a 5.6.21 para obter os patches de segurança mais recentes .

RolandoMySQLDBA
fonte
11
Eu fiz um script linux bash para ele, reduzi
OZZIE
9

Você realmente precisa que todo o banco de dados seja restaurado? Se não, meu 2c:

Você pode extrair tabelas específicas para fazer sua restauração em "chunks". Algo assim:

zcat your-dump.gz.sql | sed -n -e '/DROP TABLE.*`TABLE_NAME`/,/UNLOCK TABLES/p' > table_name-dump.sql

Fiz isso uma vez e demorou 10 minutos para extrair a tabela de que precisava - minha restauração completa levou 13 a 14 horas, com um dump de 35 GB (gziped).

O parâmetro /pattern/,/pattern/pwith -nfaz uma fatia "entre os padrões" - incluindo-os.

De qualquer forma, para restaurar os 35 GB, usei uma máquina AWS EC2 (c3.8xlarge), instalei o Percona via yum (Centos) e apenas adicionei / alterei as seguintes linhas my.cnf:

max_allowed_packet=256M
wait_timeout=30000

Eu acho que os números são muito altos, mas funcionaram para minha configuração.

Bruno J. Araujo
fonte
5

A maneira mais rápida de importar seu banco de dados é copiar os arquivos (.frm, .MYD, .MYI) se MyISAM, diretamente para o / var / lib / mysql / "nome do banco de dados".

Caso contrário, você pode tentar: mysql > use database_name; \. /path/to/file.sql

Essa é outra maneira de importar seus dados.

Alex
fonte
1

Uma maneira de ajudar a acelerar a importação é bloquear a tabela durante a importação. use a opção --add-locks no mysqldump.

mysqldump --add-drop-table --add-locks --database db > db.sql

ou você pode ativar alguns parâmetros úteis com --opt, isso ativa várias coisas úteis para o despejo.

mysqldump --opt --database db > db.sql

Se você tiver outro dispositivo de armazenamento no servidor, use-o - copiar de um dispositivo para outro é uma maneira de acelerar as transferências.

você também pode filtrar tabelas que não são necessárias com --ignore-table

pgee70
fonte