Linhas ausentes após a conversão online do MyISAM para o InnoDB

16

Temos um banco de dados razoavelmente pequeno que queríamos converter do MyISAM para o InnoDB. Sendo noobs de banco de dados, acabamos de converter (usando alter table) sem sequer derrubar o site.

Agora que a conversão está concluída, muitas linhas intermitentes parecem estar ausentes. Isso possivelmente ocorre devido a operações durante a conversão? Ou a questão está em outro lugar?

Yuvi
fonte
Quais tabelas estão faltando linhas? Os que você converteu ou outras tabelas?
longneck

Respostas:

20

A execução de um ALTER para alterar os mecanismos de armazenamento não fará com que as linhas desapareçam. No entanto, deixe-me oferecer alguns conselhos, pois você disse que é 'noobs do banco de dados' na sua pergunta.

Ao modificar o esquema existente ou fazer qualquer coisa que possa afetar os dados, aqui estão alguns conselhos básicos:

  1. Faça um backup primeiro.
  2. Tenha um plano de mudança.
  3. Teste seu plano em um host offline.
  4. Tenha um plano de teste para comparar dados anteriores e posteriores.
  5. Programe e faça um tempo de inatividade.
  6. Faça um backup e uma captura instantânea imediatamente após o tempo de inatividade entrar em vigor e verificar se o tráfego parou.
  7. Se você estiver executando o MYISAM, use 'CHECK TABLE' para avaliar com o que está lidando antes de ALTERAR.
  8. Copie a tabela localmente, além do seu backup, apenas por precaução.
  9. Prossiga com cuidado, ative "--show warnings" e outras saídas para ter uma imagem completa ao fazer as alterações.
  10. Se os dados forem importantes para você, contrate um DBA, mesmo que seja apenas para consultar durante a migração, para que você tenha um veterano experiente ao seu lado.

Provavelmente há muito mais em que eu poderia entrar, mas as opções acima fornecerão opções quando algo der errado.

No que diz respeito aos dados / linhas ausentes, não há como saber se há um snapshot "antes / depois" para comparar. Você pode comparar com o backup mais recente para verificar pelo menos isso.

randomx
fonte
Eu li isso. Bom plano de recuperação de desastres. Sua resposta recebe +1 por ser mais sensível à pergunta do que eu, além de um plano daqui para frente.
RolandoMySQLDBA 28/08
11
@randy Marcado isso como questão favorito por causa de sua boa resposta
techexplorer
8

Uma das melhores maneiras de converter o MyISAM para o InnoDB sem muito tempo de inatividade tem apenas um pré-requisito: Use um escravo de replicação.

Aqui está uma visão geral do plano

  1. Criar configuração de mestre de replicação / escravo
  2. Converta todas as tabelas MyISAM do escravo em InnoDB
  3. Aponte seu aplicativo para o Escravo

Parece simples? Há muitos detalhes por trás disso.

Criar configuração de mestre de replicação / escravo

Existe uma maneira elegante de criar um Escravo sem muita perturbação para o Mestre. Eu escrevi dois posts:

Em vez de detalhar como usar o rsync, leia essas duas postagens.

Converta todas as tabelas MyISAM do escravo em InnoDB

No DB Slave, você pode a seguinte instrução SQL:

Para o MySQL 5.5:

SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;')
FROM information_schema.tables
WHERE engine = 'MyISAM' AND table_schema NOT IN
('information_schema','mysql','performance_schema');

Versão para MySQL anterior ao MySQL 5.5

SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;')
FROM information_schema.tables
WHERE engine = 'MyISAM' AND table_schema NOT IN
('information_schema','mysql');

Usando a saída da consulta, você tem um script de conversão para o escravo.

Você deve colocar essas duas linhas na parte superior do script:

SET SQL_LOG_BIN = 0;
STOP SLAVE;

O script primeiro desabilitará o registro binário (se você configurou o escravo para ter registros binários), interromperá a replicação e converterá cada tabela MyISAM em InnoDB.

Aqui está como criar esse script e executá-lo:

SQLSTMT="SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;') FROM information_schema.tables WHERE engine = 'MyISAM' AND table_schema NOT IN ('information_schema','mysql','performance_schema')"
INNODB_CONV_SCRIPT=MassConvertMyISAMTablesToInnoDB.sql
echo "SET SQL_LOG_BIN = 0;" > ${INNODB_CONV_SCRIPT}
echo "STOP SLAVE;" >> ${INNODB_CONV_SCRIPT}
mysql -h(IP of Master) -u... -p... --skip-column-names -A -e"${SQL}" >> ${INNODB_CONV_SCRIPT}
echo "START SLAVE;" >> ${INNODB_CONV_SCRIPT}
mysql -h(IP of Slave) -u... -p... --skip-column-names -A < ${INNODB_CONV_SCRIPT}

Aponte seu aplicativo para o Escravo

Execute consultas SELECT do escravo. Se você estiver satisfeito com o conteúdo dos dados no Escravo, sinta-se à vontade para apontar seu aplicativo para o escravo da seguinte maneira:

  1. No Escravo, execute SHOW SLAVE STATUS\Ge verifique se Seconds_Behind_Master é 0
  2. No Slave, mysqldump -h (IP do Slave) -u ... -p ... - única transação - rotinas - gatilhos - todos os bancos de dados> MySQLBackup.sql (Ei, um backup seria bom sobre Agora)
  3. No Master, execute service mysql stop(o tempo de inatividade é iniciado)
  4. Repita a etapa 1
  5. Aponte seu aplicativo para o Escravo (o tempo de inatividade termina na primeira conexão do aplicativo)

Se você chegou a esse ponto ileso, PARABÉNS !!!

BÔNUS ADICIONADOS : Se você configurar a Replicação Mestre / Mestre (também conhecida como Replicação Circular) em vez de Mestre / Escravo, poderá fazer isso:

  1. No Escravo, execute SHOW SLAVE STATUS\Ge verifique se Seconds_Behind_Master é 0
  2. No Slave, mysqldump -h (IP do Slave) -u ... -p ... - única transação - rotinas - gatilhos - todos os bancos de dados> MySQLBackup.sql (Ei, um backup seria bom sobre Agora)
  3. Aponte seu aplicativo para o Escravo (o tempo de inatividade inicia e termina na primeira conexão do aplicativo)
  4. No novo mestre, execute STOP SLAVE;
  5. No novo mestre, execute CHANGE MASTER TO MASTER_HOST='';

O que você tem agora é Mestre / Escravo ao contrário. O novo mestre possui dados do InnoDB e o antigo mestre agora é escravo dos dados do MyISAM. Se você dividir leituras e gravações, as leituras podem ir do escravo (as leituras são mais rápidas do MyISAM do que o InnoDB) e as gravações vão para o mestre (suporte transacional para o InnoDB). Como Hannah Montana canta, você obtém o melhor dos dois mundos (sim, eu tenho duas filhas que amam o show) !!!

OUTRO BÔNUS ADICIONADO : Como o Master agora é InnoDB, você pode executar o mysqldump do Master sem tempo de inatividade e sem interferir nas transações. A única desvantagem é aumentar a E / S da CPU e do disco. Você pode, portanto, fazer um mysqldump de estruturas de tabela apenas no Master (InnoDB) e um mysqldump dos dados apenas no slave (Esse dump não terá referências ao InnoDB ou MyISAM. Serão apenas dados) mais um mysqldump do estruturas de tabela para o escravo ter o layout MyISAM.

As possibilidades podem continuar por causa desta nova configuração ...

UPDATE 2011-08-27 19:50 EDT

Me desculpe. Eu não li completamente a pergunta. Você já realizou a conversão .

Somente se você já tiver o log binário ativado e tiver um backup anterior, poderá

  • restaure / var / lib / mysql para outro local, como / var / lib / mysql2
  • corre service mysql stop
  • corre service mysql start --datadir=/var/lib/mysql2
  • mysqldump o banco de dados desse backup para /root/olddata.sql
  • execute o mysqlbinlog em todos os logs binários em / var / lib / mysql (não em / var / lib / mysql2) a partir do momento desde o último backup em /root/changes.sql
  • Carregue changes.sql no mysql (já que ele ainda está apontando para / var / lib / mysql2)

Isso deve capturar tudo o que foi gravado e a conversão deve ser ativada . Novamente, tudo isso é contigente porque você já teve o log binário ativado antes do último backup . Caso contrário, minhas condolências.

RolandoMySQLDBA
fonte