Skip to content

Instantly share code, notes, and snippets.

@felix-orduz
Created May 28, 2015 19:58
Show Gist options
  • Select an option

  • Save felix-orduz/ebe64fb4f66d43001039 to your computer and use it in GitHub Desktop.

Select an option

Save felix-orduz/ebe64fb4f66d43001039 to your computer and use it in GitHub Desktop.
Script para realizar backups parciales de mysql
#!/bin/bash
source ~/.bashrc
shopt -s expand_aliases
#Variables
databases=()
command=''
current_logbin=''
indices=''
namebin=''
pass_mysql=''
path_bin_mysql='mysql'
path_bin_mysqldump='mysqldump'
path_mysqlbinlog='mysqlbinlog'
path_socket_mysql=''
position_current_binlog=0
position_last_binlog=0
user_mysq=''
withzero=''
validate_mysql=1
login_path=''
log_path=''
level_log=0;
#Procesa las opciones
while getopts "p:s:u:q:w:l:e:r:t:" opts; do
case $opts in
p) path_bin_mysql=$OPTARG;;
s) path_socket_mysql=$OPTARG;;
u) user_mysq=$OPTARG;;
q) pass_mysql=$OPTARG;;
w) path_bin_mysqldump=$OPTARG;;
l) login_path=$OPTARG;;
e) path_mysqlbinlog=$OPTARG;;
r) log_path=$OPTARG;;
t) level_log=$OPTARG;;
?) exit 1;;
esac
done
shift $(($OPTIND-1))
#Funtions
log() {
local level=${1?}
shift
now=$(date +"%m/%d/%Y %H:%M:%S")
local code= line="$*"
if [ ! -z $log_path ]; then
echo "[$now] $level: $line" >> $log_path
fi;
if [ -t 2 ]
then
case "$level" in
INFO) code=36 ;;
DEBUG) code=30 ;;
WARN) code=33 ;;
ERROR) code=31 ;;
*) code=37 ;;
esac
#nivel error
if [ $level_log -eq 3 ]; then
echo -e "\e[${code}m[$now] $level: \e[0m${line}"
fi
if [[ ($level_log -eq 2 ) && ( $code -eq 33 || $code -eq 36 ) ]]; then
echo -e "\e[${code}m[$now] $level: \e[0m${line}"
fi
if [[ ($level_log -eq 1 ) && ( $code -eq 36 ) ]]; then
echo -e "\e[${code}m[$now] $level: \e[0m${line}"
fi
else
echo "[$now] $level: $line"
fi >&2
}
#recibe el stderr
logger(){
while read line; do
log "ERROR" $line
done
}
# Read the file in parameter and fill the array named "databases"
getArray() {
i=0
while read line # Read a line
do
local inidce=$(echo $line | cut -d: -f1)
databases[$inidce]=$(echo $line | cut -d: -f2) # Put it into the array called databases
indices=$indices" "$inidce
done < $1
}
#valida que un comando exista
validate_cmd() {
cmd=$1
path_cmd=$2;
if [ $path_cmd == $cmd ]; then
validate=$(type $cmd >/dev/null 2>&1 && echo "1" || echo "0")
if [ $validate = '0' ]; then
log "ERROR" "$cmd no esta instalado"
exit 0;
fi
else
if [ ! -x $path_cmd ]; then
log "ERROR" "Error: Ruta No valida de $cmd"
exit 0;
fi
fi
}
#exrrae el bin log actual de la base de datos
getCurrentLogBin() {
alias command_master=$path_bin_mysql' -e "show master status" -s';
log "INFO" "Get Current Logbin";
current_logbin=$(command_master 2> >(logger))
if [ $? == '1' ]; then
log "ERROR" "ERROR EXTRAYENDO LOGBIN"
exit 1;
fi
current_logbin=$(echo $current_logbin | cut -d' ' -f1)
}
flushLogs(){
command_flush=$path_bin_mysql" -e 'FLUSH LOGS;' ";
alias command_flush=$command_flush
$(command_flush 2> >(logger))
}
#directorio de salida
validate_output_directory() {
if [ ! -d output ]; then
mkdir output
fi
#Se limpia el directorio de salida
if [ "$(ls -A output)" ]; then
rm output/*
fi
#
}
log 'INFO' 'Start Execution';
validate_output_directory
validate_cmd "mysql" $path_bin_mysql
validate_cmd "mysqlbinlog" $path_mysqlbinlog
if [ ! -z $path_socket_mysql ]; then
path_bin_mysql=$path_bin_mysql" -S "$path_socket_mysql
path_bin_mysqldump=$path_bin_mysqldump" -S "$path_socket_mysql
path_mysqlbinlog=$path_mysqlbinlog" -S "$path_socket_mysql
fi
if [ ! -z $user_mysq ]; then
path_bin_mysql=$path_bin_mysql" -u "$user_mysq
path_bin_mysqldump=$path_bin_mysqldump" -u "$user_mysq
path_mysqlbinlog=$path_mysqlbinlog" -u "$user_mysq
fi
if [ ! -z $pass_mysql ]; then
path_bin_mysql=$path_bin_mysql" -p"$pass_mysql
path_bin_mysqldump=$path_bin_mysqldump" -p"$pass_mysql
path_mysqlbinlog=$path_mysqlbinlog" -p"$pass_mysql
fi
if [ ! -z $login_path ]; then
path_bin_mysql=$path_bin_mysql" --login-path="$login_path
path_bin_mysqldump=$path_bin_mysqldump" --login-path="$login_path
path_mysqlbinlog=$path_mysqlbinlog" --login-path="$login_path
fi
#validaciones
#valida que directorio de configuracion exista
if [ ! -d conf ]; then
log "ERROR" "Directorio conf no existe"
exit 0;
fi
#valida que el archivo de configacion exista
if [ ! -e conf/positions.txt ]; then
log "ERROR" "Archivo positions no existe"
fi
#se obtine el logbin actual
getCurrentLogBin
#Databases a evaluar
getArray "conf/positions.txt"
#se extrae el dump parcial de cada base de datos
for e in $indices
do
if [ "$current_logbin" = "${databases[$e]}" ]; then
command=$path_mysqlbinlog" -d "$e" /opt/mysql/BOGOTA/data/"$current_logbin" > output/"$e".sql"
eval $command
else
position_last_binlog=$(echo ${databases[$e]} | cut -d. -f2 | sed 's/^0*//')
position_current_binlog=$(echo $current_logbin | cut -d. -f2 | sed 's/^0*//')
namebin=$(echo $current_logbin | cut -d. -f1)
while [ $position_last_binlog -le $position_current_binlog ];
do
withzero=$(echo $position_last_binlog | sed -e :a -e 's/^.\{1,5\}$/0&/;ta')
command=$path_mysqlbinlog" -d "$e" /opt/mysql/BOGOTA/data/"$namebin"."$withzero" >> output/"$e".sql"
eval $command
position_last_binlog=$(( $position_last_binlog + 1 ))
done
fi
done
flushLogs
getCurrentLogBin
touch conf/positions.txt.new
for e in $indices
do
echo $e":"$current_logbin >> conf/positions.txt.new
done
mv conf/positions.txt conf/positions.txt.old
mv conf/positions.txt.new conf/positions.txt
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment