MySQL implementa ALTER TABLE
come una ricreazione della tabella, quindi nel sistema esistono due copie della tabella in una fase durante il processo. Avrai bisogno di oltre 12 GB di spazio libero per questa operazione.
Libera un po' di spazio. In alternativa, imposta il tuo server per utilizzare una directory temporanea diversa , dove c'è abbastanza spazio.
Alternativa all'alternativa (il WHILE
potrebbe essere necessario eseguire il wrapping in una stored procedure):
- crea una nuova tabella (
temp_table
) con la nuova struttura - trasferisci i dati in piccoli lotti da
original_table
intemp_table
- rilascia
original_table
e rinominatemp_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;
Se la tua tabella utilizza InnoDB, è possibile una soluzione più elaborata con SELECT ... FOR UPDATE;
invece dei lucchetti da tavolo, ma spero che tu abbia un'idea.