- Published on
Automating MongoDB Database Backup Using Cron and Shell Script
In this post, I want to write about how to automatically backup a database using Cron and Shell Script. I believe that database backup is very important, as I myself, being a server administrator, have experienced a security breach, and the last backup I had was very old and was done manually. Of course, that incident was quite an adrenaline rush, haha.
Okay... enough with the story... let's discuss what Cron is and what Shell Script is.
Cron is a default program available on Linux or Unix operating systems that is used to run tasks scheduled in the crontab (cron table).
Shell Script is a series of commands that will be executed by the shell. Wait... then what is Shell?
Shell is a program that acts as a bridge between the user and the operating system so they can communicate with each other. ~~I think that’s how it works.~~
Create Shell Script
First, let's create the shell script file
touch mongodb_backup.sh
nano mongodb_backup.sh
Here, I’m using someone else's script, which I’ve slightly modified to suit my server’s needs.
Here’s the script along with an explanation:
#!/bin/bash
######################################################################
##
## MongoDB Database Backup Script
## Written By: Rahul Kumar
## URL: https://tecadmin.net/shell-script-backup-mongodb-database/
## Updated on: June 20, 2020
##
######################################################################
set -e
export PATH=/bin:/usr/bin:/usr/local/bin
TODAY=`date +"%d%b%Y"` # Get today’s date
LAST_DAY=`date -d "-$(date +%d) days +1 month" +%d%b%Y` # Get the last day of the current month
DB_BACKUP_PATH='/home/user/backups/daily' # Path for daily backup directory
DB_BACKUP_PATH_MONTHLY='/home/user/backups/monthly' # Path for monthly backup directory, leave empty if monthly backup is not needed
MONGO_HOST='localhost'
MONGO_PORT='27017'
# If MongoDB is protected with a username and password,
# Set AUTH_ENABLED to 1
# and add the correct values for MONGO_USER and MONGO_PASSWD
AUTH_ENABLED=0 # Change to 1 if authentication is required
MONGO_USER=''
MONGO_PASSWD=''
# Set DATABASE_NAMES to "ALL" to backup all databases,
# or specify database names separated by spaces to backup
# only specific databases.
DATABASE_NAMES='db_name' # Value of the database name to be backed up
## Number of days to keep the local backup copy
BACKUP_RETAIN_DAYS=7 # Number of days to keep the backup stored locally
######################################################################
######################################################################
mkdir -p ${DB_BACKUP_PATH}/${TODAY} # Create a directory for today’s backup
AUTH_PARAM=""
# If MongoDB requires user authentication
if [ ${AUTH_ENABLED} -eq 1 ]; then
# Add username and password parameters
AUTH_PARAM=" --username ${MONGO_USER} --password ${MONGO_PASSWD} "
fi
# If the value of DATABASE_NAMES is ALL
if [ ${DATABASE_NAMES} = "ALL" ]; then
# Backup all databases
echo "You have chosen to backup all databases"
mongodump --host ${MONGO_HOST} --port ${MONGO_PORT} ${AUTH_PARAM} --out ${DB_BACKUP_PATH}/${TODAY}/
else
# If not, backup according to the list
echo "Running backup for selected databases"
for DB_NAME in ${DATABASE_NAMES}
do
mongodump --host ${MONGO_HOST} --port ${MONGO_PORT} --db ${DB_NAME} ${AUTH_PARAM} --out ${DB_BACKUP_PATH}/${TODAY}/
done
fi
# If today’s date is the same as the last day of the month
# and DB_BACKUP_PATH_MONTHLY is not empty
if [ "$TODAY" == "$LAST_DAY" ] && [ ! -z ${DB_BACKUP_PATH_MONTHLY} ]; then
# Create a monthly directory
mkdir -p ${DB_BACKUP_PATH_MONTHLY}
# Copy today’s backup to the monthly directory
cp -ar ${DB_BACKUP_PATH}/${TODAY} ${DB_BACKUP_PATH_MONTHLY}/${LAST_DAY}
fi
######## Remove backups older than {BACKUP_RETAIN_DAYS} days ########
# Get today’s date minus the value of BACKUP_RETAIN_DAYS
DBDELDATE=`date +"%d%b%Y" --date="${BACKUP_RETAIN_DAYS} days ago"`
# If DB_BACKUP_PATH is not empty
if [ ! -z ${DB_BACKUP_PATH} ]; then
cd ${DB_BACKUP_PATH}
# If DBDELDATE is not empty
# and DBDELDATE is a directory
if [ ! -z ${DBDELDATE} ] && [ -d ${DBDELDATE} ]; then
# Delete the backup directory
rm -rf ${DBDELDATE}
fi
fi
######################### End of script ##############################
From the script above, we’ve created a shell script that can be executed daily to perform daily and monthly database backups by creating directories according to the date the script is executed and automatically deleting old directories based on the backup retention days we’ve set in the script.
Next, we need to set the file’s permissions so it can be executed:
chmod +x mongodb_backup.sh
Create Crontab
After that, we create a crontab to execute the script by running the command:
crontab -e
Then add the following script:
0 2 * * * /home/user/backups/mongodb_backup.sh >> /home/user/backups/mongodb_backup.log 2>&1
The script above means that we are adding a task for cron to run the mongodb_backup.sh script every day at 2 AM.
Additional
If you encounter the error ... mongodump error Unrecognized field 'snapshot'.
while executing the script, add the --forceTableScan
option to the mongodump command in the script:
mongodump --forceTableScan --host ${MONGO_HOST} --port ${MONGO_PORT} ${AUTH_PARAM} --out ${DB_BACKUP_PATH}/${TODAY}/
This usually happens when the mongodump tool version differs from the target database version.
Oh yeah, to restore the database, you can use the following command:
mongorestore -d db_name db_name_directory
You can download the original script from GitHub.
That’s all, see ya~