Considerations before starting
The Backup button visible on the http://your_odoo_example.com/web/database/manager
URL, packages both the Filestore and the Database on a compressed *.zip
file, that the Odoo Database Manager through the same URL can decompress and restore.
It's also important to know that to generate a full backup of Odoo three essential parts are needed:
- Filesystem (Usually a GIT Repo)
- Database (Can be done through the Odoo Database Manager as stated before)
- FileStore (Can be done through the Odoo Database Manager as stated before)
Without a backup and restore of the Filestore, there's a chance of getting errors and having Odoo not work well, or at least make the log unreadable if it's flooded with attachment errors.
It's recommended that you stop the Odoo Services on both current and target Database locations, PostgreSQL will complain about the Database still being accessed.
Requirements:
- Access to the
psql
command
- The user and password to your Odoo database
The information on both user and password is most likely on the odoo.conf file, assuming it is on the most used path /etc/odoo/odoo.conf
it's easy to retrieve with:
grep 'db_password\|db_user\|db_name' /etc/odoo/odoo.conf
Test access to the psql
console with the resulting values of db_user, db_name and db_password executing:
psql -U db_user -d db_name
it should either log in directly or ask for a password, the result should be something like this:
❯ psql db_user -d db_name
Password for user db_user:
psql (11.13)
Type "help" for help.
db_name=#
Getting an error message most likely means PostgreSQL will need additional configuration on the pg_hba.conf
and/or postgres.conf
files, it'll be a topic on its own to also cover it here.
The bash
commands
With all that information and if everything went good accessing psql
, we are ready for a solution to do it through bash,
Execute via psql
commands, one to generate a Database dump,
preferably one that will also compress the file for easier transport
if you need to download, this is a simple version of one of the
options:
pg_dump -U db_user -d db_name | bzip2 >
backup_name-DDMMYYY.sql.bz2
To restore the Database dump execute a similar command that will
restore it from the *.sql.bz2
file, however, it needs to first
be created as an empty target Database, with:
createdb -U db_user db_name
Have in mind that if you have restored the Database before, and you
want to use the same name, you'll need to drop the Database you are
not going to use anymore, for that you can use:
dropdb -U db_user target_db_name
MAKE SURE! you're not dropping the original Database you intend to backup.
Once you have the empty target Database to restore the backup you'll
need to run a command that will decompress the dump and then write
it on the empty target Database:
bzcat backup_name-DDMMYYY.sql.bz2 | psql -U db_user -d target_db_name
That should be good enough to get your Database back up and running
Finally set the owner of the Database to the user of the target Database location:
psql -U db_user -d target_db_name -c "ALTER DATABASE \"target_db_name\" OWNER TO target_db_user"
The bash
script
To really streamline the process create via vim or nano at the .bashrc
PATH
an executable command to use regardless of the current directory being worked on, an example that will work for a Standard Debian/Ubuntu Linux distribution is:
sudo nano /usr/local/bin/your_command_name
Assuming the Service names for both Odoo and PostgreSQL are respectively, odoo and PostgreSQL this is an option for a bash
script to achieve the task:
#!/bin/bash
## Variables
# Name of Local Database to Drop and Recreate
target_db_name="replace_with_your_db_name"
# Local Credentials
db_user="replace_with_your_db_user"
db_password="replace_with_your_db_password"
target_db_user="replace_with_your_targer_db_user"
## Database Backup Files selection
# Set all the files in an array named $files
files=( /replace_with_your/path_to/database_backups/*.sql.bz2 )
shopt -s extglob
# Build the string to use for the case options
string="@(${files[0]}"
# Add file names to the string
for((i=1;i<${#files[@]};i++))
do
string+="|${files[$i]}"
done
# Add the rest of the syntax to $string resulting in something like @(file1|file2|file3|...|fileN)
string+=")"
# Case for Database Backup *.sql.bz2 File
select file in "${files[@]}" "quit"
do
case $file in
## If the choice is one of the files (if it matches $string)
$string)
## PostgreSQL commands
# Stops Odoo Server Service
systemctl stop odoo
# Starts PostgreSQL Service
systemctl restart PostgreSQL
# Drop target_db_name
PGPASSWORD=$db_password psql -U $db_user -c "DROP DATABASE \"$target_db_name\""
# Creates Empty target_db_name
PGPASSWORD=$db_password psql -U $db_user -c "CREATE DATABASE \"$target_db_name\""
# Generates Target Database from dump file
bzcat $file | PGPASSWORD=$db_password psql -U $db_user $target_db_name
# New Database gets psql User by Default as Owner, must change to Local Database instance owner
PGPASSWORD=$db_password psql -U $db_user -d $target_db_name -c "ALTER DATABASE \"$target_db_name\" OWNER TO $taregt_db_owner"
# Starts PostgreSQL Service
systemctl restart PostgreSQL
# Starts Odoo Server Service
systemctl start odoo
;;
"quit")
## Exit
echo
echo
exit
;;
*)
file=""
echo "Please choose a number from 1 to $((${#files[@]}+1))"
;;
esac
done
The bash
script will require sudo execution since it involves stopping and starting daemon services:
sudo your_command_name
About the db_name and db_password on the bash
script
There are better ways to do this, f example, it's not necessary to set the db_password on the bash
script, it can be passed by setting it as an environment variable or through a encrypted secrets file along with the db_user, I'm sure there are other topics that will cover them but this should get things started.
I hope this helps someone.