Pourquoi utiliser innodb_file_per_table?

27

Il existe de nombreux articles exagérant (à mon humble avis bien sûr) la nécessité de innodb_file_per_table. Je comprends qu'avec innodb_file_per_table, il devrait y avoir un meilleur contrôle sur les tables individuelles; comme sauvegarder chaque table séparément. Cependant, la revendication d'une meilleure performance est discutable.

Dans mon test, il n'y a pas de différence de performances pour innodb_file_per_tableet ibdata1pour une base de données de 60 Go. Bien sûr, c'était un test simple avec des requêtes normales, et la situation peut être différente pour des requêtes complexes dans la vie réelle (c'est la raison pour laquelle j'ai posé cette question). Linux 64 bits avec ext4peut gérer efficacement les fichiers volumineux.

Avec innodb_file_per_table, plus d'opérations d'E / S disque sont nécessaires; et ceci est important dans les JOINs et les FOREIGN KEYcontraintes compliquées .

L'espace disque logique est partagé sur un seul ibdata; comment des espaces de table dédiés pour des tables distinctes peuvent économiser de l'espace disque? Bien sûr, il est plus facile de libérer de l'espace table pour chaque table ALTER, mais c'est toujours un processus coûteux (avec verrouillage de table).

QUESTION: Est-ce que innodb_file_per_tablea un effet sur une meilleure performance de MySQL? Si oui, pourquoi?

Googlebot
la source
Voir cette réponse à ma question: dba.stackexchange.com/questions/7924/… pourrait aussi aider.
KM.

Réponses:

19

Je ne pense pas que ce soit une question de performance mais de gestion.

Avec un fichier séparé par table, vous pouvez par exemple stocker différentes bases de données dans différents périphériques de stockage.

Vous pouvez traiter le cas de très grandes bases de données dans des systèmes de fichiers qui ne peuvent pas gérer de gros fichiers (au moins reporter le problème jusqu'à ce qu'une table atteigne la limite de taille de fichier).

Vous n'avez pas de croissance d'espace de table incontrôlée. Si vous avez de grandes tables que vous supprimez, le ibdatafichier reste petit.

Un aspect qui peut avoir un certain effet sur les performances est la fragmentation des données de table et des index, qui sera limitée par table. Mais cela nécessite des tests pour être confirmé.

ypercubeᵀᴹ
la source
La croissance de l'espace disque logique est exactement la raison pour laquelle vous le souhaitez innodb_file_per_table.
sjas
13

Pourquoi utiliser innodb_file_per_table?

Parce qu'il est plus facile à gérer individuellement car cela peut être fait au niveau du fichier. Cela signifie que même si le serveur est en panne, vous pouvez toujours copier des données en copiant les fichiers de table tandis que l'utilisation d'un espace table partagé signifie soit copier tout ce qui peut être inutilement massif, soit trouver un moyen de faire fonctionner le serveur pour extraire des données ( vous ne voulez vraiment pas extraire manuellement les données avec un éditeur hexadécimal).

Quelqu'un a averti que vous ne pouvez pas simplement copier et coller des .ibdfichiers d'un serveur à un autre. Cela peut être vrai, mais cela ne devrait pas s'appliquer aux sauvegardes sur le même serveur (j'utilise ici le terme sauvegarde dans le sens traditionnel de faire une copie, c'est-à-dire ne pas changer radicalement le tout). De plus, il ibdata1est automatiquement recréé au démarrage (comme le montre l' étape de suppressionibdata1 de la plupart des guides de «conversion en fichier par table»). En tant que tel, vous n'avez pas besoin de copier ibdata1en plus de vos .ibdfichiers (et leurs .frmfichiers correspondants , etc.).

Si vous essayez de récupérer une table perdue, il devrait être suffisant de copier ses fichiers .ibdet .frm, ainsi que information_schema(ce qui est beaucoup plus petit que ibdata1). De cette façon, vous pouvez les mettre dans un serveur factice et extraire votre table sans avoir à copier le tout, chose massive.

Cependant, la revendication d'une meilleure performance est discutable. … Avec innodb_file_per_table, davantage d'opérations d'E / S disque sont nécessaires; et cela est important dans les contraintes complexes JOINs et FOREIGN KEY.

Sans surprise, les performances dépendront entièrement de la ou des bases de données spécifiques utilisées. Une personne aura (même considérablement) des résultats différents d'une autre.

Il est vrai qu'il y aura plus d'opérations d'E / S disque avec fichier par table, mais seulement légèrement plus. Pensez au fonctionnement du système.

  • Pour une base de données monolithique:

    1. Le serveur est démarré
    2. ibdata1 est ouvert
    3. L'en-tête et les métadonnées sont lus
    4. Les structures et les métadonnées sont mises en cache en mémoire
    5. Les requêtes arrivent
      1. Le serveur accède au disque et lit les données depuis le dossier déjà ouvert ibdata1
      2. Le serveur peut mettre en cache les données en mémoire
  • Pour une base de données par table:

    1. Le serveur est démarré
    2. ibdata1 est ouvert
    3. L'en-tête et les métadonnées sont lus
    4. Chaque .ibddossier individuel est ouvert
    5. L'en-tête et les métadonnées sont lues à partir de chaque .ibdfichier
    6. Les structures et les métadonnées sont mises en cache en mémoire
    7. Les requêtes arrivent
      1. Le serveur accède au disque et lit les données du .ibdfichier déjà ouvert
      2. Le serveur peut mettre en cache les données en mémoire

Vous remarquerez que lorsque le serveur est en cours d'exécution, vous ne pouvez pas déplacer les fichiers de données car le serveur a des poignées ouvertes vers eux. En effet, quand il démarre, il les ouvre et les laisse ouverts. Il ne les ouvre et ne les ferme pas pour chaque requête individuelle.

En tant que tel, il n'y a que quelques opérations d'E / S supplémentaires au début, lorsque le serveur démarre; pas pendant qu'il fonctionne. De plus, bien que chaque .ibdfichier individuel ait sa propre surcharge distincte (signatures de fichiers, structures, etc.), ils sont mis en cache en mémoire et ne sont pas relus pour chaque requête. De plus, les mêmes structures sont lues même avec un espace table partagé, donc il n'y a pratiquement pas (voire pas du tout) de mémoire supplémentaire requise.

Innodb_file_per_table a-t-il un effet sur une meilleure performance de mysql?

En fait, si quoi que ce soit, la performance peut en fait être pire .

Lorsque vous utilisez un espace table partagé, les opérations de lecture et d'écriture peuvent parfois / souvent être combinées de sorte que le serveur lit un échantillon de données de plusieurs tables en une seule fois ibdata.

Cependant, si les données sont réparties sur plusieurs fichiers, il doit alors effectuer une opération d'E / S distincte pour chacun individuellement.

Bien sûr, cela dépend à nouveau entièrement de la base de données en question; l'impact sur les performances réelles dépendrait de la taille, de la fréquence des requêtes et de la fragmentation interne de l'espace table partagé. Certaines personnes peuvent remarquer une grande différence tandis que d'autres ne voient aucun impact.

L'espace disque logique est partagé sur des ibdata uniques; comment des espaces de table dédiés pour des tables séparées peuvent économiser de l'espace disque?

Ce ne est pas. Si quoi que ce soit, cela augmente l'utilisation du disque.

Je n'ai pas de base de données de 60 Go pour tester, mais ma base de données personnelle «dérisoire» qui contient mon installation WordPress et quelques petites tables pour un usage personnel et des tests de développement pesait environ 30 Mo tout en utilisant un espace table partagé. Après l'avoir converti en fichier par table, il a gonflé à ~ 85 Mo. Même en supprimant tout et en réimportant, c'était toujours> 60 Mo.

Cette augmentation est due à deux facteurs:

  • La taille minimale absolue pour ibdata1est, pour une raison quelconque, de 10 Mo, même si vous n'y avez rien d'autre que information_schemastocké.

  • Avec un espace table partagé, ibdata1n'a que des frais généraux comme les signatures de fichiers, les métadonnées, etc., mais avec chaque table, chaque .ibdfichier individuel a tout cela. Cela signifie que le total (même avec une hypothétique <10 Mo ibdata1) serait un peu plus élevé d'au moins:

    GetTotalSizeofOverhead() * GetNumTables()

Évidemment, ces augmentations ne vont pas être énormes (sauf si vous utilisez un hôte qui limite la taille de votre base de données ou les stockez sur un lecteur flash, etc.), mais elles augmentent néanmoins, et tout en basculant ( chaque ) table vers un fichier -par table, vous pouvez réduire ibdata1à 10 Mo, le total global sera toujours plus qu'il ne l'était.

Synetech
la source
11

C'est ma raison pour TOUJOURS utiliser innodb_file_per_table:

Sans fichier par table, le fichier ibdata ne compresse, ne rétrécit ou ne diminue jamais dans l'espace. Pas lorsque vous supprimez une ligne, supprimez une table ou une base de données. 2 Go de données peuvent devenir un fichier de 20 Go en un rien de temps si vous disposez d'un système de mise en file d'attente actif.

Supposons que vous souhaitiez effectuer une sauvegarde de votre table actuelle de 1 Go avant une modification, puis la supprimer ensuite. Vous êtes coincé avec un Go d'espace désormais inutilisé dans votre ibdata. Bummer.

Il existe probablement d'innombrables exemples de cas où des mesures temporaires gonflent le fichier de données unique, mais il suffit de dire qu'à mon avis, il n'y a jamais de raison de NE PAS utiliser innodb_file_per_table

En outre, voici un bon article à lire: http://code.openark.org/blog/mysql/reasons-to-use-innodb_file_per_table

randomx
la source
1
J'ai réalisé que c'était toujours bien de le faire aussi. Les baies de stockage magnétiques soutenues par des disques SSD peuvent gérer plus efficacement les caches de lecture / écriture contre des fichiers plus petits pour les tables. Pour un tas de tables qui% 99,99 du temps sont simplement lues mais non écrites, elles sont toujours dans le cache du contrôleur de stockage, ce qui représente une grande réduction du temps de réponse.
sdkks
5

Ma raison de ne pas utiliser innodb_file_per_table est la performance.

J'ai fait quelques tests pour notre base de données avec 450 tables sur mysql 5.5.45 Linux CentOS version 6.7

Pour les tests unitaires qui insèrent des appareils dans la base de données avant chaque test (n'utilisant pas toutes les tables à chaque fois) et les tests eux-mêmes fonctionnent beaucoup avec la base de données (insertions, mise à jour, suppressions, sélections), les performances étaient 3 à 5 fois meilleures lorsque les tables de base de données n'étaient pas séparés en plusieurs fichiers.

Je recommande de tester votre base de données avec les requêtes que vous souhaitez utiliser et de la comparer avant de décider d'utiliser innodb_file_per_table

Vous pouvez peut-être découvrir que pour le serveur de production, vous pouvez utiliser innodb_file_per_table mais pour l'environnement CI (continue l'intégration) qui démarre les tests unitaires (utilise beaucoup DB) et aussi les développeurs qui commencent beaucoup les tests unitaires est préférable de ne pas l'utiliser en raison des performances.

Tomor
la source
2
Je suppose que cela est dû au temps nécessaire pour allouer les fichiers initiaux pour les 450 tables par rapport à l'allocation d'un seul fichier. En production, cela ne se produira qu'une seule fois, donc cela ne devrait pas être un problème, mais vous faites valoir que pour créer rapidement une base de données, puis la détruire complètement et la répéter encore et encore sur un seul fichier ibdata est préférable.
ColinM
2

Cela rend les données plus faciles à gérer car vous pouvez récupérer de l'espace inutilisé, ce qui est bien.

Je pense que si votre base de données est utilisée principalement pour certaines requêtes, cela n'affectera pas beaucoup les performances. Il doit toujours lire la même quantité de données. Je ne pense pas que les fichiers dont il lit les données importent beaucoup.

Cependant, cela peut aggraver les performances sur une base de données qui effectue de nombreuses insertions et mises à jour. En effet, mysql appelle fsync () sur le fichier de stockage après avoir validé une transaction. S'il n'y a qu'un seul fichier, il passe un appel et attend que l'appel se termine. S'il y a beaucoup de fichiers, il doit effectuer l'appel plusieurs fois et attendre que tous ces appels reviennent avant que la commande commit ne puisse revenir.

Voici un article d'une personne qui a rencontré ce problème: http://umangg.blogspot.com/2010/02/innodbfilepertable.html

Sarel Botha
la source
2

Selon l'article ci-dessous, les performances ne concernent pas la gestion des données (opérations crud elles-mêmes) mais plutôt la création et la suppression d'objets.

innodb_file_per_table rend la création massive et la suppression d'objets plus lentes que le stockage ibdata et pour la production n'est pas applicable mais pour un test continu devrait être pertinent.

https://www.percona.com/blog/2015/02/24/mysqls-innodb_file_per_table-slowing/

Flavio Peinado
la source