Les utilisateurs se plaignent que le système fonctionne lentement lorsque mysqldump est en cours

9

La base de données MYSQL (ibdata1) a une taille de 73 Go et est configurée pour s'exécuter en tant que serveur de base de données dédié sur Windows 2008 O / S pour les tables INNODB. Nous exécutons la sauvegarde en utilisant mysqldump mysqldump --skip-opt --quick --single-transaction --create-options --extended-insert --disable-keys --add-drop-table --complete-insert - set-charset - compress --log-error = Proddb0635.err -u root -pjohndoe Proddb> \ devNas \ devNas \ sqlbackup \ LIVE \ db \ Proddb0635.sql

Le fichier de sauvegarde Proddb0635.sql est stocké sur un serveur distinct du serveur de base de données. La RAM est de 12 Go. La taille du pool de mémoire tampon INNODB est de 6 Go. Mem.pool supplémentaire est de 32 Mo. La taille du cache de requête est de 2 Go. La longueur du tampon net est de 16 M max. taille du paquet 1 Go.

la version de mysql est 5.0.67.

Lorsque la sauvegarde n'est pas en cours d'exécution, les utilisateurs sont satisfaits des performances.

Lorsque la sauvegarde est en cours d'exécution, le taux de succès du pool de mémoire tampon INNODB est proche de 100%. Il n'y a aucune lecture ou écriture en attente. innodb wait free is 0. L'utilisation du processeur n'est pas élevée min 9% à max 15% Le taux de succès du cache de requête est faible d'environ 40% avec ou sans mysqlbackup en cours d'exécution. Actuellement, le Gestionnaire des tâches de Windows affiche que 10 Go de RAM sont utilisés. Dois-je augmenter le cache de requête avec seulement 2 Go de RAM disponibles? mysqlld-nt prend 9,2 Go de RAM et mysqldump prend 5 Mo de RAM. Alos, a noté que la taille du fichier de vidage est la même en présence ou en l'absence de l'option --compress.

Dois-je diminuer la taille du pool de tampons iNNODB?

Merci

dbachacha
la source

Réponses:

8

Il existe un problème connu sous Windows: lorsque vous envoyez un fichier volumineux vers un autre serveur, toute la mémoire finit par être allouée au cache système au lieu des processus utilisateur. Vous pouvez consulter la section Mémoire physique (Mo) du gestionnaire de tâches pour voir la quantité de mémoire allouée au cache système.

Cela peut être résolu en sauvegardant sur un disque local, puis en demandant à la machine distante d'extraire ce fichier.

mrdenny
la source
Merci, mrdenny. Nous avons nos disques stockés sur SAN. Est-ce que cela fait aussi une différence?
dbachacha
1
C'est un problème, peu importe la façon dont le stockage est présenté. Étant donné que le stockage est un stockage SAN, il n'est pas nécessaire de copier les fichiers sur le réseau vers une autre machine. Présentez un nouveau LUN au serveur MySQL puis sauvegardez sur cette machine. Si vous devez transférer les fichiers sur une autre machine pour la sauvegarde sur bande, utilisez le SAN. Capturez le LUN, présentez l'instantané au serveur de sauvegarde, sauvegardez les fichiers, puis supprimez l'instantané. Répétez le lendemain. Tout cela peut probablement être écrit.
mrdenny
Votre 1ère suggestion: les # n'ont pas changé dans le cache système. En ce qui concerne le LUN, je le transmettrai à mes collègues qui travaillent dans l'équipe System & Network.
dbachacha
J'ai déplacé le script de sauvegarde pour qu'il s'exécute sur un autre serveur et il y a une amélioration considérable. De plus, nous avons constaté que le code d'application ne réutilisait pas une connexion simple mais ouvrait / fermait dans plusieurs fonctions regroupées en une seule demande au serveur de base de données. De plus, j'ai constaté qu'une carte NIC est partagée par les données de sauvegarde et les données transactionnelles en ligne. Nous prévoyons donc d'avoir une carte réseau dédiée uniquement pour la sauvegarde. Merci beaucoup.
dbachacha
7

Voici quelques réflexions que j'ai sur l'amélioration des performances de mysqldump, compte tenu de votre situation. Voici votre commande:

mysqldump --skip-opt --quick --single-transaction --create-options --extended-insert --disable-keys --add-drop-table --complete-insert --set-charset --compress - -log-error = Proddb0635.err -u root -pjohndoe Proddb> \ devNas \ devNas \ sqlbackup \ LIVE \ db \ Proddb0635.sql

La première chose que je remarque est que vous redirigez la sortie vers un système de fichiers. Il indique «devNas», donc je vais supposer qu'il s'agit d'un stockage en réseau . Je suis un fan du NAS pour les sauvegardes, mais il doit être connecté sur une carte réseau physique distincte du trafic de production . Vous ne saturez peut-être pas la bande passante, mais ils rivalisent toujours. Cela va être plus problématique en raison de l'indicateur --quick, car il vide toutes les lignes au lieu de les conserver en mémoire.

La prochaine chose que je vois est que vous avez invoqué --compress. Il semble que vous exécutiez mysql localement puisque vous n'avez pas utilisé le commutateur -h. Cela peut utiliser un processeur local inutile dans ce contexte. --Compress est-il nécessaire? Il compresse uniquement les données entre le client mysqldump et le serveur mysql, pas le contenu du fichier.

Ensuite, je vois que vous utilisez l'indicateur --single-transaction. Cela va entraîner un processeur supplémentaire car il teste chaque sélection dans le cadre de mysqldump.

Cela n'a rien à voir avec les performances, mais vous utilisez --disable-keys qui ne fonctionne que sur MyISAM ( manuel ).

Vous voudrez peut-être essayer d'exécuter mysqldump à distance à partir d'un hôte hors ligne et de déplacer le fichier de vidage vers le NAS après la fin pour supprimer le plus possible cette opération de la bande.

randomx
la source
Oui, j'ai vérifié auprès de l'administrateur réseau et système. Il s'agit du stockage en réseau. Je peux essayer de déplacer mysqldump vers un autre serveur. De plus, maintenant, il était logique pour moi d'utiliser l'utilisation de --compress. Le manuel dit que --compress fonctionne avec le client et le serveur, mais je le mets pour voir si cela fait une différence. Quel type de données circule entre le client qui exécute mysqldump et le serveur de base de données mysql. Les données circulent entre le serveur de base de données mysql et devNas. La documentation MySQl et le livre Database Design and Tuning préfèrent l'utilisation d'une seule transaction pour les tables INNODB.
dbachacha
J'ai déplacé le script de sauvegarde pour qu'il s'exécute sur un autre serveur et il y a une amélioration considérable. De plus, nous avons constaté que le code d'application ne réutilisait pas une connexion simple mais ouvrait / fermait dans plusieurs fonctions regroupées en une seule demande au serveur de base de données. De plus, j'ai constaté qu'une carte NIC est partagée par les données de sauvegarde et les données transactionnelles en ligne. Nous prévoyons donc d'avoir une carte réseau dédiée uniquement pour la sauvegarde. Merci beaucoup.
dbachacha
Je suis content que cela aide. Meilleurs vœux.
randomx
Ici, j'ai besoin d'aide pour comprendre le scénario suivant: La base de données mysql est sur le serveur A. mysqldump s'exécute sur le serveur B qui vide les données sur le serveur C. Nous avons une carte réseau dédiée du serveur A au serveur C. Est-ce correct? Je ne savais pas si hier soir le mysqldump fonctionnait sur le serveur A. Je voudrais l'exécuter sur un autre serveur pour réduire les conflits de CPU.
dbachacha
mysqldump est un «utilitaire client», ce qui signifie que vous pouvez l'exécuter à partir de n'importe quel hôte disposant de privilèges pour accéder aux tables de la base de données. La stratégie pour vous serait d'exécuter mysqldump à partir du shell du serveur C en ciblant les tables du serveur A. Bien sûr, vous devrez accorder l'accès du serveur C au schéma que vous souhaitez vider.
randomx
2

OBSERVATION # 1

Voici quelque chose à garder à l'esprit lors de l'exécution d'un mysqldump contre InnoDB.

Les pages sales présentes dans le pool de tampons InnoDB doivent d'abord être vidées sur le disque. Un mysqldump déclenchera le vidage d'une table InnoDB qui contient encore des pages sales.

Il y a une option de serveur appelé innodb_max_dirty_pages_pct . La valeur par défaut est 75 est MySQL 5.5 et 90 dans les versions de MySQL antérieures à 5.5. Dans un environnement de production, il est OK de laisser ce nombre à la valeur par défaut.

Pour voir si vous avez beaucoup de pages sales dans le pool de tampons InnoDB, exécutez ceci:

SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';

BTW une page est 16K comme le montrent de ceci:

SHOW GLOBAL STATUS LIKE 'Innodb_page_size';

En ce qui concerne InnoDB et mysqldump, vous pouvez réduire ce nombre dans deux circonstances.

CIRCONSTANCE 1: Réglez-le en permanence sur 0

Ajoutez simplement ceci à my.ini:

[mysqld]
innodb_max_dirty_pages_pct=0

Cela gardera le pool de tampons InnoDB maigre et méchant. L'étape de vidage de la table InnoDB qui est en cours de vidage sera rapide car quelques pages sales que possible (peut-être 0) devront être vidées avant que mysqldump ne fonctionne dessus.

Le seul inconvénient est que si vous mysqldump à partir d'une base de données à fort trafic, il peut y avoir une augmentation plus faible des E / S d'écriture en raison du vidage plus fréquent des pages sales. Vous pouvez déterminer si c'est le cas sans redémarrer mysql en exécutant ceci:

SET GLOBAL innodb_max_dirty_pages_pct = 0;

Laissez le paramètre pendant 12 à 24 heures, si les performances d'écriture sont acceptables, vous êtes prêt à partir. Sinon, réglez-le avec:

SET GLOBAL innodb_max_dirty_pages_pct = 90;

CIRCONSTANCE 2: Réglez-le à 0 environ 1 heure avant mysqldump

SET GLOBAL innodb_max_dirty_pages_pct = 0;

Exécutez le mysqldump

SET GLOBAL innodb_max_dirty_pages_pct = 90;

OBSERVATION # 2

Vous avez --complete-insert comme option mysqldump. Cela incorporera les noms de colonne à chaque statament INSERT avant la clause VALUES. Même avec --extended-insert, sur chaque lot de lignes insérées, les noms de colonnes sont envoyés dans mysqldump. Vous pouvez réduire la quantité d'octets envoyés à mysqldump en supprimant --complete-insert.

RECOMMANDATION

Si vous avez un autre serveur Windows qui peut être configuré en tant qu'esclave, faites les mysqldumps depuis cet esclave plutôt que depuis la machine de production.

RolandoMySQLDBA
la source
Je vous remercie. J'ai oublié de mentionner que les utilisateurs se plaignent que "sauvegarder" prend du temps plutôt que de lire. Je mettrai immédiatement en œuvre votre observation n ° 2. J'aime vraiment votre recommandation d'avoir un esclave puis de prendre mysqldump de l'esclave.
dbachacha
innodb_buffer_pool_dirty_pages n'était pas trop élevé juste avant le démarrage de la sauvegarde. Il est d'environ 9 à max. 196. Master-Slave est également une bonne recommandation.
dbachacha
1
J'ai déplacé le script de sauvegarde pour qu'il s'exécute sur un autre serveur et il y a une amélioration considérable. De plus, nous avons constaté que le code d'application ne réutilisait pas une connexion simple mais ouvrait / fermait dans plusieurs fonctions regroupées en une seule demande au serveur de base de données. De plus, j'ai constaté qu'une carte NIC est partagée par les données de sauvegarde et les données transactionnelles en ligne. Nous prévoyons donc d'avoir une carte réseau dédiée uniquement pour la sauvegarde. Merci beaucoup. Si rien de tout cela ne fonctionne, je suis sûr que le maître esclave sera bon aussi.
dbachacha