Database Scripts

Beta
 Log In    |   Sign Up

MongoDB : Mongodb data and configuration backup

Added on Dec-23-2015 by Jelong
For MongoDB

Tags : mongodb;mongodump;

Mongodb data backup by using mongodump utility. Read mongodb environment and save configuration file or else save the mongod parameters accordingly. This script has tested on CentOS 6.0, but it will work on most Linux version.

Versions

Tested on CentOS 6.x; Mongodb 3.0.7 under sharding environment.

DOWNLOAD

#!/bin/sh
###############################################################################
# MongoDB backup script
#
# This sciprt can use stand alone, sharding, replication, configuration mongodb
# backup with it's configurations (or configuration file).
# End of the script, it will remove old backup/log file that is older than 7 days!
#
# Usage:
#	bk_mongodb.sh ([PORT] ([SERVER_NAME or IP Address] ([OUTPUT_DIR])))
#   Ex)
#		bk_mongodb.sh 27017 1.2.3.4 ./backup
#		bk_mongodb.sh 27017 1.2.3.4   --> use default backup dir $HOME/backup
#		bk_mongodb.sh 27017           --> use default hostname, $HOME/backup
#		bk_mongodb.sh     --> use all default. 27017, hostname, $HOME/backup
#
# REV#   DATE        AUTHOR         CHANGE DESCRIPTION              
# ------ ----------  -------------- ----------------------------------------------
# 1.4    12/23/2015   Jeyong Park    general backup script with 3 optional parameters.
# --------------------------------------------------------------------------------
# Crontab Run mongodb backup everyday sample
# 0 6 * * * /bk_mongodb.sh 27017 127.0.0.1 ./backup
###############################################################################
#
#
MDB_PORT=27017               #default Port Number
MDB_HOST=`hostname -I|tr -d '[[:space:]]'`  #default IP address
OUT_DIR=$HOME/backup         #default backup dir
MDB_AUTH=                    #No auth. Otherwise MDB_AUTH=-u sa -p pw

if [ $1 ]; then 
MDB_PORT=$1
fi

if [ $2 ]; then 
MDB_HOST=$2
fi

if [ $3 ]; then 
OUT_DIR=$3
fi

### Check OUT_DIR directory
if [ ! -d $OUT_DIR ] ; then 
	echo; echo "=> Backup output directory $OUT_DIR doesn't exist!  Program Exit!!" 2>&1 | tee -a ./bk_mongodb.log
	exit -1
fi

CDATE=`date +"%Y%m%d"`
BAK_NAME=${MDB_HOST}_${MDB_PORT}_${CDATE}
LOG_FILE=$OUT_DIR/bak_mongodb_${CDATE}.log

start_time=`/bin/date '+%d %H %M %S' |
/bin/awk '{d = $1;H = $2;M = $3;S = $4;
        tick = (d - 1) * 86400;
        tick += (H - 1) * 3600;
        tick += (M - 1) * 60;
        tick += S;
        printf("%d\n", tick);
}'`

_doit()
{
    CMD="$@"
    echo "=> $CMD" 2>&1 | tee -a $LOG_FILE
    eval $CMD 2>&1 | tee -a $LOG_FILE
}

_echo()
{
	msg="$@"
	echo "$msg" 2>&1 | tee -a $LOG_FILE
}

_echo "=======================================================================" 
_echo "MongoDB backup start at " `date`
_echo "Current user: $USER"
_echo "Input target Mongdb: $MDB_HOST"
_echo "Input target Port: $MDB_PORT"
_echo "output directory: $OUT_DIR"
_echo ;
_echo "Log file : $LOG_FILE"

### verify the mongodb is accessible.
_echo; 
_echo "Verifying Mongodb connectivity ........."
_echo "Save current Mongodb configurations to ${OUT_DIR}/${MDB_HOST}_${MDB_PORT}.cfg"
mongo $MDB_HOST:$MDB_PORT $MDB_AUTH --quiet --eval 'printjson(db.adminCommand("getCmdLineOpts"))' > ${OUT_DIR}/${MDB_HOST}_${MDB_PORT}.cfg

L_CNT=`cat ${OUT_DIR}/${MDB_HOST}_${MDB_PORT}.cfg | grep -i "failed" | wc -l`
if [ "$L_CNT" != "0" ] ; then
	_echo ; _echo "=> ERROR: Mongdb $MDB_HOST port $MDB_PORT is not accessible.!!"
	exit
fi

### Mongod configuration (file) backup
CONF_FULL_FILE=`cat ${OUT_DIR}/${MDB_HOST}_${MDB_PORT}.cfg | grep \"config\" | sed 's/"config" : //' | tr -d ' \t,"'`
CONF_FILE_NAME=`echo $CONF_FULL_FILE | sed 's|\/[a-z].*\/||'`
if [ ! CONF_FULL_FILE = "" ] ; then
	_echo; 
	_echo "Mongod configuration file found: ${CONF_FULL_FILE}"
	_echo "Backup configuration file to ${OUT_DIR}/backup_${CONF_FILE_NAME}"
	_doit "cp $CONF_FULL_FILE ${OUT_DIR}/backup_${CONF_FILE_NAME}"
fi

### Read mongod deamon evnironment
L_CNT=`cat ${OUT_DIR}/${MDB_HOST}_${MDB_PORT}.cfg | grep -i "mongos" | wc -l`
if [ "$L_CNT" != "0" ] ; then
	_echo "=> It is mongos deamon.  No database backup there...."
	exit
fi

RS_NAME=`cat ${OUT_DIR}/${MDB_HOST}_${MDB_PORT}.cfg | grep \"replSet\" | sed 's/"replSet" ://' | tr -d ' \t,"'`
IS_WT=`cat ${OUT_DIR}/${MDB_HOST}_${MDB_PORT}.cfg | grep \"engine\" | sed 's/"engine" ://' | tr -d ' \t,"'`

### Read replciation environment 
IS_ARBT=( $(mongo $MDB_HOST:$MDB_PORT $MDB_AUTH --quiet --eval '(db.isMaster().arbiterOnly ? true : false)') )
#IS_PRIM=( $(mongo $MDB_HOST:$MDB_PORT $MDB_AUTH --quiet --eval '(db.isMaster().ismaster ? true : false)') )

if [ "$RS_NAME" != "" ] ; then
	_echo; _echo "Mongodb ReplicatSet name: $RS_NAME"
fi

if [ "$IS_ARBT" = "true" ] ; then
	_echo; _echo "=> It is ArbiterOnly db. No database backup there...."
	exit
fi

##### FULL Backup 
_echo; 
_echo "Database Backup start ........."
_echo "Backup working folder : ${OUT_DIR}/${BAK_NAME}/"
if [[ "$RS_NAME" != "" ]] ; then

	## Disable the balancer that equalizes the distribution of data among the shards.
	_echo; _echo "Set Balancer stop ........."
	_doit "mongo $MDB_HOST:$MDB_PORT/config $MDB_AUTH --quiet --eval 'sh.setBalancerState(false)' "
	
	## Lock replica set members. Only for MMAPv1 storage engine
	if [ "$IS_WT" != "wiredTiger" ] ; then
		_echo; _echo "Database fsyncLock()  ........."
		_doit "mongo $MDB_HOST:$MDB_PORT/admin $MDB_AUTH --quiet --eval 'printjson(db.fsyncLock())' "
	fi
	
	## Backup with Oplog option
	_doit "mongodump -h ${RS_NAME}/${MDB_HOST}:${MDB_PORT} $MDB_AUTH --oplog -o ${OUT_DIR}/${BAK_NAME} "

	if [ "$IS_WT" != "wiredTiger" ] ; then
		_echo; _echo "Database fsyncUnlock()  ........."
		_doit "mongo $MDB_HOST:$MDB_PORT/admin $MDB_AUTH --quiet --eval 'printjson(db.fsyncUnlock())' "
	fi
	
	_echo; _echo "Sharding Balancer re-start ........."
	_doit "mongo $MDB_HOST:$MDB_PORT/config $MDB_AUTH --quiet --eval 'sh.setBalancerState(true)' "
	BSTS=( $(mongo $MDB_HOST:$MDB_PORT $MDB_AUTH --quiet --eval 'sh.getBalancerState()') )
	if [ "$BSTS" != "true" ] ; then
		_echo ; _echo "=> ERROR: Balancer re-start failed!! Please check your mongos status!!........."
		_doit "mongo $MDB_HOST:$MDB_PORT/config $MDB_AUTH --quiet --eval 'sh.startBalancer()' "
	fi
else
	_doit "mongodump -h ${MDB_HOST}:${MDB_PORT} $MDB_AUTH -o ${OUT_DIR}/${BAK_NAME} "
fi

#### Compressing backup files
if [ -d "$OUT_DIR/$BAK_NAME" ]; then
	_echo; _echo "Backup file compressing ........."
	_doit "tar --remove-files -czf ${OUT_DIR}/${BAK_NAME}.tar.gz  ${OUT_DIR}/${BAK_NAME}"
else
	_echo; _echo "=> ERROR: Backup file not found!! Backup process exit.."
	exit
fi

#### Remove working dir
if [ -f "${OUT_DIR}/${BAK_NAME}.tar.gz" ]; then
	_echo; _echo "Remove working folder ${OUT_DIR}/${BAK_NAME} ....."
	_doit "rm -rf ${OUT_DIR}/${BAK_NAME}"
else
	_echo; _echo "=> ERROR: Compressed backup ${BAK_NAME}.tar.gz file not found!! Backup process exit.."
	exit
fi
	
#### Remove Old Backup, Log files
_echo; _echo "Remove old backup *.gz files that older than 7 days. ....."
_doit "find ${OUT_DIR}/*${MDB_HOST}_${MDB_PORT}_*.gz -mtime +7 -exec rm -rd {} \;"
_doit "find ${OUT_DIR}/bak_mongodb_*.log -mtime +7 -exec rm -rd {} \;"

end_time=`/bin/date '+%d %H %M %S' |
/bin/awk '{d = $1;H = $2;M = $3;S = $4;
        tick = (d - 1) * 86400;
        tick += (H - 1) * 3600;
        tick += (M - 1) * 60;
        tick += S;
        printf("%d\n", tick);
}'`

elapsed=`expr $end_time - $start_time`
_echo; _echo "=> MongoDB backup has done. $elapsed seconds elapsed"


    

Report Script

blog comments powered by Disqus