Skip to content

Instantly share code, notes, and snippets.

@mmrwoods
Created October 26, 2010 16:11
Show Gist options
  • Save mmrwoods/647198 to your computer and use it in GitHub Desktop.
Save mmrwoods/647198 to your computer and use it in GitHub Desktop.
Mongo DB init script for Linux and OSX
#!/bin/bash
# Nasty, intentionally verbose script to start/stop mongod
# Mark Woods - March 2010
RUNTIME_USER='nobody' # only applicable on Linux, otherwise runs as current user
LOGPATH='/var/log/mongodb/mongod.log'
CONFIGFILE='/etc/mongod.conf'
DBPATH='/opt/mongodb/data/db'
BINPATH='/opt/mongodb/bin/mongod'
PSCMD='ps aux | egrep "bin/[m]ongod" > /dev/null 2>&1'
STARTCMD="$BINPATH --fork --dbpath $DBPATH --logpath $LOGPATH --logappend"
REPAIRCMD="$BINPATH --repair --dbpath $DBPATH"
STOPCMD='killall -2 mongod'
KILLCMD='killall -9 mongod'
RETVAL=0
# use optional config file if exists
if [ -f $CONFIGFILE ]; then
STARTCMD="$STARTCMD -f $CONFIGFILE"
fi
mongod_set_runtime_user_and_check_paths() {
CURRENT_USER=`whoami`
if [ `uname` = "Linux" ]; then
# run as configured runtime user if Linux (I don't know how to do this in BSD/OSX)
if [ ! $CURRENT_USER = 'root' ]; then
echo "WARNING: cannot set runtime user for mongod because you are not root, mongod will run under user $CURRENT_USER"
RUNTIME_USER=$CURRENT_USER
RUNTIME_GROUP=`id -gn $CURRENT_USER`
else
RUNTIME_GROUP=`id -gn $RUNTIME_USER`
if [ ! $? -eq 0 ]; then
echo "WARNING: runtime user $RUNTIME_USER does not exist, setting to nobody"
RUNTIME_USER='nobody'
RUNTIME_GROUP=`id -gn $RUNTIME_USER`
fi
STARTCMD="su $RUNTIME_USER -c '$STARTCMD'"
fi
else
RUNTIME_USER=$CURRENT_USER
RUNTIME_GROUP=`id -gn $CURRENT_USER`
fi
if [ ! -d $DBPATH ]; then
echo "WARNING: dbpath $DBPATH does not exist"
if [ $CURRENT_USER = "root" ]; then
echo "Creating dbpath $DBPATH..."
mkdir -p $DBPATH
chmod 750 $DBPATH
chown -R $RUNTIME_USER:$RUNTIME_GROUP $DBPATH
fi
fi
if [ $CURRENT_USER = "root" ]; then
chown -R $RUNTIME_USER:$RUNTIME_GROUP $DBPATH # brutal, but effective
fi
LOGDIR=`dirname $LOGPATH`
if [ ! -d $LOGDIR ]; then
echo "WARNING: log directory $LOGDIR doesn't exist"
if [ $CURRENT_USER = "root" ]; then
echo "Creating log directory $LOGDIR..."
mkdir -p $LOGDIR
chmod 750 $LOGDIR
chown -R $RUNTIME_USER:$RUNTIME_GROUP $LOGDIR
fi
else
if [ `uname` = "Linux" ] && [ $CURRENT_USER = "root" ]; then
TOUCHCMD="su $RUNTIME_USER -c 'touch $LOGPATH > /dev/null 2>&1'"
else
TOUCHCMD="touch $LOGPATH > /dev/null 2>&1"
fi
eval $TOUCHCMD
if [ ! $? -eq 0 ]; then
echo "WARNING: cannot write to log file $LOGPATH"
fi
fi
}
mongod_running() {
eval $PSCMD
if [ $? -eq 0 ]; then
IS_RUNNING="true"
else
IS_RUNNING="false"
fi
}
mongod_start() {
mongod_running
if [ "$IS_RUNNING" = "true" ]; then
echo "Mongod is already running"
echo exiting
exit 2
fi
mongod_set_runtime_user_and_check_paths
echo "Starting mongod..."
eval $STARTCMD
RETVAL=$?
if [ ! $RETVAL -eq 0 ]; then
echo "ERROR: Mongod failed to start"
echo "Check that user $RUNTIME_USER can write to dbpath $DBPATH and logpath $LOGPATH"
echo "If that doesn't help, check the log file at $LOGPATH"
else
sleep 3
mongod_running
if [ "$IS_RUNNING" = "false" ]; then
echo "WARNING: Mongod has not yet started, please wait..."
sleep 5
mongod_running
if [ "$IS_RUNNING" = "false" ]; then
echo "ERROR: Mongod hasn't started"
echo "Check that user $RUNTIME_USER can write to dbpath $DBPATH and logpath $LOGPATH"
echo "If that doesn't help, check the log file at $LOGPATH"
exit 2
fi
fi
fi
}
mongod_stop() {
mongod_running
if [ "$IS_RUNNING" = "false" ]; then
echo "Mongod does not seem to be running"
return
fi
echo "Stopping mongod..."
eval $STOPCMD
RETVAL=$?
if [ ! $RETVAL -eq 0 ]; then
if [ `whoami` = "root" ]; then
echo "Mongod failed to shut down"
else
echo "Mongod failed to shut down, this might be just because you don't have permission to stop it"
fi
echo "The log file at $LOGPATH may contain more information"
echo "If you need to send the KILL signal to the process, you MUST repair all databases afterwards by running: $0 repair"
exit $RETVAL
else
sleep 5
mongod_running
if [ "$IS_RUNNING" = "true" ]; then
echo "Mongod has not yet shut down properly, please wait and do NOT kill the process!"
sleep 15
mongod_running
if [ "$IS_RUNNING" = "true" ]; then
echo "Mongod still hasn't shut down properly..."
if [ `whoami` = "root" ]; then
echo "This is probably because some database operation that hasn't completed is preventing the server from shutting down"
else
echo "This might be just because you don't have permission to stop it, or it could be that some database operation that hasn't completed is preventing the server from shutting down"
fi
echo "You can use the mongo shell to show and kill running operataions - see db.currentOP() and db.killOP()"
echo "If you need to send the KILL signal to the process, you MUST repair all databases afterwards by running: $0 repair"
exit 2
fi
fi
fi
}
mongod_repair() {
# check that there is sufficient disk space to run a repair...
# note: choice of tools used to determine free and used space based on compatibility between linux and bsd/osx
FREE_GIGABYTES=`df -h / | sed '1,1d' | awk '{ print $4 }' | sed 's/[^0-9]\.//g'` # FIXME: assumes mongo is on root partition
USED_GIGABYTES=$((`ls -lk $DBPATH | head -1 | cut -d' ' -f2`/1048576))
REQUIRED_GIGABYTES=$((USED_GIGABYTES+5)) # add an extra 5 gigs to allow for some other process chewing up disk space while repair runs
if [ `echo "$REQUIRED_GIGABYTES < $FREE_GIGABYTES" | bc` -eq 0 ]; then
echo "Not enough disk space to run repair (${FREE_GIGABYTES}G free, but need ${REQUIRED_GIGABYTES}G), exiting..." 1>&2
exit 1
fi
mongod_running
if [ "$IS_RUNNING" = "true" ]; then
echo "Mongod is already running - shutting down in 10 seconds in order to start a repair..."
echo "WARNING: databases will not be accessible until the repair process has finished (which could easily take an hour)"
sleep 1 ; wait
for n in {9..0} ; do
printf $n ; sleep 1 ; wait ; printf \\b
done
fi
mongod_stop
echo "Repairing all mongo databases..."
eval $REPAIRCMD
RETVAL=$?
mongod_running
if [ "$IS_RUNNING" = "true" ]; then
sleep 10
mongod_stop
fi
mongod_start
}
mongod_status() {
mongod_running
if [ "$IS_RUNNING" = "true" ]; then
echo "Mongod is running"
else
echo "Mongod is not running"
fi
}
case "$1" in
start)
mongod_start
;;
stop)
mongod_stop
;;
restart)
mongod_stop
mongod_start
;;
repair)
mongod_repair
;;
status)
mongod_status
;;
*)
echo "Usage: $0 {start|stop|restart|repair|status}"
exit 1
;;
esac
exit $RETVAL
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment