Comment vider efficacement une énorme base de données innodb MySQL?

8

J'ai un serveur de base de données MySQL de production Ubuntu 10.04 où la taille totale de la base de données est de 260 Go tandis que la taille de la partition racine est elle-même de 300 Go où la base de données est stockée, ce qui signifie essentiellement environ 96% de / est plein et il n'y a plus d'espace pour stocker le vidage / la sauvegarde etc. Aucun autre disque n'est connecté au serveur pour l'instant.

Ma tâche consiste à migrer cette base de données vers un autre serveur assis dans un centre de données différent. La question est de savoir comment le faire efficacement avec un minimum de temps d'arrêt?

Je pense à:

  • Demande de connecter un lecteur supplémentaire au serveur et d'effectuer un vidage sur ce lecteur. [EDIT: Ce n'est pas possible maintenant.]
  • Transférez le vidage sur un nouveau serveur, restaurez-le et rendez le nouveau serveur esclave de celui existant pour garder les données synchronisées
  • Lorsque la migration est nécessaire, interrompez la réplication, mettez à jour la configuration de l'esclave pour accepter les demandes de lecture / écriture et rendez l'ancien serveur en lecture seule pour qu'il n'accepte aucune demande d'écriture et ne dise pas aux développeurs d'applications de mettre à jour leur configuration avec la nouvelle adresse IP pour db.

Quelles sont vos suggestions pour améliorer cette approche ou toute autre meilleure approche pour cette tâche?

Jagbir
la source

Réponses:

9

Si vous envisagez de migrer vers un autre DB Server avec exactement la même version de MySQL, vous pouvez rsyncle datadirde l'ancien serveur vers le nouveau serveur.

Cela fonctionnera quelle que soit la disposition des fichiers InnoDB ou même la présence de tables MyISAM.

  1. installez la même version de mysql sur ServerB que ServerA a
  2. Sur ServerA, exécutez RESET MASTER;pour effacer tous les journaux binaires avant le processus rsycn. Si la journalisation binaire n'est pas activée, vous pouvez ignorer cette étape.
  3. Sur ServerA, exécutez à SET GLOBAL innodb_max_dirty_pages_pct = 0;partir de mysql et environ 10 minutes (cela purge les pages sales du pool de tampons InnoDB. Cela permet également d'effectuer un arrêt mysql plus rapidement) Si votre base de données est entièrement MyISAM, vous pouvez ignorer cette étape.
  4. rsync / var / lib / mysql de ServerA vers / var / lib / mysql sur ServerB
  5. Répétez l'étape 3 jusqu'à ce qu'une rsync prenne moins de 1 minute
  6. service mysql stop sur ServerA
  7. Effectuer un rsync supplémentaire
  8. scp ServerA: /etc/my.cnf vers ServerB: / etc /.
  9. service mysql start sur ServerB
  10. service mysql start sur ServerA (facultatif)

Essentiellement, voici ce qu'un tel script souhaiterait

mysql -u... -p... -e"RESET MASTER;"
mysql -u... -p... -e"SET GLOBAL innodb_max_dirty_pages_pct = 0;"
RSYNCSTOTRY=10
cd /var/lib/mysql
X=0
while [ ${X} -lt ${RSYNCSTOTRY} ]
do
    X=`echo ${X}+1|bc`
    rsync -r * targetserver:/var/lib/mysql/.
    sleep 60
done
service mysql stop
rsync -r * targetserver:/var/lib/mysql/.
service mysql start

Un autre membre du DBA StackExchange a dit que je devrais m'éloigner de FLUSH TABLES WITH READ LOCK;quelque chose sur mysqlperformanceblog.com

J'ai lu et appris que les sélections contre les tables InnoDB au milieu d'un FLUSH TABLES WITH READ LOCK;peuvent encore permettre aux écritures de se produire d'une manière ou d'une autre. Comme indiqué dans le commentaire d' Arlukin , LVM fonctionnerait très bien avec FLUSH TABLES WITH READ LOCKInnoDB (+1 pour son commentaire).

Pour tous les utilisateurs non LVM, vous êtes d'accord avec une base de données entièrement MyISAM à utiliser avec FLUSH TABLES WITH READ LOCK;. Pour InnoDB, respectez l' --single-tranactionutilisation dans mysqldumps s'il vous plaît.

RolandoMySQLDBA
la source
2
C'est ainsi que nous procédons, lorsque nous devons synchroniser manuellement une configuration maître-esclave. Fonctionne vraiment bien. Mais sur nos derniers serveurs, nous utilisons des instantanés LVM, nous n'avons donc pas besoin d'arrêter le serveur. Juste avant de faire l'instantané LVM, nous exécutons "TABLES DE RINÇAGE AVEC VERROUILLAGE EN LECTURE", de sorte que les fichiers peuvent être copiés. Le lvm-snapshot est également très bon si vous souhaitez copier tous les fichiers à des fins de sauvegarde. Configurez donc votre nouveau serveur avec LVM et ajoutez de l'espace supplémentaire pour pouvoir faire des instantanés.
Arlukin
Merci pour la réponse détaillée. Et si les versions de MySQL sont différentes? L'ancien est 5.1 avec ubuntu 10.04 tandis que dans les plus récents, je suis prêt à utiliser 12.04 avec 5.5 par défaut. Quelle approche dans un tel cas recommandez-vous? Il est désormais hors de question de connecter un disque supplémentaire, de sorte que les données doivent être envoyées à distance, que ce soit par vidage / rsync ou par tout autre moyen.
Jagbir
1

Un vidage et une restauration d'une base de données de cette taille prendrait des heures. Je le ferais, selon les versions de mysql tant que le numéro de version augmente et qu'il n'y a pas de sauts dans le numéro de révision principal. Vous devriez pouvoir prendre les fichiers de base de données bruts dans / var / lib / mysql et les placer sur le nouveau serveur, définir les autorisations et démarrer le serveur avec le commutateur --skip-grant-tables. Ajoutez les autorisations nécessaires pour les utilisateurs reflétant la nouvelle adresse IP, puis redémarrez normalement.

Je voudrais aborder la taille de votre base de données car elle est trop grande pour être efficace.

James Park-Watt
la source
Il existe 4 bases de données d'une taille d'environ 50 à 90 Go, ce qui fait une taille globale de 260 Go. Il est peut-être inefficace mais je dois vivre avec maintenant. Les versions de MySQL sont également différentes, que proposez-vous dans ce cas?
Jagbir
Si les versions de mysql sont différentes, faites d'abord un essai à blanc et testez soigneusement tant que le numéro de version sur le nouveau serveur est supérieur à celui de l'ancien, vous devriez être d'accord. S'il échoue, vous pouvez être bloqué en utilisant la restauration mysqldump &&.
James Park-Watt
1

Vous pouvez suivre ces étapes pour migrer cette énorme base de données InnoDB.

  • Installez SSHFS et montez la partition appropriée du serveur distant sur le serveur de production
  • Utilisez Percona XtraBackup pour obtenir une copie à chaud de la base de données InnoDB et l'enregistrer directement dans le répertoire monté SSHFS
  • Cette tâche prendra plusieurs heures. Pour minimiser l'effet du script de copie à chaud sur le serveur en direct, définissez une priorité faible sur celui-ci à l'aide de renice

    $ renice -n 5 -p <SCRIPT-PID>

  • Assurez-vous que les deux serveurs exécutent la même version du serveur MySQL.
  • Une fois la copie à chaud terminée, vous pouvez la restaurer sur le nouveau serveur démarrer le processus de réplication

Vous pouvez rencontrer une lenteur au cours de ce processus, mais certainement aucun temps d'arrêt. Percona XtraBackup créera une copie à chaud qui est plus rapide et moins consommatrice de ressources par rapport à mysqldump. C'est idéal pour une énorme base de données InnoDB.

Selon les modèles d'utilisation et les statistiques, vous pouvez exécuter ce processus lorsqu'il y a un trafic minimum sur le serveur. Peut-être que faire cela le week-end est une bonne idée? Ce qui précède n'est qu'un aperçu du processus. Vous devrez peut-être parcourir la documentation de Percona XtraBackup et SSHFS.

vagarwal
la source
1

Vous pouvez simplement vider la base de données directement sur le serveur distant ...

$ mysqldump | ssh user@server 'cat - > dumpfile.sql.gz'

... SQL devrait bien compresser, vous devriez donc faire cela beaucoup plus rapidement avec l'une de ces options, même si cela dépendra également de la quantité de RAM que vous avez dans la boîte ...

$ mysqldump | ssh -C user@server 'cat - > dumpfile.sql.gz'
$ mysqldump | gzip -c | ssh user@server 'cat - > dumpfile.sql.gz'
Bon à tout faire
la source