Est-il possible de nettoyer un moteur de stockage mysql innodb pour 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 pour qu'il ne stocke pas les données des tables supprimées?
Ou dois-je reconstruire une nouvelle base de données à chaque fois?
Réponses:
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 qu'il /var/lib/mysql/ibdata1
s'agit du fichier le plus chargé de l'infrastructure InnoDB. Il contient normalement six types d'informations:
Pictorial Representation of ibdata1
De nombreuses personnes 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.
OPTIMIZE TABLE
?Malheureusement, l'exécution OPTIMIZE TABLE
sur une table InnoDB stockée dans le fichier d'espace table partagé ibdata1
fait deux choses:
ibdata1
ibdata1
grandir car les données contiguës et les pages d'index sont ajoutées àibdata1
Vous pouvez cependant séparer les données de table et les index de table ibdata1
et les gérer indépendamment.
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
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 une table mydb.mytable
avec un datadir de /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 de 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 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 la représentation illustrée d'ibdata1 ). VOUS NE POUVEZ PAS SIMPLEMENT SUPPRIMER ibdata1
À CE POINT !!! Veuillez noter que cela ibdata1
n'a pas du tout diminué.
Pour réduire 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)
Supprimez 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 que toutes les autorisations 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
Connectez-vous à mysql et exécutez SET GLOBAL innodb_fast_shutdown = 0;
(cela supprimera 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 de bas de page: quel que soit votre jeu innodb_buffer_pool_size
, assurez-vous que innodb_log_file_size
25% de innodb_buffer_pool_size
.
Aussi: innodb_flush_method=O_DIRECT
n'est pas disponible sous Windows)
Supprimer ibdata*
et ib_logfile*
, éventuellement, vous pouvez supprimer tous les dossiers dans /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).
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 dedans /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' 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
sera en fait réduit.
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 un fichier de 50 Go ibdata1
à seulement 500 Mo!
Essaie. Si vous avez d'autres questions à ce sujet, demandez simplement. Croyez-moi; cela fonctionnera aussi bien à court terme qu'à long terme.
À l'étape 6, si mysql ne peut pas redémarrer en raison de la mysql
suppression du début du schéma, 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
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 July 03, 2006
, Percona avait un bel article sur les raisons pour lesquelles choisir un innodb_log_file_size approprié . Plus tard, Nov 21, 2008
Percona a poursuivi avec un autre article sur la façon de calculer la taille appropriée en fonction 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 où j'ai référencé ces deux articles Percona.
Aug 27, 2012
: Réglage correct pour une table InnoDB de 30 Go sur un serveur avec 48 Go de RAMJan 17, 2013
: MySQL 5.5 - Innodb - innodb_log_file_size supérieur à 4 Go combinés?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 avec plus de précision au fil du temps en production, vous pouvez redimensionner les journaux pendant un cycle de maintenance en quelques minutes.
innodb_open_tables
si nécessaire. La valeur par défaut est 300.
Le moteur InnoDB ne stocke pas les données supprimées. Lorsque vous insérez et supprimez des lignes, l'espace inutilisé reste alloué dans les fichiers de stockage InnoDB. Au fil du temps, l'espace global ne diminuera pas, mais avec le 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 l'espace utilisé par le moteur grâce à une réorganisation manuelle des tables. Pour ce faire, videz 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.