#!/usr/bin/python # -*- encoding: utf-8 -*- ###################################################################################################### ## ## ## SCRIPT EN PYTHON PARA EL RESPALDO DE BASES DE DATOS POSTGRES Y SUBIDA A MEGA ## ## ## ## Almacenará tres tipos de copia: ## ## - Diarias: el sistema realizará una copia diaria por base de datos y eliminará aquellas ## ## que tengan más de N_DAYS_AGO_DIARY_BACKUP días de antiguedad ## ## - Semanales: el sistema realizará una copia semanal cada viernes de cada base de datos y ## ## eliminará aquellas que tengan más de N_WEEKS_AGO_BACKUP semanas de antiguedad ## ## - Mensuales: el sistema realizará una copia mensual los días 1 de cada mes y eliminará ## ## aquellas que tengan más de N_MONTHS_AGO_BACKUP meses de antiguedad ## ## ## ## ## ## * para poder subir los ficheros a mega es necesario instalar el siguiente requerimiento ## ## https://github.com/richardasaurus/mega.py ## ## ## ## sudo pip install mega.py ## ## ## ## ## ## @bienvenidosaez ## ## ## ###################################################################################################### from time import gmtime, strftime import subprocess import os import glob import time from mega import Mega # sudo pip install mega.py HOST = 'localhost' # hostname del servidor de postgres DATABASE_LIST = ( { 'name' : 'mydb', 'username' : 'myuser', 'password' : 'mypass' }, ) BACKUP_DIR = '/var/dbbackup/' # directorio para guardar las copias MONTH_DAY = '01' # día del mes para la copia mensual WEEK_DAY = '1' # día de la semana para las copias semanal [1(Monday), 7] N_DAYS_AGO = 2 # nº de copias diarias a almacenar N_WEEKS_AGO = 4 # nº de copias semanas que se almecenarán N_MONTHS_AGO = 12 # nº de copias mensuales que se almacenarán DUMPER = """ pg_dump --no-privileges --no-owner --no-reconnect -h localhost -U %s -f %s -F c %s """ # MEGA MEGA = True # True = sube los archivos generados a la cuenta MEGA indicada MEGA_EMAIL = 'mega@email.com' # Email de MEGA MEGA_PASSWORD = 'megapass' # Password de MEGA MEGA_FOLDER = 'megafolder' # Directorio donde subir los backup en MEGA def log(string): print time.strftime('%Y-%m-%d-%H-%M-%S', time.gmtime()) + ': ' + str(string) def diary_backup(database): global BACKUP_DIR global MEGA global MEGA_FOLDER global DUMPER # Seteamos el password como variable de entorno para que pg_dump la coja de ahí os.putenv('PGPASSWORD', database['password']) print("===== START diary backup for %s =====" % database['name']) # Iteramos sobre las copias diarias, este apartado se ejecutará en cada ejecución del fichero glob_list = glob.glob(BACKUP_DIR + database['name'] + '_diary_backup*' + '.pgdump') for file in glob_list: file_info = os.stat(file) if file_info.st_ctime < x_days_ago: log("Delete diary backup: %s" % file) os.unlink(file) else: log("Keep diary backup: %s" % file) thetime = str(strftime("%Y-%m-%d")) file_name = database['name'] + '_diary_backup_' + thetime + ".sql.pgdump" command = DUMPER % (database['username'], BACKUP_DIR + file_name, database['name']) log(command) subprocess.call(command, shell=True) if MEGA: mega_upload_file(BACKUP_DIR + file_name, MEGA_FOLDER) print("===== END diary backup for %s =====\n" % database['name']) def week_backup(database): global BACKUP_DIR global MEGA global MEGA_FOLDER global DUMPER print("\n===== START week backup for %s =====" % database['name']) glob_list = glob.glob(BACKUP_DIR + database['name'] + '_week_backup*' + '.pgdump') for file in glob_list: file_info = os.stat(file) if file_info.st_ctime < x_montsh_ago: log("Delete week backup: %s" % file) os.unlink(file) else: log("Keep week backup: %s" % file) thetime = str(strftime("%Y-%m-week-%U")) file_name = database['name'] + '_week_backup_' + thetime + ".sql.pgdump" command = DUMPER % (database['username'], BACKUP_DIR + file_name, database['name']) log(command) subprocess.call(command, shell=True) if MEGA: mega_upload_file(BACKUP_DIR + file_name, MEGA_FOLDER) print("===== END week backup for %s =====\n" % database['name']) def month_backup(database): global BACKUP_DIR global MEGA global MEGA_FOLDER global DUMPER print("===== START month backup for %s =====" % database['name']) # Iteramos sobre las copias mensuales glob_list = glob.glob(BACKUP_DIR + database['name'] + '_month_backup*' + '.pgdump') for file in glob_list: file_info = os.stat(file) if file_info.st_ctime < x_montsh_ago: log("Delete month backup: %s" % file) os.unlink(file) else: log("Keep month backup: %s" % file) thetime = str(strftime("%Y-%m")) file_name = database['name'] + '_month_backup_' + thetime + ".sql.pgdump" command = DUMPER % (database['username'], BACKUP_DIR + file_name, database['name']) log(command) subprocess.call(command, shell=True) if MEGA: mega_upload_file(BACKUP_DIR + file_name, MEGA_FOLDER) print("===== END month backup for %s =====\n" % database['name']) def mega_connect(): global MEGA_EMAIL global MEGA_PASSWORD mega = Mega() m = mega.login(MEGA_EMAIL, MEGA_PASSWORD) return m def mega_upload_file(file_to_upload, destination_path): m = mega_connect() file_info = os.stat(file_to_upload) total_space = m.get_storage_space()['total'] total_used = m.get_storage_space()['used'] total_free = total_space - total_used if total_free > file_info.st_size: folder = m.find(destination_path) return m.upload(file_to_upload, folder[0]) else: return False # Si el directorio no existe lo creamos if not os.path.isdir(BACKUP_DIR): os.makedirs(BACKUP_DIR, 0770) x_days_ago = time.time() - ( 60 * 60 * 24 * N_DAYS_AGO ) x_weeks_ago = time.time() - ( 60 * 60 * 24 * N_WEEKS_AGO * 7) x_montsh_ago = time.time() - ( 60 * 60 * 24 * N_MONTHS_AGO * 30) # Iteramos sobre las bases de datos de las listas for database in DATABASE_LIST: #La copia diaria la ejecutamos siempre diary_backup(database) # Si estamos en el día del mes indicado en la variable MOTH_DAY hay que ejecutar la parte mensual del backup if MONTH_DAY == time.strftime('%d', time.gmtime()): month_backup(database) # Si estamos en el día de la semanaindicado en la variable WEEK_DAY hay que ejecutar la parte semanal del backup if WEEK_DAY == time.strftime('%u', time.gmtime()): week_backup(database)