Database Scripts

Beta
 Log In    |   Sign Up

MongoDB : mongodb backup v1.6

Added on May-12-2016 by Jelong
For MongoDB

Tags : backuplinuxmongodbmongodumpscript

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!

Versions

CentOS 6.x, mongodb 3.x

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] ([Backup hostname or IP] ([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.5    1/8/2016   Jeyong Park     general backup script with 3 optional parameters.
#                                   Authentification should be added in script.
# 1.6	 5/2/2016	Jeyong Park		Add email, change log items
# --------------------------------------------------------------------------------
# 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 is current server
OUT_DIR=$HOME/backup          #default backup dir
MDB_AUTH=                     #"-u dba -p dart_dba" format
DBA_EMAIL=x@y.z

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 [ ! -w $OUT_DIR ] ; then 
	echo; echo "=> Output directory $OUT_DIR is not writable!  Program Exit!!" 2>&1 | tee -a ./bk_mongodb.log
	mail -s "${HOSTNAME} : Mongodb ${MDB_HOST} Backup Fails!" $DBA_EMAIL < ./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 "Source Mongdb: $MDB_HOST"
_echo "MongoDB 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}/admin $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.!!"
	mail -s "${HOSTNAME} : Mongodb ${MDB_HOST} Backup Fails!" $DBA_EMAIL < $LOG_FILE
	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}/admin $MDB_AUTH --quiet --eval '(db.isMaster().arbiterOnly ? true : false)') )
#IS_PRIM=( $(mongo ${MDB_HOST}:${MDB_PORT}/admin $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}/admin $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} --quiet"

	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}/admin $MDB_AUTH --quiet --eval 'sh.setBalancerState(true)' "
	BSTS=( $(mongo ${MDB_HOST}:${MDB_PORT}/admin $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}/admin $MDB_AUTH --quiet --eval 'sh.startBalancer()' "
	fi
else
	_doit "mongodump -h ${MDB_HOST}:${MDB_PORT} $MDB_AUTH -o ${OUT_DIR}/${BAK_NAME} "
fi

_echo; _echo "${MDB_HOST} mongodump has completed at " `date`

#### Compressing backup files
if [ -d "$OUT_DIR/$BAK_NAME" ]; then
	_echo; _echo "Backup file compressing ........."
	cd $OUT_DIR
	(
	_doit "tar --remove-files -czf ${BAK_NAME}.tar.gz  ${BAK_NAME}"
	)
else
	_echo; _echo "=> ERROR: Backup file not found!! Backup process exit.."
	mail -s "${HOSTNAME} : Mongodb ${MDB_HOST} Backup Fails!" $DBA_EMAIL < $LOG_FILE
	exit
fi

_echo; _echo "${MDB_HOST} backup compression has completed at " `date`

#### 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.."
	mail -s "${HOSTNAME} : Mongodb ${MDB_HOST} Backup Fails!" $DBA_EMAIL < $LOG_FILE
	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 -rf {} \;"
_doit "find ${OUT_DIR}/bak_mongodb_*.log -mtime +7 -exec rm -rf {} \;"

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 took $elapsed seconds. Finished at" `date`


#### Send email with log file
mail -s "${HOSTNAME} : Mongodb ${MDB_HOST} Backup Completes" $DBA_EMAIL < ${LOG_FILE}


    

Report Script

blog comments powered by Disqus