Ir para o conteúdo

Blogue ·

A retenção torna-se a colocação

Mudar uma máquina entre dois bastidores tem um instante perigoso: aquele em que o destino não está reservado nem ocupado. Eis como o eliminámos.

Por Provibr

Mudar um servidor de uma unidade de bastidor para outra é, fisicamente, um trabalho curto com uma chave de fendas e um segundo par de mãos. A falha interessante vive na administração à volta disso, e vive num único instante: aquele em que o destino já não está reservado e ainda não está ocupado.

Se a escrita de outra pessoa cair nesse instante, ficam duas máquinas registadas no mesmo slot. Numa base de dados isso lê-se como uma violação de restrição sobre a qual se pode discutir. No chão do centro de dados lê-se como um técnico parado à frente de um bastidor, com uma máquina nas mãos e sem sítio onde a pôr.

A janela, e como não ter nenhuma

A sequência óbvia são três passos. Libertar a marcação antiga, libertar a retenção para movimentação sobre o destino, escrever a colocação nova. Dentro de uma transação, essa janela é invisível para as outras sessões, o que é precisamente a razão pela qual é fácil deixá-la ficar: passa em todos os testes que se escrevam. Continua a ser uma janela, porque a instrução a seguir opera sobre um slot que a instrução anterior libertou, e basta uma ordenação errada numa reestruturação posterior.

Fazemos uma coisa mais simples. A retenção para movimentação é promovida em vez de substituída. As linhas que registam que unidades estão ocupadas ficam exatamente onde estão; só o cabeçalho muda de espécie, deixando de ser uma retenção para movimentação e passando a ser uma colocação, e a sua data de expiração passa a nula na mesma atualização. A colocação antiga fecha na mesma transação. Não há momento nenhum em que o destino esteja livre, portanto não há segunda oportunidade de colisão, e a coisa toda é uma atualização em vez de uma inserção que tem de correr bem.

O identificador da marcação mantém-se ao longo da promoção, e é essa a maneira de verificar que foi mesmo isto que aconteceu, e não uma coisa que apenas se lhe parece vista de fora.

Pôr a expiração a nula não é arrumação. Uma restrição de verificação na base de dados recusa uma colocação que traga uma, porque uma colocação que deixa de contar em silêncio numa terça-feira enquanto a máquina continua aparafusada lá dentro é um bastidor que o software acredita ter uma unidade livre. Uma reserva que expira é uma funcionalidade; uma colocação que expira é uma mentira com um temporizador em cima.

O árbitro continua a ser um índice

Nada do que está acima é aquilo que impede uma dupla marcação. Isso continua a ser um índice único parcial sobre o bastidor, a face e o slot, limitado às linhas que não foram libertadas, e uma retenção assenta debaixo dele exatamente como uma colocação.

Dois técnicos que escolham a mesma unidade no mesmo segundo veem-na ambos livre na função de planeamento que corre antes da escrita, e exatamente um deles passa pela base de dados. A escrita do outro falha no índice, e o único caminho que escreve a ocupação apanha essa violação e transforma-a numa recusa legível a nomear as unidades em conflito. Qual das frases sai é escolhido pelo nome da restrição que disparou, porque «esta unidade está ocupada» e «esta máquina já está noutro sítio» mandam uma pessoa para dois bastidores diferentes. Uma inserção direta que salte esse caminho recebe em vez disso a violação em bruto. Medido das duas maneiras, porque raciocinar sobre níveis de isolamento não é prova.

A função de planeamento é uma mensagem, não uma defesa. A defesa é o índice. Manter esses dois papéis separados é o que permite que a mensagem seja útil sem que ninguém fique tentado a confiar nela.

Nove estados, e duas saídas que deixam de existir

Uma movimentação tem nove estados: rascunho, planeada, aprovada, em curso, à espera de verificação, a precisar de reconciliação, concluída, cancelada e falhada. Quais as transições legais é um registo sobre os nove e não uma instrução switch. Um switch com ramo por omissão deixa um estado recém-acrescentado cair para permitido, e a direção perigosa aqui é precisamente essa: um estado que alguém acrescenta porque está a acontecer alguma coisa invulgar seria o primeiro estado autorizado a fazer o que quer que fosse.

A linha interessante é a que sai de in_progress, porque desapareceram dela duas saídas que todos os estados anteriores têm: não há caminho de volta para aprovado nem caminho para cancelado. Nesse momento alguém tem a máquina nas mãos, e as únicas saídas honestas são «comunicado como feito», «não sabemos» e «falhou». Cancelar é uma decisão tomada de antemão; depois de comunicado trabalho físico, uma reversão na base de dados é uma afirmação sobre o mundo físico que ninguém verificou.

Os três estados terminais, concluída, cancelada e falhada, transportam listas vazias em vez de entrada nenhuma. Essa é a diferença entre «daqui não segue nada» e «ninguém pensou nisto», e só a primeira é uma decisão.

Uma segunda tabela diz, por estado, se o destino deve continuar retido. A entrada que vale a pena defender é needs_reconcile, que o mantém. Nesse momento ninguém sabe onde está a máquina, pelo que libertar o destino poderia pôr uma segunda máquina numa unidade que talvez já esteja ocupada.

Em movimentação não é em trânsito

Os ativos têm um estado de processo, e este trabalho acrescentou moving ao lado do já existente in_transit. Soam a sinónimos e não são. moving significa que a máquina está a ser deslocada dentro deste centro de dados e que o espaço de destino está reservado. in_transit significa que vai a caminho entre duas instalações e que, portanto, não está em lado nenhum. Ambos bloqueiam a entrega a um cliente, mas respondem a perguntas diferentes quando alguém pergunta onde está uma máquina, e fundi-los tornaria errada a resposta à segunda pergunta. A separação é imposta e não apenas descrita: uma restrição de verificação na base de dados exige que a instalação de origem e a instalação de destino de uma movimentação sejam a mesma, pelo que uma movimentação é por construção uma coisa que acontece dentro de um mesmo edifício, e a estrada entre duas instalações é um processo diferente com uma palavra diferente para ele.

O estado que a máquina tinha antes da movimentação fica guardado na verificação prévia congelada, e não é presumido. O hardware acabado de chegar está em staging, e repor tudo em normal no fim daria em silêncio saída da receção a todas as máquinas deslocadas.

Duas saídas do não saber, e nenhuma é uma reversão

Quando o resultado físico é incerto, a movimentação passa a needs_reconcile e alguém tem de ir ver. Há duas respostas, e ambas ficam registadas como observações.

ObservaçãoO que acontece à movimentaçãoO que acontece ao espaço
Vista no destinoConcluídaA retenção torna-se a colocação, como acima
Vista na origemFalhada, com um motivo a dizer que nunca chegou a ser executadaA retenção é libertada; a colocação original fica intacta

A segunda é deliberadamente falhada e não cancelada. Alguém fez trabalho físico e a máquina não se mexeu; isso é um resultado, não uma escolha. E não é uma reversão: a base de dados não é reposta num estado que finge que nada aconteceu. O histórico de localização é apenas de acrescento, as correções são novas entradas compensatórias, e a diferença aparece um mês mais tarde, quando alguém pergunta por que razão uma máquina esteve parada um dia. Uma reversão não deixa nada para trás. Uma entrada compensatória mostra que houve uma incerteza e como ela foi resolvida.

Essas linhas de histórico transportam identificadores de instalação e de bastidor sem chaves estrangeiras, de propósito. Um bastidor que seja retirado de serviço para o ano não muda o que lá esteve em março passado.

Duas pequenas decisões que vão contar mais tarde

A movimentação aponta para a sua operação em segundo plano com uma referência que está em SET NULL quando a operação é eliminada, em vez de CASCADE. As operações são podadas ao fim de noventa dias. A administração de hardware não é, e uma propagação significaria que a política de retenção das barras de progresso apaga em silêncio o registo de para onde foi uma máquina.

E um índice único parcial permite uma movimentação aberta por ativo. Sem ele, duas pessoas podem planear dois destinos diferentes para a mesma máquina, e ambas parecem corretas no ecrã de cada uma.

O que registaríamos

  1. Promover, não voltar a criar. Se uma reserva e uma atribuição têm a mesma forma, mudar a espécie em vez de libertar e escrever, e verificar que o identificador sobreviveu.
  2. Manter o árbitro na base de dados e a explicação no código. O índice decide quem ganha; a função de planeamento diz que unidades estão em conflito.
  3. Escrever a tabela de transições sobre todos os estados. Um ramo por omissão transforma um estado novo num estado permitido.
  4. Depois de comunicado trabalho físico, nunca reverter. Acrescentar um estado que signifique «desconhecido» e dar-lhe duas saídas documentadas, ambas observações.
  5. Fazer do histórico uma coisa apenas de acrescento e deixar que as correções sejam linhas novas, porque o facto de alguma coisa ter estado incerta é, por si só, informação.
  6. Verificar a que está agarrada a política de retenção. Uma propagação de uma tabela de vida curta para uma de vida longa é um erro de perda de dados com calendário.

Para ser claro quanto ao ponto em que isto está: o trabalho de logística de centro de dados vive atrás de um sinalizador de lançamento que está desligado por predefinição, com uma definição por organização por cima dele, pelo que nada disto é comprável hoje. Quatro coisas estão por provar. O evento de progresso em direto de uma movimentação foi exercitado sem o seu barramento de mensagens. Cancelar uma movimentação a partir do ecrã de operações não foi conduzido num navegador. Uma retenção genuinamente expirada nunca foi observada, e não existe de propósito varredura nenhuma que limpe uma, porque uma retenção que se arruma sozinha enquanto alguém está parado à frente do bastidor é exatamente a contradição que o índice existe para impedir. E a mesma verificação de instalação descrita acima nunca chegou a disparar, porque não foi semeada uma segunda instalação com que a fazer disparar.

Do trabalho de centro de dados no Provibr. A razão pela qual um índice único parcial é o único limite real à ocupação está em o único limite real à ocupação de um bastidor, e a razão pela qual as cinco perguntas de capacidade sobre um bastidor não podem ser somadas está em espaço em bastidor não é capacidade.

Comece com um host e um agente

Crie uma conta, instale o agente com um único comando e ligue o seu primeiro host Proxmox. O período experimental dura 14 dias e não pede quaisquer dados de pagamento.