Comment puis-je surveiller la progression d'une importation d'un fichier .sql volumineux?

204

J'importe 7 Go foobar.sqlpour restaurer une table dans une base de données locale.

$ 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

Comment puis-je suivre ses progrès?

Qazwsx
la source
1
Les réponses à cette question montrent qu'il s'agit d'un manque clair du client mysql
William Entriken

Réponses:

267

Si vous importez simplement à partir d'un fichier de vidage à partir de la CLI sous * nix, par exemple

mysql -uxxx -pxxx dbname < /sqlfile.sql

installez d’abord le visualiseur de pipe sur votre système d’exploitation, puis essayez quelque chose comme ceci:

pv sqlfile.sql | mysql -uxxx -pxxxx dbname

qui affichera une barre de progression pendant l'exécution du programme.

C'est très utile et vous pouvez également l'utiliser pour obtenir une estimation de la progression de mysqldump.

pv le vide sqlfile.sqlet les passe à mysql (à cause de l'opérateur de pipe). Pendant qu'il est en dumping, cela montre les progrès. La chose intéressante est que mysql utilise les données aussi rapidement qu’il peut les faire progresser, de sorte que pv puisse afficher la progression de l’importation. Je n'ai aucune preuve. Mais il semble que oui. J'imagine que certains tampons sont utilisés, mais je pense qu'à un moment donné, mysqlil ne lit plus de données alors qu'il est encore occupé à traiter.

Pipe Viewer capture d'écran

Rob
la source
1
Je suppose que mysql pourrait avoir un tampon, dans lequel certaines données pourraient être transférées, sans être complètement "traitées" (c'est-à-dire que s'il échoue, pv peut avoir légèrement sur-rapporté ce qui entre réellement). Mais en général, c'est comme ça que les tuyaux fonctionnent. C'est la même raison que vous pouvez faire sudo hd /dev/sda1 | lesset ne pas avoir toute votre partition système en mémoire.
snapfractalpop
2
@snapfractalpop pvne sera pas très précis dans de nombreux cas, car certaines parties de SQL prendront plus de temps que d’autres. Une ligne qui constitue une simple insertion sera beaucoup plus rapide qu'une ligne qui crée un index sur une table qui a déjà plusieurs lignes, par exemple. Mais une idée approximative de l’avancement de la sortie devrait être utile, sauf si le tampon de lecture utilisé mysqlest particulièrement volumineux (pour une entrée de 7 Go, il faudrait que la mémoire tampon soit très grande pour que le rendu pvne soit pas du tout utile.
David Spillett
1
@ DavidSpillett en effet. Votre commentaire reflète mon sentiment. Fondamentalement, pv est brut, mais efficace. Ce que j'aime le plus c'est sa généralité. Telle est la beauté des pipes Unix (merci McIlroy).
Snapfractalpop
1
@rob C'est génial mec, pourriez-vous également donner un exemple avec mysqldump?
Josué Alexandre Ibarra
Très belle solution! Si le mot de passe est manuel, pv n'attend cependant pas qu'il affiche sa progression
Pierre de LESPINAY 10/02/2017
27

Si vous avez déjà lancé l'importation, vous pouvez exécuter cette commande dans une autre fenêtre pour voir la taille actuelle de vos bases de données. Cela peut être utile si vous connaissez la taille totale du fichier .sql que vous importez.

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édit pour: http://forums.mysql.com/read.php?108,201578,201578


La référence MySQL 8.0 stipule ce qui suit concernant la précision:

DATA_LENGTH

Pour MyISAM, DATA_LENGTH est la longueur du fichier de données, en octets.

Pour InnoDB, DATA_LENGTH est la quantité approximative de mémoire allouée pour l'index clusterisé, en octets. Plus précisément, il s’agit de la taille de l’index clusterisé, exprimée en pages, multipliée par la taille de la page InnoDB.

 

INDEX_LENGTH

Pour MyISAM, INDEX_LENGTH est la longueur du fichier d'index, en octets.

Pour InnoDB, INDEX_LENGTH est la quantité approximative de mémoire allouée pour les index non clusterisés, en octets. Plus précisément, il s'agit de la somme des tailles d'index non groupées, exprimée en pages, multipliée par la taille de page InnoDB.

Josh Grinberg
la source
Ma table est maintenant à 12 Gio selon les commandes de cette réponse, et continue à importer. Mon fichier sqldump n’est que de 5 Gio. Je serais intéressé par une explication de cette différence
lucidbrot
17

Lorsque vous exécutez un mysqldump d'une base de données unique, toutes les tables sont vidées dans l'ordre alphabétique.

Naturellement, le rechargement de mysqldump dans une base de données se ferait également par ordre alphabétique.

Vous pouvez simplement faire une SHOW PROCESSLIST; et découvrez la connexion à la base de données exécutant mysqldump. Lorsque le vidage est rechargé, la connexion à la base de données disparaîtra.

Si vous voulez savoir quelles tables se trouvent dans le fichier de vidage, exécutez ceci contre foobar.sql

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

MISE À JOUR 2012-05-02 13:53 EDT

Désolé de ne pas avoir remarqué qu'il n'y a qu'une seule table.

Si la table est MyISAM, le seul moyen de surveiller est du point de vue du système d'exploitation. La raison? La table est verrouillée en écriture pendant le rechargement. Qu'est-ce que tu cherches? La taille des fichiers .MYDet .MYI. Bien sûr, vous devez comparer cela avec la taille de la table auparavant sur l'autre serveur de base de données que vous avez importé.

Si la table est InnoDB et que innodb_file_per_table est activé, le seul moyen de surveiller le système est du point de vue du système d'exploitation. La raison? La table est verrouillée en écriture pendant le rechargement. Qu'est-ce que tu cherches? La taille du .ibdfichier. Bien sûr, vous devez comparer cela avec la taille de la table auparavant sur l'autre serveur de base de données que vous avez importé.

Si la table est InnoDB et que innodb_file_per_table est désactivé, même le point de vue du système d'exploitation ne peut vous aider.

MISE À JOUR 2012-05-02 13:56 EDT

J'ai abordé quelque chose comme ceci l'année dernière: Comment puis-je obtenir% progress pour "type db.sql | mysql"

MISE À JOUR 2012-05-02 14:09 EDT

Depuis un mysqldump standard, le tableau est verrouillé de la manière suivante:

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;

ensuite, il n’ya aucun moyen d’avancer avec mysql tant que le verrou de la table n’est pas libéré.

Si vous pouvez obtenir LOCK TABLESet UNLOCK TABLEScommenter le fichier de vidage ...

  • si la table est MyISAM, SELECT COUNT (*) fonctionnerait
  • Si la table est InnoDB, SELECT COUNT (*) ralentirait / arrêterait la charge jusqu'à ce que le décompte soit terminé.
RolandoMySQLDBA
la source
Ça a marché. Merci. Une dernière question est, par expérience, savez - vous si le temps d'importation est à peu près linéaire par rapport aux .MYDet la .MYItaille des fichiers?
Qazwsx
1
Le rechargement de la table est linéaire. Les reconstructions d'index sont linéaires. Il y a des années, ce n'était pas comme si j'avais posé cette question à MySQL ( lists.mysql.com/mysql/202489 ) et j'en ai parlé dans DBA StackExchange ( dba.stackexchange.com/a/2697/877 )
RolandoMySQLDBA
8

Toutes les 2 secondes, vous verrez les processus en cours d'exécution.

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

Si vous le souhaitez moins fréquemment, ajoutez -n xx est le nombre de secondes. 5 secondes seraient:

watch -n 5 'echo "show processlist;" | mysql -uuser -ppassword';
Marcelo Luiz Onhate
la source
Pouvez-vous poster un exemple de sortie? En outre, cela montre-t-il simplement le processus ou indique-t-il vraiment la progression de l'importation, ce que je demandais vraiment?
Qazwsx
C'est un code tellement utile. Thankyou
NarayaN
6

Si vous voulez juste vérifier s’il est bloqué, vous pouvez interroger

show processlist; 

et voir ce qui est en cours d'exécution.

SCL
la source
5

Comme solution pour quelqu'un qui ne peut pas faire travailler le pv ou pour qui le pv raconte des mensonges. Vous pouvez surveiller la taille du fichier ibdata1 dans / var / lib / mysql, qui contient les données. Cela aura la même taille (ou à peu près) de la taille du fichier dans votre serveur source.

S'il y a beaucoup de tables, vous pouvez aussi les regarder apparaître une par une dans / var / lib / mysql / <nom de la base de données>.

J'ai utilisé ce fait récemment lorsqu'une base de données à long terme avait constitué un fichier journal d'environ 20G sur une période de trois ou quatre ans. J'ai remarqué que le transfert prenait des siècles et utilisais cette technique pour suivre les progrès.

Je pense qu'il est hautement improbable que le jour se lève lorsqu'une base de données n'implique pas un fichier quelque part ou autre. En attendant, vous pouvez surveiller le fichier pour voir comment un transfert progresse. La méthode que j’ai suggérée a été quelque chose que vous pouvez faire sous une forme ou une autre depuis l’écriture de la première base de données SQL. Je n’ai jamais eu l’intention de suggérer que c’était une technique «officielle» à laquelle un jockey manuel pourrait avoir recours. Il suppose un niveau général de maîtrise de l’informatique en général et de l’unix en particulier.

Nerak99
la source
2

Si votre base de données est par ailleurs silencieuse (c’est-à-dire qu’aucun autre utilisateur n’est actif) et que vous souhaitez uniquement consulter les activités de lecture / écriture, pourquoi ne pas simplement procéder de la manière suivante:

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

Vous verrez le nombre de lectures / écritures / insertions / attentes / mises à jour.

Si vous insérez par exemple, vous verrez quelque chose comme:

Innodb_rows_inserted                          | 28958 

Où 28958 est le nombre de lignes insérées pour votre intervalle (10 secondes dans mon cas).

utilisateur113373
la source
1

Pour quelqu'un qui recherche l'exemple de pipe viewer, mysqldumpvous feriez simplement quelque chose comme ceci:

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

Le -Wdrapeau indique simplement à pv d'attendre le premier octet avant de montrer la progression (après l'invite)

Mauricio Trajano
la source
0

Vous pouvez surveiller une importation dans le dossier \ Msql \ Data [nom de la base de données]

Hotcronchy
la source
0

Ok, un autre travail autour. Mais cela peut être la pire option et inexacte.

Ceci dit, voici ma solution pour Windows:

Ouvrez le gestionnaire de tâches en appuyant sur

CTRL + SHIFT + ESC

Copier la vitesse du disque "mysqld.exe"

e.g. 11mb/s

Mettez cela dans une calculatrice comme celle-ci: https://techinternets.com/copy_calc?do

Estimez l'ETA. Mon cas était:

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

Résultats:

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

Je suis tellement surpris que personne ne vienne de poster 'mysql -v' en option. Si cela reste bloqué, la sortie s'arrête.

dtc
la source
3
"Suivre les progrès" signifie généralement essayer d'estimer l'état d'avancement du processus ou son achèvement, ce mysql -vqui ne sera pas le cas. En outre, crachant 7 Go de données sur le terminal considérablement ralentir la restauration.
Mustaccio
Je vois, merci pour l'explication. C’est vrai, la sortie de 7 Go ne serait pas bonne pour la sortie dans le terminal. Je suppose que l’utilisation de -v était juste pour un petit cas de test local où ma base de données restait bloquée.
dtc
2
Cette suggestion m'a aidé à identifier un problème, même si cela était peu pratique pour une utilisation avec des fichiers volumineux. (Le mien était petit).
Casey Perkins