diff --git a/repair_mysql_tables.sh b/repair_mysql_tables.sh new file mode 100755 index 0000000..a7f8a3d --- /dev/null +++ b/repair_mysql_tables.sh @@ -0,0 +1,362 @@ +#!/usr/bin/env bash + +working_dir="$(dirname $(realpath $0))" +conf_file="${working_dir}/conf/mysql_credetials.conf" + +tmp_log_file="$(mktemp)" + + +# ------------- +# - Variable settings +# ------------- +DEFAULT_MYSQL_CREDENTIAL_ARGS="--login-path=local" +ALL_DATABASES=false + + +# ------------- +# --- Some functions +# ------------- + +usage() { + + [[ -n "$1" ]] && error "$1" + + [[ $terminal ]] && echo -e " +\033[1mUsage:\033[m + + $(basename $0) + +\033[1mDescription\033[m + + Script repairs (and reorganizes) all tables of the given databases by executing MySQL + command 'REPAIR TABLE'. If this was successfully, also 'OPTIMIZE TABLE' command will + be triggered. + +\033[1mOptions\033[m + + No Options available + +\033[1mFiles\033[m + + $conf_file: Configuration file + + +" + + clean_up 1 + + +} + + +clean_up() { + + # Perform program exit housekeeping + rm -f $tmp_log_file + exit $1 +} + + +echononl(){ + if $terminal ; then + echo X\\c > /tmp/shprompt$$ + if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then + echo -e -n "$*\\c" 1>&2 + else + echo -e -n "$*" 1>&2 + fi + rm /tmp/shprompt$$ + fi +} + + +fatal(){ + echo "" + if $terminal ; then + if [[ -n "$*" ]] ; then + echo -e " [ \033[31m\033[1mFatal\033[m ]: $*" + echo "" + echo -e " \033[31m\033[1mScript will be interrupted.\033[m\033[m" + else + echo -e " \033[31m\033[1mFatal error\033[m: \033[1mScript will be interrupted.\033[m" + fi + else + if [[ -n "$*" ]] ; then + echo " [ Fatal ]: $*" + echo "" + echo " Script was terminated.." + else + echo " Fatal error: Script was terminated.." + fi + fi + echo "" + clean_up 1 +} + + +error(){ + echo "" + if $terminal ; then + echo -e " [ \033[31m\033[1mError\033[m ]: $*" + else + echo " [ Error ]: $*" + fi + echo "" +} + +warn (){ + if $terminal ; then + echo "" + echo -e " [ \033[33m\033[1mWarning\033[m ]: $*" + echo "" + else + echo " [ Warning ]: $*" + fi +} + +info (){ + if $terminal ; then + echo "" + echo -e " [ \033[32m\033[1mInfo\033[m ]: $*" + echo "" + else + echo " [ Info ]: $*" + fi +} + +echo_ok() { + if $terminal ; then + echo -e "\033[80G[ \033[32mok\033[m ]" + fi +} +echo_failed(){ + if $terminal ; then + echo -e "\033[80G[ \033[1;31mfailed\033[m ]" + fi +} +echo_skipped() { + if $terminal ; then + echo -e "\033[80G[ \033[37mskipped\033[m ]" + fi +} + +trim() { + local var="$*" + var="${var#"${var%%[![:space:]]*}"}" # remove leading whitespace characters + var="${var%"${var##*[![:space:]]}"}" # remove trailing whitespace characters + echo -n "$var" +} + + + +trap clean_up SIGHUP SIGINT SIGTERM + + +# - Is this script running on terminal ? +# - +if [[ -t 1 ]] ; then + terminal=true +else + terminal=false +fi + +mysql=`which mysql` + +if [ -z "$mysql" ]; then + if [ -x "/usr/local/mysql/bin/mysql" ]; then + mysql=/usr/local/mysql/bin/mysql + else + fatal "No binary 'mysql' found!" + fi +fi + + +# - Print help? +# - +if [[ "$(trim $*)" = "-h" ]] || [[ "$(trim $*)" = "--help" ]] ; then + usage +fi + +# ------------- +# - Get Database from commandline +# ------------- + +if [[ -n "$1" ]] ; then + DATABASES="$1" +else + if $terminal ; then + + warn "No Databses given!" + + echo "" + echo -e " \033[33mType upper case \033[1mYES\033[m\033[33m to trigger 'REPAIR TABLES' on all tables of all databases\033[m" + echo "" + echo -en " \033[37m\033[1mContinue?\033[m " + read OK + if [[ "$OK" = "YES" ]] ; then + echo "" + echo "" + echo -e "\033[1;37m-----------\033[m" + echo "" + echo "" + echo -e " \033[32mRunning \033[1;37mREPAIR TABLES\033[m\033[32m on all tables of all databases..\033[m" + echo "" + else + fatal "Abort by user request - Answer as not 'YES'" + fi + else + usage "No Databses given!" + fi +fi + + +# ------------- +# - Load Settings from configuration file +# ------------- + +if $terminal ; then + echo "" +fi +echononl " Loading configuration settings from $(basename ${conf_file}).." +if [[ -f "$conf_file" ]]; then + source "$conf_file" > $tmp_log_file 2>&1 + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + fatal "$(cat $tmp_log_file)" + fi +else + echo_skipped + if $terminal ;then + warn "No Configuration File found. Loading defaults.." + fi +fi + + +[[ -z "$mysql_credential_args" ]] && mysql_credential_args="$DEFAULT_MYSQL_CREDENTIAL_ARGS" + +if [[ ${#mysql_credential_args_arr[@]} -eq 0 ]]; then + [[ -z "$mysql_credential_args" ]] && mysql_credential_args="$DEFAULT_MYSQL_CREDENTIAL_ARGS" + mysql_credential_args_arr="default:$mysql_credential_args" +fi + +declare -i length_table_name +declare -i number_blank_signd +declare -i index_i +for _val in ${mysql_credential_args_arr[@]} ; do + + _all_success=true + + IFS=':' read -a _val_arr <<< "${_val}" + mysql_version="${_val_arr[0]}" + mysql_credential_args="${_val_arr[1]}" + + + if [[ -z "$DATABASES" ]] ; then + + if $terminal ; then + echo "" + echo -e "[ \033[37m\033[1mMySQL $mysql_version\033[m ]: repair (and optimize) tables of databases at host '$(hostname -f)'." + fi + + DATABASES="$($mysql $mysql_credential_args -N -s -e "show databases")" + ALL_DATABASES=true + fi + + length_table_name=0 + for db in $DATABASES ; do + + [ "$db" = "information_schema" ] && continue + [ "$db" = "performance_schema" ] && continue + [ "$db" = "mysql" ] && continue + + if $terminal ;then + echo "" + echo -e " [$(date)] Repair (and optimize) tables in database '${db}'.." + fi + + TABLES="$($mysql $mysql_credential_args $db -N -s -e "show tables" 2> $tmp_log_file )" + if [[ $? -ne 0 ]]; then + _all_success=false + error "Getting tables of database '${db}' failed.\n $(cat "$tmp_log_file")" + error_messages_arr+=("Getting tables of database '${db}' failed.") + continue + fi + + for table in $TABLES ; do + + if $terminal ; then + blank_signs="" + if [[ $length_table_name -gt ${#table} ]]; then + number_blank_sign=$(expr $length_table_name - ${#table}) + index_i=0 + while [[ $index_i -lt $number_blank_sign ]] ; do + blank_signs="$blank_signs " + (( index_i++ )) + done + echo -en "\033[1G" + fi + echo -en "\033[1G \033[32mRepair table \033[1m$table\033[m$blank_signs\033[1G" + fi + length_table_name=${#table} + + $mysql $mysql_credential_args $db -N -s -e "REPAIR TABLE \`$table\`" > $tmp_log_file 2>&1 + + if [[ $? -ne 0 ]]; then + + _all_success=false + error "Repairing table '$table' failed.\n$(cat "$tmp_log_file")" + error_messages_arr+=("MySQL $mysql_version: Error while repairing table '${table}' of database '$db'.") + + else + + $mysql $mysql_credential_args $db -N -s -e "OPTIMIZE TABLE \`$table\`" > $tmp_log_file 2>&1 + + if [[ $? -ne 0 ]]; then + error "Reoptimizing table \"${table}\" of database \"$db\" failed.\n$(cat "$tmp_log_file")" + error_messages_arr+=("MySQL $mysql_version: Error while (re-)optimizing table '${table}' of database '$db'.") + fi + fi + + done + + if $terminal ;then + echo -en "\033[1G [$(date)] End repairing tables of database '${db}'.." + echo + fi + + done + + if $_all_success ; then + if $ALL_DATABASES ; then + info_messages_arr+=("MySQL $mysql_version: Repairing MySQL tables of all databases was successful.") + else + info_messages_arr+=("MySQL $mysql_version: Repairing MySQL tables of database '${db}' was successful.") + fi + fi + + if $terminal && $ALL_DATABASES ; then + echo "" + echo -e "[ \033[37m\033[1mMySQL $mysql_version\033[m ]: Finished repairing MySQL databases at host $(hostname -f)." + echo "" + fi +done + +if [[ ${#info_messages_arr[@]} -gt 0 ]]; then + for msg in "${info_messages_arr[@]}" ; do + if $terminal ; then + info "$msg" + fi + done +fi + +if [[ ${#error_messages_arr[@]} -gt 0 ]]; then + for msg in "${error_messages_arr[@]}" ; do + if $terminal ; then + error "$msg" + fi + done +fi + +clean_up 0