Como posso monitorar o progresso de uma importação de um arquivo .sql grande?

204

Estou importando 7 GB foobar.sqlpara restaurar uma tabela em um banco de dados local.

$ mysql -h localhost -u root 'my_data' < foobar.sql

$ mysql --version
/usr/local/mysql/bin/mysql  Ver 14.12 Distrib 5.0.96, for apple-darwin9.8.0 (i386) using readline 5.1

Como posso monitorar seu progresso?

qazwsx
fonte
1
As respostas a esta pergunta mostrar esta é uma deficiência clara do cliente mysql
William Entriken

Respostas:

267

Se você está apenas importando de um arquivo de despejo da CLI no * nix, por exemplo,

mysql -uxxx -pxxx dbname < /sqlfile.sql

instale primeiro o visualizador de tubos no seu sistema operacional e tente algo como isto:

pv sqlfile.sql | mysql -uxxx -pxxxx dbname

que mostrará uma barra de progresso à medida que o programa é executado.

É muito útil e você também pode usá-lo para obter uma estimativa do progresso do mysqldump.

O pv despeja sqlfile.sqle os passa para o mysql (por causa do operador de pipe). Enquanto está despejando, mostra o progresso. O legal é que o mysql leva os dados apenas o mais rápido possível, para que o pv possa mostrar o progresso da importação. Eu não tenho nenhuma prova. Mas parece que sim. Acho que há algum buffer usado, mas em algum momento acho mysqlque não lê mais dados quando ainda está ocupado processando.

Captura de tela do Pipe Viewer

Roubar
fonte
1
Eu acho que o mysql pode ter um buffer, no qual alguns dados podem ser canalizados, sem serem totalmente "processados" (ou seja, se ocorrer um erro, o pv pode ter relatado um pouco o que realmente entra). Mas, em geral, é assim que os tubos funcionam. É o mesmo motivo que você pode fazer sudo hd /dev/sda1 | lesse não ter toda a partição do sistema na memória.
precisa saber é o seguinte
2
O @snapfractalpop pvnão será muito preciso em muitos casos, porque alguns trechos do SQL levarão mais tempo para serem processados ​​do que outros. Uma linha que constitui uma inserção simples será executada muito mais rapidamente do que aquela criada no índice em uma tabela que já possui muitas linhas, por exemplo. Mas, como uma idéia aproximada do progresso, a saída deve ser útil, a menos que o buffer de leitura usado mysqlseja particularmente grande (para uma entrada de 7 Gb, o buffer precisaria ser muito grande para tornar pva saída da impressora inútil .
David Spillett
1
@DavidSpillett de fato. Seu comentário reflete meu sentimento. Basicamente, o PV é bruto, mas eficaz. O que eu mais gosto é o quão geral é. Essa é a beleza dos tubos unix (obrigado McIlroy).
snapfractalpop
1
@rob Isso é incrível, você também pode dar um exemplo mysqldump?
Josue Alexander Ibarra
Solução muito boa! Se a senha é manual, pv não esperar por ele para exibir a sua progressão embora
Pierre de LESPINAY
27

Se você já iniciou a importação, poderá executar este comando em outra janela para ver o tamanho atual de seus bancos de dados. Isso pode ser útil se você souber o tamanho total do arquivo .sql que está importando.

SELECT table_schema "Data Base Name", sum( data_length + index_length ) / 1024 / 1024 "Data Base Size in MiB" 
FROM information_schema.TABLES GROUP BY table_schema;  

Crédito para: http://forums.mysql.com/read.php?108,201578,201578


A Referência do MySQL 8.0 afirma o seguinte sobre a precisão:

DATA_LENGTH

Para MyISAM, DATA_LENGTH é o comprimento do arquivo de dados, em bytes.

Para o InnoDB, DATA_LENGTH é a quantidade aproximada de memória alocada para o índice em cluster, em bytes. Especificamente, é o tamanho do índice clusterizado, em páginas, multiplicado pelo tamanho da página do InnoDB.

 

INDEX_LENGTH

Para MyISAM, INDEX_LENGTH é o comprimento do arquivo de índice, em bytes.

Para o InnoDB, INDEX_LENGTH é a quantidade aproximada de memória alocada para índices não agrupados em bytes. Especificamente, é a soma dos tamanhos de índice não agrupados, em páginas, multiplicados pelo tamanho da página do InnoDB.

Josh Grinberg
fonte
Minha tabela está agora em 12 GiB, de acordo com os comandos desta resposta, e ainda está sendo importada. Meu arquivo sqldump tem apenas 5 GiB. Eu estaria interessado em uma explicação para essa discrepância
lucidbrot
17

Quando você executa um mysqldump de um único banco de dados, todas as tabelas são despejadas em ordem alfabética.

Naturalmente, a recarga do mysqldump em um banco de dados também estaria em ordem alfabética.

Você poderia apenas fazer uma SHOW PROCESSLIST; e descubra a conexão com o banco de dados executando o mysqldump. Quando o despejo é recarregado, a conexão com o banco de dados desaparece.

Se você quiser saber quais tabelas estão no arquivo de despejo, execute isso em foobar.sql

cat foobar.sql | grep "^CREATE TABLE" | awk '{print $3}'

ATUALIZAÇÃO 02-05-2012 13:53 EDT

Desculpe por não perceber que existe apenas uma tabela.

Se a tabela for MyISAM, a única maneira de monitorar é do ponto de vista do SO. O motivo? A tabela está bloqueada para gravação durante o recarregamento. O que procura? O tamanho dos arquivos .MYDe .MYI. Obviamente, você precisa comparar isso com o tamanho da tabela anterior no outro servidor de banco de dados do qual você importou.

Se a tabela for InnoDB e você tiver innodb_file_per_table ativado, a única maneira de monitorar é do ponto de vista do SO. O motivo? A tabela está bloqueada para gravação durante o recarregamento. O que procura? O tamanho do .ibdarquivo. Obviamente, você precisa comparar isso com o tamanho da tabela anterior no outro servidor de banco de dados do qual você importou.

Se a tabela for InnoDB e você tiver innodb_file_per_table desativado, nem mesmo o ponto de vista do sistema operacional pode ajudar.

ATUALIZAÇÃO 02-05-2012 13:56 EDT

Abordei algo como isso no ano passado: Como obtenho% progresso para "tipo db.sql | mysql"

ATUALIZAÇÃO 02-05-2012 14:09 EDT

Como um mysqldump padrão grava a tabela como esta:

LOCK TABLES `a` WRITE;
/*!40000 ALTER TABLE `a` DISABLE KEYS */;
INSERT INTO `a` VALUES (123),(451),(199),(0),(23);
/*!40000 ALTER TABLE `a` ENABLE KEYS */;
UNLOCK TABLES;

então, não há como obter progresso com o mysql até que o bloqueio da tabela seja liberado.

Se você pode obter LOCK TABLESe UNLOCK TABLEScomentar fora do arquivo de despejo ...

  • se a tabela for MyISAM, SELECT COUNT (*) funcionaria
  • se a tabela for InnoDB, SELECT COUNT (*) provavelmente diminuiria / interromperia o carregamento até a contagem ser concluída
RolandoMySQLDBA
fonte
Isso funcionou. Obrigado. Uma última pergunta é, por experiência, você sabe se o tempo de importação é aproximadamente linear em relação aos tamanhos de arquivo .MYDe .MYI?
Qazwsx
1
O recarregamento da tabela é linear. As recriações de índice são lineares. Anos atrás, não era como eu arrisquei isso como uma pergunta ao MySQL ( lists.mysql.com/mysql/202489 ) e mencionei isso no DBA StackExchange ( dba.stackexchange.com/a/2697/877 )
RolandoMySQLDBA
8

A cada 2 segundos, você verá os processos em execução.

watch 'echo "show processlist;" | mysql -uuser -ppassword';

Se você quiser menos frequência, adicione -n xonde x é o número de segundos. 5 segundos seria:

watch -n 5 'echo "show processlist;" | mysql -uuser -ppassword';
Marcelo Luiz Onhate
fonte
Você pode postar um exemplo de saída? Além disso, ele apenas mostra o processo ou realmente indica o andamento da importação, que eu estava realmente pedindo?
Qazwsx
Este é um código tão útil. Obrigado
Narayan
6

Se você quiser apenas verificar se está parado, pode consultar

show processlist; 

e veja o que está sendo executado.

SCL
fonte
5

Como uma solução para alguém que não consegue que o pv trabalhe ou para quem o pv conta mentiras. Você pode monitorar o tamanho do arquivo ibdata1 em / var / lib / mysql, que contém os dados. Isso acabará com o mesmo tamanho (ou mais ou menos) do tamanho do arquivo no servidor de origem.

Se houver muitas tabelas, você também poderá vê-las aparecer uma a uma em / var / lib / mysql / <nome do banco de dados>.

Por acaso, usei esse fato recentemente, quando um banco de dados de longo prazo construiu um arquivo de log de cerca de 20G por um período de três ou quatro anos. Notei que a transferência estava demorando muito tempo e usei essa técnica para monitorar o progresso.

Eu acho que é altamente improvável que o dia amanhecerá quando um banco de dados não envolver um arquivo em algum lugar. Enquanto isso, você pode monitorar o arquivo para ver como a transferência está progredindo. O método que sugeri foi algo que você poderia fazer de uma forma ou de outra desde que o primeiro banco de dados sql foi gravado. Eu nunca pretendi sugerir que era qualquer tipo de técnica "oficial" que um jóquei manual pudesse recorrer. Ele assume um nível geral de proficiência em computadores em geral e unix em particular.

nerak99
fonte
2

Se seu banco de dados estiver quieto (por exemplo, não há outros usuários ativos) e você quiser apenas ver a atividade de leitura / gravação, por que não fazer algo como:

mysqladmin -h<host>-uroot -p<yourpass> extended -r -i 10 |grep 'row'

Você verá o número de leituras / gravações / inserções / esperas / atualizações.

Se você estiver inserindo, por exemplo, verá algo como:

Innodb_rows_inserted                          | 28958 

Onde 28958 é o número de linhas inseridas para o seu intervalo (10 segundos no meu caso).

user113373
fonte
1

Para alguém que está procurando o exemplo do visualizador de tubos usando, mysqldumpvocê faria algo assim:

mysqldump -hxxx -uxxx -p dbname | pv -W > dump.sql

A -Wflag apenas diz ao pv para aguardar o primeiro byte chegar antes de mostrar o progresso (após o prompt)

Mauricio Trajano
fonte
0

Você pode monitorar uma importação na pasta \ Msql \ Data [nome do banco de dados]

Hotcronchy
fonte
0

Ok, outra solução. Mas essa pode ser a pior e imprecisa opção.

Dito isto, aqui está minha solução para Windows:

Abra o Gerenciador de tarefas pressionando

CTRL + SHIFT + ESC

Copie a velocidade do valor do disco "mysqld.exe"

e.g. 11mb/s

Coloque isso em uma calculadora como esta: https://techinternets.com/copy_calc?do

Estime o ETA. Meu caso foi:

Speed: 8 MB/s
Size: 4.9 GB
0 Hours, 11 Minutes and 29 Seconds

Resultados:

Beg -> 11:19
ETA -> 11:31
End -> 11:39
Daniel
fonte
-1

Estou tão surpreso que ninguém acabou de postar 'mysql -v' como uma opção. Se ficar preso, a saída será interrompida.

dtc
fonte
3
"Monitorar o progresso" geralmente significa tentar estimar até que ponto o processo progrediu ou quando seria concluído, o que mysql -vnão oferecerá. Além disso, o envio de 7 GB de dados para o terminal diminuirá significativamente a restauração.
mustaccio
entendo, obrigado pela explicação. isso é verdade, a saída de 7 GB não seria boa para saída no terminal. Eu acho que eu usando -v foi apenas para um pequeno caso de teste local onde meu db ficaria preso.
dtc
2
Essa sugestão me ajudou a identificar um problema, por mais impraticável que seja para usar com arquivos grandes. (A minha era pequena).
Casey Perkins