Quel est le meilleur moyen de réduire la taille d’ibdata dans mysql?


63

J'ai des serveurs de production dont la ibdatataille des fichiers augmente de jour en jour.

Il a déjà consommé 290 Go d'espace.

Les tables dans les serveurs sont principalement InnoDB et il y a beaucoup de demandes de lecture et d'écriture.

La taille du fichier journal augmente également. Il y a une quantité énorme de données dans les tableaux.

Comment puis-je contrôler la taille croissante des deux?

Je n'utilise pas innodb_file_per_table.

Réponses:


104

Gardez à l'esprit que le fichier le plus occupé de l'infrastructure InnoDB est / var / lib / mysql / ibdata1.

Ce fichier contient normalement de nombreuses classes d'informations (quand innodb_file_per_table vaut 0)

  • Données de la table
  • Index de table
  • Données MVCC (Multiversioning Concurrency Control)
    • Rollbacks Segments
    • Annuler le tablespace
  • Métadonnées de table
  • Voir la représentation illustrée

De nombreuses personnes créent plusieurs fichiers ibdata dans l'espoir d'améliorer la gestion et les performances de l'espace disque. Cela n'aide pas.

Malheureusement, OPTIMIZE TABLE par rapport à une table InnoDB stockée dans ibdata1 fait deux choses:

  • Rend les données et les index de la table contigus dans ibdata1
  • Cela fait grossir ibdata1 parce que les données contiguës sont ajoutées à ibdata1

Vous pouvez séparer les données de table et les index de table de ibdata1 et les gérer indépendamment à l'aide de innodb_file_per_table . Pour réduire ibdata1 une fois pour toutes, vous devez procéder comme suit:

Étape 01) MySQLDump toutes les bases de données dans un fichier texte SQL (appelez-le SQLData.sql) ( Plus de détails ici )

Étape 02) Supprimez toutes les bases de données (sauf mysql, performance_schemaet information_schema)

Etape 03) Arrêtez 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

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) Supprimer ibdata1, ib_logfile0 et ib_logfile1

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

Etape 06) Redémarrez mysql

Cela recréera ibdata1 à 10 Mo, ib_logfile0 et ib_logfile1 à 1G chacun

Étape 07) Recharger SQLData.sql dans mysql

ibdata1 augmentera mais ne contiendra que des métadonnées de table

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 (Accueil de la table de données et index de table pour mydb.mytable)

ibdata1 ne contiendra plus jamais de données InnoDB ni d'index.

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

Je l'ai fait plusieurs fois dans ma carrière en tant que DBA MySQL

En fait, la première fois que j'ai fait cela, j'ai compressé un fichier ibdata1 de 50 Go en 500 Mo.

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

Si vous souhaitez voir combien de données réelles sont stockées dans MyISAM et InnoDB, veuillez lancer la requête suivante:

SELECT IFNULL(B.engine,'Total') "Storage Engine",
CONCAT(LPAD(REPLACE(FORMAT(B.DSize/POWER(1024,pw),3),',',''),17,' '),' ',
SUBSTR(' KMGTP',pw+1,1),'B') "Data Size", CONCAT(LPAD(REPLACE(
FORMAT(B.ISize/POWER(1024,pw),3),',',''),17,' '),' ',
SUBSTR(' KMGTP',pw+1,1),'B') "Index Size", CONCAT(LPAD(REPLACE(
FORMAT(B.TSize/POWER(1024,pw),3),',',''),17,' '),' ',
SUBSTR(' KMGTP',pw+1,1),'B') "Table Size"
FROM (SELECT engine,SUM(data_length) DSize,SUM(index_length) ISize,
SUM(data_length+index_length) TSize FROM information_schema.tables
WHERE table_schema NOT IN ('mysql','information_schema','performance_schema')
AND engine IS NOT NULL GROUP BY engine WITH ROLLUP) B,
(SELECT 3 pw) A ORDER BY TSize;

Même avec les paramètres suggérés pour my.cnf (que j'ai déjà), en supprimant ib_logfile0 et 1, puis en démarrant mysql, les nouveaux fichiers sont créés et en quelques secondes, ils atteignent la taille de la base de données affichée par votre requête précédente. Vous ne savez pas si mysql copie toutes les tables et tous les index dans ces fichiers tout en conservant chaque table dans un fichier séparé.
Allen King le
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.