Backup script for mongodb
This commit is contained in:
File diff suppressed because it is too large
Load Diff
111
mongodb-backup.sh
Executable file
111
mongodb-backup.sh
Executable file
@@ -0,0 +1,111 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Use script by passing username, password and path: ./mongodb-backup.sh USER PASSWORD PATH
|
||||
|
||||
mongo_host="localhost"
|
||||
mongo_port="27017"
|
||||
mongo_user=$1
|
||||
mongo_password=$2
|
||||
mongo_auth_db="admin"
|
||||
backup_folder_root=$3
|
||||
|
||||
# set the threshold date as two weeks ago
|
||||
threshold_date=$(date --date="-2 weeks" +%Y%m%d)
|
||||
|
||||
# set the backup parent directory name as today's date in YYYYMMDD format
|
||||
backup_parent_dir=$(date +%Y%m%d)
|
||||
|
||||
# set the backup child directory name as the current time in HH:MM format
|
||||
backup_child_dir=$(date +%H:%M:%S)
|
||||
|
||||
# set the full backup path name as a variable
|
||||
backup_path="${backup_folder_root}/$backup_parent_dir/$backup_child_dir"
|
||||
|
||||
# create the backup parent directory if it doesn't exist
|
||||
mkdir -p "$backup_path"
|
||||
|
||||
# loop through all directories in the parent directory
|
||||
for dir in */; do
|
||||
# check if the directory name is in YYYYMMDD format
|
||||
if [[ "$dir" =~ ^[0-9]{8}/$ ]]; then
|
||||
# get the directory name as a date string
|
||||
dir_date=$(echo "$dir" | sed 's/\///')
|
||||
# compare the directory date to the threshold date
|
||||
if [ "$dir_date" -lt "$threshold_date" ]; then
|
||||
# delete the directory and its contents
|
||||
echo "Deleting $dir"
|
||||
# rm -rf "$dir"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# create the backup child directory if it doesn't exist
|
||||
mkdir -p "$backup_path"
|
||||
|
||||
# Connect to MongoDB
|
||||
|
||||
mongo_uri="mongodb://${mongo_user}:${mongo_password}@${mongo_host}:${mongo_port}/${mongo_auth_db}"
|
||||
mongo_cmd="mongo ${mongo_uri} --quiet"
|
||||
|
||||
# Get information about all current databases and collections
|
||||
declare -A db_current
|
||||
db_collection_info=$($mongo_cmd --eval 'db.getMongo().getDBNames().forEach(function(dbName){var database = db.getSiblingDB(dbName);database.getCollectionNames().forEach(function(collName){var size=database.getCollection(collName).stats().size;print(dbName + "-" + collName + "=" + size);});});')
|
||||
while read -r line; do
|
||||
# split line by equals sign to get key and value
|
||||
key=${line%=*}
|
||||
value=${line#*=}
|
||||
# add key-value pair to dictionary
|
||||
db_current["$key"]="$value"
|
||||
done <<< "$db_collection_info"
|
||||
|
||||
# Get data from previous backup
|
||||
declare -A db_previous
|
||||
# read key-value pairs from file and add to array
|
||||
while IFS='=' read -r key value; do
|
||||
db_previous["$key"]="$value"
|
||||
done < "${backup_folder_root}/db_info.txt"
|
||||
|
||||
# We need the previous backup folder...
|
||||
# get a sorted list of directory names
|
||||
dirlist=$(find ${backup_folder_root}/$backup_parent_dir -maxdepth 1 -type d -printf '%f\n' | sort -n)
|
||||
# find the index of the current directory name
|
||||
index=$(echo "$dirlist" | grep -n "$backup_child_dir" | cut -d: -f1)
|
||||
prev_index=$((index - 1))
|
||||
prev_dirname=$(echo "$dirlist" | sed "${prev_index}q;d")
|
||||
prev_path="${backup_folder_root}/$backup_parent_dir/$prev_dirname"
|
||||
|
||||
echo "Previous directory name: $prev_dirname"
|
||||
echo "Current directory name: $backup_child_dir"
|
||||
|
||||
# if previous folder doesn't exist, or is empty, do a full backup
|
||||
if [ -z "$prev_dirname" ] || [ ! -d "${prev_path}" ] || [ -z "$(find "${prev_path}" -mindepth 1 -print -quit)" ]; then
|
||||
mongodump --username "$mongo_user" --password "$mongo_password" --authenticationDatabase admin --out "$backup_path"
|
||||
else
|
||||
# otherwise only backup what has changed.
|
||||
# Get the list of db folders in previous backup folder
|
||||
for folder_path in "$prev_path"/*/; do
|
||||
database_folder=$(basename "$folder_path")
|
||||
for collection_path in "$folder_path"/*.bson; do
|
||||
filename=$(basename "$collection_path")
|
||||
collection_name="${filename%.*}"
|
||||
collection_key="${database_folder}-${collection_name}"
|
||||
# Check size of previous backed-up collection
|
||||
if test "${db_previous["$collection_key"]}" = "${db_current["$collection_key"]}"; then
|
||||
# Collection size is the same
|
||||
# Move the backup to the new folder
|
||||
mkdir -p "${backup_path}/${database_folder}"
|
||||
mv ${prev_path}/${database_folder}/${collection_name}.* ${backup_path}/${database_folder}
|
||||
# Create symbolic link from files in previous folder to newest one
|
||||
ln -sf ${backup_path}/${database_folder}/${collection_name}.bson ${prev_path}/${database_folder}/${collection_name}.bson
|
||||
ln -sf ${backup_path}/${database_folder}/${collection_name}.metadata.json ${prev_path}/${database_folder}/${collection_name}.metadata.json
|
||||
else
|
||||
# Collection size has changed - backup new data
|
||||
mongodump --username "$mongo_user" --password "$mongo_password" --authenticationDatabase admin --out "$backup_path" --db="$database_folder" --collection="$collection_name"
|
||||
fi
|
||||
done
|
||||
done
|
||||
fi
|
||||
|
||||
# Write current data info to file for next time
|
||||
echo "${db_collection_info}" > "${backup_folder_root}/db_info.txt"
|
||||
|
||||
@@ -6,14 +6,15 @@
|
||||
|
||||
LOG_FILE="/root/scripts/logs/mongodb-status.log"
|
||||
|
||||
status=$(sudo systemctl status mongod)
|
||||
status=$(sudo systemctl status mongodb.service)
|
||||
current_time=$(date +"%Y-%m-%d %T")
|
||||
|
||||
if echo "$status" | grep -qE "Active: running|Active: active"; then
|
||||
echo "[$current_time] Success $(echo "$status" | grep "Main PID")" >> $LOG_FILE
|
||||
else
|
||||
echo "[$current_time] Failed" >> $LOG_FILE
|
||||
sudo service mongod restart
|
||||
sudo systemctl restart mongodb.service
|
||||
echo "MongoDB database service has stopped running, and was restarted" | mail -s "MongoDB down" tessmarka@gmail.com
|
||||
fi
|
||||
|
||||
lines=$(wc -l < $LOG_FILE)
|
||||
|
||||
Reference in New Issue
Block a user