Pergunta

Ao fazer uma instrução ALTER TABLE no MySQL, toda a tabela é leitura bloqueado para a duração da declaração. Se é uma grande mesa, isso significa inserir ou instruções de atualização pode ser bloqueado por um tempo looooong. Existe uma maneira de fazer um "hot alter", como a adição de uma coluna de tal maneira a que a tabela ainda é atualizável em todo o processo?

Na maior parte eu estou interessado em uma solução para o MySQL, mas eu estaria interessado em outros RDBMS se o MySQL não pode fazê-lo.

Para esclarecer, o meu propósito é simplesmente o tempo de inatividade evitar quando um novo recurso que requer uma coluna extra de tabela é empurrado para a produção. Qualquer esquema de banco de dados irá mudar ao longo do tempo, isso é apenas um fato da vida. Eu não vejo por que devemos aceitar que essas mudanças deve inevitavelmente resultar em tempo de inatividade; isso é apenas fraco.

Foi útil?

Solução

A única outra opção é fazer manualmente o que muitos sistemas RDBMS fazer de qualquer maneira ...
- Criar uma nova tabela

Você pode copiar o conteúdo da tabela antiga sobre um pedaço de cada vez. Embora sempre ser cauteloso de qualquer INSERT / UPDATE / DELETE na tabela de origem. (Poderia ser gerido por um gatilho. Embora isso possa causar uma desaceleração, não é um bloqueio ...)

Uma vez terminado, alterar o nome da tabela de origem, em seguida, alterar o nome da nova tabela. De preferência em uma transação.

Uma vez terminado, recompilar quaisquer procedimentos armazenados, etc, que utilizam essa tabela. Os planos de execução, provavelmente, deixará de ser válido.

EDIT:

Alguns comentários foram feitos sobre esta limitação ser um pouco pobre. Então eu pensei que eu iria colocar uma nova perspectiva sobre ele para mostrar por que é como é ...

  • Adicionar um novo campo é como trocar um campo em cada linha.
  • Bloqueios de campo seria muito mais difícil do que Bloqueios de linha, não importa bloqueios de tabela.

  • Você está realmente mudando a estrutura física do disco, cada registro movimentos.
  • Este é realmente como uma atualização sobre a tabela inteira, mas com mais impacto ...

Outras dicas

Percona torna uma ferramenta chamada pt-online-esquema de mudança de que permite que isso seja feito.

É essencialmente faz uma cópia da tabela e modifica a nova tabela. Para manter a nova tabela em sincronia com o original usa gatilhos para atualização. Isso permite que a tabela original para ser acessado enquanto a nova tabela é preparada em segundo plano.

Este é semelhante ao Dems método acima sugerido, mas isso faz isso de uma forma automatizada.

Algumas de suas ferramentas têm uma curva de aprendizagem, ou seja, a conexão com o banco de dados, mas uma vez que você tem que para baixo, eles são ótimas ferramentas para ter.

Ex:

pt-online-schema-change --alter "ADD COLUMN c1 INT" D=db,t=numbers_are_friends

Esta questão a partir de 2009. Agora MySQL oferece uma solução:

em linha DDL

Um recurso que melhora o desempenho, simultaneidade e disponibilidade de tabelas InnoDB durante as operações (Tabela principalmente ALTER) DDL. Vejo Seção 14.11, “InnoDB e DDL Online” para obter mais informações.

Os detalhes variam de acordo com o tipo de operação. Em alguns casos, da tabela pode ser alterado simultaneamente enquanto o ALTER TABLE é em progresso. A operação pode ser capaz de ser realizada sem fazer uma cópia da tabela, ou usando um tipo especialmente optimizado de cópia tabela. Espaço utilização é controlada pela innodb_online_alter_log_max_size configuração opção.

Ele permite que você ajuste o equilíbrio entre desempenho e simultaneidade durante a operação de DDL, por escolher se deseja bloquear o acesso à mesa inteiramente (LOCK = cláusula de exclusividade), permitem consultas, mas não DML (LOCK = cláusula compartilhado), ou permitir a plena consulta e DML acesso à tabela (LOCK = cláusula NONE). Quando você omitir a cláusula LOCK ou especificar um lock = padrão, o MySQL permite o máximo de concorrência possível, dependendo do tipo de operação.

Performing alterações no local sempre que possível, em vez de criar uma nova cópia da tabela, evita aumentos temporários na utilização do espaço em disco e I / O sobrecarga associada com a cópia da mesa e reconstruir índices secundários.

MySQL manual 5,6 Referência -> InnoDB e Online DDL para mais informações.

Parece que DDL on-line também está disponível em MariaDB

Como alternativa, você pode usar ALTER TABLE ONLINE para garantir que sua ALTER não TABLE não bloquear operações simultâneas (leva sem bloqueios). Isto é equivalente a BLOQUEIO = NONE.

MariaDB KB sobre ALTER TABLE

on-line ferramenta de alteração de esquema Ver ficha do Facebook.

http://www.facebook.com/notes / mysql-at-facebook / on-line-schema-change-for-mysql / 430801045932

Não para os fracos de coração; mas vai fazer o trabalho.

Eu recomendo Postgres se isso é uma opção. Com postgres não há essencialmente nenhum tempo de inatividade com os seguintes procedimentos:

Outra grande característica é que a maioria das instruções DDL são transacionais, então você poderia fazer uma migração inteira dentro de uma transação SQL, e se algo der errado, a coisa toda fica revertida.

Eu escrevi este um pouco atrás, talvez possa lançar mais algumas dicas sobre os outros méritos.

Uma vez que você perguntou sobre outras bases de dados, aqui estão algumas informações sobre a Oracle.

Como adicionar uma coluna NULL a uma tabela Oracle é uma operação muito rápida, uma vez que só atualiza o dicionário de dados. Isto é um bloqueio exclusivo sobre a mesa para um período muito curto de tempo. Terá, no entanto, invalidar qualquer depedant procedimentos armazenados, visões, gatilhos, etc. Estes irão começar recompilados automaticamente.

A partir daí, se necessário, você pode criar o índice usando a cláusula ONLINE. Novamente, apenas dados muito curtos dicionário fechaduras. Ele vai ler a tabela inteira à procura de coisas para indexar, mas não bloqueia qualquer um ao fazer isto.

Se você precisa adicionar uma chave estrangeira, você pode fazer isso e obter Oracle para confiar em você que os dados estão corretos. Caso contrário, ele precisa ler a tabela inteira e validar todos os valores que podem ser lento (criar o seu índice primeiro).

Se você precisa colocar um padrão ou valor calculado para cada linha da nova coluna, você precisa executar uma atualização maciça ou talvez um pequeno programa utilitário que preenche os novos dados. Isso pode ser lento, especialmente se as linhas ficar em forma alot maior e não mais em seus blocos. Bloqueio pode ser gerenciado durante esse processo. Desde o velho Versino da sua aplicação, que ainda está em execução, não sabe sobre esta coluna você pode precisar de um gatilho sorrateira ou para especificar um padrão.

A partir daí, você pode fazer um switcharoo em seus servidores de aplicativos para a nova versão do código e ele vai continuar correndo. Soltar o seu gatilho sorrateira.

Como alternativa, você pode usar DBMS_REDEFINITION que é uma caixa preta projetado para fazer esse tipo de coisa.

Tudo isso é muito preocupou em teste, etc que só temos uma interrupção domingo de manhã cedo sempre que lançar uma versão maior.

Se você não pode pagar o tempo de inatividade do banco de dados ao fazer atualizações de aplicativos que você deve considerar a manutenção de um cluster de dois nós para alta disponibilidade. Com uma configuração de replicação simples, você pode fazer mudanças quase totalmente estruturais on-line como o que você sugere:

  • espera para todas as alterações a serem replicadas em um escravo passivo
  • mudar o escravo passiva para ser o mestre ativo
  • fazer as mudanças estruturais para o velho mestre
  • mudanças replicada de volta a partir do novo mestre para o velho mestre
  • fazer o mestre trocar novamente e a nova implantação aplicativo simultaneamente

Nem sempre é fácil, mas ele funciona, geralmente com 0 tempo de inatividade! O segundo nó não tem que ser apenas um passivo, ele pode ser usado para testar, fazendo estatísticas ou como um nó de fallback. Se você não tem replicação de infra-estrutura pode ser configurado dentro de uma única máquina (com duas instâncias do MySQL).

Não. Se você estiver usando tabelas MyISAM, para meu melhor compreensão eles só fazem bloqueios de tabela - não há bloqueios de registros, eles apenas tentam manter tudo Hyperfast através da simplicidade. (Outras tabelas MySQL funcionam de forma diferente.) Em qualquer caso, você pode copiar a tabela para outra tabela, alterá-lo, e depois mudá-los, atualizando as diferenças.

Esta é uma alteração tão grande que eu duvido que qualquer DBMS iria apoiá-lo. É considerado um benefício de ser capaz de fazê-lo com dados da tabela em primeiro lugar.

solução temporária ...

Outra solução poderia ser, adicionar uma outra tabela com a chave primária da tabela original, juntamente com a sua nova coluna.

Preencher sua chave primária na nova tabela e valores Preencher para nova coluna na sua nova tabela, e modificar sua consulta para participar desta mesa para selecionar operações e você também precisa inserir, atualizar separadamente para este valor da coluna.

Quando você capaz de obter o tempo de inatividade, você pode alterar a tabela original, modificar suas consultas DML e soltar sua nova tabela criada anteriormente

Caso contrário, você pode ir para o agrupamento método, replicação, ferramenta pt-online-esquema de Percona

Usando o plugin InnoDB, ALTER TABLE que só incluir ou eliminar índices secundários pode ser feito "rapidamente", ou seja, sem a reconstrução da tabela.

De um modo geral no entanto, em MySQL, qualquer ALTER TABLE envolve a reconstrução de toda a tabela que pode levar muito tempo (ou seja, se a tabela tem uma quantidade útil de dados no mesmo).

Você realmente precisa para projetar seu aplicativo para que instruções ALTER TABLE não precisa ser feito regularmente; você certamente não quer qualquer ALTER TABLE feito durante o funcionamento normal da aplicação, a menos que você está preparado para esperar ou você está alterando pequenas mesas.

Eu recomendaria uma das duas abordagens:

  1. Projete suas tabelas de banco de dados com as possíveis mudanças em mente. Por exemplo, eu tenho trabalhado com sistemas de gerenciamento de conteúdo, que campos mudança de dados no conteúdo regularmente. Em vez de construir a estrutura de banco de dados físico para corresponder às exigências iniciais de campo CMS, que é muito melhor para construir em uma estrutura flexível. Neste caso, usando um campo de texto blob (varchar (max) por exemplo) para armazenar dados XML flexíveis. Isso faz com que as alterações estruturais muito menos frequente. As mudanças estruturais podem ser caros, por isso não é um benefício para o custo aqui também.

  2. tem tempo de manutenção do sistema. Ou o sistema não fica em linha durante mudanças (mensal, etc.), e as alterações são programados durante o tempo mínimo de tráfego intenso do dia (3-5am, por exemplo). As mudanças são encenadas antes do lançamento da produção, assim você terá uma boa fixo estimativa janela de tempo de inatividade.

2a. Tem servidores redundantes, de modo que quando o sistema tem tempo de inatividade, o site inteiro não vai para baixo. Isso permitiria que você a "rolar" suas atualizações fora de forma escalonada, sem tomar todo o site para baixo.

Opções 2 e 2-A não ser viável; eles tendem a ser apenas para maiores sites / operações. Eles são opções válidas, no entanto, e eu pessoalmente tenho usado todas as opções apresentadas aqui.

Se alguém ainda está lendo este ou acontece para vir aqui, esta é a grande vantagem de usar um sistema de banco de dados NoSQL como MongoDB. Eu tive o mesmo problema lidar com a alteração da tabela para qualquer colunas add para recursos ou índices adicionais sobre uma grande mesa com milhões de linhas e altas escreve. Ele acabaria bloqueio por um longo tempo para fazer isso no banco de dados VIVO frustraria os nossos usuários. Em pequenas mesas você pode ir longe com ele.

Eu odeio o fato de que temos de "projetar nossas mesas para evitar alterá-los". Eu só não acho que as obras no mundo website de hoje. Você não pode prever como as pessoas vão usar o seu software é por isso que mudar rapidamente as coisas com base no feedback do usuário. Com MongoDB, você pode adicionar "colunas" à vontade sem tempo de inatividade. Você realmente não até mesmo adicioná-los, basta inserir dados com novas colunas e ele faz isso automaticamente.

Vale a pena conferir: www.mongodb.com

Em geral, a resposta vai ser "não". Você está mudando a estrutura da tabela, que potencialmente vai exigir um monte de atualizações colunas dummy '" e eu definitivamente concordar com isso Se você espera estar fazendo isso muitas vezes, então eu vou oferecer uma alternativa para.' - uso VIEWs vez de tabelas de dados SELECTing. IIRC, alterando a definição de um ponto de vista é relativamente leve e indireto através de uma visão é feito quando o plano de consulta é compilada. a despesa é que você teria que adicionar a coluna para uma nova tabela e fazer a vista JOIN na coluna.

Claro que isso só funciona se você pode usar chaves estrangeiras para realizar cascata de exclusões e outros enfeites. A outra vantagem é que você pode criar uma nova tabela que contém uma combinação dos dados e apontar a fim de que, sem perturbar uso do cliente.

Apenas um pensamento.

A diferença entre Postgres e MySQL a este respeito é que, em Postgres não re-cria uma tabela, mas os dados modifica dicionário que é semelhante ao Oracle. Portanto, a operação é rápida, enquanto ele ainda está necessita de atribuir um bloqueio de tabela DDL exclusivo para curto espaço de tempo como dito acima por outros.

No MySQL a operação irá copiar os dados para uma nova tabela enquanto bloqueia transações, que tem sido a dor principal para MySQL DBAs antes da v. 5.6.

A boa notícia é que desde o MySQL 5.6 liberação da restrição tem sido principalmente levantou e você agora pode desfrutar do verdadeiro poder do banco de dados MySQL.

Como SeanDowney mencionou, pt-online-schema-change é uma das melhores ferramentas para fazer o que você tem descrito na pergunta aqui. Eu fiz recentemente uma série de mudanças de esquema em um DB ao vivo e foi muito bem. Você pode ler mais sobre isso no meu blog aqui: http://mrafayaleem.com/2016/02/08/live-mysql-schema-changes-with-percona/ .

Você deve definitivamente tentar pt-online-schema-change. Tenho vindo a utilizar esta ferramenta para fazer migrações no AWS RDS com vários escravos e tem funcionado muito bem para mim. Eu escrevi um post elaborado sobre como fazer o que pode ser útil para você.

Blog: http://mrafayaleem.com / 2016/02/08 / live-mysql-esquema-changes-com-Percona /

colunas

manequim são uma boa idéia se você pode prever o seu tipo (e torná-los anulável). Veja como seu mecanismo de armazenamento alças nulos.

MyISAM irá bloquear tudo, se você sequer mencionar um nome de tabela de passagem, no telefone, no aeroporto. Ele só faz isso ...

Dito isto, os bloqueios não são realmente que tratam uma grande; contanto que você não está tentando adicionar um valor padrão para a nova coluna para cada linha, mas deixá-lo sentar-se como nula, e seu mecanismo de armazenamento é inteligente o suficiente para não ir a escrevê-lo, você deve estar ok com um bloqueio que só é realizada por tempo suficiente para atualizar os metadados. Se você tentar escrever um novo valor, bem, você é brinde.

TokuDB pode adicionar / soltar colunas e adicionar índices "quente", a mesa está totalmente disponível durante todo o processo. Ele está disponível via www.tokutek.com

Não é verdade.

Você está alterando a estrutura subjacente da tabela, depois de tudo, e isso é um pouco de informação que é muito importante para o sistema subjacente. Você também é (provavelmente) se movendo muito dos dados ao redor no disco.

Se você está pensando em fazer isso muito, você é melhor fora simplesmente preenchimento da tabela com colunas "dummy" que estão disponíveis para uso futuro.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top