MySQL InnoDB - innodb_file_per_table contre?

32

Par défaut, MySQL InnoDB stocke toutes les tables de toutes les bases de données dans un seul fichier global. Vous pouvez changer cela en définissant innodb_file_per_table dans la configuration, qui crée ensuite un fichier de données pour chaque table.

Je me demande pourquoi innodb_file_per_tablen'est pas activé par défaut. Y a-t-il des inconvénients à l'utiliser?

Jusqu'à la crique
la source

Réponses:

32

J'ai la réponse complète pour celui-ci.

Une fois que innodb_file_per_table est mis en place, les nouvelles tables InnoDB peuvent être réduites à l’aide de: ALTER TABLE <innodb-table-name> ENGINE=InnoDB';Ceci réduira les nouveaux .ibdfichiers GARANTIS.

Si vous utilisez ALTER TABLE <innodb-table-name> ENGINE=InnoDB';une table InnoDB créée avant d'utiliser innodb_file_per_table, les données et index de cette table seront extraits du fichier ibdata1 et stockés dans un .ibdfichier, ce qui laissera un pigeon permanent dans ibdata1 qui ne pourra jamais être réutilisé. .

Le ibdata1fichier contient normalement quatre types d'informations

  • Données de table
  • Index de table
  • Données MVCC (Multiversioning Concurrency Control)
    • Segments de restauration
    • Annuler l'espace
  • Métadonnées de table (dictionnaire de données)
  • Double Write Buffer (é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)
  • Voir le Pictorial Representation of ibdata1

Voici le moyen le plus sûr de réduire le fichier ibdata1 pour toujours ...

ÉTAPE 01) MySQLDump toutes les bases de données dans un fichier texte SQL (appelez-le SQLData.sql)

ÉTAPE 02) Supprimez toutes les bases de données (sauf les schémas mysql, information_schema et performance_schema)

ÉTAPE 03) Arrêter mysql

ÉTAPE 04) Ajoutez les lignes suivantes à /etc/my.cnf

[mysqld]
innodb_file_per_table
innodb_flush_method=O_DIRECT
innodb_log_file_size=1G
innodb_buffer_pool_size=4G
innodb_data_file_path=ibdata1:10M:autoextend

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.

  • ÉTAPE 05) Supprimez ibdata1, ib_logfile0 et ib_logfile1 ( voir la mise à jour ci-dessous avant de supprimer! )

À ce stade, il ne devrait y avoir que le schéma mysql dans / var / lib / mysql

  • ÉTAPE 06) Redémarrez mysql

Cela recréera ibdata1 à 10 Mo (ne configurez pas l'option), ib_logfile0 et ib_logfile1 à 1G chacun

  • ÉTAPE 07) Recharger SQLData.sql dans mysql

ibdata1 croîtra mais ne contiendra que des métadonnées de table et des données MVCC intermittentes.

Chaque table InnoDB existera en dehors de ibdata1

Supposons que vous ayez une table InnoDB nommée mydb.mytable. Si vous allez dans /var/lib/mysql/mydb, vous verrez deux fichiers représentant la table

  • mytable.frm (En-tête de moteur de stockage)
  • mytable.ibd(Home of Table Data et Index de table pour mydb.mytable)

ibdata1 ne contiendra plus jamais de données InnoDB et d’index.

Avec l' option innodb_file_per_table dans /etc/my.cnf, vous pouvez exécuter OPTIMIZE TABLE mydb.mytableOR ALTER TABLE mydb.mytable ENGINE=InnoDB;et le fichier /var/lib/mysql/mydb/mytable.ibdsera réduit.

J'ai fait cela à plusieurs reprises dans ma carrière en tant que DBA MySQL sans aucun problème par la suite. En fait, la première fois que j'ai fait cela, j'ai réduit un fichier ibdata1 de 50 Go à 50 Mo.

Essaie. Si vous avez d'autres questions à ce sujet, écrivez-moi. Croyez-moi. Cela fonctionnera à court terme et à long terme.

MISE À JOUR 2013-07-02 15:08 EDT

Il y a une mise en garde à cet égard que j'ai mise à jour dans d'autres de mes publications mais que j'ai ratée: je mets à jour ma réponse un peu plus avec innodb_fast_shutdown car j'avais l'habitude de redémarrer mysql et d'arrêter mysql pour le faire. Désormais, cette étape est essentielle car chaque transaction non validée peut comporter d’autres éléments mobiles à l’intérieur et à l’extérieur des journaux de transactions InnoDB ( voir Infrastructure InnoDB ).

Veuillez noter que définir innodb_fast_shutdown sur 2 effacerait également les journaux, mais qu'il resterait encore des pièces mobiles et qu'il serait sélectionné lors de la récupération après un crash au démarrage de mysqld. La valeur 0 est la meilleure.

RolandoMySQLDBA
la source
Excellente information - merci! 50 Go >> 50 Mo - c'est assez impressionnant!
UpTheCreek
Bonjour, j'ai essayé de faire exactement ce que vous avez écrit ici, le problème est que le serveur ne démarre pas après. si je fais le service mysql commence il se bloque juste là. Si je reviens à mon ancien fichier cnf, tout va bien. Avez-vous une idée à ce sujet?
Nicola Peluchetti
Cette question est pour Nicola: As-tu fait l'étape 5 ???
RolandoMySQLDBA
Une autre question pour @ Nicola: combien de RAM avez-vous dans votre système ???
RolandoMySQLDBA
2
Faites attention! L'option innodb_fast_shutdown=0doit être définie dans MySQL, avant de la fermer pour supprimer les fichiers journaux! ( ib_logfile0et ib_logfile1) Sinon, vous pourriez perdre des données!
Totor
12

Voir bug .

Y a-t-il des inconvénients à l'utiliser?

  • plus de fichiers ouverts
  • ouvrir / rouvrir les frais généraux
  • Le fichier .ibd ne se réduit pas (voir 1 , 2 )

J'utilise toujours innodb_file_per_table sur des bases de données volumineuses.

Alvosu
la source
Même si vous ne l'utilisez pas, les fichiers ibdata ne seront pas réduits, que ce soit :(
minaev le
1
Merci. Je me demande également pourquoi il n'y a pas d'option d'avoir un fichier par base de données?
UpTheCreek
1
@ UpTheCreek, les tables sont des entités. Les bases de données sont des groupes d'entités logiques, plutôt que des entités à part entière. C'est plus évident avec MyISAM, où les bases de données sont des répertoires et les tables sont des fichiers.
John Gardeniers
Je voulais juste signaler que même si les fichiers .ibd ne rétrécissent pas automatiquement , ni ne ibdata1, l'alternative au fichier par table. Au moins, il est possible de réduire un fichier .ibd en utilisant optimize table, ce qui est trivial par rapport à la réduction de ibdata1.
RomanSt
8

innodb_file_per_table est activé par défaut dans MariaDB.

Alex
la source
1
Pas dans le mien (la version par défaut de CentOS 7). Vous avez besoin de l’équivalent de MySQL 5.6.6 ou plus récent. Sinon, la valeur par défaut est désactivée .
Courses de légèreté avec Monica
2

La raison pour laquelle j’ai choisi de ne pas utiliser innodb_file_per_table, c’est que chaque table est placée dans son propre fichier, ce qui signifie que chaque table reçoit son propre surdébit distinct (signatures de fichier, etc.), ce qui entraîne la taille totale et globale du MySQLrépertoire. plus grand que si vous utilisez un espace de table partagé. De plus, il y a plus d'espace perdu à cause du relâchement des grappes lorsqu'il y a plusieurs petits fichiers au lieu d'un seul et gros.

Certes, les frais généraux supplémentaires ne représentent pas une somme énorme dans le grand schéma, en particulier si vous utilisez un disque volumineux ou avez une base de données géante, mais pour moi (et probablement pour beaucoup d’utilisateurs à domicile), tout s’ajoute et C’était encore trop pour le petit disque avec de gros clusters où je gardais mon magasin MySQL.

Par exemple, mon magasin de base de données avec mes bases de données de WordPress et quelques autres petites bases de données (phpBB, dev, certains tests AMP, etc.), la conversion à table par table a changé de 32 Mo à 50 Mo, et est même pas , y compris le ibdata1qui encore nécessite un minimum de 10 Mo , pour un total d' au moins 60 Mo.

Comme je l'ai dit, cela ne pose peut-être pas trop de problèmes à certaines personnes, en particulier aux entreprises, mais si vous êtes un utilisateur à domicile hébergeant uniquement votre site, votre blog, etc. un fournisseur d’hôte car de nombreux hôtes limitent la taille de votre base de données en plus de l’utilisation totale du disque.

Synetech
la source
1
Je pensais que vous étiez cinglé (qui se soucie de dix mégaoctets ???) jusqu'à ce que vous compreniez le problème des quotas serrés chez les fournisseurs d'hébergement. Je n'aurais jamais pensé à ça.
Dan Pritts
@DanPritts, en particulier des hôtes gratuits. En outre, vous pouvez avoir une commande géante, mais pas tout le monde. J'ai étendu ma partition principale de données de 1 Go à 2 Go au cours de la dernière année car elle était trop étroite, mais même 10 Mo ici et 10 Mo ici (surtout avec les fichiers journaux) peuvent le manger rapidement. De plus, n'oubliez pas que les déchets de grappe s'ajoutent. Enfin, ce n'est même pas nécessairement un disque dur . Par exemple, je suis en train de «portabiliser» mon site Web afin de pouvoir l’héberger depuis n’importe quel système, de sorte qu’un lecteur flash de 2 Go est déjà limité. Par conséquent, il est essentiel de garder les petites tailles et d'éviter les écritures. Et puis il y a les systèmes embarqués!
Synetech
De plus, ce n'est pas 10 Mo (c'est la taille minimum absolue pour IBDATA1). Il est passé de 30 Mo à environ 85 Mo. En supprimant le tout et en important un dump, je me suis retrouvé avec 69 Mo au lieu des 30 Mo précédents (on devine quelle base de données en a occupé plus de la moitié). Pour une raison quelconque, malgré l'utilisation de per-table, mon ibdata1est toujours 18MB. ☹
Synetech
Cela ressemble plutôt à quelque chose que j'avais avec une installation de CMS avec ou sans selinux activé, à en juger par la taille de fichier de 32M vs. 50M. Je ne peux pas vraiment croire aux chiffres. Combien de bases de données avez-vous même dont les métadonnées de fichiers peuvent s’ajouter à la taille de MEGABYTES sur des systèmes identiques?
jeudi
2

Juste pour ajouter un peu plus d'informations

Depuis mysql 5.6.6, il est activé par défaut

PerroVerd
la source
1

avec innodb_file_per_table = 1, la table d’extraction peut être plus lente, voir ici

Alex Zheng
la source
et 'créer une table' peut aussi devenir plus lent. Voir mysql-nordic.blogspot.co.il/2015/02/…
Dror Harari