Est-il possible de nettoyer un moteur de stockage mysql innodb afin qu'il ne stocke pas de données à partir de tables supprimées?
Ou dois-je reconstruire une nouvelle base de données à chaque fois?
Voici une réponse plus complète en ce qui concerne InnoDB. C'est un peu long, mais ça en vaut la peine.
N'oubliez pas que _/var/lib/mysql/ibdata1
_ est le fichier le plus occupé de l'infrastructure InnoDB. Il contient normalement six types d’informations:
Pictorial Representation of ibdata1
De nombreuses personnes créent plusieurs fichiers ibdata
dans l'espoir d'améliorer la gestion de l'espace disque et les performances, mais cette conviction est erronée.
OPTIMIZE TABLE
?Malheureusement, vous exécutez OPTIMIZE TABLE
sur une table InnoDB stockée dans le fichier d'espace table partagé _ibdata1
_ fait deux choses:
ibdata1
_ibdata1
_ parce que les données contiguës et les pages d'index sont ajoutées à _ibdata1
_Vous pouvez toutefois séparer les données de table et les index de table de _ibdata1
_ et les gérer indépendamment.
OPTIMIZE TABLE
avec innodb_file_per_table
?Supposons que vous ajoutiez innodb_file_per_table
à /etc/my.cnf (my.ini)
. Pouvez-vous alors simplement lancer OPTIMIZE TABLE
sur toutes les tables InnoDB?
Bonne nouvelle : lorsque vous exécutez OPTIMIZE TABLE
avec innodb_file_per_table
activé, cela produira un fichier _.ibd
_ pour cette table. . Par exemple, si vous avez la table _mydb.mytable
_ avec un datadir de _/var/lib/mysql
_, elle produira les éléments suivants:
/var/lib/mysql/mydb/mytable.frm
_/var/lib/mysql/mydb/mytable.ibd
__.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 la vie en ibdata
. L'entrée du dictionnaire de données pour chaque table, y compris _mydb.mytable
_, reste dans le dictionnaire de données (voir le représentation illustrée de ibdata1 ). VOUS NE POUVEZ PAS SUPPRIMER SIMPLEMENT _ibdata1
_ AT CE POINT !!! Veuillez noter que _ibdata1
_ n'a pas du tout diminué.
Pour réduire _ibdata1
_ une fois pour toutes, vous devez procéder comme suit:
Sauvegardez (par exemple, avec mysqldump
) toutes les bases de données dans un fichier texte _.sql
_ (_SQLData.sql
_ est utilisé ci-dessous)
Supprimez toutes les bases de données (sauf mysql
et _information_schema
_) MISE EN GARDE: Par précaution, exécutez ce script pour créer absolument sûr que vous avez toutes les subventions utilisateur en place:
_mkdir /var/lib/mysql_grants
cp /var/lib/mysql/mysql/* /var/lib/mysql_grants/.
chown -R mysql:mysql /var/lib/mysql_grants
_
Connectez-vous à mysql et exécutez _SET GLOBAL innodb_fast_shutdown = 0;
_ (Ceci effacera complètement toutes les modifications transactionnelles restantes de _ib_logfile0
_ et _ib_logfile1
_)
Arrêter MySQL
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
_
(Note: Quel que soit votre choix pour _innodb_buffer_pool_size
_, assurez-vous que _innodb_log_file_size
_ correspond à 25% de _innodb_buffer_pool_size
_.
Aussi: _innodb_flush_method=O_DIRECT
_ n'est pas disponible sous Windows)
Supprimer _ibdata*
_ et _ib_logfile*
_, Vous pouvez éventuellement supprimer tous les dossiers de _/var/lib/mysql
_, à l'exception de _/var/lib/mysql/mysql
_.
Démarrez MySQL (Ceci recréera _ibdata1
_ [10 Mo par défaut] et _ib_logfile0
_ et _ib_logfile1
_ à 1G chacun).
Importer _SQLData.sql
_
Maintenant, _ibdata1
_ continuera à 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 de données InnoDB ni d'index pour d'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 l'option _innodb_file_per_table
_ dans _/etc/my.cnf
_, vous pouvez exécuter _OPTIMIZE TABLE mydb.mytable
_ et le fichier _/var/lib/mysql/mydb/mytable.ibd
_ sera en fait réduit.
C'est ce que j'ai souvent fait dans ma carrière de DBA MySQL. En fait, la première fois que j'ai fait cela, j'ai réduit un fichier 50 Go _ibdata1
_ à seulement 500 Mo!
Essaie. Si vous avez d'autres questions à ce sujet, il suffit de demander. Croyez-moi; cela fonctionnera à court terme et à long terme.
A l'étape 6, si mysql ne peut pas redémarrer en raison de la suppression du schéma mysql
, commencez par revenir à l'étape 2. Vous avez créé la copie physique du schéma mysql
. 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
_
Retournez à l'étape 6 et continuez
En ce qui concerne la définition de innodb_log_file_size à 25% de innodb_buffer_pool_size à l'étape 5, cette règle générale est plutôt ancienne.
De retour sur _July 03, 2006
_, Percona avait publié un bel article pourquoi choisir innodb_log_file_size approprié . Plus tard, le _Nov 21, 2008
_, Percona a publié un autre article sur comment calculer la taille appropriée en fonction de la charge de travail maximale en conservant une heure de modifications .
Depuis, j'ai écrit des articles dans DBA StackExchange sur le calcul de la taille du journal et la référence de ces deux articles Percona.
Aug 27, 2012
_: Réglage approprié pour la table InnoDB de 30 Go sur le serveur avec 48 Go de RAMJan 17, 2013
_: MySQL 5.5 - Innodb - innodb_log_file_size supérieur à 4 Go combiné?Personnellement, je voudrais toujours aller avec la règle des 25% pour une configuration initiale. Ensuite, comme la charge de travail peut être déterminée avec plus de précision dans le temps en production, vous pouvez redimensionner les journaux pendant un cycle de maintenance en juste quelques minutes.
Le moteur InnoDB ne stocke pas les données supprimées. Lorsque vous insérez et supprimez des lignes, l'espace non utilisé est laissé dans les fichiers de stockage InnoDB. Au fil du temps, l'espace total ne diminuera pas, mais au fil du temps, l'espace "supprimé et libéré" sera automatiquement réutilisé par le serveur de base de données.
Vous pouvez affiner et gérer davantage l'espace utilisé par le moteur via une réorganisation manuelle des tables. Pour ce faire, exportez les données dans les tables affectées à l'aide de mysqldump, supprimez les tables, redémarrez le service mysql, puis recréez les tables à partir des fichiers de vidage.