web-dev-qa-db-fra.com

MySql - changer innodb_file_per_table pour une base de données live

J'ai une grande base de données MySql (150 Go) et seulement maintenant, j'ai remarqué que le innodb_file_per_table est défini sur off, ce qui fait que la base de données entière est hébergée sur un seul fichier (ibdata1). Je veux activer innodb_file_per_table et la diviser rétroactivement en plusieurs fichiers, quelle est la meilleure façon de procéder?

19
Ran

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 le [mysqld] titre, démarrez 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

[~ # ~] mise en garde [~ # ~] : pour supprimer totalement les transactions non validées des fichiers InnoDB, exécutez cette

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 extraira 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.

32
RolandoMySQLDBA

Si vous voulez 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 voulez simplement réduire vos pertes et "perdre" ces 150 Go sur le disque dur, vous pouvez simplement activer innodb_file_per_table dans my.cnf et redémarrez votre serveur.

Ensuite, pour chaque table, lancez:

ALTER TABLE x DISABLE KEYS;
ALTER TABLE x ENGINE=InnoDB;
ALTER TABLE x ENABLE KEYS; 

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.

5
Derek Downey