MySQL implementa
ALTER TABLE
como uma recriação de tabela, portanto, duas cópias da tabela existem no sistema em algum estágio durante o processo. Você precisará de mais de 12 GB de espaço livre para esta operação. Liberte algum espaço. Como alternativa, defina seu servidor para usar um diretório temporário diferente , onde há espaço suficiente.
Alternativa à alternativa (o
WHILE
pode precisar ser encapsulado em um procedimento armazenado):- criar uma nova tabela (
temp_table
) com a nova estrutura - transfira dados em pequenos lotes de
original_table
emtemp_table
- solte
original_table
e renomeietemp_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 sua tabela usa InnoDB, uma solução mais elaborada é possível com
SELECT ... FOR UPDATE;
em vez de fechaduras de mesa, mas acredito que você entendeu a ideia.