Ir al contenido

¿Cómo sabes si una copia de seguridad de Odoo realmente se restaurará?

¿Cómo sabes si una copia de seguridad de Odoo realmente se restaurará?
Benjamin Akboka Apengu
agosto 24, 2026 · 15 min leído


Casi todos los que utilizan Odoo tienen copias de seguridad. Casi nadie tiene una restauración.

Esas son dos cosas diferentes, y la brecha entre ellas es de donde provienen los días malos. Un trabajo de copia de seguridad que te dará un sistema funcional y uno que no te dará nada se ven exactamente iguales desde afuera: mismo horario, misma marca verde, mismo archivo aterrizando en el mismo cubo cada noche. Nada en ningún lugar te dice cuál tienes.

Esta no es una guía para configurar copias de seguridad de Odoo. Ya has hecho eso, y ya hay muchas de esas. Esta es la otra mitad: cómo probar que la cosa que has estado recolectando cada noche durante el último año realmente volverá, en un martes normal, en aproximadamente una hora.

Respuesta corta

No puedes saber si una copia de seguridad de Odoo se restaurará hasta que la hayas restaurado. No hay ninguna propiedad del archivo de copia de seguridad, del registro de trabajo o del cubo de almacenamiento que te lo diga. Una copia de seguridad que producirá un sistema funcional y una que no producirá nada se ven idénticas desde afuera.

Para averiguarlo, restáuralo en una base de datos aislada con `psql -v ON_ERROR_STOP=1` (sin esa bandera, una restauración fallida aún sale `0`), confirma que el `filestore/` de la copia de seguridad contiene cada archivo que la restaurada `ir_attachment` referencia, luego compara los recuentos de registros y un total financiero contra producción. Ejecútalo trimestralmente y registra cuánto tiempo tomó. Ese número es tu verdadero tiempo de recuperación.

El procedimiento completo está a continuación, y toma aproximadamente una hora la primera vez.

Dos verificaciones para ejecutar ahora mismo

1. ¿Tu copia de seguridad contiene los archivos, o solo la base de datos?

unzip -l backup.zip | grep -c 'filestore/'

Cero significa que tienes una copia de seguridad de la base de datos, no una copia de seguridad de Odoo.

Los archivos adjuntos, documentos subidos, imágenes de productos, PDFs generados y archivos adjuntos de correo electrónico no se almacenan en PostgreSQL por defecto. La base de datos contiene una `ir_attachment` fila cuya `store_fname` apunta a una ruta, y el archivo en sí vive en el directorio de filestore en el disco. Restaura solo la base de datos y cada registro vuelve con sus documentos vacíos.

Eso aún puede ser una elección deliberada. Algunos equipos mantienen archivos adjuntos en almacenamiento de objetos y los respaldan por separado. Debería ser una elección que hiciste, no una que descubras.

2. ¿Los archivos adjuntos ya están rotos en producción?

Esta es la que sorprende a la gente. Ejecútalo contra tu base de datos en vivo, antes de cualquier pregunta de respaldo:

DB=odoo_prod
FS=/var/lib/odoo/filestore/$DB

psql -d "$DB" -tAc \
"SELECT store_fname FROM ir_attachment WHERE store_fname IS NOT NULL" \
| LC_ALL=C sort -u > /tmp/db_files.txt
( cd "$FS" && find . -type f -printf '%P\n' ) | LC_ALL=C sort > /tmp/fs_files.txt

echo "archivos adjuntos cuyo archivo falta: $(comm -23 /tmp/db_files.txt /tmp/fs_files.txt | wc -l)"
echo "archivos huérfanos sin fila de adjunto: $(comm -13 /tmp/db_files.txt /tmp/fs_files.txt | wc -l)"

El primer número debería ser cero.

Si no lo es, esos documentos ya se han ido, y han estado ausentes un tiempo, porque Odoo no lo anuncia. Un archivo de filestore faltante se detecta, se registra a nivel INFO, y regresa como una cadena de bytes vacía. El archivo adjunto mantiene su nombre de archivo original y su tamaño registrado, y se descarga como nada.

Esta es la razón por la que existe todo el procedimiento a continuación: verificar una restauración abriéndola y haciendo clic por ahí pasará con cada archivo adjunto roto. Los registros, los nombres de archivo y los tamaños de archivo lucen exactamente como deberían.

La barra: lo que "probado" realmente significa

La regla general habitual para copias de seguridad es 3-2-1-1-0: tres copias de los datos, en dos tipos de medios, una fuera del sitio, una fuera de línea o inmutable, y cero errores en una restauración verificada.

La mayoría de las configuraciones de Odoo funcionan razonablemente bien en los primeros cuatro números y omiten el último por completo. Lo cual es una pena, porque el cero es el único que prueba que el resto valía algo. Copias que no puedes restaurar son solo almacenamiento.

Hay dos números más que deberías poder decir en voz alta, y solo una restauración real te dará alguno de ellos:

  • RPO: cuánto dato perderías. No "hacemos copias de seguridad cada noche a las 2am". Si la falla ocurre a las 4pm, pierdes catorce horas de facturación. ¿Es eso aceptable? Esa es una pregunta de negocio con una respuesta real, y la respuesta suele ser diferente del horario que alguien estableció una vez y nunca volvió a mirar.
  • RTO: cuánto tiempo estarías fuera. Este es el que se adivina, y la suposición es generosa. Una prueba de restauración lo convierte en una medición: descarga, restauración, copia de filestore, carga de módulo, verificaciones. En una base de datos grande, el número real a menudo se encuentra horas lejos del que la gente asume, y es mucho mejor aprender eso hoy.

Todo lo que sigue es sobre llegar a ese cero.

Cómo probar una copia de seguridad de Odoo, paso a paso

Antes de comenzar, obtén un objetivo aislado: una rama de staging, un servidor de repuesto, o una laptop con Docker. No producción, y nada que comparta una ruta de red con el servidor de correo de producción, proveedores de pago o sincronización bancaria.

Paso 1: Obtén la copia de seguridad de donde realmente vive

Descárgala del bucket de almacenamiento, con credenciales que no son de producción, en una máquina que no es el servidor de producción.

Una copia de seguridad que solo puedes recuperar *usando* el servidor de producción no es una copia de seguridad. Es una segunda copia de la cosa contra la que te estás protegiendo. Este paso es la prueba de eso, y es el que la gente omite porque se siente más como administración que como ingeniería.

Paso 2: Prueba que el archivo esté intacto antes de usarlo

unzip -t backup.zip && unzip -l backup.zip | tail -3

`unzip -t` verifica los checksums internos del archivo. Esto detecta descargas truncadas y cargas a medio terminar, que importan más de lo que deberían, porque un `dump.sql` se restaura silenciosamente hasta el punto donde fue cortado.

Paso 3: Lee el manifiesto y compáralo con el objetivo

Cada volcado zip de Odoo lleva un `manifest.json`, escrito por `dump_db_manifest` (odoo/service/db.py):

unzip -p backup.zip manifest.json | python3 -m json.tool | head -20

Registra la versión de Odoo, la versión principal de PostgreSQL y cada módulo instalado con su versión. Entre ellos te dicen exactamente lo que necesita este volcado antes de que pueda significar algo.

Verifica tres cosas:

  • versión contra la versión de Odoo del objetivo. La misma versión es una restauración. Una diferente es una actualización, y las actualizaciones pertenecen a un ensayo, no a un incidente.
  • pg_version contra el PostgreSQL del objetivo. De más antiguo a más nuevo es rutina. De más nuevo a más antiguo es donde las restauraciones comienzan a perder declaraciones.
  • módulos contra lo que está instalado en el objetivo, incluyendo terceros, OCA y los tuyos.

Vale la pena saber: `restore_db` extrae `dump.sql` y los `filestore/` miembros y nada más. El manifiesto está escrito en cada copia de seguridad y no es leído por nada en la base de código. Existe para ti.

Paso 4: Restaura el SQL tú mismo, con errores activados

Este es el paso que separa una prueba de una esperanza. No uses el administrador de bases de datos para ello:

createdb restore_test_2026_08
time unzip -p backup.zip dump.sql \
| psql -v ON_ERROR_STOP=1 --dbname=restore_test_2026_08
echo "exit: $?"

-v ON_ERROR_STOP=1 es el objetivo completo de este paso. Sin esa bandera, `psql` omite las declaraciones que fallan, continúa hasta el final del archivo y sale `0`, por lo que una base de datos parcial se informa como una restauración exitosa. Con ella, la restauración se detiene en el primer error y sale `3`, y obtienes el texto del error: la extensión faltante, el rol ausente, la brecha de versión.

La salida `0` ahora significa lo que siempre asumiste que significaba.

`tiempo` te da el componente único más grande de tu RTO real. Escríbelo. Lo querrás en el paso 8.

Paso 5: Verifica que el filestore esté completo antes de copiarlo

Ahora que la base de datos está restaurada, compara lo que espera con lo que realmente contiene la copia de seguridad:

unzip -Z1 backup.zip | sed -n 's|^filestore/||p' \
| grep -v '/$' | grep -v '^$' | LC_ALL=C sort > /tmp/zip_files.txt
psql -d restore_test_2026_08 -tAc \
"SELECT store_fname FROM ir_attachment WHERE store_fname IS NOT NULL" \
| LC_ALL=C sort -u > /tmp/db_files.txt

echo "adjuntos sin archivo en esta copia de seguridad: $(comm -23 /tmp/db_files.txt /tmp/zip_files.txt | wc -l)"

Cero es el pase. Cualquier otro número te está diciendo exactamente cuántos documentos esta copia de seguridad no puede devolverte.

Ambos `LC_ALL=C` y el `grep -v '^$'` importan: el orden de clasificación debe coincidir en ambos lados, y `unzip -Z1` emite la entrada de directorio bare `filestore/` que se convierte en una línea vacía y envenena silenciosamente la comparación.

Luego copia los archivos en su lugar como `filestore/restore_test_2026_08` en el directorio de datos del objetivo, y establece la propiedad para que Odoo pueda leer y escribirlos.

Paso 6: Neutraliza antes de que alguien lo abra

Los datos de producción restaurados llegan con sus servidores de correo saliente, acciones programadas, proveedores de pago y conectores intactos. La neutralización es un paso separado y opcional. No ocurre porque hayas restaurado.

Ejecuta esto antes de que Odoo comience, y arranca Odoo con semántica de copia para que la base de datos restaurada obtenga su propia identidad en lugar de la de producción. Lo que cubre la neutralización, lo que deja armado y por qué la parte de identidad es importante tiene su propia guía *(enlace a la publicación aquí al publicar)*. Léela antes de ejecutar este procedimiento contra datos reales.

Paso 7: Verifica los datos contra números que ya conoces

Ningún código de salida puede hacer esta parte.

Antes de comenzar, ejecuta una huella en producción y guarda la salida:

SELECT 'account_move'      AS t, count(*), max(id), max(write_date) FROM account_move
UNION ALL SELECT 'account_move_line', count(*), max(id), max(write_date) FROM account_move_line
UNION ALL SELECT 'sale_order', count(*), max(id), max(write_date) FROM sale_order
UNION ALL SELECT 'stock_move', count(*), max(id), max(write_date) FROM stock_move
UNION ALL SELECT 'res_partner', count(*), max(id), max(write_date) FROM res_partner;

Ejecuta la misma consulta contra la restauración y compara las dos. Los conteos de filas detectan datos faltantes; `max(id)` detecta una restauración que se detuvo temprano; `max(write_date)` detecta una copia de seguridad que es más antigua de lo que piensas.

Agrega las tablas que importan a *tu* negocio. Si vives en órdenes de fabricación o suscripciones, ponlas en la lista.

Luego, en la interfaz:

  • Un total financiero que puedes verificar. Ingresos del año actual, o un saldo bancario. Un número que es correcto o incorrecto.
  • Abre tres adjuntos de diferentes meses, incluyendo uno de esta semana, y verifica el tamaño del archivo descargado, no solo que algo se haya descargado. Este es el único lugar donde se muestra el comportamiento del archivo vacío.
  • Carga una pantalla de cada módulo personalizado. Un módulo que falta en el objetivo deja sus tablas restauradas y sus datos inalcanzables, y la interfaz es donde lo ves.

Paso 8: Regístralo, luego destruye la base de datos de prueba

Escribe cuatro cosas: la fecha, qué copia de seguridad usaste, el tiempo total transcurrido y qué falló.

El tiempo transcurrido es tu RTO: medido, no adivinado. Cuatro de estos registros y tienes una tendencia, que es el momento en que esto deja de ser una tarea y se convierte en evidencia. También es el número que debes llevar cuando alguien pregunta si el hosting es adecuado, porque responde a la pregunta que realmente están haciendo.

Luego elimina la base de datos de prueba y quita la copia del almacén de archivos.

Cómo se ve un pase

  • `unzip -t` limpio
  • El manifiesto coincide con el objetivo en la versión de Odoo, la versión de PostgreSQL y la lista de módulos
  • `psql -v ON_ERROR_STOP=1` sale `0`
  • Cero adjuntos faltantes de la copia de seguridad
  • La huella digital coincide con la producción en conteos, id máximo y fecha de escritura máxima
  • Tres adjuntos se abren al tamaño de archivo correcto
  • La pantalla de cada módulo personalizado se carga
  • Tiempo transcurrido registrado

Cualquier cosa menos que eso es un hallazgo, y un hallazgo hoy vale mucho más que el mismo hallazgo durante una interrupción.

¿Con qué frecuencia, y quién?

Trimestral es el mínimo. También ejecútalo después de cualquier cosa que cambie la forma del sistema: un cambio de hosting, una actualización de PostgreSQL, una actualización de versión de Odoo, un nuevo módulo en producción, o un cambio en dónde se almacenan las copias de seguridad.

Una persona nombrada es la responsable. No "el equipo". Las pruebas de respaldo suenan como algo que cualquiera podría hacer, por eso generalmente termina siendo hecho por nadie. Toma una hora por trimestre. Ponlo en un calendario con un nombre.

Mantén los registros juntos, en lo que tu empresa ya utiliza. Cuatro entradas fechadas con tiempos transcurridos es una posición de recuperación ante desastres. Cero entradas es una esperanza, por muy buena que sea la configuración de respaldo.

Qué automatizar, y qué queda humano

Automatiza las partes objetivas y aburridas: una restauración que se detiene en error, una verificación de integridad de archivo, una comparación de completitud de almacenamiento, un registro de tamaño y suma de verificación para cada copia de seguridad, y una alerta cuando una copia de seguridad llega más de unos pocos por ciento más pequeña que la anterior. Ninguna de esas necesita juicio, y todo es programable.

Lo que no se automatiza es el paso 7. "Completo" se define por números que solo tu negocio conoce: los ingresos del mes pasado, el conteo de facturas, si el documento que necesita tu contador se abre. Ninguna plataforma puede verificar eso por ti, y cualquier plataforma que diga que verifica completamente tus restauraciones está usando la palabra para significar algo más pequeño.

Así que: la automatización debería hacer que una restauración fallida sea imposible de pasar por alto, y un humano aún verifica que el contenido sea correcto. La segunda parte es media hora un cuarto.

Lo que esto realmente es

Las copias de seguridad no se descuidan. Se ejecutan, se ponen en verde, y casi todos las tienen. La brecha está entre una copia de seguridad que se *toma* y una copia de seguridad que es *restaurable*, y permanece abierta porque ambos estados se ven idénticos desde afuera. Una copia de seguridad que nunca se restaurará se ve exactamente como una que sí lo hará, hasta el día que la necesites. Que es el peor día posible para descubrirlo.

Esa es la diferencia entre Odoo funcionando y Odoo funcionando correctamente, en la forma más costosa que toma. Nada dramático. Solo un archivo que nadie abrió nunca, durante un año.

Y te cuesta algo cada día antes de eso. Nadie confía del todo en las copias de seguridad, así que nadie confía del todo en hacer cambios tampoco. Las actualizaciones se posponen, las actualizaciones de módulos se posponen, y el sistema se aleja aún más de cualquier cosa que querrías restaurar de todos modos.

Restauraciones que se prueban porque suceden

La versión confiable de esto no es una mejor lista de verificación. Es un camino de restauración que se ejecuta con suficiente frecuencia para haber sido probado, y que falla ruidosamente cuando falla.

En Skysize Odoo hosting, la restauración se ejecuta `psql -q -v ON_ERROR_STOP=1`, la misma bandera que el paso 4, así que un fallo a nivel de declaración aborta la restauración y falla el trabajo en lugar de producir una base de datos parcial con un código de salida limpio. Las líneas que de otro modo abortarían una restauración legítima (configuraciones de servidor solo más recientes de un `pg_dump más reciente, DDL de extensión gestionada por el proveedor) se eliminan deliberadamente, y el número eliminado se escribe en el registro del trabajo. Eliminado a propósito y contado, en lugar de omitido y descartado.

Las restauraciones son azul-verde: una nueva base de datos y un nuevo contenedor se inician en un nuevo puerto mientras la implementación anterior sigue sirviendo, y la nueva debe comenzar y pasar una verificación de salud antes de que se realice cualquier cambio. Solo entonces se elimina la implementación antigua. Si algún paso falla, la implementación a medio construir se desmantela y el contenedor antiguo nunca se toca. Estás exactamente donde estabas, aún sirviendo. Y las ramas de staging se neutralizan automáticamente cuando llegan los datos de producción, lo que hace que restaurar en staging para *verificar* una copia de seguridad sea una tarde ordinaria en lugar de un riesgo.

Lo que nada de eso hace, y preferiríamos decirlo: no verifica que los totales de tu factura sean correctos. Nuestra verificación de salud prueba que la implementación restaurada arranca y responde. No puede probar que las facturas del jueves pasado estén allí. El paso 7 sigue siendo tuyo, en cualquier plataforma.

Construido por exingenieros de Odoo, certificado ISO 27001. Habla con un experto en hosting de Odoo sobre cómo se ve realmente tu recuperación.

Si prefieres ejecutarlo en tu propia máquina, en tu propio país, Skysize BYOS pone la misma plataforma en tu servidor. Conecta tu servidor.

¿Cómo sabes si una copia de seguridad de Odoo realmente se restaurará?
Benjamin Akboka Apengu
Escribe sobre la infraestructura de Odoo en Skysize, un proveedor de alojamiento Odoo gestionado con sede en Bélgica que atiende a empresas y agencias en todo el mundo.