Il n'y a vraiment qu'une seule façon d'y parvenir. Vous devrez exporter les données à l'aide de mysqldumps, supprimer toutes les bases de données, arrêter mysqld, supprimer ib_logfile0, supprimer ib_logfile1, supprimer ibdata1, ajouter innodb_file_per_table
sous l'en- [mysqld]
tête, démarrer mysql.
J'ai posté cette réponse dans StackOverflow en octobre 2010
Voici les étapes répertoriées verticalement:
É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 le schéma mysql)
Étape 03) Arrêtez mysql
CAVEAT : pour nettoyer totalement les transactions non validées des fichiers InnoDB, exécutez ce
mysql -uroot -p... -Ae"SET GLOBAL innodb_fast_shutdown = 0;"
service mysql stop
É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
Sidenote: Quel que soit votre ensemble pour innodb_buffer_pool_size, assurez-vous que innodb_log_file_size représente 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
Étape 06) Redémarrez mysql
Cela va recréer ibdata1 à 10 Mo, ib_logfile0 et ib_logfile1 à 1G chacun
Étape 07) Rechargez SQLData.sql dans mysql
ibdata1 augmentera mais ne contiendra que des métadonnées de table
Chaque table InnoDB existera en dehors d'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 du moteur de stockage)
- mytable.ibd (Accueil des données de table et des index de table pour mydb.mytable)
ibdata1 ne contiendra plus de données et d'index InnoDB.
Avec l'option innodb_file_per_table dans /etc/my.cnf, vous pouvez exécuter OPTIMIZE TABLE mydb.mytable et le fichier /var/lib/mysql/mydb/mytable.ibd se réduira réellement.
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 réduit 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. !!!
Il existe une alternative qui extrait la table InnoDB sans rétrécir ibdata1.
Étape 01) 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
Étape 02) service mysql restart
Étape 03) Pour extraire une seule table InnoDB appelée mydb.mytable, procédez comme suit:
ALTER TABLE mydb.mytable ENGINE=InnoDB;
Cela va créer un fichier pleus garder le fichier de structure d'origine
- /var/lib/mysql/mydb/mytable.frm
- /var/lib/mysql/mydb/mytable.ibd
Vous pouvez le faire pour chaque table InnoDB. Malheureusement, ibdata1 restera 150 Go.
ERROR 1071 (42000) at line 25: Specified key was too long; max key length is 1000 bytes
des idées?innodb_file_per_table
puis effectuez laALTER TABLE
sur chaque table, pouvez-vous supprimer le fichier ibdata1 pour récupérer l'espace sans avoir à restaurer?Si vous souhaitez récupérer l'espace d'ibdata, un vidage / restauration est votre seul choix, comme le souligne Rolando . Il est également préférable que les performances le fassent.
Cependant, si vous souhaitez simplement réduire vos pertes et «perdre» ces 150 Go sur le disque dur, vous pouvez simplement activer
innodb_file_per_table
le fichier my.cnf et redémarrer votre serveur.Ensuite, pour chaque table, lancez:
Le problème ici est que les grands espaces de table prendront un certain temps.
Ce que je suggérerais, c'est de configurer un esclave de votre base de données en direct, d'exécuter la conversion sur l'esclave, puis d'éteindre le maître / esclave et de copier le nouvel espace de données sur le maître, ou de promouvoir l'esclave pour qu'il soit maître une fois qu'il a rattrapé le retard. .
Vous allez avoir du mal à effectuer ce changement sans aucun temps d'arrêt.
la source