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,50 +227,181 @@ 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 if $terminal ; then
echo "" echo ""
echo -e "[ \033[37m\033[1mMySQL $mysql_version\033[m ]: repair (and optimize) tables of databases at host '$(hostname -f)'." 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)'."
fi fi
ALL_DATABASES=true ALL_DATABASES=true
else else
found=false found=false
for db in $DATABASES ; do for db in $DATABASES ; do
if [[ "$db" = "$GIVEN_DATABASE" ]]; then if [[ "$db" = "$DATABASE_NAME" ]]; then
DATABASES="$GIVEN_DATABASE" DATABASES="$DATABASE_NAME"
found=true found=true
break
fi fi
done done
if ! $found ; then if ! $found ; then
continue warn "No Database '$DATABASE_NAME' found at $MYSQL_CUR_DISTRIBUTION ${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_LEVEL}"
fi clean_up 0
fi fi
fi
length_table_name=0
for db in $DATABASES ; do length_table_name=0
for db in $DATABASES ; do
[ "$db" = "information_schema" ] && continue [ "$db" = "information_schema" ] && continue
[ "$db" = "performance_schema" ] && continue [ "$db" = "performance_schema" ] && continue
@ -285,14 +409,14 @@ for _val in ${mysql_credential_args_arr[@]} ; do
if $terminal ;then if $terminal ;then
echo "" echo ""
if [[ -n "$GIVEN_DATABASE" ]] ; then if [[ -n "$DATABASE_NAME" ]] ; then
echo -e " [$(date)] Repair (and optimize) tables in database '${db}'.." echo -e " [$(date)] Repair (and optimize) tables in database '${db}'.."
else else
echo -e " [ \033[37m\033[1mMySQL $mysql_version\033[m $(date) ] Repair (and optimize) tables in database '${db}'.." 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
fi fi
TABLES="$($mysql $mysql_credential_args $db -N -s -e "show tables" 2> $tmp_log_file )" TABLES="$($mysql $MYSQL_CREDENTIAL_ARGS $db -N -s -e "show tables" 2> $tmp_log_file )"
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then
_all_success=false _all_success=false
error "Getting tables of database '${db}' failed.\n $(cat "$tmp_log_file")" error "Getting tables of database '${db}' failed.\n $(cat "$tmp_log_file")"
@ -304,7 +428,7 @@ for _val in ${mysql_credential_args_arr[@]} ; do
# - Ommit InnoDB tables # - 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'")" _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 if [[ "${_engine,,}" = 'innodb' ]] ; then
echo -e " [$(date)] Ommit table '$table' - The storage engine (InnoDB) doesn't support repair" echo -e " [$(date)] Ommit table '$table' - The storage engine (InnoDB) doesn't support repair"
continue continue
@ -325,21 +449,21 @@ for _val in ${mysql_credential_args_arr[@]} ; do
fi fi
length_table_name=${#table} length_table_name=${#table}
$mysql $mysql_credential_args $db -N -s -e "REPAIR TABLE \`$table\`" > $tmp_log_file 2>&1 $mysql $MYSQL_CREDENTIAL_ARGS $db -N -s -e "REPAIR TABLE \`$table\`" > $tmp_log_file 2>&1
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then
_all_success=false _all_success=false
error "Repairing table '$table' failed.\n$(cat "$tmp_log_file")" error "Repairing table '$table' failed.\n$(cat "$tmp_log_file")"
error_messages_arr+=("MySQL $mysql_version: Error while repairing table '${table}' of database '$db'.") error_messages_arr+=("$MYSQL_CUR_DISTRIBUTION ${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_LEVEL}: Error while repairing table '${table}' of database '$db'.")
else else
$mysql $mysql_credential_args $db -N -s -e "OPTIMIZE TABLE \`$table\`" > $tmp_log_file 2>&1 $mysql $MYSQL_CREDENTIAL_ARGS $db -N -s -e "OPTIMIZE TABLE \`$table\`" > $tmp_log_file 2>&1
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then
error "Reoptimizing table \"${table}\" of database \"$db\" failed.\n$(cat "$tmp_log_file")" 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'.") error_messages_arr+=("$MYSQL_CUR_DISTRIBUTION ${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_LEVEL}: Error while (re-)optimizing table '${table}' of database '$db'.")
fi fi
fi fi
@ -350,23 +474,23 @@ for _val in ${mysql_credential_args_arr[@]} ; do
echo echo
fi 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 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