#!/bin/bash
#===============================================================================
#
#          FILE: LIVEDBbackup
#
#         USAGE: LIVEDBbackup
#
#   DESCRIPTION: Backup databases from LIVE servers slowly to prevent high
#                loading on LIVE servers, and use the lowest priority on I/O
#                and process scheduling for pg_dump.
#
#  REQUIREMENTS: pg_dump
#
#         NOTES:
#
#          BUGS:  ---
#        AUTHOR: rickz (Rick Zhang), xlrickz@gmail.com
#       COMPANY: X-LEGEND Entertainment Corp.
#       CREATED: Fri Oct 26 11:50:06 KST 2012
#      REVISION: 1.0
#
#          TODO:
#
#===============================================================================

#set -o nounset                              # Treat unset variables as an error
#set -m                                      # Enable job control

##################################################
#   If you are not using this script with Ctrl   #
# You will have to manually set the config below #
##################################################

# LIVE DB backup directory
LIVE_DB_BACKUP_DIR="$HOME/LIVEDBbackup/"

# Delete DB backup files that total size excced $LIVE_DB_BACKUP_MAX_TOTAL_SIZE(in MB)
LIVE_DB_BACKUP_MAX_TOTAL_SIZE="30000"

# PostgreSQL username
PG_USER=""

# PostgreSQL password
PG_PASSWORD=""

# Set number list
SET_NUMBER_LIST=""

# Database Name
ACCOUNT_DB_NAME=""
MEMBER_DB_NAME=""
GAME_DB_NAME=""

# Game database name with set number?(If you are not using Ctrl, you will have to set "0" in here.)
GAME_DB_NAME_WITH_SET_NUMBER="1"

################################
#  DO NOT EDIT ANYTHING BELOW  #
################################
[ -r ~/.gamerc ] && source ~/.gamerc

[ "$1" != "" ] && LIVE_DB_BACKUP_DIR="$1"

# PostgreSQL version
PG_VERSION="$(pg_dump --version|awk '{print $NF}')"

if [ "$PG_PASSWORD" == "" ] ; then
   export PGPASSWORD="$LIVE_SERVER_DB_PASSWORD"
else
   export PGPASSWORD="$PG_PASSWORD"
fi

if [ "$PG_USER" == "" ] ; then
   export PGUSER="spiritking"
else
   export PGUSER="$PG_USER"
fi

echo ==============================================================================================================
date +"Backup Start: %Y%m%dT%H%M"

# Check database connections
[ "$ACCOUNT_DB_NAME" == "" ] || psql -h ACCOUNTDB $ACCOUNT_DB_NAME <<< '' > /dev/null 2>&1 \
&& echo "DB '$ACCOUNT_DB_NAME' connection: OK" || echo "Error: Could not connect to DB '$ACCOUNT_DB_NAME'"
[ "$MEMBER_DB_NAME" == "" ] || psql -h ACCOUNTDB $MEMBER_DB_NAME <<< '' > /dev/null 2>&1 \
&& echo "DB '$MEMBER_DB_NAME' connection: OK" || echo "Error: Could not connect to DB '$MEMBER_DB_NAME'"
for SET in $SET_NUMBER_LIST ; do
   [ "$GAME_DB_NAME_WITH_SET_NUMBER" == "1" ] && DBNAME="$GAME_DB_NAME$SET" || DBNAME="$GAME_DB_NAME"
   psql -h GAMEDB$SET $DBNAME <<< '' > /dev/null 2>&1 && echo "DB '$DBNAME' connection: OK" || echo "Error: Could not connect to DB '$DBNAME'"
done
echo

sleep 3

mkdir -p "$LIVE_DB_BACKUP_DIR"


# Backup Account and Member DB
for DBNAME in $ACCOUNT_DB_NAME $MEMBER_DB_NAME ; do
   DATE="$(date +%Y%m%dT%H%M)"
   echo -n "$DBNAME@ACCOUNTDB, Elapsed real time: "
   DB_SIZE="$(psql -h ACCOUNTDB $DBNAME $PGUSER <<< "copy (select pg_catalog.pg_size_pretty(pg_catalog.pg_database_size('$DBNAME'))) to stdout csv;")"
   TIME="%e" time ionice -n 7 nice -n 19 pg_dump -h ACCOUNTDB $DBNAME -F c -Z 9 > "$LIVE_DB_BACKUP_DIR/ACCOUNTDB-$DBNAME-$DATE.custom-$PG_VERSION.sql"
   echo "$DB_SIZE -> $(du -sh "$LIVE_DB_BACKUP_DIR/ACCOUNTDB-$DBNAME-$DATE.custom-$PG_VERSION.sql")"
   echo
done


# Backup Game DBs
for SET in $SET_NUMBER_LIST ; do
   [ "$GAME_DB_NAME_WITH_SET_NUMBER" == "1" ] && DBNAME="$GAME_DB_NAME$SET" || DBNAME="$GAME_DB_NAME"
   DATE="$(date +%Y%m%dT%H%M)"
   echo -n "$DBNAME@GAMEDB$SET, Elapsed real time: "
   DB_SIZE="$(psql -h GAMEDB$SET $DBNAME $PGUSER <<< "copy (select pg_catalog.pg_size_pretty(pg_catalog.pg_database_size('$DBNAME'))) to stdout csv;")"

   
   # Exit now if the MissionServer is not running(It must be under maintenance)
   ssh GAMEDB$SET 'ps -Ao cmd |grep -q "[M]issionServer"' || exit

   # If the MissionServer started less than 10 minutes, delay 10 minutes
   [ $(ssh GAMEDB$SET 'echo $((($(date +%s)-$(date -d "$(LC_ALL=C ps -o lstart -C $(ps -Ao cmd |grep "[M]issionServer"|sed "s/\.\///g") |grep " [0-9][0-9]:[0-9][0-9]:[0-9][0-9] " || echo now)" +%s))/60))') -gt 10 ] \
   || sleep 600
   TIME="%e" time ionice -n 7 nice -n 19 pg_dump -h GAMEDB$SET $DBNAME -F c -Z 9 > "$LIVE_DB_BACKUP_DIR/GAMEDB$SET-$DBNAME-$DATE.custom-$PG_VERSION.sql" \

   echo "$DB_SIZE -> $(du -sh "$LIVE_DB_BACKUP_DIR/GAMEDB$SET-$DBNAME-$DATE.custom-$PG_VERSION.sql")"
   echo
done

# Delete old backups that total size exceed $LIVE_DB_BACKUP_MAX_TOTAL_SIZE(In MB)
cd "$LIVE_DB_BACKUP_DIR"
if grep -q "^[0-9]\+$" <<< "$LIVE_DB_BACKUP_MAX_TOTAL_SIZE" ; then
   TOTAL_SIZE=0
   for DB_BACKUP_FILE in `ls -t *.custom-*.sql`;do 
      TOTAL_SIZE=$(($TOTAL_SIZE+$(stat -c %s $DB_BACKUP_FILE)/1048576))
      if [ $TOTAL_SIZE -gt $LIVE_DB_BACKUP_MAX_TOTAL_SIZE ] ; then
	rm -fv $DB_BACKUP_FILE
      fi
   done
fi

date +"Backup End: %Y%m%dT%H%M"

