repair_mysql_tables.sh: support multiple MySQL instances.

This commit is contained in:
Christoph 2019-11-06 00:38:54 +01:00
parent ffd923f3e4
commit c8a177e2c2

View File

@ -10,8 +10,11 @@ tmp_log_file="$(mktemp)"
# - Variable settings # - Variable settings
# ------------- # -------------
DEFAULT_MYSQL_CREDENTIAL_ARGS="--defaults-file=/usr/local/mysql/sys-maint.cnf" DEFAULT_MYSQL_CREDENTIAL_ARGS="--defaults-file=/usr/local/mysql/sys-maint.cnf"
ALL_DATABASES=false ALL_DATABASES=false
DATABASE_NAME_NEEDED=true
# ------------- # -------------
# --- Some functions # --- Some functions
@ -24,7 +27,7 @@ usage() {
[[ $terminal ]] && echo -e " [[ $terminal ]] && echo -e "
\033[1mUsage:\033[m \033[1mUsage:\033[m
$(basename $0) <DB-Name> $(basename $0) [DB-Name]
\033[1mDescription\033[m \033[1mDescription\033[m
@ -32,6 +35,8 @@ usage() {
command 'REPAIR TABLE'. If this was successfully, also 'OPTIMIZE TABLE' command will command 'REPAIR TABLE'. If this was successfully, also 'OPTIMIZE TABLE' command will
be triggered. be triggered.
If no database was given at command line all tables of ALL databases are checked.
\033[1mOptions\033[m \033[1mOptions\033[m
No Options available No Options available
@ -140,6 +145,16 @@ echo_skipped() {
fi fi
} }
is_number() {
return $(test ! -z "${1##*[!0-9]*}" > /dev/null 2>&1);
# - also possible
# -
#[[ ! -z "${1##*[!0-9]*}" ]] && return 0 || return 1
#return $([[ ! -z "${1##*[!0-9]*}" ]])
}
trim() { trim() {
local var="$*" local var="$*"
var="${var#"${var%%[![:space:]]*}"}" # remove leading whitespace characters var="${var#"${var%%[![:space:]]*}"}" # remove leading whitespace characters
@ -182,32 +197,10 @@ fi
# ------------- # -------------
if [[ -n "$1" ]] ; then if [[ -n "$1" ]] ; then
GIVEN_DATABASE="$1" DATABASE_NAME_NEEDED=false
DATABASE_NAME="$1"
else else
GIVEN_DATABASE="" DATABASE_NAME=""
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 fi
@ -234,139 +227,270 @@ else
fi fi
fi fi
if [[ -n "$mysql_credential_args" ]]; then
[[ -z "$mysql_credential_args" ]] && mysql_credential_args="$DEFAULT_MYSQL_CREDENTIAL_ARGS" MYSQL_CREDENTIAL_ARGS="$mysql_credential_args"
else
if [[ ${#mysql_credential_args_arr[@]} -eq 0 ]]; then MYSQL_CREDENTIAL_ARGS="$DEFAULT_MYSQL_CREDENTIAL_ARGS"
[[ -z "$mysql_credential_args" ]] && mysql_credential_args="$DEFAULT_MYSQL_CREDENTIAL_ARGS"
mysql_credential_args_arr="default:$mysql_credential_args"
fi fi
declare -i index_arr=0
# - Get MySQL Version
# -
if [[ ${#mysql_credential_args_arr[@]} -gt 0 ]] ; then
echo ""
echo -e "\033[32m--\033[m"
echo ""
echo "Which installation contains the database to be repaired?"
echo ""
echo ""
declare -a _tmp_arr=()
while [[ $index_arr -lt ${#mysql_credential_args_arr[@]} ]] ; do
IFS=':' read -a _val_arr <<< "${mysql_credential_args_arr[$index_arr]}"
mysql_version="${_val_arr[0]}"
mysql_credential_args="${_val_arr[1]}"
mysql_dist_string="$(mysql $mysql_credential_args -N -s -e "SELECT VERSION()" 2> /dev/null)"
if [[ "$mysql_dist_string" =~ MariaDB ]]; then
mysql_dist="MariaDB $mysql_version"
else
mysql_dist="MySQL/Percona $mysql_version"
fi
echo -e " [\033[33m$index_arr\033[m] \033[33m$mysql_dist\033[m"
_temp_arr[${index_arr}]="$mysql_credential_args"
#_temp_arr+=("$mysql_credential_args")
(( index_arr++ ))
done
_OK=false
echo ""
echononl "Eingabe: "
while ! $_OK ; do
read _IN
if is_number "$_IN" && [[ -n ${_temp_arr[$_IN]} ]]; then
MYSQL_CREDENTIAL_ARGS="${_temp_arr[$_IN]}"
_OK=true
else
echo ""
echo -e "\tFalsche Eingabe !"
echo ""
echononl "Eingabe: "
fi
done
fi
if $DATABASE_NAME_NEEDED ; then
echo ""
echo -e "\033[32m--\033[m"
echo ""
echo "Insert Database name which should be repaired.."
echo ""
echo -e " \033[33mLeave empty to repair tables of all databases\033[m"
echo ""
echononl "Database name: "
read DATABASE_NAME
#while [ "X$DATABASE_NAME" = "X" ] ; do
# echo -e "\n\t\033[33m\033[1mEingabe erforderlich.\033[m\n"
# echononl "Database name: "
# read DATABASE_NAME
#done
fi
# - Get MySQL Version
# -
echo ""
echo -e "\033[32m--\033[m"
echo ""
echononl " Get MySQL Version"
_version="$(mysql $MYSQL_CREDENTIAL_ARGS -N -s -e "SELECT VERSION()" 2> $tmp_log_file)"
if [[ $? -ne 0 ]] ; then
echo_failed
fatal "$(cat $tmp_log_file)"
else
echo_ok
fi
IFS='.' read -r -a version_arr <<< "$_version"
declare -i MAJOR_VERSION="${version_arr[0]}"
declare -i MINOR_VERSION="${version_arr[1]}"
_path_level="${version_arr[2]}"
declare -i PATCH_LEVEL="${_path_level%%-*}"
## - Get current MySQL Distribution
## -
echononl " Get MySQL distribution .."
if [[ -z "$_version" ]]; then
echo_failed
fatal "No installed MySQL server or distribution found!"
elif [[ "$_version" =~ MariaDB ]]; then
MYSQL_CUR_DISTRIBUTION="MariaDB"
else
MYSQL_CUR_DISTRIBUTION="MySQL"
fi
echo_ok
echo ""
echo -e "\033[32m--\033[m"
echo ""
echo ""
echo ""
echo -e "\033[32m\033[1m====================\033[m"
echo "Settings: Repair tables of MySQL Database '$DATABASE_NAME'"
echo -e "\033[32m\033[1m====================\033[m"
echo ""
echo " MySQL Distribution...........: $MYSQL_CUR_DISTRIBUTION"
echo " MySQL Version................: ${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_LEVEL}"
echo " MySQL Credentials............: $MYSQL_CREDENTIAL_ARGS"
echo ""
if [[ -n "$DATABASE_NAME" ]]; then
echo " Database name................: $DATABASE_NAME"
else
echo -e " Database name................: -- \033[033mall databases\033[m --"
fi
echo ""
echo ""
echo -e -n "\033[1mContinue repairing tables with above settings? [y/n]:\033[m "
read OK
while [[ "X${OK}X" = "XX" ]] ; do
echo ""
echo -e -n "\033[1mContinue with above settings? [y/n]:\033[m "
read OK
done
if [[ "${OK,,}" != 'yes' ]] && [[ "${OK,,}" != 'y' ]]; then
fatal "Abort by user request."
fi
declare -i length_table_name declare -i length_table_name
declare -i number_blank_signd declare -i number_blank_signd
declare -i index_i declare -i index_i
for _val in ${mysql_credential_args_arr[@]} ; do
_all_success=true _all_success=true
IFS=':' read -a _val_arr <<< "${_val}" DATABASES="$(mysql $MYSQL_CREDENTIAL_ARGS -N -s -e "show databases")"
mysql_version="${_val_arr[0]}"
mysql_credential_args="${_val_arr[1]}"
DATABASES="$($mysql $mysql_credential_args -N -s -e "show databases")" if [[ -z "$DATABASE_NAME" ]] ; then
if [[ -z "$GIVEN_DATABASE" ]] ; then if $terminal ; then
echo ""
if $terminal ; then echo -e " [ \033[37m\033[1m$MYSQL_CUR_DISTRIBUTION ${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_LEVEL}\033[m ]: repair (and optimize) tables of ALL databases at host '$(hostname -f)'."
echo ""
echo -e "[ \033[37m\033[1mMySQL $mysql_version\033[m ]: repair (and optimize) tables of databases at host '$(hostname -f)'."
fi
ALL_DATABASES=true
else
found=false
for db in $DATABASES ; do
if [[ "$db" = "$GIVEN_DATABASE" ]]; then
DATABASES="$GIVEN_DATABASE"
found=true
fi
done
if ! $found ; then
continue
fi
fi fi
length_table_name=0 ALL_DATABASES=true
for db in $DATABASES ; do else
found=false
for db in $DATABASES ; do
if [[ "$db" = "$DATABASE_NAME" ]]; then
DATABASES="$DATABASE_NAME"
found=true
break
fi
done
if ! $found ; then
warn "No Database '$DATABASE_NAME' found at $MYSQL_CUR_DISTRIBUTION ${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_LEVEL}"
clean_up 0
fi
fi
[ "$db" = "information_schema" ] && continue
[ "$db" = "performance_schema" ] && continue
[ "$db" = "mysql" ] && continue
if $terminal ;then length_table_name=0
echo "" for db in $DATABASES ; do
if [[ -n "$GIVEN_DATABASE" ]] ; then
echo -e " [$(date)] Repair (and optimize) tables in database '${db}'.."
else
echo -e " [ \033[37m\033[1mMySQL $mysql_version\033[m $(date) ] Repair (and optimize) tables in database '${db}'.."
fi
fi
TABLES="$($mysql $mysql_credential_args $db -N -s -e "show tables" 2> $tmp_log_file )" [ "$db" = "information_schema" ] && continue
if [[ $? -ne 0 ]]; then [ "$db" = "performance_schema" ] && continue
_all_success=false [ "$db" = "mysql" ] && continue
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
echo ""
if [[ -n "$DATABASE_NAME" ]] ; then
echo -e " [$(date)] Repair (and optimize) tables in database '${db}'.."
else
echo -e " [ \033[37m\033[1m$MYSQL_CUR_DISTRIBUTION ${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_LEVEL}\033[m $(date) ] Repair (and optimize) tables in database '${db}'.."
fi
fi
# - Ommit InnoDB tables TABLES="$($mysql $MYSQL_CREDENTIAL_ARGS $db -N -s -e "show tables" 2> $tmp_log_file )"
# - if [[ $? -ne 0 ]]; then
_engine="$($mysql $mysql_credential_args -N -s -e "SELECT ENGINE FROM information_schema.TABLES WHERE TABLE_SCHEMA = '$db' AND TABLE_NAME = '$table'")" _all_success=false
if [[ "${_engine,,}" = 'innodb' ]] ; then error "Getting tables of database '${db}' failed.\n $(cat "$tmp_log_file")"
echo -e " [$(date)] Ommit table '$table' - The storage engine (InnoDB) doesn't support repair" error_messages_arr+=("Getting tables of database '${db}' failed.")
continue continue
fi fi
if $terminal ; then for table in $TABLES ; do
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 # - Ommit InnoDB tables
# -
_engine="$($mysql $MYSQL_CREDENTIAL_ARGS -N -s -e "SELECT ENGINE FROM information_schema.TABLES WHERE TABLE_SCHEMA = '$db' AND TABLE_NAME = '$table'")"
if [[ "${_engine,,}" = 'innodb' ]] ; then
echo -e " [$(date)] Ommit table '$table' - The storage engine (InnoDB) doesn't support repair"
continue
fi
if [[ $? -ne 0 ]]; then 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}
_all_success=false $mysql $MYSQL_CREDENTIAL_ARGS $db -N -s -e "REPAIR TABLE \`$table\`" > $tmp_log_file 2>&1
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 if [[ $? -ne 0 ]]; then
$mysql $mysql_credential_args $db -N -s -e "OPTIMIZE TABLE \`$table\`" > $tmp_log_file 2>&1 _all_success=false
error "Repairing table '$table' failed.\n$(cat "$tmp_log_file")"
error_messages_arr+=("$MYSQL_CUR_DISTRIBUTION ${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_LEVEL}: Error while repairing table '${table}' of database '$db'.")
if [[ $? -ne 0 ]]; then else
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 $mysql $MYSQL_CREDENTIAL_ARGS $db -N -s -e "OPTIMIZE TABLE \`$table\`" > $tmp_log_file 2>&1
if $terminal ;then if [[ $? -ne 0 ]]; then
echo -en "\033[1G [$(date)] End repairing tables of database '${db}'.." error "Reoptimizing table \"${table}\" of database \"$db\" failed.\n$(cat "$tmp_log_file")"
echo error_messages_arr+=("$MYSQL_CUR_DISTRIBUTION ${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_LEVEL}: Error while (re-)optimizing table '${table}' of database '$db'.")
fi fi
fi
done done
if $_all_success ; then if $terminal ;then
if $ALL_DATABASES ; then echo -en "\033[1G [$(date)] End repairing tables of database '${db}'.."
info_messages_arr+=("MySQL $mysql_version: Repairing MySQL tables of all databases was successful.") echo
else fi
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 done
if $_all_success ; then
if $ALL_DATABASES ; then
info_messages_arr+=("$MYSQL_CUR_DISTRIBUTION ${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_LEVEL}: Repairing MySQL tables of all databases was successful.")
else
info_messages_arr+=("$MYSQL_CUR_DISTRIBUTION ${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_LEVEL}: Repairing MySQL tables of database '${db}' was successful.")
fi
fi
if $terminal && $ALL_DATABASES ; then
echo ""
echo -e " [ \033[37m\033[1m$MYSQL_CUR_DISTRIBUTION ${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_LEVEL}\033[m ]: Finished repairing MySQL databases at host $(hostname -f)."
echo ""
fi
if [[ ${#info_messages_arr[@]} -gt 0 ]]; then if [[ ${#info_messages_arr[@]} -gt 0 ]]; then
for msg in "${info_messages_arr[@]}" ; do for msg in "${info_messages_arr[@]}" ; do
if $terminal ; then if $terminal ; then