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/ibdata1s'agit du fichier le plus chargé de l'infrastructure InnoDB. Il contient normalement six types d'informations:
De nombreuses personnes créent plusieurs ibdatafichiers dans l'espoir d'une meilleure gestion de l'espace disque et de meilleures performances, mais cette croyance est erronée.
Supposons que vous deviez ajouter innodb_file_per_tableà /etc/my.cnf (my.ini). Pouvez-vous alors simplement exécuter OPTIMIZE TABLEtoutes les tables InnoDB?
Bonne nouvelle : lorsque vous exécutez OPTIMIZE TABLEavec innodb_file_per_tableactivé, cela produira un .ibdfichier pour cette table. Par exemple, si vous avez une table mydb.mytableavec un datadir de /var/lib/mysql, il produira ce qui suit:
/var/lib/mysql/mydb/mytable.frm
/var/lib/mysql/mydb/mytable.ibd
Le .ibdcontiendra 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.mytablede 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 ibdata1n'a pas du tout diminué.
Nettoyage de l'infrastructure InnoDB
Pour réduire ibdata1une fois pour toutes, vous devez faire ce qui suit:
Dump (par exemple, avec mysqldump) toutes les bases de données dans un .sqlfichier texte ( SQLData.sqlest utilisé ci-dessous)
Supprimez toutes les bases de données (à l'exception de mysqlet information_schema) CAVEAT : Par précaution, veuillez exécuter ce script pour vous assurer que toutes les autorisations utilisateur sont en place:
Connectez-vous à mysql et exécutez SET GLOBAL innodb_fast_shutdown = 0;(cela supprimera complètement toutes les modifications transactionnelles restantes de ib_logfile0et ib_logfile1)
Arrêter MySQL
Ajoutez les lignes suivantes à /etc/my.cnf(ou my.inisous Windows)
(Note de bas de page: quel que soit votre jeu innodb_buffer_pool_size, assurez-vous que innodb_log_file_size25% de innodb_buffer_pool_size.
Aussi: innodb_flush_method=O_DIRECTn'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_logfile0et ib_logfile1à 1G chacun).
Importer SQLData.sql
Maintenant, ibdata1continuera de croître mais ne contiendra que des métadonnées de table car chaque table InnoDB existera en dehors de ibdata1. ibdata1ne 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_tableoption dans /etc/my.cnf, vous pouvez exécuter OPTIMIZE TABLE mydb.mytableet le fichier /var/lib/mysql/mydb/mytable.ibdsera 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 Goibdata1 à 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.
CAVEAT
À l'étape 6, si mysql ne peut pas redémarrer en raison de la mysqlsuppression du début du schéma, revenez à l'étape 2. Vous avez fait la copie physique du mysqlschéma. Vous pouvez le restaurer comme suit:
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.
J'ai également utilisé l'option innodb_file_per_table à bon escient, ayant 200 bases de données avec 200 tables chacune sur un seul serveur, j'ai pu créer un lien symbolique entre les bases de données de différence sur différentes partitions, utilisant donc plus de tampons IO et de broches qui auraient autrement été disponibles :)
Dave Rix
2
@SeanDowney BTW n'oubliez pas de relancer innodb_open_tablessi nécessaire. La valeur par défaut est 300.
RolandoMySQLDBA
2
@ giorgio79 vous devez définir votre insertion en masse sur une valeur plus élevée. C'est un bon point. J'ajouterai l'essentiel de votre question à ma réponse.
RolandoMySQLDBA
3
Dans les systèmes 32 bits, une valeur de 4 Go pour innodb_buffer_pool_size n'est pas autorisée. Mysql démarrera silencieusement avec innodb désactivé et les tables restaurées seront changées en myisam. Utilisez une valeur légèrement plus petite pour le corriger.
David
5
Bon dieu. Je veux juste dire que c'est peut-être l'une des meilleures réponses que j'aie jamais vues sur Tellement bon travail, monsieur. M'a aidé à trouver une solution à mon problème lorsque j'obtenais une ERREUR 2013 (HY000) lors de l'importation d'une base de données de 154g. Merci pour l'excellente réponse!
Josh Brown
4
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.
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
Architecture InnoDB
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.Puis-je courir
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.Puis-je courir
OPTIMIZE TABLE
avecinnodb_file_per_table
?Supposons que vous deviez ajouter
innodb_file_per_table
à/etc/my.cnf (my.ini)
. Pouvez-vous alors simplement exécuterOPTIMIZE TABLE
toutes les tables InnoDB?Bonne nouvelle : lorsque vous exécutez
OPTIMIZE TABLE
avecinnodb_file_per_table
activé, cela produira un.ibd
fichier pour cette table. Par exemple, si vous avez une tablemydb.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 dansibdata
. L'entrée du dictionnaire de données pour chaque table, y comprismydb.mytable
, reste toujours dans le dictionnaire de données (voir la représentation illustrée d'ibdata1 ). VOUS NE POUVEZ PAS SIMPLEMENT SUPPRIMERibdata1
À CE POINT !!! Veuillez noter que celaibdata1
n'a pas du tout diminué.Nettoyage de l'infrastructure InnoDB
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
etinformation_schema
) CAVEAT : Par précaution, veuillez exécuter ce script pour vous assurer que toutes les autorisations utilisateur sont en place:Connectez-vous à mysql et exécutez
SET GLOBAL innodb_fast_shutdown = 0;
(cela supprimera complètement toutes les modifications transactionnelles restantes deib_logfile0
etib_logfile1
)Arrêter MySQL
Ajoutez les lignes suivantes à
/etc/my.cnf
(oumy.ini
sous Windows)(Note de bas de page: quel que soit votre jeu
innodb_buffer_pool_size
, assurez-vous queinnodb_log_file_size
25% deinnodb_buffer_pool_size
.Aussi:
innodb_flush_method=O_DIRECT
n'est pas disponible sous Windows)Supprimer
ibdata*
etib_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] etib_logfile0
etib_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 deibdata1
.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écuterOPTIMIZE 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.
CAVEAT
À 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 dumysql
schéma. Vous pouvez le restaurer comme suit:Revenez à l'étape 6 et continuez
MISE À JOUR 2013-06-04 11:13 EDT
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.
la source
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.
la source