Mysql
 sql >> Base de données >  >> RDS >> Mysql

Howto :Nettoyer un moteur de stockage mysql InnoDB ?

Voici une réponse plus complète concernant InnoDB. C'est un processus un peu long, mais cela peut en valoir la peine.

Gardez à l'esprit que /var/lib/mysql/ibdata1 est le fichier le plus utilisé de l'infrastructure InnoDB. Il contient normalement six types d'informations :

  • Données de tableau
  • Index des tables
  • MVCC (Multiversioning Concurrency Control) Données
    • Segments d'annulation
    • Annuler l'espace
  • Métadonnées de table (Dictionnaire de données)
  • Double tampon d'écriture (écriture en arrière-plan pour éviter de dépendre de la mise en cache du système d'exploitation)
  • Insert Buffer (gestion des modifications apportées aux index secondaires non uniques)
  • Consultez la Pictorial Representation of ibdata1

Architecture InnoDB

Beaucoup de gens créent plusieurs ibdata fichiers dans l'espoir d'une meilleure gestion de l'espace disque et de meilleures performances, mais cette croyance est erronée.

Puis-je exécuter OPTIMIZE TABLE ?

Malheureusement, l'exécution de OPTIMIZE TABLE par rapport à une table InnoDB stockée dans le fichier d'espace table partagé ibdata1 fait deux choses :

  • Rend les données et les index de la table contigus à l'intérieur de ibdata1
  • Fait ibdata1 croître car les pages de données et d'index contiguës sont ajoutées vers ibdata1

Vous pouvez cependant séparer les données de table et les index de table de ibdata1 et gérez-les de manière indépendante.

Puis-je exécuter OPTIMIZE TABLE avec innodb_file_per_table ?

Supposons que vous deviez ajouter innodb_file_per_table vers /etc/my.cnf (my.ini) . Pouvez-vous alors simplement exécuter OPTIMIZE TABLE sur toutes les tables InnoDB ?

Bonne nouvelle  :Lorsque vous exécutez OPTIMIZE TABLE avec innodb_file_per_table activé, cela produira un .ibd fichier pour cette table. Par exemple, si vous avez la table mydb.mytable avec un répertoire de données /var/lib/mysql , il produira ce qui suit :

  • /var/lib/mysql/mydb/mytable.frm
  • /var/lib/mysql/mydb/mytable.ibd

Le .ibd contiendra les pages de données et les pages d'index pour cette table. Génial.

Mauvaise nouvelle  :Tout ce que vous avez fait est d'extraire les pages de données et les pages d'index de mydb.mytable de vivre à ibdata . L'entrée du dictionnaire de données pour chaque table, y compris mydb.mytable , reste toujours dans le dictionnaire de données (Voir la Représentation illustrée de ibdata1 ). VOUS NE POUVEZ PAS SUPPRIMER SIMPLEMENT ibdata1 A CE POINT !!! Veuillez noter que ibdata1 n'a pas du tout rétréci.

Nettoyage de l'infrastructure InnoDB

Pour réduire ibdata1 une fois pour toutes, vous devez faire ce qui suit :

  1. Dump (par exemple, avec mysqldump ) toutes les bases de données dans un .sql fichier texte (SQLData.sql est utilisé ci-dessous)

  2. Supprimer toutes les bases de données (sauf pour mysql et information_schema ) MISE EN GARDE  :Par mesure de précaution, veuillez exécuter ce script pour vous assurer que toutes les autorisations d'utilisateur sont en place :

    mkdir /var/lib/mysql_grants
    cp /var/lib/mysql/mysql/* /var/lib/mysql_grants/.
    chown -R mysql:mysql /var/lib/mysql_grants
    
  3. Connectez-vous à mysql et exécutez SET GLOBAL innodb_fast_shutdown = 0; (Cela effacera complètement toutes les modifications transactionnelles restantes de ib_logfile0 et ib_logfile1 )

  4. Arrêter MySQL

  5. Ajoutez les lignes suivantes à /etc/my.cnf (ou my.ini sous Windows)

    [mysqld]
    innodb_file_per_table
    innodb_flush_method=O_DIRECT
    innodb_log_file_size=1G
    innodb_buffer_pool_size=4G
    

    (Sidenote :Quel que soit votre ensemble pour innodb_buffer_pool_size , assurez-vous que innodb_log_file_size est de 25 % de innodb_buffer_pool_size .

    Aussi :innodb_flush_method=O_DIRECT n'est pas disponible sous Windows)

  6. Supprimer ibdata* et ib_logfile* , En option, vous pouvez supprimer tous les dossiers dans /var/lib/mysql , sauf /var/lib/mysql/mysql .

  7. Démarrez MySQL (Cela va recréer ibdata1 [10 Mo par défaut] et ib_logfile0 et ib_logfile1 à 1G chacun).

  8. Importer SQLData.sql

Maintenant, ibdata1 continuera de croître mais ne contiendra que des métadonnées de table car chaque table InnoDB existera en dehors de ibdata1 . ibdata1 ne contiendra plus les données InnoDB et les index des autres tables.

Par exemple, supposons que vous ayez une table InnoDB nommée mydb.mytable . Si vous regardez dans /var/lib/mysql/mydb , vous verrez deux fichiers représentant la table :

  • mytable.frm (En-tête du moteur de stockage)
  • mytable.ibd (Données de table et index)

Avec le innodb_file_per_table option dans /etc/my.cnf , vous pouvez exécuter OPTIMIZE TABLE mydb.mytable et le fichier /var/lib/mysql/mydb/mytable.ibd va en fait rétrécir.

J'ai fait cela plusieurs fois dans ma carrière en tant que DBA MySQL. En fait, la première fois que j'ai fait cela, j'ai réduit de 50 Go ibdata1 fichier jusqu'à seulement 500 Mo !

Essaie. Si vous avez d'autres questions à ce sujet, il suffit de demander. Fais-moi confiance; cela fonctionnera à court terme comme à long terme.

MISE EN GARDE

A l'étape 6, si mysql ne peut pas redémarrer à cause du mysql schema begin abandonné, revenez à l'étape 2. Vous avez fait la copie physique du mysql schéma. Vous pouvez le restaurer comme suit :

mkdir /var/lib/mysql/mysql
cp /var/lib/mysql_grants/* /var/lib/mysql/mysql
chown -R mysql:mysql /var/lib/mysql/mysql

Revenez à l'étape 6 et continuez

MISE À JOUR 2013-06-04 11:13 EDT

En ce qui concerne la configuration de innodb_log_file_size à 25 % de innodb_buffer_pool_size à l'étape 5, la règle générale est plutôt ancienne.

De retour le July 03, 2006 , Percona avait un bel article pourquoi choisir un bon innodb_log_file_size . Plus tard, le Nov 21, 2008 , Percona a poursuivi avec un autre article sur comment calculer la taille appropriée en fonction de la charge de travail maximale en gardant une heure de modifications .

Depuis, j'ai écrit des articles dans le DBA StackExchange sur le calcul de la taille du journal et où j'ai fait référence à ces deux articles Percona.

Personnellement, j'irais toujours avec la règle des 25% pour une configuration initiale. Ensuite, comme la charge de travail peut être déterminée plus précisément au fil du temps en production, vous pouvez redimensionner les journaux pendant un cycle de maintenance en quelques minutes.