Estou trabalhando na criação de serviços que possam fazer um backup lógico do MySQL, bem como um backup físico do MySQL. Os backups lógicos seriam feitos a cada 4 horas, enquanto os backups físicos seriam feitos uma vez por dia em um horário específico. Ambos dependem do desligamento do escravo MySQL no qual o backup se baseia. Eles também precisam lidar com a não execução simultânea. Além disso, ao inicializar/reinicializar, eles não devem ser executados na primeira invocação.
O backup lógico está usando mysqldump
e depois fazendo upload para o S3. O backup físico está tirando um instantâneo do EBS.
Estou executando uma versão simples de caso de estresse, em que ambos disparam em um intervalo de 1 minuto. O banco de dados está vazio e pequeno. O volume do EBS é 1GiB. Ambos podem ser feitos em menos de um minuto.
Eu uso um serviço de timer para acionar o oneshot. Também fiz com que cada cronômetro se Conflicts
ligasse e também reajustei o cronômetro em ExecStopPost
.
Um exemplo de arquivo de serviço é semelhante. Cada um faz referência ao outro
[Unit]
After=mysql-slave.service
Conflicts=other-backup-type.timer
[Service]
Type=oneshot
# Just arbitrary name for this example
ExecStart=do_backup.sh
ExecStopPost=/bin/systemctl start other-backup-type.timer
O que vi systemctl list-timers
é que ambos os temporizadores estão sincronizados. Quando ambos atingirem 0, um será acionado. O que descobri é que uma vez feito, o outro não será acionado. Parece que neste caso o cronômetro está realmente parado, mas o gatilho para o outro tiro nunca é acionado.
Existe uma maneira de lidar com isso adequadamente sem precisar compensar o tempo? Descobri que se eu compensar um pouco o período de tempo, ele funciona (os segundos não podem ser um fator de 60). Estou verificando se existe uma maneira melhor/mais elegante de oferecer suporte a isso.
Responder1
Não tenho certeza se esta é a resposta 100% correta. Eu passei por muitas permutações e com base nisso, cheguei a isso.
Observacionalmente, parece que se eu tiver 2 temporizadores (A e B) configurados como Conflicts=
e também tiver uma colisão na expiração com outro temporizador (por exemplo, ambos configurados para disparar a cada minuto), então aquele que dispara (digamos que é A ) primeiro interrompe o outro e depois aciona seu serviço. No entanto, esta parada faz com que o acionamento do serviço do temporizador B seja perdido. Suponho que o gatilho seja acionado em alguma fila e acabe sendo acionado no processo de parada.