MySQL implementuje ALTER TABLE
jako ponowne utworzenie tabeli, więc na pewnym etapie procesu w systemie istnieją dwie kopie tabeli. Do tej operacji potrzebujesz ponad 12 GB wolnego miejsca.
Zwolnij trochę miejsca. Alternatywnie skonfiguruj serwer tak, aby używał innego katalogu tymczasowego , gdzie jest wystarczająco dużo miejsca.
Alternatywa dla alternatywy (WHILE
może wymagać zapakowania w procedurę składowaną):
- utwórz nową tabelę (
temp_table
) z nową strukturą - przesyłaj dane w małych partiach z
original_table
dotemp_table
- upuść
original_table
i zmień nazwętemp_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;
Jeśli twoja tabela używa InnoDB, możliwe jest bardziej skomplikowane rozwiązanie z SELECT ... FOR UPDATE;
zamiast zamków stołowych, ale ufam, że wpadłeś na pomysł.