J'ai une application symfony avec une base de données InnoDB d'environ 2 Go avec 57 tables. La majorité de la taille de la base de données réside dans une seule table (~ 1,2 Go). J'utilise actuellement mysqldump pour sauvegarder la base de données tous les soirs.
En raison de ma connexion comcast, souvent si j'exécute un vidage manuellement, ma connexion au serveur expirera avant la fin du vidage, ce qui m'obligera à réexécuter le vidage. [Je lance actuellement un cron qui fait le vidage tous les soirs, c'est juste pour les vidages que je lance manuellement.]
Existe-t-il un moyen d'accélérer les vidages pour le problème de dépassement de délai de connexion, mais également de limiter la durée d'occupation du serveur par ce processus?
BTW, je travaille actuellement sur la réduction de la taille de la base de données globale pour résoudre ce problème.
Le principal goulot d'étranglement dans le vidage comme celui-ci est les E/S du lecteur. Vous lisez une charge de données et l'écrivez à nouveau. Vous pouvez accélérer cela de plusieurs manières:
gzip
ou similaire. Cela réduira la quantité d'écriture en cours (donc réduisez la charge globale IO, et la quantité de mouvement de la tête) au détriment du temps CPU (que vous pouvez avoir beaucoup de rechange à ces temps de toute façon).--quick
option pour réduire l'impact RAM de la sauvegarde de grandes tables).Vous pouvez cependant résoudre le mauvais problème: il pourrait être plus facile de résoudre les chutes de connexion à la place (bien que la réduction de la charge d'E/S imposée par vos sauvegardes contribuera à réduire l'effet que vous avez sur les autres utilisateurs, il vaut donc la peine d'essayer de toute façon). Pourriez-vous exécuter vos sauvegardes manuelles via écran (ou des outils similaires comme tmux )? De cette façon, si votre connexion au serveur tombe, vous pouvez simplement vous reconnecter et vous reconnecter à la session screen
sans qu'aucun processus ne soit interrompu.
Si vous envoyez les données directement via la connexion (c.-à-d. Que vous exécutez mysqldump sur votre machine locale contre une base de données distante, de sorte que le vidage s'affiche localement), vous feriez mieux de commencer par exécuter le vidage sur le serveur, en compressant au besoin, puis en transférant les données sur le réseau à l'aide d'un outil (tel que rsync
) qui prend en charge les transferts partiels afin que vous puissiez reprendre le transfert (au lieu de redémarrer) si une interruption de connexion l'interrompt.
Dans le cadre de votre "réduction de la taille de la base de données globale pour résoudre ce problème", je suppose qu'une grande partie de vos données ne change pas. Vous pourrez peut-être déplacer une grande partie du 1,2 Go de cette table principale vers une autre et la supprimer de celles qui sont copiées par l'appel mysqldump
. Vous n'avez pas besoin de sauvegarder ces données à chaque fois si elles ne changent jamais. Le fractionnement des données entre les tables et les bases de données de cette manière est généralement appelé partitionnement des données et peut également vous permettre de répartir les données et la charge d'E/S sur plusieurs disques. La base de données haut de gamme a intégré la prise en charge du partitionnement automatique, bien que dans mysql, vous devrez probablement le faire manuellement et modifier votre couche d'accès aux données pour en tenir compte.
S'éloigner du sujet pour ce site (vous devriez donc probablement passer à ServerFault ou SuperUser pour demander si vous avez besoin de plus de détails): Si vous semblez perdre des connexions en raison de l'inactivité, vérifiez les options de votre serveur SSH et de votre client SSH pour faire assurez-vous que les paquets persistants sont activés et envoyés assez souvent. Si vous voyez des chutes même si la connexion est active, vous pouvez également essayer d'utiliser OpenVPN ou similaire pour envelopper la connexion - il devrait gérer une courte chute, même complète si votre connexion entière est interrompue pendant quelques secondes, de sorte que le client SSH et serveur ne remarque pas.
APERÇU DE LA SAUVEGARDE AVEC mysqldump
IMHO Faire des sauvegardes est devenu plus une forme d'art si vous savez comment l'aborder
Vous avez des options
Option 1: mysqldump une instance entière de mysql
C'est le plus simple, le plus simple !!!
mysqldump -h... -u... -p... --hex-blob --routines --triggers --all-databases | gzip > MySQLData.sql.gz
Tout écrit dans un seul fichier: structures de table, index, déclencheurs, procédures stockées, utilisateurs, mots de passe cryptés. D'autres options mysqldump peuvent également exporter différents styles de commandes INSERT, un fichier journal et des coordonnées de position à partir de journaux binaires, des options de création de base de données, des données partielles (option --where), etc.
Option 2: mysqldump bases de données séparées dans des fichiers de données séparés
Commencez par créer une liste de bases de données (2 techniques pour ce faire)
Technique 1
mysql -h... -u... -p... -A --skip-column-names -e"SELECT schema_name FROM information_schema.schemata WHERE schema_name NOT IN ('information_schema','mysql')" > ListOfDatabases.txt
Technique 2
mysql -h... -u... -p... -A --skip-column-names -e"SELECT DISTINCT table_schema FROM information_schema.tables WHERE table_schema NOT IN ('information_schema','mysql')" > ListOfDatabases.txt
La technique 1 est le moyen le plus rapide. La technique 2 est la plus sûre et la plus sûre. La technique 2 est meilleure car, parfois, les utilisateurs créent des dossiers à usage général dans/var/lib/mysql (datadir) qui ne sont pas liés à la base de données. L'information_schema enregistrerait le dossier en tant que base de données dans la table information_schema.schemata. La technique 2 contournerait les dossiers qui ne contiennent pas de données mysql.
Une fois que vous avez compilé la liste des bases de données, vous pouvez passer en revue la liste et les mysqldump, même en parallèle si vous le souhaitez.
for DB in `cat ListOfDatabases.txt`
do
mysqldump -h... -u... -p... --hex-blob --routines --triggers ${DB} | gzip > ${DB}.sql.gz &
done
wait
S'il y a trop de bases de données à lancer en même temps, jetez-les en parallèle 10 à la fois:
COMMIT_COUNT=0
COMMIT_LIMIT=10
for DB in `cat ListOfDatabases.txt`
do
mysqldump -h... -u... -p... --hex-blob --routines --triggers ${DB} | gzip > ${DB}.sql.gz &
(( COMMIT_COUNT++ ))
if [ ${COMMIT_COUNT} -eq ${COMMIT_LIMIT} ]
then
COMMIT_COUNT=0
wait
fi
done
if [ ${COMMIT_COUNT} -gt 0 ]
then
wait
fi
Option 3: mysqldump des tables séparées dans des fichiers de données séparés
Commencez par créer une liste de tableaux
mysql -h... -u... -p... -A --skip-column-names -e"SELECT CONCAT(table_schema,'.',table_name) FROM information_schema.tables WHERE table_schema NOT IN ('information_schema','mysql')" > ListOfTables.txt
Vider ensuite toutes les tables par groupes de 10
COMMIT_COUNT=0
COMMIT_LIMIT=10
for DBTB in `cat ListOfTables.txt`
do
DB=`echo ${DBTB} | sed 's/\./ /g' | awk '{print $1}'`
TB=`echo ${DBTB} | sed 's/\./ /g' | awk '{print $2}'`
mysqldump -h... -u... -p... --hex-blob --triggers ${DB} ${TB} | gzip > ${DB}_${TB}.sql.gz &
(( COMMIT_COUNT++ ))
if [ ${COMMIT_COUNT} -eq ${COMMIT_LIMIT} ]
then
COMMIT_COUNT=0
wait
fi
done
if [ ${COMMIT_COUNT} -gt 0 ]
then
wait
fi
Option 4: UTILISEZ VOTRE IMAGINATION
Essayez des variantes des options susmentionnées et des techniques pour des instantanés propres
Exemples
[~ # ~] mise en garde [~ # ~]
Seule l'option 1 apporte tout. L'inconvénient est que mysqldumps créé de cette façon ne peut être rechargé que dans la même version majot de mysql que le mysqldump a été généré. En d'autres termes, un mysqldump d'une base de données MySQL 5.0 ne peut pas être chargé en 5.1 ou 5.5. La raison ? Le schéma mysql est totalement différent parmi les principales versions.
Les options 2 et 3 n'incluent pas l'enregistrement des noms d'utilisateur et des mots de passe.
Voici le moyen générique de vider les subventions SQL pour les utilisateurs qui est lisible et plus portable
mysql -h... -u... -p... --skip-column-names -A -e"SELECT CONCAT('SHOW GRANTS FOR ''',user,'''@''',Host,''';') FROM mysql.user WHERE user<>''" | mysql -h... -u... -p... --skip-column-names -A | sed 's/$/;/g' > MySQLGrants.sql
L'option 3 n'enregistre pas les procédures stockées, vous pouvez donc effectuer les opérations suivantes
mysqldump -h... -u... -p... --no-data --no-create-info --routines > MySQLStoredProcedures.sql &
Un autre point à noter concerne InnoDB. Si vous disposez d'un grand pool de mémoire tampon InnoDB, il est judicieux de le vider du mieux que vous le pouvez avant d'effectuer des sauvegardes. Sinon, MySQL passe le temps à vider les tables avec des pages sales restantes hors du pool de tampons. Voici ce que je propose:
Environ 1 heure avant d'effectuer la sauvegarde, exécutez cette commande SQL
SET GLOBAL innodb_max_dirty_pages_pct = 0;
Dans MySQL 5.5, innodb_max_dirty_pages_pct par défaut est 75. Dans MySQL 5.1 et inversement, innodb_max_dirty_pages_pct par défaut est 90. En définissant innodb_max_dirty_pages_pct sur 0, cela accélérera le vidage des pages sales sur le disque. Cela empêchera ou au moins atténuera l'impact du nettoyage des validations en deux phases incomplètes des données InnoDB avant d'effectuer tout mysqldump sur les tables InnoDB.
MOT FINAL SUR mysqldump
La plupart des gens évitent mysqldump en faveur d'autres outils et ces outils sont en effet bons.
Ces outils comprennent
Si vous avez l'esprit d'un vrai DBA MySQL, vous pouvez embrasser mysqldump et avoir la maîtrise complète qui peut être atteinte. Que toutes vos sauvegardes soient le reflet de vos compétences en tant que DBA MySQL .
Jetez un œil au maître de réplication MySQL à esclave. Il vous permet de cloner la base de données du maître vers un autre serveur de base de données avec la même base de données. Cela inclut les identités maître et esclave. Slave se fait la copie exacte du serveur de base de données maître et/ou de ses bases de données. Il peut y avoir une relation un, un, plusieurs, plusieurs entre maître (s) et esclave (s).
L'esclave lit en continu le journal binaire sur le maître (le journal du bin stocke les requêtes écrites sur le serveur de base de données maître) et obtient une entrée sur son serveur de base de données esclave. (cela signifie que votre base de données principale ne sera pas affectée du tout)
La bonne nouvelle est que cela n'affectera pas trop votre serveur MySQL car vous ne remarquerez aucun temps d'arrêt ou réponse lente aux requêtes. Nous l'utilisons pour les bases de données 10 Go et cela fonctionne comme un charme sans aucun temps d'arrêt.
Plan A: Voir aussi Xtrabackup de Percona. Cela permet une sauvegarde en ligne d'InnoDB, sans aucun verrouillage significatif.
Plan B: un esclave peut être arrêté et vous pouvez effectuer une sauvegarde cohérente par plusieurs moyens (copier des fichiers, mysqldump, xtrabackup, etc.)
Plan C: Instantané LVM. Après une configuration cryptée, le temps d'arrêt d'une sauvegarde est inférieur à une minute, quelle que soit la taille de la base de données. Vous arrêtez mysqld, faites l'instantané, redémarrez mysqld, puis copiez l'instantané. La dernière étape peut prendre du temps, mais MySQL n'est pas en panne.
Plan D: Instantané d'un esclave - aucun temps d'arrêt.
Quelques points d'administration d'abord: vous connectez-vous pour faire un ftp ou êtes-vous connecté et il est en train de mourir? Si ssh, assurez-vous d'utiliser écran pour pouvoir reprendre après le plantage de comcast. Si ftp, assurez-vous de le compresser/tar avant l'envoi.
Essayez également le paramètre --opt ou --quick
--opt Cette option active un ensemble d'options supplémentaires pour rendre les opérations de vidage et de rechargement plus efficaces. Plus précisément, cela équivaut à utiliser les options --add-drop-table, --add-locks, --all, --quick, --extended-insert, --lock-tables et --disable-keys ensemble. Notez que cette option rend la sortie moins portable et moins susceptible d'être comprise par d'autres systèmes de base de données.
--quick Cette option indique à mysqldump d'écrire la sortie de vidage lors de la lecture de chaque ligne du serveur, ce qui pourrait être utile pour les grandes tables. Par défaut, mysqldump lit toutes les lignes d'une table en mémoire avant d'écrire la sortie; pour les grandes tables, cela nécessite de grandes quantités de mémoire, ce qui peut entraîner l'échec du vidage.
J'ai également eu des problèmes avec les délais d'attente lors des vidages de grandes bases de données. J'ai finalement résolu si en envoyant des commandes individuelles pour chaque table de la base de données et en ajoutant tout à un fichier comme celui-ci:
TABLES=`mysql -u $USER -p$PWD -Bse 'show tables' $DB`
for TABLE in $TABLES
do
mysqldump -u $USER -p$PWD $DB $TABLE >> dump.sql
done
Je pense que la question est de savoir comment restaurer plus rapidement à partir des fichiers de vidage créés par mysqldump, pas une solution de sauvegarde différente.
Pour cela, vous pouvez créer des groupes de tables dans votre schéma et créer un utilisateur DB distinct pour chaque groupe, puis enfin utiliser les autorisations MySQL pour ne pas autoriser l'insertion de tables pour utiliser tous les utilisateurs DB sauf un.
Il s'agit d'une technique éprouvée, rapide, presque parallèle mais pas sûre à 100%, du temps qu'il faudra pour restaurer à partir de grandes décharges comme 500G ou plus. Mais à mon humble avis, vous avez besoin de quelque chose de parallèle. Consultez le lien ci-dessous pour un exemple.
[Restauration rapide et parallèle à partir de vidages SQL (mysqldump) pour MySQL] [1]
"Restauration rapide et parallèle à partir de vidages SQL (mysqldump) pour MySQL"