A técnica a seguir, que estou prestes a mostrar, exigirá tripas de aço.
Dados os seguintes critérios
- datadir é
/var/lib/mysql
- mesa é
mydb.mytb
- coluna enum chamada é chamada
enum_col
- engine is MyISAM
Aqui está uma rachadura que desafia a morte:
CREATE TABLE mydb.mybt LIKE mydb.mytb;
ALTER TABLE mydb.mybt MODIFY enum_col ENUM('First value','Second value');
SET wait_timeout=86400; SET interactive_timeout=86400;
FLUSH TABLES WITH READ LOCK;
Em uma sessão OS / SSH separada, troque os arquivos .frm
$ mv /var/lib/mysql/mydb/mytb.frm /var/lib/mysql/mydb/myxx.frm
$ mv /var/lib/mysql/mydb/mybt.frm /var/lib/mysql/mydb/mytb.frm
$ mv /var/lib/mysql/mydb/myxx.frm /var/lib/mysql/mydb/mybt.frm
UNLOCK TABLES;
DROP TABLE mydb.mybt;
É isso aí !!!
CAVEAT: NÃO POSSO TER CRÉDITO POR ISSO!
Essa técnica vem de "MySQL de alto desempenho: otimização, backups, replicação e muito mais", páginas 146-148 no subtítulo Acelerando a tabela ALTER TABLE . O parágrafo 1 diz:
A técnica que estamos prestes a demonstrar não é suportada, não documentada e pode não funcionar. Use-o por sua conta e risco. Aconselhamos que você faça backup dos seus dados primeiro!
De uma chance ! (Por favor, deixe-nos saber como ficou)
UPDATE 2011-10-05 17:49 EDT
Se a tabela for MyISAM e você tiver espaço suficiente na produção e uma janela de tempo de inatividade direta, tente o seguinte:
service mysql restart --skip-networking
Em uma sessão OS / SSH separada, faça uma cópia da tabela
cp /var/lib/mysql/mydb/mytb.frm /var/lib/mysql/mydb/mytbplay.frm
cp /var/lib/mysql/mydb/mytb.MYD /var/lib/mysql/mydb/mytbplay.MYD
cp /var/lib/mysql/mydb/mytb.MYI /var/lib/mysql/mydb/mytbplay.MYI
INFORMATION_SCHEMA.TABLES
detectará automaticamente a presença da nova tabela chamada mydb.mytbplay
.
Execute o algoritmo de tripas de aço em mydb.mytbplay
Você testa a integridade de mydb.mytbplay
Se você está satisfeito
ALTER TABLE mydb.mytb RENAME mydb.mytb_backup;
ALTER TABLE mydb.mytbplay RENAME mydb.mytb;
service mysql restart
De uma chance!