Desde que você solicitou especificamente:
Fila com falha ou falta de trabalhos de backup, mesmo se o computador estiver inativo ou desligado
Ao executar tarefas de backup no servidor , seria relativamente fácil repetir tarefas (com falha na fila), já que podemos assumir que o servidor será o fator "estável". Os backups perdidos em fila de espera podem ser executados roteando o cronjob para um script, criando uma fila sempre que o backup falhar.
Quando as tarefas são executadas no cliente , a história é um pouco diferente. Quando executamos o trabalho em cron
, como percebemos que um trabalho falhou? Como o trabalho não foi iniciado se o computador cliente estiver inativo ou desligado, as coisas seriam muito mais complicadas de serem configuradas no cron.
Portanto, se você deseja executar backups agendados, garantindo que trabalhos com falha ou perdidos serão executados na primeira vez, sugiro não usar o cron em todos os .
Configurar backups agendados / enfileirados em um único arquivo
A solução abaixo é relativamente simples de configurar, seguindo as etapas abaixo:
- Grave e teste um comando
rsync
backup. Usegrsync
se você não tiver certeza sobre como fazer isso. -
Copie o script abaixo em um arquivo vazio, digite o nome (por exemplo) da tarefa de backup, como:
backup1.py
-
Na cabeça do script, faça as configurações apropriadas:
#--- enter the working rsync command below rsync = "rsync -r -t --progress -s '/home/jacob/Bureaublad/test2' '/home/jacob/Bureaublad/test1'" #--- set backup time interval below in hours/minutes interval = [0, 10] #--- set message True if you'd like a warning if a job failed (else False) message = True
Digite o comando
rsync
entre aspas duplas , como no exemplo.- Salve o script com
unique_name.py
- Salve o script com
É isso. A partir do horário de início do script, os backups serão executados exatamente após cada intervalo. Se o trabalho falhar, ele será enfileirado (repetido uma vez por minuto) até que possa ser executado com êxito. Depois disso, o novo backup é definido na hora exata agendada (próxima).
-
Posteriormente, teste execute o script com o comando:
python3 /path/to/script.py
Se tudo funcionar bem, adicione-o aos aplicativos de inicialização: Dash > Aplicativos de inicialização > Adicionar. Adicione o comando:
python3 /path/to/script.py
O script
#!/usr/bin/env python3
import subprocess
import time
import os
import datetime
#--- enter the working rsync command below
rsync = "rsync -r -t -s '/home/jacob/Bureaublad/test2' '/home/jacob/Bureaublad/test1'"
#--- set backup time interval below in hours/minutes
interval = [24, 0]
#--- set message True if you'd like a warning if a job failed (else False)
message = True
#--- set the max- size of the logfile below (n- lines)
maxlog = 100
#--- don't change anything below
backup_id = os.path.basename(__file__).split(".")[0]
home = os.environ["HOME"]
datefile = home+"/next_backup_"+backup_id; logfile = home+"/backup_log_"+backup_id
print(datefile, logfile)
interval = (interval[0]*3600)+(interval[1]*60)
failed = False
def failed_message():
# shows a zenity message if a backup failed
subprocess.Popen([
"zenity",
"--info",
"--text="+backup_id+" failed\n"+\
"See "+logfile])
def readable_t(sec):
# converts epoch time to readable date & time
return datetime.datetime.fromtimestamp(sec).strftime('%Y-%m-%d %H:%M:%S')
def currtime():
# returns current (epoch) time
return int(time.strftime("%s"))
def sync(failed):
# performs the rsync command, on errors: writes to log and shows message
try:
subprocess.check_call(["/bin/bash", "-c", rsync])
set_next(planned, interval, currt)
return False
except subprocess.CalledProcessError:
if failed == False:
open(logfile, "+a").write(readable_t(planned)+" failed\n")
if message == True:
failed_message()
return True
def next_run():
# reads current queue file, creates it if it doesn't exist
try:
return int(open(datefile).read())
except FileNotFoundError:
currt = currtime()
open(datefile, "wt").write(str(currt))
return currt
def set_next(lastr, interval, currt):
# creates the next queue, maintains the log file
nextrun = lastr
while nextrun <= currt:
nextrun += interval
open(datefile, "wt").write(str(nextrun))
newline = [readable_t(lastr)+" succesfully finished on "+\
readable_t(currtime())+"\n"]
try:
limited_lines = open(logfile).readlines()[-maxlog+1:]+newline
except FileNotFoundError:
limited_lines = newline
with open(logfile, "wt") as log:
for l in limited_lines:
print("4")
log.write(l)
while True:
time.sleep(60)
planned = next_run(); currt = currtime()
if currt > planned:
failed = sync(failed)
Além disso
-
O script mantém um arquivo de log, nomeado após o backupscript.
O número máximo de linhas, para manter no arquivo de log, pode ser definido na cabeça do script:#--- set the max- size of the logfile below (n- lines) maxlog = 50
Um exemplo
Noexemploabaixo,oscriptédefinidoparabackupacadacincominutos,apartirdas11:10am.
- Osdoisprimeiros(11:10,11:15)sãorealizadoscomsucesso
- Oterceiro(planejado11:20)falha,devidoaofatodequeolaptopdorme.Otrabalhoéenfileiradoeexecutadoligeiramenteatrasado.Otrabalhoterminaàs11:27,opróximobackupagendadoéexecutadoàs10:30
Emseguida,otrabalhoagendadopara11:35falhadevidoaofatodeoservidornãoestardisponível.Sevocêdefinir
message=True
:Otrabalhoéenfileiradoeexecutadocomêxitomaistarde,às11:41:44
eassimpordiante
Comoredefinirahoradeiníciodobackup?
Bastaexcluiroarquivodafilanoseudiretóriopessoaldatarefadebackupcorrespondente(começandocomnext_backup_
).Ahoraatualseráanovahoradeiníciodociclo.
Comofuncionasobocapô
- Quandooscriptéiniciado,oprimeirobackupécriado(apartirdeumminutoapartirdainicializaçãodoscript).
- Quandoatarefaéconcluída,oscriptcriaumarquivodefila,programadonahora(inicial)dotrabalhoconcluído+ointervalodebackup.
- Umavezporminuto,oscriptverificaseoarquivodafilaestá"com o passar do tempo", comparando a hora atual com a hora da fila. Nesse caso, o script executa a tarefa de backup, cria a nova fila e assim por diante.
O que acontece se o laptop (cliente) estiver desligado?
Em seguida, o arquivo de fila criado mais recente não é atualizado (sobrescrito) pelo script, portanto, ele executará o backup atrasado na primeira vez após a inicialização (ou ativação) do computador.
Como está a próxima fila de backups criada depois disso?
O próximo backup é sempre calculado em etapas inteiras do intervalo de backup e sempre estará "em fase". Em outras palavras; se o primeiro backup tiver sido feito às 12:00 e você definir o intervalo como[24, 0]
, o próximo backup sempre será enfileirado em12:00
do dia seguinte.
Vários trabalhos de backup?
O script dura a maior parte do tempo. Se não, só olha para o arquivo da fila uma vez por minuto. Sinceramente significa nada para o seu sistema, é muito bem possível executar várias tarefas de backup, cada uma com seu próprio log & arquivo de fila, ao mesmo tempo. Como os arquivos de log e de filas são nomeados de acordo com o nome do script, tudo o que você precisa fazer é dar a cada um dos scripts um nome exclusivo