Copias de seguridad de una aplicación odoo …

… lo que tengo y lo que pretendo.

En mi lugar de trabajo tenemos dos instalaciones casi independientes funcionando bajo odoo. Según la hemos ido utilizando me he dado cuenta de que se está desbordando la capacidad del servidor de copias de seguridad y que las copias incrementales han llegado a un punto que no se distinguen de las completas.

Tanto es así que si la instalación ocupa, en bruto, 43Gb, estamos salvando a diario cerca de 300Gb y no tiene sentido.

Revisando la configuración del servidor me doy cuenta varios errores que tanto yo como la consultora que mantiene la instalación estamos cometiendo. A saber:

  • Todas las noches a las 3am se lanza un script que crea lo siguiente:
    • Volcado completo de las bases de datos empleando pg_dumpall.
    • Empaquetado (con tar y comprimido) de todo el árbol de la aplicación bajo /opt/odoo donde reside el software principal y varios repositorios git con su trabajo.
    • Estos empaquetados se guardan bajo la fecha del día y se conservan nada menos que 30 de ellos.
  • Todas las noches a las 23pm (el día antes del anterior en realidad) se lanzan las copias planificadas con bareos y se salva aquello que se ha modificado desde el anterior.

Vista desde el cliente web de bareos

Así que tenemos una situación en la que los datos que deben salvarse se preparan después de hacer la copia. Y tenemos siempre tres juegos de copias que en realidad corresponden a un día de trabajo. Vale. Así no.

Las copias ahora mismo

Mirando el script de instalación de la gente que mantiene el sistema, el que se lanza a las 3am, su trabajo consiste en lo siguiente:

  1. Obtiene un volcado de todas las bases de datos del servidor empleando pg_dumpall y comprime vía gzip el resultado. Un archivo con todo a diario.
  2. Crea un paquete (también comprimido) de directorios vía tar en los que se incluye:
    1. /opt/odoo
    2. /etc/odoo/*
    3. /etc/init.d/odoo*
    4. /var/log/odoo/*

Conserva, eso sí, los 30 últimos empaquetados de este tipo por lo que restaurar desde a una fecha dada es sencillo.

¿ Qué ocurre entonces cuando integras este sistema de copias en otro como bareos ? Pues que los niveles de copia patinan un poco; las copias incrementales o diferenciales llegan a ser técnicamente copias completas. Y así, pues tampoco.

Y sin embargo

Tenemos que mantener parte de este esquema, al menos en local, debido a que la consultora externa que mantiene el sistema necesita que siga así. Estoy seguro de que podrían adaptarse a lo que les pida si es razonable pero no quiero complicar más la situación.

Ellos deben saber que, ya que instalaron el mecanismo de copias, éste sigue en el mismo sitio y pueden restaurar el sistema de la misma manera.

El único gran cambio que voy a realizar desde su punto de vista es que su programa de volcado estará integrado entre los propios de bareos y que funcionarán a la par.

Para el programa odoo en sí he escrito este pequeño script que me asegura una copia limpia para salvar:

#!/usr/bin/env bash

# Parámetros
VERSION=0.1
BACKUP=/var/backups/odoo-latest
RSYNC="$(which rsync) -avlm --delete " 

# Preparamos árbol de archivos para copias con bareos
[ ! -d $BACKUP ] && install -d -o root -g root -m 0700 $BACKUP

# Sincronizamos configuración, registros y programa 
$RSYNC /opt/odoo $BACKUP/code
$RSYNC --include="*/" --include="*odoo*" --exclude="*" /etc /var/backups/odoo-latest/
$RSYNC /var/log/odoo $BACKUP/log 

Y el directorio me queda de esta forma:

tree -L 1 /var/backups/odoo-latest/
/var/backups/odoo-latest/
├── code
├── etc
└── log

Ahora los datos

Existen dos formas de salvar bases de datos en PostgreSQL: la primera es emplear el famoso volcado en texto como instrucciones SQL. Es un todo o nada (aunque hay cosas que pueden excluirse, claro) y me sigue pareciendo una medida algo burda.

Actualmente el volcado principal ocupa cerca de 43Gb de texto plano. Si se sigue un mínimo orden sólo se verán modificaciones en las últimas líneas, pero por lo que he podido ver en la documentación ni pg_dumpall ni pg_dump mencionan nada al respecto. Asumo que será así, por lo que mi estrategia consiste en dividir en fragmentos el archivo SQL empleando la herramienta split (sin comprimir) y así dejar que sea el programa de copias el que decida qué se ha modificado y qué no.

$ sudo -u postgres nice pg_dumpall > /tmp/postgresql.sql
$ cd /var/backups/odoo-bareos
$ cat /tmp/postgresql.sql | split --suffix-length=4 --bytes 100M -d - odoo-pg-
$ ls -ltra | tail 
-rw-r--r-- 1 root root 104857600 nov 30 07:29 odoo-pg-0222
-rw-r--r-- 1 root root 104857600 nov 30 07:29 odoo-pg-0223
-rw-r--r-- 1 root root 104857600 nov 30 07:29 odoo-pg-0224
-rw-r--r-- 1 root root 104857600 nov 30 07:30 odoo-pg-0225
-rw-r--r-- 1 root root 104857600 nov 30 07:30 odoo-pg-0226
-rw-r--r-- 1 root root 104857600 nov 30 07:30 odoo-pg-0227
-rw-r--r-- 1 root root 104857600 nov 30 07:30 odoo-pg-0228
-rw-r--r-- 1 root root 104857600 nov 30 07:30 odoo-pg-0229
-rw-r--r-- 1 root root 104857600 nov 30 07:30 odoo-pg-0230
-rw-r--r-- 1 root root  61694889 nov 30 07:30 odoo-pg-0231
$

La segunda forma es más compleja y necesita una mayor comprensión por mi parte. Hablaré de ella en otro artículo si consigo ponerla en marcha, pero se trata de algo llamado Continuous Archiving and Point-in-Time Recovery (PITR).

Enlaces y referencias