MySQL implémente ALTER TABLE
comme une recréation de table, donc deux copies de la table existent sur le système à un certain stade du processus. Vous aurez besoin de plus de 12 Go d'espace libre pour cette opération.
Libérez de l'espace. Sinon, configurez votre serveur pour qu'il utilise un répertoire temporaire différent , où il y a suffisamment d'espace.
Alternative à l'alternative (le WHILE
peut avoir besoin d'être encapsulé dans une procédure stockée) :
- créer une nouvelle table (
temp_table
) avec la nouvelle structure - transférer des données par petits lots depuis
original_table
danstemp_table
- supprimer
original_table
et renommeztemp_table
-- useful only if concurrent access is allowed during migration
LOCK TABLES original_table WRITE, temp_table WRITE;
SELECT COUNT(*) INTO @anythingleft FROM original_table;
WHILE @anythingleft DO
-- transfer data
INSERT INTO temp_table
SELECT
original_table.old_stuff,
"new stuff"
FROM original_table
ORDER BY any_sortable_column_with_unique_constraint -- very important!
LIMIT 1000; -- batch size, adjust to your situation
DELETE FROM original_table
ORDER BY any_sortable_column_with_unique_constraint
LIMIT 1000; -- ORDER BY and LIMIT clauses MUST be exactly the same as above
SELECT COUNT(*) INTO @anythingleft FROM original_table;
END WHILE;
-- delete, rename
DROP TABLE original_table;
UNLOCK TABLES;
RENAME TABLE old_table TO original_table;
Si votre table utilise InnoDB, une solution plus élaborée est possible avec SELECT ... FOR UPDATE;
au lieu de verrous de table, mais j'espère que vous avez saisi l'idée.