J'ai une table InnoDB de 700 Go dans laquelle je n'écris plus de données (lecture uniquement). Je voudrais supprimer les anciennes données qu'il contient et récupérer cet espace disque (car j'en manque). La partie de suppression est assez facile, car j'ai un index primaire auto-inc afin que je puisse simplement itérer en morceaux en l'utilisant et supprimer les lignes, mais cela ne me ramènera pas l'espace. Je suppose OPTIMIZE TABLE
que oui, mais cela pourrait prendre une éternité sur une table de 700 Go, alors y a-t-il une autre option que je néglige?
Édité par RolandoMySQLDBA
En supposant que votre table est mydb.mytable
, veuillez exécuter la requête suivante et la publier ici afin que vous puissiez déterminer l'espace disque requis pour la réduction de la table:
SELECT
FORMAT(dat/POWER(1024,3),2) datsize,
FORMAT(ndx/POWER(1024,3),2) ndxsize,
FORMAT((dat+ndx)/POWER(1024,3),2) tblsize
FROM (SELECT data_length dat,index_length ndx
FROM information_schema.tables WHERE
table_schema='mydb' AND table_name='mytable') A;
Nous devons également voir la structure de la table, si cela est autorisé.
Édité par Noam
Voici la sortie de la requête:
datsize ndxsize tblsize
682.51 47.57 730.08
Ceci est la structure de la table ( SHOW CREATE TABLE
)
`CREATE TABLE `mybigtable` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`uid` int(11) NOT NULL,
`created_at` datetime NOT NULL,
`tid` bigint(20) NOT NULL,
`text` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`ft` tinyint(1) NOT NULL,
`irtsd` bigint(20) NOT NULL,
`irtuid` int(11) NOT NULL,
`rc` int(11) NOT NULL,
`r` tinyint(1) NOT NULL,
`e` text CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, `timezone` varchar(5) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `uid_tid` (`uid`,`tid`)) ENGINE=InnoDB AUTO_INCREMENT=2006963844 DEFAULT CHARSET=utf8`
ALTER TABLE ... ENGINE=InnoDB;
(si vous avez la place pour le faire). La plupart sont simplement satisfaits de leurs SSD très rapides et ne s'inquiéteraient plus.Réponses:
C'est une bonne question. Vous avez plusieurs solutions mais votre table est assez grande donc aucune ne sera sans douleur :)
Vous avez trois solutions pour "réduire" les tables InnoDB:
1. OPTIMISER LE TABLEAU
Vous pouvez utiliser
OPTIMIZE TABLE
comme vous l'avez mentionné, mais vous devez vous soucier de lainnodb_file_per_table
variable:Laissez-moi expliquer:
Le
OPTIMIZE TABLE
whith tables InnoDB, verrouille la table, copiez les données dans une nouvelle table propre (c'est pourquoi le résultat est réduit), supprimez la table d'origine et renommez la nouvelle table avec le nom d'origine. C'est pourquoi vous devriez vous soucier d'avoir le double de la volumétrie de votre table disponible sur votre disque (pendant le fonctionnement, vous aurez besoin de 2x700 Go).Lorsque vous êtes dans le innodb_file_per_table = ON. Toutes les tables ont leur propre fichier de données. Donc, l'
OPTIMIZE
instruction créera un nouveau fichier de données (~ 700 Go) lorsque l'opération sera terminée, MySQL supprimera l'original et renommera le nouveau (donc à la fin, les 700 Go - probablement moins car ils seront réduits - de données généré pendant l'opération sera publié)Lorsque vous êtes dans le innodb_file_per_table = OFF. Toutes les données vont dans un seul fichier de données: ibdata . Ce fichier a une triste particularité, il ne peut pas être réduit. Ainsi, au cours du
OPTIMIZE
processus, votre nouvelle table sera créée (près de 700 Go), mais même après l'opération de suppression et de changement de nom (et la fin de laOPTIMIZE
phase), votre ibdata ne libérera pas les ~ 700 Go, donc vous vouliez libérer des données mais vous avez 700 Go en plus, non?2. ALTER TABLE
Vous pouvez également utiliser une
ALTER TABLE
instruction, leALTER TABLE
fonctionnera de la même manière queOPTIMIZE TABLE
. Vous pouvez simplement utiliser:3. ALTER TABLE (EN LIGNE)
Le problème de
OPTIMIZE
etALTER TABLE
qu'il verrouille la table pendant le fonctionnement. Vous pouvez utiliser l'outil Percona: pt-online-schema-change (depuis Percona Toolkit: lien ). pt-online-schema ... construira un mécanisme avec des déclencheurs et une table temporaire que vous permettez à la table d'origine d'être disponible pour la lecture et l'écriture pendant l'opération. J'utilise cet outil en production pour le grosALTER
c'est assez cool.Notez que vous devriez avoir fait
FOREIGN KEY
référence à votre table, FK et les déclencheurs risquent de produire un gâchis. Pour vérifier ces conditions préalables, interrogez:Voici comment j'utilise pt-online-schema-change:
Notez que ma note sur innodb_file_per_table est également vraie pour cette solution.
4. mysqldump
La dernière solution consiste à recréer toutes les bases de données à partir d'un vidage. Terriblement long, mais terriblement efficace. Notez que c'est la seule solution pour "réduire" le fichier ibdata.
Max.
la source
Si vous manquez de taille de disque, je vous suggère de faire comme Max suggéré avec pt-online-schema-change (ONLINE). J'ai été dans la même situation avec une table beaucoup plus petite (200 Go) et j'ai choisi de faire de la compression en même temps. Quelque chose dans le sens de cela devrait fonctionner:
Cela ne fonctionnera que si vous êtes au format de fichier barracuda et au format COMPACT de la table. Vous devez également activer innodb_file_per_table. Cela peut faire des merveilles sur la taille de votre tableau, surtout s'il y a beaucoup de texte et si vous utilisez des KEY_BLOCK_SIZE plus petits tels que 8K ou même 4K (la valeur par défaut est 16K). Vous pouvez également vérifier combien d'espace vous pouvez gagner à partir de plusieurs benchmarks concernant ce problème sur d'autres blogs, mais la documentation MySQL annonce 25% à 50% (c'était presque 90% pour moi).
Notez que cela peut également affecter les performances lors de l'exécution de SELECT (à partir de la documentation MySQL):
MySQL doit également décompresser les données lorsqu'il n'est pas dans le pool de tampons. Soyez donc prévenu.
Cela a vraiment bien fonctionné dans mon cas. J'avais un long texte. 200 Go sont devenus 26 Go. Les performances n'ont pas été modifiées.
Pour plus d'informations en profondeur, consultez ces liens:
https://dev.mysql.com/doc/refman/5.5/en/innodb-compression-usage.html
https://dev.mysql.com/doc/refman/5.5/en/innodb-compression-internals.html
la source