Est-il possible de nettoyer un moteur de stockage mysql innodb afin qu'il ne stocke pas les données des tables supprimées ?
Ou dois-je reconstruire une nouvelle base de données à chaque fois ?
Est-il possible de nettoyer un moteur de stockage mysql innodb afin qu'il ne stocke pas les données des 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 processus un peu long, mais qui peut en valoir la peine.
Gardez à l'esprit que /var/lib/mysql/ibdata1
est le fichier le plus utilisé dans l'infrastructure InnoDB. Il abrite normalement six types d'informations :
Pictorial Representation of ibdata1
De nombreuses personnes créent plusieurs ibdata
en espérant une meilleure gestion de l'espace disque et de meilleures performances, mais cette croyance est erronée.
OPTIMIZE TABLE
?Malheureusement, l'exécution OPTIMIZE TABLE
contre une table InnoDB stockée dans le fichier de tablespace partagé ibdata1
fait deux choses :
ibdata1
ibdata1
grandissent parce que les pages contiguës de données et d'index sont en annexe à ibdata1
Vous pouvez cependant séparer les données de la table et les index de la table des données de la table. ibdata1
et les gérer de manière indépendante.
OPTIMIZE TABLE
avec innodb_file_per_table
?Supposons que vous deviez ajouter innodb_file_per_table
à /etc/my.cnf (my.ini)
. Pouvez-vous alors simplement exécuter OPTIMIZE TABLE
sur toutes les tables InnoDB ?
Bonne nouvelle : Quand vous exécutez OPTIMIZE TABLE
avec innodb_file_per_table
activé, cela produira un .ibd
pour cette table. Par exemple, si vous avez la table mydb.mytable
avec un répertoire de données de /var/lib/mysql
il produira ce qui suit :
/var/lib/mysql/mydb/mytable.frm
/var/lib/mysql/mydb/mytable.ibd
Le site .ibd
contiendra les pages de données et les pages d'index pour cette table. Super.
Mauvaises nouvelles : Tout ce que vous avez fait, c'est d'extraire les pages de données et les pages d'index du site. mydb.mytable
de vivre dans 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 l'article de l'article de la loi sur la protection des données). Représentation graphique de ibdata1 ). VOUS NE POUVEZ PAS SIMPLEMENT SUPPRIMER ibdata1
À CE STADE ! !! Veuillez noter que ibdata1
n'a pas du tout diminué.
Pour rétrécir ibdata1
une fois pour toutes, vous devez faire ce qui suit :
Dump (par exemple, avec mysqldump
) toutes les bases de données dans un .sql
fichier texte ( SQLData.sql
est utilisé ci-dessous)
Abandonnez toutes les bases de données (à l'exception de mysql
et information_schema
) CAVEAT : Par précaution, veuillez exécuter ce script pour vous assurer absolument que vous avez toutes les autorisations d'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 l'application ib_logfile0
et ib_logfile1
)
Arrêter MySQL
Ajoutez les lignes suivantes à /etc/my.cnf
(ou my.ini
sur 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 jeu 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)
Supprimer ibdata*
et ib_logfile*
Si vous le souhaitez, vous pouvez supprimer tous les dossiers de la section /var/lib/mysql
sauf /var/lib/mysql/mysql
.
Démarrez MySQL (Cela recréera ibdata1
[10 Mo par défaut] et ib_logfile0
et ib_logfile1
à 1G chacun).
Importation SQLData.sql
Maintenant, ibdata1
s'agrandira toujours mais ne contiendra que les métadonnées des tables car chaque table InnoDB existera en dehors de la section 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 la 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 se réduire.
Je l'ai fait de nombreuses fois au cours de ma carrière de DBA MySQL. En fait, la première fois que j'ai fait cela, j'ai rétréci une 50GB ibdata1
à seulement 500 Mo !
Essayez-le. Si vous avez d'autres questions à ce sujet, n'hésitez pas à les poser. Faites-moi confiance, cela fonctionnera aussi bien à court terme qu'à long terme.
À l'étape 6, si mysql ne peut pas redémarrer en raison de l'échec de l'opération mysql
Si le schéma commence à tomber, reportez-vous à 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
Retournez à l'étape 6 et continuez
En ce qui concerne la fixation innodb_log_file_size à 25 % de innodb_buffer_pool_size à l'étape 5, cette règle de couverture est plutôt de la vieille école.
Retour sur July 03, 2006
Percona a publié un article intéressant Pourquoi choisir une taille de fichier innodb_log_file_size appropriée ? . Plus tard, le Nov 21, 2008
Percona a poursuivi avec un autre article sur comment calculer la taille appropriée sur la base de la charge de travail maximale en conservant une heure de changements. .
J'ai depuis écrit des articles dans le DBA StackExchange sur le calcul de la taille du journal et j'y ai fait référence à ces deux articles de Percona.
Aug 27, 2012
: Réglage correct d'une table InnoDB de 30 Go sur un serveur avec 48 Go de RAM
Jan 17, 2013
: MySQL 5.5 - Innodb - innodb_log_file_size supérieure à 4GB combinés ?
Personnellement, je continuerais à appliquer 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 pourriez redimensionner les journaux pendant un cycle de maintenance en quelques minutes seulement.
J'ai aussi utilisé l'option innodb_file_per_table avec beaucoup d'effet, ayant 200 bases de données avec 200 tables chacune sur un seul serveur, j'ai pu symlinker des bases de données différentes sur des partitions différentes, utilisant ainsi plus de tampons IO et de broches qui auraient été autrement disponibles :)
C'est une excellente solution. Nous étions à court d'espace disque sur deux de nos machines et cette solution a permis de libérer environ un tiers du disque. C'est un processus effrayant puisque vous supprimez vos bases de données, mais cela fonctionne ! Nous avons même constaté une légère augmentation des performances.
@SeanDowney N'oubliez pas d'élever innodb_open_tables
si nécessaire. La valeur par défaut est de 300.
Le moteur InnoDB ne stocke pas les données supprimées. Au fur et à mesure que vous insérez et supprimez des lignes, de l'espace inutilisé reste alloué dans les fichiers de stockage InnoDB. Au fil du temps, l'espace total ne diminuera pas, mais l'espace "supprimé et libéré" sera automatiquement réutilisé par le serveur de base de données.
Vous pouvez affiner et gérer l'espace utilisé par le moteur en réorganisant manuellement les tables. Pour ce faire, videz les données des tables concernées à l'aide de mysqldump, supprimez les tables, redémarrez le service mysql, puis recréez les tables à partir des fichiers de vidage.
Pour info, après m'être beaucoup creusé la tête, je viens de découvrir que O_DIRECT ne peut pas être utilisé sous Windows.
"Sous Windows, la méthode de vidage est toujours async_unbuffered et ne peut être modifiée"
De : http://dev.mysql.com/doc/refman/5.0/en/innodb-parameters.html#sysvar_innodb_flush_method
Je suis ce guide pour une réinitialisation complète (comme Root) :
mysqldump --all-databases --single-transaction | gzip -c > /tmp/mysql.all.sql.gz
service mysql stop
mv /var/lib/mysql /var/lib/mysql.old; mkdir -m700 /var/lib/mysql; chown mysql:mysql /var/lib/mysql
mysql_install_db # mysql 5.5
mysqld --initialize-insecure # mysql 5.7
service mysql start
zcat /tmp/mysql.all.sql.gz | mysql
service mysql restart
Vous pouvez utiliser la requête OPTIMIZE TABLE périodiquement pour optimiser votre stockage et accélérer un peu les requêtes SELECT. Lien vers le manuel MySQL : http://dev.mysql.com/doc/refman/5.1/en/optimize-table.html
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
0 votes
Qu'est-ce qui vous fait penser que MySQL stocke les données des tables supprimées ?
1 votes
Si je supprime un tas de tables énormes, mes fichiers de stockage InnoDB ne diminuent pas.
2 votes
@RobertMunteanu : voir bugs.mysql.com/bug.php?id=1341