Atualizando um banco de dados MySQL

6

Temos um sistema on-line usando o banco de dados MySQL. Precisamos mesclar um banco de dados de backup mais antigo (Tabelas completas, não um arquivo de despejo) com o atual. Sem experimentar nenhum tempo de inatividade do servidor, como você faria isso? Note que o sistema está online 24/7. Quais são os problemas que podem surgir?

Obrigado.

    
por DragonBorn 01.06.2009 / 15:59

5 respostas

7

Ao mexer com o sistema de arquivos do MySQL, você precisa parar o servidor MySQL. Para evitar o tempo de inatividade em sua máquina ativa, use uma máquina de backup / virtualizada com a mesma versão do servidor MySQL. Enquanto o servidor MySQL BACKUP está parado, copie as tabelas (eu suponho .FRM, .MYI etc?) Para o sistema de arquivos em / var / lib / mysql / BACKUP_DB (o diretório correspondente do BACKUP_DB).

Inicie o servidor MySQL BACKUP e assegure-se de que os dados foram carregados corretamente usando scripts ou CLI. Quando verificado, mysqldump o banco de dados BACKUP_DB para que possa ser carregado no servidor live:

mysqldump --extended-insert BACKUP_DB > /root/sql/BACKUP_DB.sql

Você agora converteu seus dados de backup brutos em instruções SQL que podem ser carregadas no MySQL sem tempo de inatividade (ao contrário dos dados brutos). Mova BACKUP_DB.sql para a máquina ativa.

Importe BACKUP_DB.sql para sua instância do LIVE MySQL como um banco de dados diferente:

mysql BACKUP_DB < /root/sql/BACKUP_DB.sql

Agora você deve ter o banco de dados de backup carregado no MySQL como BACKUP_DB.

Agora, depende das instruções INSERT IGNORE ou REPLACE INTO (você sobrescreve dados antigos ou "preenche os espaços em branco" em seus índices?):

mysqldump --no-create-db
--no-create-info --extended-insert --insert-ignore MERGE_SOURCE | mysql BACKUP_DB

Ou, para a ação REPLACE INTO:

mysqldump --no-create-db --no-create-info --extended-insert MERGE_SOURCE | sed 's/INSERT INTO/REPLACE INTO/g' | mysql BACKUP_DB

Como alternativa, em vez de direcionar a saída de volta para o MySQL, envie para um arquivo e revise as instruções SQL.

mysqldump --no-create-db --no-create-info --extended-insert --insert-ignore MERGE_SOURCE > /root/sql/merge.sql
mysqldump --no-create-db --no-create-info --extended-insert MERGE_SOURCE | sed 's/INSERT INTO/REPLACE INTO/g' > /root/sql/merge.sql

Por fim, para evitar o tempo de inatividade, despeje o primeiro banco de dados ao longo do segundo:

mysqldump BACKUP_DB | mysql CURRENT_DB

Você sempre pode bloquear o banco de dados primeiro para evitar que os dados sejam gravados (por exemplo) na tabela z com uma chave estrangeira na tabela (que já foi gravada):

FLUSH TABLES WITH READ LOCK;

(executa o despejo como etapa anterior)

UNLOCK TABLES;

Adicione o comando FLUSH ao início de seu arquivo .sql de despejo e UNLOCK até o final.

Certifique-se de quadruplicar verificar seus nomes de banco de dados neste cenário! Faça qualquer pergunta de acompanhamento que você não tenha certeza, pois este é um dado de alto risco. Execute (e anote em detalhes) as etapas exatas necessárias em um servidor de desenvolvimento, se possível, ou virtualize seu teste ou crie um teste em pequena escala. Apenas teste. E, claro, faça backups suficientes para cobrir qualquer eventualidade de perda de dados.

    
por 01.06.2009 / 17:04
5

Para este exemplo, vamos supor que seu banco de dados se chame "zig" e seu banco de dados de backup se chame "zig_backup". Também assumirei que seu banco de dados de backup e seu banco de dados ativo têm o mesmo esquema.

Também assumirei que seu banco de dados ativo está sendo atualizado constantemente e você não pode executar a mesclagem "offline" e, em seguida, ativar um comutador para tornar a cópia mesclada "ativa".

As questões a ter em conta são:

  • Potencial para índices ou chaves primárias em antigo / novo para conflito por algum motivo (geralmente, se um erro foi cometido ou os registros foram perdidos acidentalmente)
  • Deleções que ocorreram desde o backup não devem ser "mescladas"

O processo a ser atualizado exigirá planejamento em termos de quais tabelas serão mescladas primeiro e quais serão mescladas por último. Minha tendência geral para fazer o levantamento pesado primeiro (mesas grandes), então trabalhe seu caminho para as mesas menores. Dependendo do tamanho dos seus dados, isso pode não importar.

O processo de mesclagem seria então:

  1. Restaure o banco de dados de backup ao lado do banco de dados ativo com um nome de banco de dados modificado (por exemplo, "zig_backup")
  2. Para cada tabela no banco de dados ativo, mesclar a partir do banco de dados de backup
  3. Para cada tabela no banco de dados de backup, verifique se a tabela existe no banco de dados ativo e, se não, adicione-a.

O método mais seguro seria fazer uma junção de tabela completa e apenas inserir as linhas que não correspondem:

for each table in the "live" database:
    INSERT INTO zig.$table
    SELECT BACKUP.* FROM zig_backup.$table AS BACKUP
    LEFT OUTER JOIN zig.$table AS LIVE ON LIVE.ID=BACKUP.ID
    WHERE LIVE.ID IS NULL;

Isso, é claro, requer conhecimento das chaves primárias de cada tabela. Um "REPLACE" direto pode não funcionar, pois as linhas no banco de dados ativo podem ter sido alteradas e seus dados alterados serão sobrescritos pelo

Para mesclar tabelas ausentes, faça:

\u zig_backup
SHOW TABLES

Para obter uma lista de todas as tabelas, e para determinar se a tabela existe no banco de dados ativo, você pode fazer:

\u zig
SHOW TABLES LIKE 'tablename';

Como alternativa, uma tabela no banco de dados de backup que não existe no banco de dados "ativo" pode ser copiada para o diretório de banco de dados ativo.

Por fim, lidar com exclusões do banco de dados "ao vivo" é, na melhor das hipóteses, difícil, especialmente porque você está mesclando que alguns dados estão faltando por um motivo ou outro.

    
por 08.06.2009 / 06:44
3

Configure a replicação e alterne o DB-server para o escravo quando estiver pronto e bem testado (!!!).

A menos que você tenha algumas limitações técnicas para realizar isso, essa é uma variante válida (quero dizer, você deve poder testar as alterações antes de colocá-las em um ambiente 24 horas por dia, 7 dias por semana).

    
por 06.06.2009 / 09:38
2

Supondo que você tenha o espaço em disco, configurei um banco de dados de migração e copie / mescle os dados nele. Configure uma cópia do seu ambiente da Web para se conectar ao banco de dados de migração e testá-lo completamente. Em seguida, quando estiver satisfeito, altere as sequências de conexão em seu ambiente de produção para examinar o novo banco de dados de migração.

    
por 01.06.2009 / 16:13
1

você pode usar a opção -T do mysqldump para obter a saída das tabelas como valores separados por tabulações. Em seguida, crie uma cópia do banco de dados ativo conforme Kyle sugere. Em seguida, use o mysqlimport para reimportar os dados para a cópia dinâmica e testá-los lá. Quando estiver pronto para mudar de live para live-copy, você precisará obter algum tempo de inatividade.

Eu não tentei isso sozinho Caveat Emptor .

    
por 01.06.2009 / 17:06