首页 > ODOO > 正文

Odoo 数据库备份与恢复怎么做?实操指南

fenij 2026-08-03 2 ODOO

Odoo 的所有业务数据都在 PostgreSQL 里——客户、订单、库存、财务凭证。数据库丢了,上面的一切都没了。备份这事看着简单,但 Odoo 的备份有几个坑:文件存储(attachments)不在数据库里、多数据库环境容易漏、pg_dump 版本不匹配会报错。下面把备份和恢复都走一遍。

方式一:Odoo 自带的数据库管理界面

Odoo 有个 web 界面的备份功能,访问 https://你的域名/web/database/manager,点 Backup 就能下载一个 zip 包。这个 zip 包含数据库 dump 和文件存储目录。

方便是方便,但有几个问题:

  • 大数据库(几个 GB)容易超时失败,nginx/PHP 的超时限制会截断下载
  • 备份过程会锁表,生产环境白天备份可能影响业务
  • 没法自动化,得手动点

小库(几百 MB 以内)可以用这个方式。大库用下面的命令行。

方式二:命令行备份(推荐)

命令行备份分两部分:PostgreSQL 数据库 + Odoo 文件存储。

备份 PostgreSQL

# 找到 Odoo 用的数据库名
sudo -u postgres psql -c "\l" | grep odoo

# 用 pg_dump 导出(custom 格式,恢复时更灵活)
sudo -u postgres pg_dump -Fc -d odoo_prod -f /backup/odoo_prod_$(date +%Y%m%d).dump

-Fc 是 custom 格式,比纯 SQL 文本恢复快,而且支持选择性恢复单张表。如果用纯文本格式(-Fp),恢复时得手动处理依赖顺序,大库会很慢。

备份文件存储

Odoo 的附件、上传的图片、文档都存在文件系统里,默认路径在 ~/.local/share/Odoo/filestore/数据库名/。这个目录必须一起备份,否则恢复后所有附件都是裂图。

# 打包文件存储
tar czf /backup/filestore_$(date +%Y%m%d).tar.gz -C ~/.local/share/Odoo/filestore/ odoo_prod/

如果你的 odoo.conf 里配了 data_dir,去那个路径找 filestore。

自动化备份脚本

写个脚本放 crontab 里每天跑:

#!/bin/bash
# /opt/odoo/backup.sh
DB_NAME="odoo_prod"
BACKUP_DIR="/backup"
DATE=$(date +%Y%m%d)
RETAIN_DAYS=30

# 备份数据库
sudo -u postgres pg_dump -Fc -d $DB_NAME -f $BACKUP_DIR/db_${DB_NAME}_${DATE}.dump

# 备份文件存储
DATA_DIR=$(grep ^data_dir /etc/odoo/odoo.conf | cut -d= -f2 | tr -d ' ')
if [ -z "$DATA_DIR" ]; then
    DATA_DIR="$HOME/.local/share/Odoo"
fi
tar czf $BACKUP_DIR/filestore_${DB_NAME}_${DATE}.tar.gz -C $DATA_DIR/filestore/ $DB_NAME/

# 删除超过保留天数的旧备份
find $BACKUP_DIR -name "db_${DB_NAME}_*.dump" -mtime +$RETAIN_DAYS -delete
find $BACKUP_DIR -name "filestore_${DB_NAME}_*.tar.gz" -mtime +$RETAIN_DAYS -delete

echo "Backup done: $DATE"

加到 crontab:

# 每天凌晨 3 点备份
0 3 * * * /opt/odoo/backup.sh >> /var/log/odoo-backup.log 2>&1

异地备份

本地备份没意义——服务器挂了备份也跟着没。把备份文件传到别的地方:

# 用 rsync 传到另一台服务器
rsync -az /backup/ user@backup-server:/odoo-backups/

# 或者传到对象存储(S3/OSS/COS)
aws s3 sync /backup/ s3://your-bucket/odoo-backups/ --delete

加到备份脚本最后一行就行。

恢复数据库

测试恢复很重要,没验证过的备份等于没有备份。

恢复 PostgreSQL

# 先停 Odoo 服务
systemctl stop odoo

# 恢复数据库(custom 格式用 pg_restore)
sudo -u postgres dropdb odoo_prod
sudo -u postgres createdb odoo_prod
sudo -u postgres pg_restore -d odoo_prod -Fc /backup/db_odoo_prod_20260803.dump

如果只想恢复单张表(比如误删了某张表):

sudo -u postgres pg_restore -d odoo_prod -t sale_order -Fc /backup/db_odoo_prod_20260803.dump

注意 pg_restore 不会自动清空目标表,已存在的数据会冲突。恢复单表前先 TRUNCATE。

恢复文件存储

# 解压文件存储到对应目录
tar xzf /backup/filestore_odoo_prod_20260803.tar.gz -C $DATA_DIR/filestore/

# 确保权限正确
chown -R odoo:odoo $DATA_DIR/filestore/odoo_prod/

# 启动 Odoo
systemctl start odoo

常见踩坑

pg_dump 版本不匹配:如果备份和恢复用的 PostgreSQL 版本不一样,pg_restore 可能报错。尽量用相同版本。实在不行,用纯文本格式 -Fp 导出,然后 psql < dump.sql 导入,跨版本兼容性更好。

文件存储路径搞错:恢复后附件打不开,十有八九是 filestore 路径不对。在 Odoo 后台看一条带附件的记录,检查浏览器请求的附件 URL 对应的物理路径,和你的 filestore 目录对上。

多数据库环境:如果服务器上有多个 Odoo 数据库,备份脚本要遍历所有库。别只备了生产库忘了测试库(虽然测试库丢了不太心疼,但配置数据还是有价值的)。

更多 Odoo 运维教程,请访问 fenij.com

常见问题

问:备份文件多大算正常?
答:取决于业务量和附件数量。纯数据库通常几百 MB 到几 GB。文件存储可能更大——如果有大量产品图片或文档附件,几十 GB 也有可能。定期检查备份文件大小变化,突然增大可能是有异常数据写入。

问:能不能用 Odoo 的 database manager 界面恢复?
答:可以,但大文件容易超时。命令行恢复更可靠。如果一定要用界面恢复,先把 PHP/nginx 的 max_execution_time 和 client_max_body_size 调大。

问:pg_dump 会不会锁库影响业务?
答:pg_dump 默认不会锁表,它用一个事务快照导出一致性数据。导出过程中写入操作正常进行,但导出的是开始那一刻的数据状态。大库导出可能消耗较多 IO,建议在低峰期执行。