commit 9ec6b1c2e1dab2cbf37ffdb9c5574e7c6c188500 Author: Christoph Date: Tue Feb 21 02:31:30 2017 +0100 Initial import diff --git a/FORWARDERS_IN.sql b/FORWARDERS_IN.sql new file mode 100644 index 0000000..5443a89 --- /dev/null +++ b/FORWARDERS_IN.sql @@ -0,0 +1,33 @@ +DROP FUNCTION IF EXISTS FORWARDERS_IN ; + +DELIMITER | + +CREATE FUNCTION FORWARDERS_IN (forewarders_str TEXT, + email_str TEXT, + vacation_domain TEXT , + list_seperator CHAR , + vacation_enable BOOLEAN) + RETURNS TEXT + DETERMINISTIC + BEGIN + DECLARE return_str TEXT; + DECLARE local_email_part TEXT; + DECLARE domain_email_part TEXT; + + + SET return_str = email_str; + + IF vacation_enable THEN + SET local_email_part = SUBSTRING(email_str,1, LOCATE('@',email_str) - 1); + SET domain_email_part = SUBSTRING(email_str, LOCATE('@',email_str) + 1, LENGTH(email_str)); + SET return_str = CONCAT(return_str, list_seperator, local_email_part, "#" ,domain_email_part,"@", vacation_domain); + END IF; + + IF LENGTH(forewarders_str) > 2 THEN + SET return_str = CONCAT(return_str, list_seperator, forewarders_str); + END IF; + + RETURN return_str; + END | + +DELIMITER ; diff --git a/FORWARDERS_OUT.sql b/FORWARDERS_OUT.sql new file mode 100644 index 0000000..d41ea8b --- /dev/null +++ b/FORWARDERS_OUT.sql @@ -0,0 +1,55 @@ +DROP FUNCTION IF EXISTS FORWARDERS_OUT ; + +DELIMITER | + +CREATE FUNCTION FORWARDERS_OUT (email_str TEXT, vacation_domain TEXT , list_seperator CHAR) + RETURNS TEXT + DETERMINISTIC + BEGIN + DECLARE forward_str TEXT; + DECLARE local_email_part TEXT; + DECLARE domain_email_part TEXT; + DECLARE first_char CHAR; + DECLARE last_char CHAR; + + -- get list of forwarders + -- + SELECT goto INTO forward_str FROM alias WHERE address=email_str; + + -- entferne mailbox emailadresse + -- + SET forward_str = REPLACE(forward_str, email_str, '' ); + -- SELECT REPLACE(forward_str, email_str, '' ) INTO forward_str; + + -- entferne vacation adresse + -- + SET local_email_part = SUBSTRING(email_str,1, LOCATE('@',email_str) - 1); + SET domain_email_part = SUBSTRING(email_str, LOCATE('@',email_str) + 1, LENGTH(email_str)); + SET forward_str = REPLACE(forward_str, CONCAT(local_email_part, "#" ,domain_email_part,"@", vacation_domain), ''); + -- SELECT REPLACE(forward_str, CONCAT(list_seperator,list_seperator), list_seperator) INTO forward_str; + + -- enferne doppelte seperatorzeichen + -- + WHILE LOCATE(CONCAT(list_seperator,list_seperator) , forward_str) DO + SET forward_str = REPLACE(forward_str, CONCAT(list_seperator,list_seperator), list_seperator); + -- SELECT REPLACE(forward_str, CONCAT(list_seperator,list_seperator), list_seperator) INTO forward_str; + END WHILE ; + + -- entferne erstes zeichen wenn es das seperatorzeichen ist + -- + IF LEFT(forward_str,1) = list_seperator THEN + SET forward_str = SUBSTRING(forward_str FROM 2); + -- SELECT SUBSTRING(forward_str FROM 2) INTO forward_str; + END IF; + + -- entferne letztes zeichen wenn es das seperatorzeichen ist + -- + IF RIGHT(forward_str,1) = list_seperator THEN + SET forward_str = SUBSTRING(forward_str , 1, LENGTH(forward_str) - 1); + -- SELECT SUBSTRING(forward_str , 1, LENGTH(forward_str) - 1) INTO forward_str; + END IF; + + RETURN forward_str; + END | + +DELIMITER ; diff --git a/OLD/dump_all_mysql_dbs.sh b/OLD/dump_all_mysql_dbs.sh new file mode 100755 index 0000000..060679a --- /dev/null +++ b/OLD/dump_all_mysql_dbs.sh @@ -0,0 +1,148 @@ +#!/usr/bin/env bash + +## - *** some defines *** - ## + +## - Backup direction +## - +backup_base_dir=$1 +backup_base_dir=${backup_base_dir:="/data/backup"} + +backup_dir=${backup_base_dir}/mysql + +mkdir -p $backup_dir + + +_local=$2 +_local=${_local:=false} + +mkdir -p $backup_dir + +## - Database connection data +## - +db_user=backup +db_pass=Rgfwcsgth6Zjk4W +db_host=localhost +db_port=3306 + +## - Some needed binaries +## - +mysql_bin=`which mysql` +mysqldump_bin=`which mysqldump` +mkdir_bin=`which mkdir` +date_bin=`which date` +gzip_bin=`which gzip` +find_bin=`which find` + +if [ -z "$mysql" ]; then + mysql="/usr/local/mysql/bin/mysql" +fi + +if [ -z "$mysqldump" ]; then + mysqldump="/usr/local/mysql/bin/mysqldump" +fi + + + +YEAR=`date +"%Y"` +MONTH=`date +"%m"` +DAY=`date +"%d"` +HOUR=`date +"%H"` +MINUTE=`date +"%M"` +DATE=${YEAR}${MONTH}${DAY}-${HOUR}${MINUTE} + +## - Hold backups at least $days days +## - +days=3 + + +## - ** End: some defines *** - ## + + + +DATABASES=`$mysql_bin -h$db_host -P$db_port -u$db_user -p$db_pass -N -s -e 'show databases'` + +## - backup all databases +## - +for i in $DATABASES ; do + + $mkdir_bin -p ${backup_dir}/${i} + + mysqldump_flags="--opt --routines -l" + if [ "$i" = "information_schema" -o "$i" = "performance_schema" ];then + mysqldump_flags="--single-transaction $mysqldump_flags" + fi + + echo -e "\tsave database $i ..." + $mysqldump_bin $mysqldump_flags -h$db_host -P$db_port -u$db_user -p$db_pass $i | \ + $gzip_bin | cat > ${backup_dir}/${i}/${i}-${DATE}.sql.gz + + ## - dumptables "user" and "db" from database mysql" + ## - + if [ "$i" = "mysql" ]; then + _flags="--add-locks --disable-keys --extended-insert --lock-tables --quick --no-create-info" + + _table=user + ## - dump table user (database mysql) + ## - each row as aseperate sql statement + ## - + ## - | awk '{gsub(/\),\(/,");\n(")}; 1' + ## - | sed 's/^(/INSERT INTO `user` VALUES (/' + ## - + ## - delete row containig host = "localhost" with empty user and password + ## - sed "/^INSERT INTO \`user\` VALUES ('[^']*','root',.\+/d" + ## - + ## - delete rows containig user "root" + ## - sed "/^INSERT INTO \`user\` VALUES ('[^']*','root',.\+/d" + ## - + ## - delete rows containig user "debian-sys-maint" + ## - sed "/^INSERT INTO \`user\` VALUES ('[^']*','debian-sys-maint',.\+/d" + ## - + $mysqldump_bin $_flags -h$db_host -P$db_port -u$db_user -p$db_pass $i $_table \ + | awk '{gsub(/\),\(/,");\n(")}; 1' \ + | sed "s/^(/INSERT INTO \`$_table\` VALUES (/" \ + | sed "/^INSERT INTO \`$_table\` VALUES ('localhost','','','.*/d" \ + | sed "/^INSERT INTO \`$_table\` VALUES ('[^']*','root','.*/d" \ + | sed "/^INSERT INTO \`$_table\` VALUES ('[^']*','debian-sys-maint','.*/d" \ + > ${backup_dir}/${i}/${i}-${_table}-${DATE}.sql + + _table=db + ## - dump table db (database mysql) + ## - each row as aseperate sql statement + ## - + ## - | awk '{gsub(/\),\(/,");\n(")}; 1' + ## - | sed 's/^(/INSERT INTO `user` VALUES (/' + ## - + ## - delete rows for database names "test*" + ## - sed "/^INSERT INTO \`$_table\` VALUES ('[^']*','test[^']*','.*/d" + ## - + $mysqldump_bin $_flags -h$db_host -P$db_port -u$db_user -p$db_pass $i $_table \ + | awk '{gsub(/\),\(/,");\n(")}; 1' \ + | sed "s/^(/INSERT INTO \`$_table\` VALUES (/" \ + | sed "/^INSERT INTO \`$_table\` VALUES ('[^']*','test[^']*','.*/d" \ + > ${backup_dir}/${i}/${i}-${_table}-${DATE}.sql + + ## - BSD sed is not GNU sed , so we used "awk" for substitution + ## - a newline. On GNU sed (like on linux systems), also the + ## - following sed statement works + ## - + #| sed 's/),(/);\n(/g' \ + fi + +done + +## - Create archive from the whole backup +## - +if ! $_local ; then + _curdir=`pwd` + cd $backup_dir + cd .. > /dev/null 2>&1 + tar -czf mysql_dump-${DATE}.tar.gz `find mysql -name "*${DATE}*"` + cd $_curdir +fi + + +## - remove all files older than $days days.. +## - +$find_bin $backup_dir -type f -mtime +${days} -exec rm {} \; + +exit 0 diff --git a/OLD/restore_all_mysql_dbs.sh b/OLD/restore_all_mysql_dbs.sh new file mode 100755 index 0000000..8df5c7f --- /dev/null +++ b/OLD/restore_all_mysql_dbs.sh @@ -0,0 +1,212 @@ +#!/usr/bin/env bash + + +## - Database connection data +## - +db_user=root +db_pass= +db_host=localhost +db_port=3306 + +## - Some needed binaries +## - +mysql_bin=`which mysql` +mysqldump_bin=`which mysqldump` +gunzip_bin=`which gunzip` +find_bin=`which find` + +echononl(){ + echo X\\c > /tmp/shprompt$$ + if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then + echo "$*\\c" 1>&2 + else + echo -n "$*" 1>&2 + fi + rm /tmp/shprompt$$ +} +fatal(){ + echo "" + echo Fehler: $* + echo -e "\n\t\033[31m\033[1mSkript wird abgebrochen\033[m\033[m\n" + exit 1 +} + + +echo "" +echo -n "Give password for database user \"${db_user}\" [$db_pass]: " +stty -echo +read _pass +stty echo +while [ "X" == "X$_pass" ];do + echononl "Enry must not be empty! []: " + stty -echo + read _pass + stty echo +done +db_pass=$_pass +echo "" + + +PATH=/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin:/root/bin + +BACKUP_BASE_DIR="/data/backup/mysql" + +if [ ! -d $BACKUP_BASE_DIR ] ; then + echo + echo " Backup directory not found" + echo + exit 1 +fi + + +logfile=restore_db_mysql.log + + + +databases=`$find_bin $BACKUP_BASE_DIR -maxdepth 1 -mindepth 1 -type d -exec basename {} \;` + +echo "" +echo "Do you want me restoring also the MySQL intern Database \"mysql\"" +echo "" +_opt1="Yes, restore all table of intern database \"mysql\"" +_opt2="Only add not present entries to table \"user\" and table \"db\"" +_opt3="No, let all tables from MySQL intern database \"mysql\" untouched" +_opt4="QUIT - exit script NOW" + +options=("$_opt1" "$_opt2" "$_opt3" "$_opt4") +PS3="Choose (1-4):" + +_restore_mysql=3 +select opt in "${options[@]}" +do + case $opt in + $_opt1) + _restore_mysql=1 + break + ;; + $_opt2) + _restore_mysql=2 + break + ;; + $_opt3) + _restore_mysql=3 + break + ;; + $_opt4) + exit 2 + ;; + *) + echo "" + echo "!! INVALID CHOISE !!" + echo "" + echo "1) $_opt1" + echo "2) $_opt2" + echo "3) $_opt3" + echo "" + ;; + esac +done + + +echo -e "\n\tRestoring Databases\n" +for db in $databases ; do + + #[ "$db" = "information_schema" ] && continue + + _list=`ls -d -t ${BACKUP_BASE_DIR}/$db/*.sql.gz` + file=`echo $_list | awk '{print$1}'` + + if [ "$db" = "information_schema" ]; then + echo "" + echononl "Do you want to restore database \"$db\" too? [yes/no]: " + read OK + while [ "X$OK" != "Xyes" -a "X$OK" != "XYes" -a "X$OK" != "Xja" -a "X$OK" != "XJa" \ + -a "X$OK" != "XNo" -a "X$OK" != "Xno" -a "X$OK" != "Xn" -a "X$OK" != "Xnein" -a "X$OK" != "XNein" ]; do + echononl "Incorrect entry! [yes/no]: " + read OK + done + echo "" + if [ $OK = "Yes" -o $OK = "yes" -o "$OK" = "ja" -o "$OK" = "Ja" ]; then + echo -e "\t\trestoring ${db} (`basename $file`) .." + gunzip_bin < $file | mysql_bin -h$db_host -u$db_user -p'$db_pass $db' + fi + elif [ "$db" = "performance_schema" ]; then + echo "" + echononl "Do you want to restore database \"$db\" too? [yes/no]: " + read OK + while [ "X$OK" != "Xyes" -a "X$OK" != "XYes" -a "X$OK" != "Xja" -a "X$OK" != "XJa" \ + -a "X$OK" != "XNo" -a "X$OK" != "Xno" -a "X$OK" != "Xn" -a "X$OK" != "Xnein" -a "X$OK" != "XNein" ]; do + echononl "Incorrect entry! [yes/no]: " + read OK + done + echo "" + if [ $OK = "Yes" -o $OK = "yes" -o "$OK" = "ja" -o "$OK" = "Ja" ]; then + echo -e "\t\trestoring ${db} (`basename $file`) .." + gunzip_bin < $file | mysql_bin -h$db_host -u$db_user -p'$db_pass $db' + fi + elif [ "$db" = "mysql" ]; then + + if [ "$_restore_mysql" = "1" ]; then + + ## - save entry for User "debian-sys-maint" + ## - + declare -i num + num=0 + num=`$mysql_bin -u$db_user -P$db_port -u$db_user -p$db_pass $db -N -s -e "SELECT count(*) from user Where USER = 'debian-sys-maint'"` + if [ $num -gt 0 ];then + COLUMNS=`$mysql_bin -h$db_host -P$db_port -u$db_user -p$db_pass -N -s -e "SHOW COLUMNS FROM user FROM mysql" | awk '{print$1}'` + stmt_update=""; + for column in $COLUMNS ; do + val="" + val=`mysql -h$db_host -P$db_port -u$db_user -p$db_pass mysql -N -s -e "SELECT $column FROM user WHERE User = 'debian-sys-maint'"` + stmt_update="UPDATE user SET $column = '$val' WHERE User = 'debian-sys-maint';$stmt_update" + done + fi + + echo -e "\t\trestoring ${db} (`basename $file`) .." + $gunzip_bin < $file | $mysql_bin -h$db_host -u$db_user -p$db_pass $db + + if [ $num -gt 0 ];then + stmt_insert="INSERT INTO user (Host,User) VALUES ('localhost','debian-sys-maint')" + $mysql_bin -u$db_user -P$db_port -u$db_user -p$db_pass $db -N -s -e "$stmt_insert" + $mysql_bin -u$db_user -P$db_port -u$db_user -p$db_pass $db -N -s -e "$stmt_update" + fi + + # FLUSH PRIVILEGES + $mysql_bin -h$db_host -P$db_port -u$db_user -p$db_pass -N -s -e "FLUSH PRIVILEGES" + + echo "" + echo "If password for database user \"root\" has changed within restoring \"${db}\"" + echo -n "database, enter the new one. If not, only type : " + stty -echo + read _pass + stty echo + if [ "X" != "X$_pass" ];then + db_pass=$_pass + fi + echo -e "\n" + elif [ "$_restore_mysql" = "2" ]; then + echo "" + _tables="db user" + for _table in $_tables ; do + _list_table=`ls -d -t ${BACKUP_BASE_DIR}/$db/mysql-${_table}-*.sql` + file_table=`echo $_list_table | awk '{print$1}'` + + echo -e "\t\trestoring table \"$_table\" from database ${db} (`basename $file_table`) .." + $mysql_bin -f -h$db_host -P$db_port -u$db_user -p$db_pass $db < $file_table + done + echo "" + fi + else + echo -e "\t\trestoring ${db} (`basename $file`) .." + $mysql_bin -h$db_host -P$db_port -u$db_user -p$db_pass -N -s -e "DROP DATABASE IF EXISTS $db" + $mysql_bin -h$db_host -P$db_port -u$db_user -p$db_pass -N -s -e "CREATE DATABASE $db CHARACTER SET utf8 COLLATE utf8_general_ci" + $gunzip_bin < $file | $mysql_bin -h$db_host -P$db_port -u$db_user -p$db_pass $db + fi + +done +echo + +$mysql_bin -h$db_host -P$db_port -u$db_user -p$db_pass -N -s -e "FLUSH PRIVILEGES" + +exit 0 diff --git a/create_databases.sh b/create_databases.sh new file mode 100755 index 0000000..01da3a5 --- /dev/null +++ b/create_databases.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +mysql_credential_args="--login-path=local" + + + +_drop=false + +echo "" +while read _db_name _db_user _db_pass ; do + echo -e "\tprocessing database \"$_db_name\"" + + if $_drop ; then + mysql $mysql_credential_args -N -s -e \ + "DROP DATABASE $_db_name" + mysql $mysql_credential_args mysql -N -s -e \ + "DELETE FROM db WHERE Db = '$_db_name'" + mysql $mysql_credential_args mysql -N -s -e \ + "DELETE FROM user WHERE User = '$_db_user'" + else + + mysql $mysql_credential_args -N -s -e \ + "CREATE DATABASE IF NOT EXISTS $_db_name CHARACTER SET utf8 COLLATE utf8_general_ci" + mysql $mysql_credential_args -N -s -e \ + "GRANT ALL ON $_db_name.* TO '$_db_user'@'localhost' IDENTIFIED BY '$_db_pass'" + mysql $mysql_credential_args -N -s -e \ + "USE mysql; UPDATE user SET Super_priv = 'Y' WHERE User = '$_db_user'" + fi + + +done < databases.txt +echo "" + +mysql $mysql_credential_args -N -s -e "FLUSH PRIVILEGES" + + +exit 0 diff --git a/flush_host_cache.sh b/flush_host_cache.sh new file mode 100755 index 0000000..c6afe5d --- /dev/null +++ b/flush_host_cache.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash + +#LOGGING=true +LOGGING=false + +mysqladmin=`realpath $(which mysqladmin) 2>/dev/null` +if [ -z "$mysqladmin" ]; then + if [ -x "/usr/local/mysql/bin/mysqladmin" ]; then + mysql=/usr/local/mysql/bin/mysqladmin + else + echo + echo -e "\t[ Error ]: \"mysqladmin\" not found !!!" + echo + exit + fi +fi + +## - Since Version 5.6, that method is considered as insecure. +## - To avoid giving the password on command line, we use an +## - encrypted option file +## - +## - Create (encrypted) option file: +## - $ mysql_config_editor set --login-path=local --socket=/var/run/mysqld/mysqld.sock --user=backup --password +## - $ Password: +## - +## - Use of option file: +## - $ mysql --login-path=local ... +## - +mysql_credential_args="--login-path=local" +#mysql_user='sys-maint' +#mysql_password='9A7NUgaJST1XiEUU' + +if $LOGGING ;then + echo -e "\n[ `date` ] Going to flush host cache.." +fi + +if [ -n "$mysql_credential_args" ] ; then + $mysqladmin $mysql_credential_args flush-hosts +else + $mysqladmin -u$mysql_user -p$mysql_password flush-hosts +fi + +[[ $? -gt 0 ]] && echo -e "\t[ Error ]: Flushing host cache failed !!" + +if $LOGGING ;then + echo -e "\n[ `date` ] End flushing host cache" +fi + +exit 0 diff --git a/flush_query_cache.sh b/flush_query_cache.sh new file mode 100755 index 0000000..f885981 --- /dev/null +++ b/flush_query_cache.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash + +#LOGGING=true +LOGGING=false + +mysql=`realpath $(which mysql) 2>/dev/null` +if [ -z "$mysql" ]; then + if [ -x "/usr/local/mysql/bin/mysql" ]; then + mysql=/usr/local/mysql/bin/mysql + else + echo + echo -e "\t[ Error ]: \"mysql\" not found !!!" + echo + exit + fi +fi + +## - Since Version 5.6, that method is considered as insecure. +## - To avoid giving the password on command line, we use an +## - encrypted option file +## - +## - Create (encrypted) option file: +## - $ mysql_config_editor set --login-path=local --socket=/var/run/mysqld/mysqld.sock --user=backup --password +## - $ Password: +## - +## - Use of option file: +## - $ mysql --login-path=local ... +## - +mysql_credential_args="--login-path=local" +#mysql_user='sys-maint' +#mysql_password='9A7NUgaJST1XiEUU' + +if $LOGGING ;then + echo -e "\n[ `date` ] Going to flush query cache.." +fi + +if [ -n "$mysql_credential_args" ] ; then + $mysql $mysql_credential_args -N -s -e "FLUSH QUERY CACHE" +else + $mysql -u$mysql_user -p$mysql_password -N -s -e "FLUSH QUERY CACHE" +fi + +[[ $? -gt 0 ]] && echo -e "\t[ Error ]: Flushing query cache failed !!" + +if $LOGGING ;then + echo -e "\n[ `date` ] End flushing query cache" +fi + +exit 0 diff --git a/max_memory_limit_mysql.sh b/max_memory_limit_mysql.sh new file mode 100755 index 0000000..be2ac0d --- /dev/null +++ b/max_memory_limit_mysql.sh @@ -0,0 +1,266 @@ +#!/usr/bin/env bash + +mysql_credential="--login-path=local" +#mysql_credential="--defaults-file=/etc/mysql/debian.cnf" +#mysql_credential="--defaults-file=/usr/local/mysql/sys-maint.cnf" + +declare -i key_buffer_size +declare -i query_cache_size +declare -i tmp_table_size +declare -i innodb_buffer_pool_size +declare -i innodb_additional_mem_pool_size +declare -i innodb_log_buffer_size +declare -i max_connections +declare -i sort_buffer_size +declare -i read_buffer_size +declare -i read_rnd_buffer_size +declare -i join_buffer_size +declare -i thread_stack +declare -i binlog_cache_size + +key_buffer_size=`mysql $mysql_credential -N -s -e \ + "SHOW VARIABLES LIKE 'key_buffer_size'" | awk '{print$2}'` +query_cache_size=`mysql $mysql_credential -N -s -e \ + "SHOW VARIABLES LIKE 'query_cache_size'" | awk '{print$2}'` +tmp_table_size=`mysql $mysql_credential -N -s -e \ + "SHOW VARIABLES LIKE 'tmp_table_size'" | awk '{print$2}'` +innodb_buffer_pool_size=`mysql $mysql_credential -N -s -e \ + "SHOW VARIABLES LIKE 'innodb_buffer_pool_size'" | awk '{print$2}'` +innodb_additional_mem_pool_size=`mysql $mysql_credential -N -s -e \ + "SHOW VARIABLES LIKE 'innodb_additional_mem_pool_size'" | awk '{print$2}'` +innodb_log_buffer_size=`mysql $mysql_credential -N -s -e \ + "SHOW VARIABLES LIKE 'innodb_log_buffer_size'" | awk '{print$2}'` +max_connections=`mysql $mysql_credential -N -s -e \ + "SHOW VARIABLES LIKE 'max_connections'" | awk '{print$2}'` +sort_buffer_size=`mysql $mysql_credential -N -s -e \ + "SHOW VARIABLES LIKE 'sort_buffer_size'" | awk '{print$2}'` +read_buffer_size=`mysql $mysql_credential -N -s -e \ + "SHOW VARIABLES LIKE 'read_buffer_size'" | awk '{print$2}'` +read_rnd_buffer_size=`mysql $mysql_credential -N -s -e \ + "SHOW VARIABLES LIKE 'read_rnd_buffer_size'" | awk '{print$2}'` +join_buffer_size=`mysql $mysql_credential -N -s -e \ + "SHOW VARIABLES LIKE 'join_buffer_size'" | awk '{print$2}'` +thread_stack=`mysql $mysql_credential -N -s -e \ + "SHOW VARIABLES LIKE 'thread_stack'" | awk '{print$2}'` +binlog_cache_size=`mysql $mysql_credential -N -s -e \ + "SHOW VARIABLES LIKE 'binlog_cache_size'" | awk '{print$2}'` + +mysql_version=`mysql $mysql_credential -N -s -e \ + "SHOW VARIABLES LIKE 'version'" | awk '{print$2}' | sed -e's/-.*$//'` +mysql_version_compile_machine=`mysql $mysql_credential -N -s -e \ + "SHOW VARIABLES LIKE 'version_compile_machine'" | awk '{print$2}'` + +declare -i max_used_connections +declare -i uptime +declare -i threads_connected + +max_used_connections=`mysql $mysql_credential -N -s -e \ + "SHOW STATUS LIKE 'Max_used_connections'" | awk '{print$2}'` +threads_connected=`mysql $mysql_credential -N -s -e \ + "SHOW STATUS LIKE 'Threads_connected'" | awk '{print$2}'` +uptime=`mysql $mysql_credential -N -s -e \ + "SHOW STATUS LIKE 'Uptime'" | awk '{print$2}'` + +_now=`date +%s` +_timestamp_start=`expr $_now - $uptime` +starttime=`date -d \@$_timestamp_start +%c` + +days=`echo "scale=0 ; $uptime / 86400" | bc -l` +days_rest=`echo "scale=0 ; $uptime % 86400" | bc -l` +hours=`echo "scale=0 ; $days_rest / 3600" | bc -l` +hours_rest=`echo "scale=0 ; $days_rest % 3600" | bc -l` +minutes=`echo "scale=0 ; $hours_rest / 60" | bc -l` +seconds=`echo "scale=0 ; $hours_rest % 60" | bc -l` +uptime_string="$days days $hours hrs $minutes min $seconds sec" + +## - +#declare -i myisam_sort_buffer_size=`mysql --login-path=local -N -s -e \ +# "SHOW VARIABLES LIKE 'myisam_sort_buffer_size'" | awk '{print$2}'` + + +echo "" + +_key_buffer_size="" +if [ $key_buffer_size -gt 1048576 ]; then + _key_buffer_size=" (`expr $key_buffer_size / 1024 / 1024`M)" +elif [ $key_buffer_size -gt 1024 ]; then + _key_buffer_size=" (`expr $key_buffer_size / 1024`K)" +fi + +_query_cache_size="" +if [ $query_cache_size -gt 1048576 ]; then + _query_cache_size=" (`expr $query_cache_size / 1024 / 1024`M)" +elif [ $key_buffer_size -gt 1024 ]; then + _query_cache_size=" (`expr $query_cache_size / 1024`K)" +fi + +_tmp_table_size="" +if [ $tmp_table_size -gt 1048576 ]; then + _tmp_table_size=" (`expr $tmp_table_size / 1024 / 1024`M)" +elif [ $tmp_table_size -gt 1024 ]; then + _tmp_table_size=" (`expr $tmp_table_size / 1024`K)" +fi + +_innodb_buffer_pool_size="" +if [ $innodb_buffer_pool_size -gt 1048576 ]; then + _innodb_buffer_pool_size=" (`expr $innodb_buffer_pool_size / 1024 / 1024`M)" +elif [ $innodb_buffer_pool_size -gt 1024 ]; then + _innodb_buffer_pool_size=" (`expr $innodb_buffer_pool_size / 1024`K)" +fi + +_innodb_additional_mem_pool_size="" +if [ $innodb_additional_mem_pool_size -gt 1048576 ]; then + _innodb_additional_mem_pool_size=" (`expr $innodb_additional_mem_pool_size / 1024 / 1024`M)" +elif [ $innodb_additional_mem_pool_size -gt 1024 ]; then + _innodb_additional_mem_pool_size=" (`expr $innodb_additional_mem_pool_size / 1024`K)" +fi + +_innodb_log_buffer_size="" +if [ $innodb_log_buffer_size -gt 1048576 ]; then + _innodb_log_buffer_size=" (`expr $innodb_log_buffer_size / 1024 / 1024`M)" +elif [ $innodb_log_buffer_size -gt 1024 ]; then + _innodb_log_buffer_size=" (`expr $innodb_log_buffer_size / 1024`K)" +fi + +_sort_buffer_size="" +if [ $sort_buffer_size -gt 1048576 ]; then + _sort_buffer_size=" (`expr $sort_buffer_size / 1024 / 1024`M)" +elif [ $sort_buffer_size -gt 1024 ]; then + _sort_buffer_size=" (`expr $sort_buffer_size / 1024`K)" +fi + +_read_buffer_size="" +if [ $read_buffer_size -gt 1048576 ]; then + _read_buffer_size=" (`expr $read_buffer_size / 1024 / 1024`M)" +elif [ $read_buffer_size -gt 1024 ]; then + _read_buffer_size=" (`expr $read_buffer_size / 1024`K)" +fi + +_read_rnd_buffer_size="" +if [ $read_rnd_buffer_size -gt 1048576 ]; then + _read_rnd_buffer_size=" (`expr $read_rnd_buffer_size / 1024 / 1024`M)" +elif [ $read_rnd_buffer_size -gt 1024 ]; then + _read_rnd_buffer_size=" (`expr $read_rnd_buffer_size / 1024`K)" +fi + +_join_buffer_size="" +if [ $join_buffer_size -gt 1048576 ]; then + _join_buffer_size=" (`expr $join_buffer_size / 1024 / 1024`M)" +elif [ $join_buffer_size -gt 1024 ]; then + _join_buffer_size=" (`expr $join_buffer_size / 1024`K)" +fi + +_thread_stack="" +if [ $thread_stack -gt 1048576 ]; then + _thread_stack=" (`expr $thread_stack / 1024 / 1024`M)" +elif [ $thread_stack -gt 1024 ]; then + _thread_stack=" (`expr $thread_stack / 1024`K)" +fi + +_binlog_cache_size="" +if [ $binlog_cache_size -gt 1048576 ]; then + _binlog_cache_size=" (`expr $binlog_cache_size / 1024 / 1024`M)" +elif [ $binlog_cache_size -gt 1024 ]; then + _binlog_cache_size=" (`expr $binlog_cache_size / 1024`K)" +fi + +echo -e "\tGlobal Buffers" +echo -e "\t--------------" +echo -e "\tkey_buffer_size...................: $key_buffer_size $_key_buffer_size" +echo -e "\tquery_cache_size..................: $query_cache_size $_query_cache_size" +echo -e "\ttmp_table_size....................: $tmp_table_size $_tmp_table_size" +echo -e "\tinnodb_buffer_pool_size...........: $innodb_buffer_pool_size $_innodb_buffer_pool_size" +echo -e "\tinnodb_additional_mem_pool_size...: $innodb_additional_mem_pool_size $_innodb_additional_mem_pool_size" +echo -e "\tinnodb_log_buffer_size............: $innodb_log_buffer_size $_innodb_log_buffer_size" +echo "" +echo -e "\tmax_connections...................: $max_connections" +echo "" +echo -e "\tPer Thread Buffers" +echo -e "\t------------------" +echo -e "\tsort_buffer_size..................: $sort_buffer_size $_sort_buffer_size" +echo -e "\tread_buffer_size..................: $read_buffer_size $_read_buffer_size" +echo -e "\tread_rnd_buffer_size..............: $read_rnd_buffer_size $_read_rnd_buffer_size" +echo -e "\tjoin_buffer_size..................: $join_buffer_size $_join_buffer_size" +echo -e "\tthread_stack......................: $thread_stack $_thread_stack" +echo -e "\tbinlog_cache_size.................: $binlog_cache_size $_binlog_cache_size" + +declare -i max_memory_usage +max_memory_usage=`expr $key_buffer_size \ + + $query_cache_size \ + + $tmp_table_size \ + + $innodb_buffer_pool_size \ + + $innodb_additional_mem_pool_size \ + + $innodb_log_buffer_size \ + + $max_connections \* \( $sort_buffer_size \ + + $read_buffer_size \ + + $read_rnd_buffer_size \ + + $join_buffer_size \ + + $thread_stack \ + + $binlog_cache_size \)` + +max_memory_usage_mb=`expr $max_memory_usage / 1024 / 1024` +#max_memory_usage_mb=`echo "scale=3; $max_memory_usage/1024/1024" | bc -l` + + +declare -i max_memory_allocated +max_memory_allocated=`expr $key_buffer_size \ + + $query_cache_size \ + + $tmp_table_size \ + + $innodb_buffer_pool_size \ + + $innodb_additional_mem_pool_size \ + + $innodb_log_buffer_size \ + + $max_used_connections \* \( $sort_buffer_size \ + + $read_buffer_size \ + + $read_rnd_buffer_size \ + + $join_buffer_size \ + + $thread_stack \ + + $binlog_cache_size \)` + +max_memory_allocated_mb=`expr $max_memory_allocated / 1024 / 1024` + + +cur_memory_usage=`ps -ylC mysqld | grep mysqld | awk '{print$8}'` +cur_memory_usage_mb=`echo "scale=0; $cur_memory_usage/1024+1" | bc -l` + + +echo "" +echo "" +echo -e "\tSUM(Global Buffers) + max_connections * SUM(Per Thread Buffers)" +echo -e "\t===============================================================" +echo "" +if [ $max_memory_usage_mb -gt 1023 ]; then + max_memory_usage_gb=`echo "scale=3; $max_memory_usage_mb/1024" | bc -l` + echo -e "\tMax Memory Limit..................: $max_memory_usage_mb MB ($max_memory_usage_gb GB)" +else + echo -e "\tMax Memory Limit..................: $max_memory_usage_mb MB" +fi +echo "" +echo "" +echo "----- (Since last MySQL start)" +echo "" +echo -e "\tStart Time........................: $starttime" +echo -e "\tUptime............................: $uptime_string" +echo "" +echo -e "\tMax Used Connections..............: $max_used_connections" +if [ $max_memory_allocated_mb -gt 1023 ]; then + max_memory_allocated_gb=`echo "scale=3; $max_memory_allocated_mb/1024" | bc -l` + echo -e "\tMax Memory Allocated..............: $max_memory_allocated_mb MB ($max_memory_allocated_gb GB)" +else + echo -e "\tMax Memory Allocated..............: $max_memory_allocated_mb MB" +fi +echo "" +echo "" +echo "----- Current Status" +echo "" +echo -e "\tMySQL Version.....................: $mysql_version ($mysql_version_compile_machine)" +echo "" +if [ $cur_memory_usage_mb -gt 1023 ]; then + cur_memory_usage_gb=`echo "scale=3; $cur_memory_usage_mb/1024" | bc -l` + echo -e "\tCurrent Memory Usage..............: $cur_memory_usage_mb MB ($cur_memory_usage_gb GB)" +else + echo -e "\tCurrent Memory Usage..............: $cur_memory_usage_mb MB" +fi +echo -e "\tTreads Connected..................: $threads_connected" +echo "" + +exit diff --git a/mysql_memory_usage.sh b/mysql_memory_usage.sh new file mode 100755 index 0000000..00317d9 --- /dev/null +++ b/mysql_memory_usage.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +echo "" +ps -ylC mysqld + +echo "" +ps -ylC mysqld | awk '{x += $8;y += 1} END {print "MySQL Memory Usage (MB): "x/1024; print "Average Proccess Size (MB): "x/((y-1)*1024)}' +echo "" diff --git a/optimize_mysql_tables-ND.sh b/optimize_mysql_tables-ND.sh new file mode 100755 index 0000000..653dcf7 --- /dev/null +++ b/optimize_mysql_tables-ND.sh @@ -0,0 +1,139 @@ +#!/usr/bin/env bash + +LOGGING=false + +mysql=`which mysql` + +if [ -z "$mysql" ]; then + if [ -x "/usr/local/mysql/bin/mysql" ]; then + mysql=/usr/local/mysql/bin/mysql + fi +fi + +# - MySQL / MariaDB credentials +# - +# - Giving password on command line is insecure an sind mysql 5.5 +# - you will get a warning doing so. +# - +# - Reading username/password fro file ist also possible, using MySQL/MariaDB +# - commandline parameter '--defaults-file'. +# - +# - Since Version 5.6, that method is considered as insecure. +# - To avoid giving the password on command line, we use an +# - encrypted option file +# - +# - Create (encrypted) option file: +# - $ mysql_config_editor set --login-path=local --socket=/var/run/mysqld/mysqld.sock --user=backup --password +# - $ Password: +# - +# - Use of option file: +# - $ mysql --login-path=local ... +# - +# - Example +# - mysql_credential_args="--login-path=local" +# - mysql_credential_args="--defaults-file=/etc/mysql/debian.cnf" (Debian default) +# - mysql_credential_args="--defaults-file=/usr/local/mysql/sys-maint.cnf" +# - +mysql_credential_args="--login-path=local" + + +if [ -n "$mysql_credential_args" ] ; then + DATABASES=`$mysql $mysql_credential_args -N -s -e "show databases"` +else + DATABASES=`$mysql -u$mysql_user -p$mysql_password -N -s -e "show databases"` +fi + +_service_extension=PRODUCTION.$$ + +for db in $DATABASES ; do + + if [ "$db" = "nd" ]; then + mv /var/www/html/projekte/nd/htdocs /var/www/html/projekte/nd/htdocs.$_service_extension + ln -s htdocs503 /var/www/html/projekte/nd/htdocs + /usr/local/apache2/bin/apachectl graceful + elif [ "$db" = "nd_archiv" ]; then + mv /var/www/html/projekte/nd-archiv/htdocs /var/www/html/projekte/nd-archiv/htdocs.$_service_extension + ln -s htdocs503 /var/www/html/projekte/nd-archiv/htdocs + /usr/local/apache2/bin/apachectl graceful + fi + + [ "$db" = "information_schema" ] && continue + [ "$db" = "performance_schema" ] && continue + [ "$db" = "mysql" ] && continue + + if $LOGGING ;then + echo -e "\n[`date`] Optimize tables in database $db.." + fi + + if [ -n "$mysql_credential_args" ] ; then + TABLES=`$mysql $mysql_credential_args $db -N -s -e "show tables"` + else + TABLES=`$mysql -u$mysql_user -p$mysql_password $db -N -s -e "show tables"` + fi + + for table in $TABLES ; do + + if [ -n "$mysql_credential_args" ] ; then + if $LOGGING ;then + $mysql $mysql_credential_args $db -N -s -e "OPTIMIZE TABLE \`$table\`" + else + $mysql $mysql_credential_args $db -N -s -e "OPTIMIZE TABLE \`$table\`" > /dev/null 2>&1 + fi + else + $mysql -u$mysql_user -p$mysql_password $db -N -s -e "OPTIMIZE TABLE \`$table\`" > /dev/null 2>&1 + fi + if [ "$?" != "0" ]; then + echo -e "\t[ Warning ]: Optimizing table \"${table}\" of database \"$db\" failed. Trying to repair.." + if [ -n "$mysql_credential_args" ] ; then + if $LOGGING ;then + $mysql $mysql_credential_args $db -N -s -e "REPAIR TABLE \`$table\`" + else + $mysql $mysql_credential_args $db -N -s -e "REPAIR TABLE \`$table\`" > /dev/null 2>&1 + fi + if [ "$?" != "0" ]; then + echo -e "\t[ERROR]: Reparing table \"${table}\" of database \"$db\" failed !!" + else + if $LOGGING ;then + $mysql $mysql_credential_args $db -N -s -e "OPTIMIZE TABLE \`$table\`" + else + $mysql $mysql_credential_args $db -N -s -e "OPTIMIZE TABLE \`$table\`" > /dev/null 2>&1 + fi + [[ $? -gt 0 ]] && echo -e "\t[ERROR]: Optimizing table \"${table}\" of database \"$db\" failed !!" + fi + else + if $LOGGING ;then + $mysql -u$mysql_user -p$mysql_password $db -N -s -e "REPAIR TABLE \`$table\`" + else + $mysql -u$mysql_user -p$mysql_password $db -N -s -e "REPAIR TABLE \`$table\`" > /dev/null 2>&1 + fi + if [ "$?" != "0" ]; then + echo -e "\t[ERROR]: Reparing table \"${table}\" of database \"$db\" failed !!" + else + if $LOGGING ;then + $mysql -u$mysql_user -p$mysql_password $db -N -s -e "OPTIMIZE TABLE \`$table\`" + else + $mysql -u$mysql_user -p$mysql_password $db -N -s -e "OPTIMIZE TABLE \`$table\`" > /dev/null 2>&1 + fi + [[ $? -gt 0 ]] && echo -e "\t[ERROR]: Optimizing table \"${table}\" of database \"$db\" failed !!" + fi + fi + fi + + done + if $LOGGING ;then + echo -e "\n[`date`] End optimize tables in database $db.." + fi + + if [ "$db" = "nd" ]; then + rm -f /var/www/html/projekte/nd/htdocs + mv /var/www/html/projekte/nd/htdocs.$_service_extension /var/www/html/projekte/nd/htdocs + /usr/local/apache2/bin/apachectl graceful + elif [ "$db" = "nd_archiv" ]; then + rm -f /var/www/html/projekte/nd-archiv/htdocs + mv /var/www/html/projekte/nd-archiv/htdocs.$_service_extension /var/www/html/projekte/nd-archiv/htdocs + /usr/local/apache2/bin/apachectl graceful + fi + +done + +exit 0 diff --git a/optimize_mysql_tables.sh b/optimize_mysql_tables.sh new file mode 100755 index 0000000..64d76e6 --- /dev/null +++ b/optimize_mysql_tables.sh @@ -0,0 +1,140 @@ +#!/usr/bin/env bash + +# - Is this script running on terminal ? +# - +if [[ -t 1 ]] ; then + terminal=true + LOGGING=true +else + terminal=false + LOGGING=false +fi + +mysql=`which mysql` + +if [ -z "$mysql" ]; then + if [ -x "/usr/local/mysql/bin/mysql" ]; then + mysql=/usr/local/mysql/bin/mysql + fi +fi + +# - MySQL / MariaDB credentials +# - +# - Giving password on command line is insecure an sind mysql 5.5 +# - you will get a warning doing so. +# - +# - Reading username/password fro file ist also possible, using MySQL/MariaDB +# - commandline parameter '--defaults-file'. +# - +# - Since Version 5.6, that method is considered as insecure. +# - To avoid giving the password on command line, we use an +# - encrypted option file +# - +# - Create (encrypted) option file: +# - $ mysql_config_editor set --login-path=local --socket=/tmp/mysql.sock --user=root --password +# - $ Password: +# - +# - Use of option file: +# - $ mysql --login-path=local ... +# - +# - Example +# - mysql_credential_args="--login-path=local" +# - mysql_credential_args="--defaults-file=/etc/mysql/debian.cnf" (Debian default) +# - mysql_credential_args="--defaults-file=/usr/local/mysql/sys-maint.cnf" +# - +mysql_credential_args="--login-path=local" + + +if [ -n "$mysql_credential_args" ] ; then + DATABASES=`$mysql $mysql_credential_args -N -s -e "show databases"` +else + DATABASES=`$mysql -u$mysql_user -p$mysql_password -N -s -e "show databases"` +fi + +if $terminal ; then + echo "" + echo "MySQL: optimize (and try to repair) tables of databases at host $(hostname -f)." + echo "" +fi + + + +for db in $DATABASES ; do + + + [ "$db" = "information_schema" ] && continue + [ "$db" = "performance_schema" ] && continue + [ "$db" = "mysql" ] && continue + + if $LOGGING ;then + echo -e "\n[`date`] Optimize tables in database $db.." + fi + + if [ -n "$mysql_credential_args" ] ; then + TABLES=`$mysql $mysql_credential_args $db -N -s -e "show tables"` + else + TABLES=`$mysql -u$mysql_user -p$mysql_password $db -N -s -e "show tables"` + fi + + for table in $TABLES ; do + + if [ -n "$mysql_credential_args" ] ; then + if $LOGGING ;then + $mysql $mysql_credential_args $db -N -s -e "OPTIMIZE TABLE \`$table\`" + else + $mysql $mysql_credential_args $db -N -s -e "OPTIMIZE TABLE \`$table\`" > /dev/null 2>&1 + fi + else + $mysql -u$mysql_user -p$mysql_password $db -N -s -e "OPTIMIZE TABLE \`$table\`" > /dev/null 2>&1 + fi + if [ "$?" != "0" ]; then + echo -e "\t[ Warning ]: Optimizing table \"${table}\" of database \"$db\" failed. Trying to repair.." + if [ -n "$mysql_credential_args" ] ; then + if $LOGGING ;then + $mysql $mysql_credential_args $db -N -s -e "REPAIR TABLE \`$table\`" + else + $mysql $mysql_credential_args $db -N -s -e "REPAIR TABLE \`$table\`" > /dev/null 2>&1 + fi + if [ "$?" != "0" ]; then + echo -e "\t[ERROR]: Reparing table \"${table}\" of database \"$db\" failed !!" + else + if $LOGGING ;then + $mysql $mysql_credential_args $db -N -s -e "OPTIMIZE TABLE \`$table\`" + else + $mysql $mysql_credential_args $db -N -s -e "OPTIMIZE TABLE \`$table\`" > /dev/null 2>&1 + fi + [[ $? -gt 0 ]] && echo -e "\t[ERROR]: Optimizing table \"${table}\" of database \"$db\" failed !!" + fi + else + if $LOGGING ;then + $mysql -u$mysql_user -p$mysql_password $db -N -s -e "REPAIR TABLE \`$table\`" + else + $mysql -u$mysql_user -p$mysql_password $db -N -s -e "REPAIR TABLE \`$table\`" > /dev/null 2>&1 + fi + if [ "$?" != "0" ]; then + echo -e "\t[ERROR]: Reparing table \"${table}\" of database \"$db\" failed !!" + else + if $LOGGING ;then + $mysql -u$mysql_user -p$mysql_password $db -N -s -e "OPTIMIZE TABLE \`$table\`" + else + $mysql -u$mysql_user -p$mysql_password $db -N -s -e "OPTIMIZE TABLE \`$table\`" > /dev/null 2>&1 + fi + [[ $? -gt 0 ]] && echo -e "\t[ERROR]: Optimizing table \"${table}\" of database \"$db\" failed !!" + fi + fi + fi + + done + if $LOGGING ;then + echo -e "\n[`date`] End optimize tables in database $db.." + fi + +done + +if $terminal ; then + echo "" + echo "Finished optimizing MySQL databases at host $(hostname -f)." + echo "" +fi + +exit 0 diff --git a/tuning-primer.sh b/tuning-primer.sh new file mode 100755 index 0000000..d3b6291 --- /dev/null +++ b/tuning-primer.sh @@ -0,0 +1,1634 @@ +#!/bin/sh + +# vim: ts=8 +######################################################################### +# # +# MySQL performance tuning primer script # +# Writen by: Matthew Montgomery # +# Report bugs to: https://bugs.launchpad.net/mysql-tuning-primer # +# Inspired by: MySQLARd (http://gert.sos.be/demo/mysqlar/) # +# Version: 1.6-r1 Released: 2011-08-06 # +# Licenced under GPLv2 # +# # +######################################################################### + +######################################################################### +# # +# Usage: ./tuning-primer.sh [ mode ] # +# # +# Available Modes: # +# all : perform all checks (default) # +# prompt : prompt for login credintials and socket # +# and execution mode # +# mem, memory : run checks for tunable options which # +# effect memory usage # +# disk, file : run checks for options which effect # +# i/o performance or file handle limits # +# innodb : run InnoDB checks /* to be improved */ # +# misc : run checks for that don't categorise # +# well Slow Queries, Binary logs, # +# Used Connections and Worker Threads # +######################################################################### +# # +# Set this socket variable ONLY if you have multiple instances running # +# or we are unable to find your socket, and you don't want to to be # +# prompted for input each time you run this script. # +# # +######################################################################### +socket= + +export black='\033[0m' +export boldblack='\033[1;0m' +export red='\033[31m' +export boldred='\033[1;31m' +export green='\033[32m' +export boldgreen='\033[1;32m' +export yellow='\033[33m' +export boldyellow='\033[1;33m' +export blue='\033[34m' +export boldblue='\033[1;34m' +export magenta='\033[35m' +export boldmagenta='\033[1;35m' +export cyan='\033[36m' +export boldcyan='\033[1;36m' +export white='\033[37m' +export boldwhite='\033[1;37m' + + +cecho () + +## -- Function to easliy print colored text -- ## + + # Color-echo. + # Argument $1 = message + # Argument $2 = color +{ +local default_msg="No message passed." + +message=${1:-$default_msg} # Defaults to default message. + +#change it for fun +#We use pure names +color=${2:-black} # Defaults to black, if not specified. + +case $color in + black) + printf "$black" ;; + boldblack) + printf "$boldblack" ;; + red) + printf "$red" ;; + boldred) + printf "$boldred" ;; + green) + printf "$green" ;; + boldgreen) + printf "$boldgreen" ;; + yellow) + printf "$yellow" ;; + boldyellow) + printf "$boldyellow" ;; + blue) + printf "$blue" ;; + boldblue) + printf "$boldblue" ;; + magenta) + printf "$magenta" ;; + boldmagenta) + printf "$boldmagenta" ;; + cyan) + printf "$cyan" ;; + boldcyan) + printf "$boldcyan" ;; + white) + printf "$white" ;; + boldwhite) + printf "$boldwhite" ;; +esac + printf "%s\n" "$message" + tput sgr0 # Reset to normal. + printf "$black" + +return +} + + +cechon () + +## -- Function to easliy print colored text -- ## + + # Color-echo. + # Argument $1 = message + # Argument $2 = color +{ +local default_msg="No message passed." + # Doesn't really need to be a local variable. + +message=${1:-$default_msg} # Defaults to default message. + +#change it for fun +#We use pure names +color=${2:-black} # Defaults to black, if not specified. + +case $color in + black) + printf "$black" ;; + boldblack) + printf "$boldblack" ;; + red) + printf "$red" ;; + boldred) + printf "$boldred" ;; + green) + printf "$green" ;; + boldgreen) + printf "$boldgreen" ;; + yellow) + printf "$yellow" ;; + boldyellow) + printf "$boldyellow" ;; + blue) + printf "$blue" ;; + boldblue) + printf "$boldblue" ;; + magenta) + printf "$magenta" ;; + boldmagenta) + printf "$boldmagenta" ;; + cyan) + printf "$cyan" ;; + boldcyan) + printf "$boldcyan" ;; + white) + printf "$white" ;; + boldwhite) + printf "$boldwhite" ;; +esac + printf "%s" "$message" + tput sgr0 # Reset to normal. + printf "$black" + +return +} + + +print_banner () { + +## -- Banner -- ## + +cecho " -- MYSQL PERFORMANCE TUNING PRIMER --" boldblue +cecho " - By: Matthew Montgomery -" black + +} + +## -- Find the location of the mysql.sock file -- ## + +check_for_socket () { + if [ -z "$socket" ] ; then + # Use ~/my.cnf version + if [ -f ~/.my.cnf ] ; then + cnf_socket=$(grep ^socket ~/.my.cnf | awk -F \= '{ print $2 }' | head -1) + fi + if [ -S "$cnf_socket" ] ; then + socket=$cnf_socket + elif [ -S /var/lib/mysql/mysql.sock ] ; then + socket=/var/lib/mysql/mysql.sock + elif [ -S /var/run/mysqld/mysqld.sock ] ; then + socket=/var/run/mysqld/mysqld.sock + elif [ -S /tmp/mysql.sock ] ; then + socket=/tmp/mysql.sock + else + if [ -S "$ps_socket" ] ; then + socket=$ps_socket + fi + fi + fi + if [ -S "$socket" ] ; then + echo UP > /dev/null + else + cecho "No valid socket file \"$socket\" found!" boldred + cecho "The mysqld process is not running or it is installed in a custom location." red + cecho "If you are sure mysqld is running, execute script in \"prompt\" mode or set " red + cecho "the socket= variable at the top of this script" red + exit 1 + fi +} + + +check_for_plesk_passwords () { + +## -- Check for the existance of plesk and login using it's credentials -- ## + + if [ -f /etc/psa/.psa.shadow ] ; then + mysql="mysql -S $socket -u admin -p$(cat /etc/psa/.psa.shadow)" + mysqladmin="mysqladmin -S $socket -u admin -p$(cat /etc/psa/.psa.shadow)" + else + mysql="mysql" + mysqladmin="mysqladmin" + # mysql="mysql -S $socket" + # mysqladmin="mysqladmin -S $socket" + fi +} + +check_mysql_login () { + +## -- Test for running mysql -- ## + + is_up=$($mysqladmin ping 2>&1) + if [ "$is_up" = "mysqld is alive" ] ; then + echo UP > /dev/null + # echo $is_up + elif [ "$is_up" != "mysqld is alive" ] ; then + printf "\n" + cecho "Using login values from ~/.my.cnf" + cecho "- INITIAL LOGIN ATTEMPT FAILED -" boldred + if [ -z $prompted ] ; then + find_webmin_passwords + else + return 1 + fi + + else + cecho "Unknow exit status" red + exit -1 + fi +} + +final_login_attempt () { + is_up=$($mysqladmin ping 2>&1) + if [ "$is_up" = "mysqld is alive" ] ; then + echo UP > /dev/null + elif [ "$is_up" != "mysqld is alive" ] ; then + cecho "- FINAL LOGIN ATTEMPT FAILED -" boldred + cecho "Unable to log into socket: $socket" boldred + exit 1 + fi +} + +second_login_failed () { + +## -- create a ~/.my.cnf and exit when all else fails -- ## + + cecho "Could not auto detect login info!" + cecho "Found potential sockets: $found_socks" + cecho "Using: $socket" red + read -p "Would you like to provide a different socket?: [y/N] " REPLY + case $REPLY in + yes | y | Y | YES) + read -p "Socket: " socket + ;; + esac + read -p "Do you have your login handy ? [y/N] : " REPLY + case $REPLY in + yes | y | Y | YES) + answer1='yes' + read -p "User: " user + read -rp "Password: " pass + if [ -z $pass ] ; then + export mysql="$mysql -S$socket -u$user" + export mysqladmin="$mysqladmin -S$socket -u$user" + else + export mysql="$mysql -S$socket -u$user -p$pass" + export mysqladmin="$mysqladmin -S$socket -u$user -p$pass" + fi + ;; + *) + cecho "Please create a valid login to MySQL" + cecho "Or, set correct values for 'user=' and 'password=' in ~/.my.cnf" + ;; + esac + cecho " " + read -p "Would you like me to create a ~/.my.cnf file for you? [y/N] : " REPLY + case $REPLY in + yes | y | Y | YES) + answer2='yes' + if [ ! -f ~/.my.cnf ] ; then + umask 077 + printf "[client]\nuser=$user\npassword=$pass\nsocket=$socket" > ~/.my.cnf + if [ "$answer1" != 'yes' ] ; then + exit 1 + else + final_login_attempt + return 0 + fi + else + printf "\n" + cecho "~/.my.cnf already exists!" boldred + printf "\n" + read -p "Replace ? [y/N] : " REPLY + if [ "$REPLY" = 'y' ] || [ "$REPLY" = 'Y' ] ; then + printf "[client]\nuser=$user\npassword=$pass\socket=$socket" > ~/.my.cnf + if [ "$answer1" != 'yes' ] ; then + exit 1 + else + final_login_attempt + return 0 + fi + else + cecho "Please set the 'user=' and 'password=' and 'socket=' values in ~/.my.cnf" + exit 1 + fi + fi + ;; + *) + if [ "$answer1" != 'yes' ] ; then + exit 1 + else + final_login_attempt + return 0 + fi + ;; + esac +} + +find_webmin_passwords () { + +## -- populate the .my.cnf file using values harvested from Webmin -- ## + + cecho "Testing for stored webmin passwords:" + if [ -f /etc/webmin/mysql/config ] ; then + user=$(grep ^login= /etc/webmin/mysql/config | cut -d "=" -f 2) + pass=$(grep ^pass= /etc/webmin/mysql/config | cut -d "=" -f 2) + if [ $user ] && [ $pass ] && [ ! -f ~/.my.cnf ] ; then + cecho "Setting login info as User: $user Password: $pass" + touch ~/.my.cnf + chmod 600 ~/.my.cnf + printf "[client]\nuser=$user\npassword=$pass" > ~/.my.cnf + cecho "Retrying login" + is_up=$($mysqladmin ping 2>&1) + if [ "$is_up" = "mysqld is alive" ] ; then + echo UP > /dev/null + else + second_login_failed + fi + echo + else + second_login_failed + echo + fi + else + cecho " None Found" boldred + second_login_failed + fi +} + +######################################################################### +# # +# Function to pull MySQL status variable # +# # +# Call using : # +# mysql_status \'Mysql_status_variable\' bash_dest_variable # +# # +######################################################################### + +mysql_status () { + local status=$($mysql -Bse "show /*!50000 global */ status like $1" | awk '{ print $2 }') + export "$2"=$status +} + +######################################################################### +# # +# Function to pull MySQL server runtime variable # +# # +# Call using : # +# mysql_variable \'Mysql_server_variable\' bash_dest_variable # +# - OR - # +# mysql_variableTSV \'Mysql_server_variable\' bash_dest_variable # +# # +######################################################################### + +mysql_variable () { + local variable=$($mysql -Bse "show /*!50000 global */ variables like $1" | awk '{ print $2 }') + export "$2"=$variable +} +mysql_variableTSV () { + local variable=$($mysql -Bse "show /*!50000 global */ variables like $1" | awk -F \t '{ print $2 }') + export "$2"=$variable +} + +float2int () { + local variable=$(echo "$1 / 1" | bc -l) + export "$2"=$variable +} + +divide () { + +# -- Divide two intigers -- # + + usage="$0 dividend divisor '$variable' scale" + if [ $1 -ge 1 ] ; then + dividend=$1 + else + cecho "Invalid Dividend" red + echo $usage + exit 1 + fi + if [ $2 -ge 1 ] ; then + divisor=$2 + else + cecho "Invalid Divisor" red + echo $usage + exit 1 + fi + if [ ! -n $3 ] ; then + cecho "Invalid variable name" red + echo $usage + exit 1 + fi + if [ -z $4 ] ; then + scale=2 + elif [ $4 -ge 0 ] ; then + scale=$4 + else + cecho "Invalid scale" red + echo $usage + exit 1 + fi + export $3=$(echo "scale=$scale; $dividend / $divisor" | bc -l) +} + +human_readable () { + +######################################################################### +# # +# Convert a value in to human readable size and populate a variable # +# with the result. # +# # +# Call using: # +# human_readable $value 'variable name' [ places of precision] # +# # +######################################################################### + + ## value=$1 + ## variable=$2 + scale=$3 + + if [ $1 -ge 1073741824 ] ; then + if [ -z $3 ] ; then + scale=2 + fi + divide $1 1073741824 "$2" $scale + unit="G" + elif [ $1 -ge 1048576 ] ; then + if [ -z $3 ] ; then + scale=0 + fi + divide $1 1048576 "$2" $scale + unit="M" + elif [ $1 -ge 1024 ] ; then + if [ -z $3 ] ; then + scale=0 + fi + divide $1 1024 "$2" $scale + unit="K" + else + export "$2"=$1 + unit="bytes" + fi + # let "$2"=$HR +} + +human_readable_time () { + +######################################################################## +# # +# Function to produce human readable time # +# # +######################################################################## + + usage="$0 seconds 'variable'" + if [ -z $1 ] || [ -z $2 ] ; then + cecho $usage red + exit 1 + fi + days=$(echo "scale=0 ; $1 / 86400" | bc -l) + remainder=$(echo "scale=0 ; $1 % 86400" | bc -l) + hours=$(echo "scale=0 ; $remainder / 3600" | bc -l) + remainder=$(echo "scale=0 ; $remainder % 3600" | bc -l) + minutes=$(echo "scale=0 ; $remainder / 60" | bc -l) + seconds=$(echo "scale=0 ; $remainder % 60" | bc -l) + export $2="$days days $hours hrs $minutes min $seconds sec" +} + +check_mysql_version () { + +## -- Print Version Info -- ## + + mysql_variable \'version\' mysql_version + mysql_variable \'version_compile_machine\' mysql_version_compile_machine + +if [ "$mysql_version_num" -lt 050000 ]; then + cecho "MySQL Version $mysql_version $mysql_version_compile_machine is EOL please upgrade to MySQL 4.1 or later" boldred +else + cecho "MySQL Version $mysql_version $mysql_version_compile_machine" +fi + + +} + +post_uptime_warning () { + +######################################################################### +# # +# Present a reminder that mysql must run for a couple of days to # +# build up good numbers in server status variables before these tuning # +# suggestions should be used. # +# # +######################################################################### + + mysql_status \'Uptime\' uptime + mysql_status \'Threads_connected\' threads + queries_per_sec=$(($questions/$uptime)) + human_readable_time $uptime uptimeHR + + cecho "Uptime = $uptimeHR" + cecho "Avg. qps = $queries_per_sec" + cecho "Total Questions = $questions" + cecho "Threads Connected = $threads" + echo + + if [ $uptime -gt 172800 ] ; then + cecho "Server has been running for over 48hrs." + cecho "It should be safe to follow these recommendations" + else + cechon "Warning: " boldred + cecho "Server has not been running for at least 48hrs." boldred + cecho "It may not be safe to use these recommendations" boldred + + fi + echo "" + cecho "To find out more information on how each of these" red + cecho "runtime variables effects performance visit:" red + if [ "$major_version" = '3.23' ] || [ "$major_version" = '4.0' ] || [ "$major_version" = '4.1' ] ; then + cecho "http://dev.mysql.com/doc/refman/4.1/en/server-system-variables.html" boldblue + elif [ "$major_version" = '5.0' ] || [ "$mysql_version_num" -gt '050100' ]; then + cecho "http://dev.mysql.com/doc/refman/$major_version/en/server-system-variables.html" boldblue + else + cecho "UNSUPPORTED MYSQL VERSION" boldred + exit 1 + fi + cecho "Visit http://www.mysql.com/products/enterprise/advisors.html" boldblue + cecho "for info about MySQL's Enterprise Monitoring and Advisory Service" boldblue +} + +check_slow_queries () { + +## -- Slow Queries -- ## + + cecho "SLOW QUERIES" boldblue + + mysql_status \'Slow_queries\' slow_queries + mysql_variable \'long_query_time\' long_query_time + mysql_variable \'log%queries\' log_slow_queries + + prefered_query_time=5 + if [ -e /etc/my.cnf ] ; then + if [ -z $log_slow_queries ] ; then + log_slow_queries=$(grep log-slow-queries /etc/my.cnf) + fi + fi + + if [ "$log_slow_queries" = 'ON' ] ; then + cecho "The slow query log is enabled." + elif [ "$log_slow_queries" = 'OFF' ] ; then + cechon "The slow query log is " + cechon "NOT" boldred + cecho " enabled." + elif [ -z $log_slow_queries ] ; then + cechon "The slow query log is " + cechon "NOT" boldred + cecho " enabled." + else + cecho "Error: $log_slow_queries" boldred + fi + cecho "Current long_query_time = $long_query_time sec." + cechon "You have " + cechon "$slow_queries" boldred + cechon " out of " + cechon "$questions" boldred + cecho " that take longer than $long_query_time sec. to complete" + + float2int long_query_time long_query_timeInt + + if [ $long_query_timeInt -gt $prefered_query_time ] ; then + cecho "Your long_query_time may be too high, I typically set this under $prefered_query_time sec." red + else + cecho "Your long_query_time seems to be fine" green + fi + +} + +check_binary_log () { + +## -- Binary Log -- ## + + cecho "BINARY UPDATE LOG" boldblue + + mysql_variable \'log_bin\' log_bin + mysql_variable \'max_binlog_size\' max_binlog_size + mysql_variable \'expire_logs_days\' expire_logs_days + mysql_variable \'sync_binlog\' sync_binlog + # mysql_variable \'max_binlog_cache_size\' max_binlog_cache_size + + if [ "$log_bin" = 'ON' ] ; then + cecho "The binary update log is enabled" + if [ -z "$max_binlog_size" ] ; then + cecho "The max_binlog_size is not set. The binary log will rotate when it reaches 1GB." red + fi + if [ "$expire_logs_days" -eq 0 ] ; then + cecho "The expire_logs_days is not set." boldred + cechon "The mysqld will retain the entire binary log until " red + cecho "RESET MASTER or PURGE MASTER LOGS commands are run manually" red + cecho "Setting expire_logs_days will allow you to remove old binary logs automatically" yellow + cecho "See http://dev.mysql.com/doc/refman/$major_version/en/purge-master-logs.html" yellow + fi + if [ "$sync_binlog" = 0 ] ; then + cecho "Binlog sync is not enabled, you could loose binlog records during a server crash" red + fi + else + cechon "The binary update log is " + cechon "NOT " boldred + cecho "enabled." + cecho "You will not be able to do point in time recovery" red + cecho "See http://dev.mysql.com/doc/refman/$major_version/en/point-in-time-recovery.html" yellow + fi +} + +check_used_connections () { + +## -- Used Connections -- ## + + mysql_variable \'max_connections\' max_connections + mysql_status \'Max_used_connections\' max_used_connections + mysql_status \'Threads_connected\' threads_connected + + connections_ratio=$(($max_used_connections*100/$max_connections)) + + cecho "MAX CONNECTIONS" boldblue + cecho "Current max_connections = $max_connections" + cecho "Current threads_connected = $threads_connected" + cecho "Historic max_used_connections = $max_used_connections" + cechon "The number of used connections is " + if [ $connections_ratio -ge 85 ] ; then + txt_color=red + error=1 + elif [ $connections_ratio -le 10 ] ; then + txt_color=red + error=2 + else + txt_color=green + error=0 + fi + # cechon "$max_used_connections " $txt_color + # cechon "which is " + cechon "$connections_ratio% " $txt_color + cecho "of the configured maximum." + + if [ $error -eq 1 ] ; then + cecho "You should raise max_connections" $txt_color + elif [ $error -eq 2 ] ; then + cecho "You are using less than 10% of your configured max_connections." $txt_color + cecho "Lowering max_connections could help to avoid an over-allocation of memory" $txt_color + cecho "See \"MEMORY USAGE\" section to make sure you are not over-allocating" $txt_color + else + cecho "Your max_connections variable seems to be fine." $txt_color + fi + unset txt_color +} + +check_threads() { + +## -- Worker Threads -- ## + + cecho "WORKER THREADS" boldblue + + mysql_status \'Threads_created\' threads_created1 + sleep 1 + mysql_status \'Threads_created\' threads_created2 + + mysql_status \'Threads_cached\' threads_cached + mysql_status \'Uptime\' uptime + mysql_variable \'thread_cache_size\' thread_cache_size + + historic_threads_per_sec=$(($threads_created1/$uptime)) + current_threads_per_sec=$(($threads_created2-$threads_created1)) + + cecho "Current thread_cache_size = $thread_cache_size" + cecho "Current threads_cached = $threads_cached" + cecho "Current threads_per_sec = $current_threads_per_sec" + cecho "Historic threads_per_sec = $historic_threads_per_sec" + + if [ $historic_threads_per_sec -ge 2 ] && [ $threads_cached -le 1 ] ; then + cecho "Threads created per/sec are overrunning threads cached" red + cecho "You should raise thread_cache_size" red + elif [ $current_threads_per_sec -ge 2 ] ; then + cecho "Threads created per/sec are overrunning threads cached" red + cecho "You should raise thread_cache_size" red + else + cecho "Your thread_cache_size is fine" green + fi +} + +check_key_buffer_size () { + +## -- Key buffer Size -- ## + + cecho "KEY BUFFER" boldblue + + mysql_status \'Key_read_requests\' key_read_requests + mysql_status \'Key_reads\' key_reads + mysql_status \'Key_blocks_used\' key_blocks_used + mysql_status \'Key_blocks_unused\' key_blocks_unused + mysql_variable \'key_cache_block_size\' key_cache_block_size + mysql_variable \'key_buffer_size\' key_buffer_size + mysql_variable \'datadir\' datadir + mysql_variable \'version_compile_machine\' mysql_version_compile_machine + myisam_indexes=$($mysql -Bse "/*!50000 SELECT IFNULL(SUM(INDEX_LENGTH),0) from information_schema.TABLES where ENGINE='MyISAM' */") + + if [ -z $myisam_indexes ] ; then + myisam_indexes=$(find $datadir -name '*.MYI' -exec du $duflags '{}' \; 2>&1 | awk '{ s += $1 } END { printf("%.0f\n", s )}') + fi + + if [ $key_reads -eq 0 ] ; then + cecho "No key reads?!" boldred + cecho "Seriously look into using some indexes" red + key_cache_miss_rate=0 + key_buffer_free=$(echo "$key_blocks_unused * $key_cache_block_size / $key_buffer_size * 100" | bc -l ) + key_buffer_freeRND=$(echo "scale=0; $key_buffer_free / 1" | bc -l) + else + key_cache_miss_rate=$(($key_read_requests/$key_reads)) + if [ ! -z $key_blocks_unused ] ; then + key_buffer_free=$(echo "$key_blocks_unused * $key_cache_block_size / $key_buffer_size * 100" | bc -l ) + key_buffer_freeRND=$(echo "scale=0; $key_buffer_free / 1" | bc -l) + else + key_buffer_free='Unknown' + key_buffer_freeRND=75 + fi + fi + + human_readable $myisam_indexes myisam_indexesHR + cecho "Current MyISAM index space = $myisam_indexesHR $unit" + + human_readable $key_buffer_size key_buffer_sizeHR + cecho "Current key_buffer_size = $key_buffer_sizeHR $unit" + cecho "Key cache miss rate is 1 : $key_cache_miss_rate" + cecho "Key buffer free ratio = $key_buffer_freeRND %" + + if [ "$major_version" = '5.1' ] && [ $mysql_version_num -lt 050123 ] ; then + if [ $key_buffer_size -ge 4294967296 ] && ( echo "x86_64 ppc64 ia64 sparc64 i686" | grep -q $mysql_version_compile_machine ) ; then + cecho "Using key_buffer_size > 4GB will cause instability in versions prior to 5.1.23 " boldred + cecho "See Bug#5731, Bug#29419, Bug#29446" boldred + fi + fi + if [ "$major_version" = '5.0' ] && [ $mysql_version_num -lt 050052 ] ; then + if [ $key_buffer_size -ge 4294967296 ] && ( echo "x86_64 ppc64 ia64 sparc64 i686" | grep -q $mysql_version_compile_machine ) ; then + cecho "Using key_buffer_size > 4GB will cause instability in versions prior to 5.0.52 " boldred + cecho "See Bug#5731, Bug#29419, Bug#29446" boldred + fi + fi + if [ "$major_version" = '4.1' -o "$major_version" = '4.0' ] && [ $key_buffer_size -ge 4294967296 ] && ( echo "x86_64 ppc64 ia64 sparc64 i686" | grep -q $mysql_version_compile_machine ) ; then + cecho "Using key_buffer_size > 4GB will cause instability in versions prior to 5.0.52 " boldred + cecho "Reduce key_buffer_size to a safe value" boldred + cecho "See Bug#5731, Bug#29419, Bug#29446" boldred + fi + + if [ $key_cache_miss_rate -le 100 ] && [ $key_cache_miss_rate -gt 0 ] && [ $key_buffer_freeRND -le 20 ]; then + cecho "You could increase key_buffer_size" boldred + cecho "It is safe to raise this up to 1/4 of total system memory;" + cecho "assuming this is a dedicated database server." + elif [ $key_buffer_freeRND -le 20 ] && [ $key_buffer_size -le $myisam_indexes ] ; then + cecho "You could increase key_buffer_size" boldred + cecho "It is safe to raise this up to 1/4 of total system memory;" + cecho "assuming this is a dedicated database server." + elif [ $key_cache_miss_rate -ge 10000 ] || [ $key_buffer_freeRND -le 50 ] ; then + cecho "Your key_buffer_size seems to be too high." red + cecho "Perhaps you can use these resources elsewhere" red + else + cecho "Your key_buffer_size seems to be fine" green + fi +} + +check_query_cache () { + +## -- Query Cache -- ## + + cecho "QUERY CACHE" boldblue + + mysql_variable \'version\' mysql_version + mysql_variable \'query_cache_size\' query_cache_size + mysql_variable \'query_cache_limit\' query_cache_limit + mysql_variable \'query_cache_min_res_unit\' query_cache_min_res_unit + mysql_status \'Qcache_free_memory\' qcache_free_memory + mysql_status \'Qcache_total_blocks\' qcache_total_blocks + mysql_status \'Qcache_free_blocks\' qcache_free_blocks + mysql_status \'Qcache_lowmem_prunes\' qcache_lowmem_prunes + + if [ -z $query_cache_size ] ; then + cecho "You are using MySQL $mysql_version, no query cache is supported." red + cecho "I recommend an upgrade to MySQL 4.1 or better" red + elif [ $query_cache_size -eq 0 ] ; then + cecho "Query cache is supported but not enabled" red + cecho "Perhaps you should set the query_cache_size" red + else + qcache_used_memory=$(($query_cache_size-$qcache_free_memory)) + qcache_mem_fill_ratio=$(echo "scale=2; $qcache_used_memory * 100 / $query_cache_size" | bc -l) + qcache_mem_fill_ratioHR=$(echo "scale=0; $qcache_mem_fill_ratio / 1" | bc -l) + + cecho "Query cache is enabled" green + human_readable $query_cache_size query_cache_sizeHR + cecho "Current query_cache_size = $query_cache_sizeHR $unit" + human_readable $qcache_used_memory qcache_used_memoryHR + cecho "Current query_cache_used = $qcache_used_memoryHR $unit" + human_readable $query_cache_limit query_cache_limitHR + cecho "Current query_cache_limit = $query_cache_limitHR $unit" + cecho "Current Query cache Memory fill ratio = $qcache_mem_fill_ratio %" + if [ -z $query_cache_min_res_unit ] ; then + cecho "No query_cache_min_res_unit is defined. Using MySQL < 4.1 cache fragmentation can be inpredictable" %yellow + else + human_readable $query_cache_min_res_unit query_cache_min_res_unitHR + cecho "Current query_cache_min_res_unit = $query_cache_min_res_unitHR $unit" + fi + if [ $qcache_free_blocks -gt 2 ] && [ $qcache_total_blocks -gt 0 ] ; then + qcache_percent_fragmented=$(echo "scale=2; $qcache_free_blocks * 100 / $qcache_total_blocks" | bc -l) + qcache_percent_fragmentedHR=$(echo "scale=0; $qcache_percent_fragmented / 1" | bc -l) + if [ $qcache_percent_fragmentedHR -gt 20 ] ; then + cecho "Query Cache is $qcache_percent_fragmentedHR % fragmented" red + cecho "Run \"FLUSH QUERY CACHE\" periodically to defragment the query cache memory" red + cecho "If you have many small queries lower 'query_cache_min_res_unit' to reduce fragmentation." red + fi + fi + + if [ $qcache_mem_fill_ratioHR -le 25 ] ; then + cecho "Your query_cache_size seems to be too high." red + cecho "Perhaps you can use these resources elsewhere" red + fi + if [ $qcache_lowmem_prunes -ge 50 ] && [ $qcache_mem_fill_ratioHR -ge 80 ]; then + cechon "However, " + cechon "$qcache_lowmem_prunes " boldred + cecho "queries have been removed from the query cache due to lack of memory" + cecho "Perhaps you should raise query_cache_size" boldred + fi + cecho "MySQL won't cache query results that are larger than query_cache_limit in size" yellow + fi + +} + +check_sort_operations () { + +## -- Sort Operations -- ## + + cecho "SORT OPERATIONS" boldblue + + mysql_status \'Sort_merge_passes\' sort_merge_passes + mysql_status \'Sort_scan\' sort_scan + mysql_status \'Sort_range\' sort_range + mysql_variable \'sort_buffer%\' sort_buffer_size + mysql_variable \'read_rnd_buffer_size\' read_rnd_buffer_size + + total_sorts=$(($sort_scan+$sort_range)) + if [ -z $read_rnd_buffer_size ] ; then + mysql_variable \'record_buffer\' read_rnd_buffer_size + fi + + ## Correct for rounding error in mysqld where 512K != 524288 ## + sort_buffer_size=$(($sort_buffer_size+8)) + read_rnd_buffer_size=$(($read_rnd_buffer_size+8)) + + human_readable $sort_buffer_size sort_buffer_sizeHR + cecho "Current sort_buffer_size = $sort_buffer_sizeHR $unit" + + human_readable $read_rnd_buffer_size read_rnd_buffer_sizeHR + cechon "Current " + if [ "$major_version" = '3.23' ] ; then + cechon "record_rnd_buffer " + else + cechon "read_rnd_buffer_size " + fi + cecho "= $read_rnd_buffer_sizeHR $unit" + + if [ $total_sorts -eq 0 ] ; then + cecho "No sort operations have been performed" + passes_per_sort=0 + fi + if [ $sort_merge_passes -ne 0 ] ; then + passes_per_sort=$(($sort_merge_passes/$total_sorts)) + else + passes_per_sort=0 + fi + + if [ $passes_per_sort -ge 2 ] ; then + cechon "On average " + cechon "$passes_per_sort " boldred + cecho "sort merge passes are made per sort operation" + cecho "You should raise your sort_buffer_size" + cechon "You should also raise your " + if [ "$major_version" = '3.23' ] ; then + cecho "record_rnd_buffer_size" + else + cecho "read_rnd_buffer_size" + fi + else + cecho "Sort buffer seems to be fine" green + fi +} + +check_join_operations () { + +## -- Joins -- ## + + cecho "JOINS" boldblue + + mysql_status \'Select_full_join\' select_full_join + mysql_status \'Select_range_check\' select_range_check + mysql_variable \'join_buffer%\' join_buffer_size + + ## Some 4K is dropped from join_buffer_size adding it back to make sane ## + ## handling of human-readable conversion ## + + join_buffer_size=$(($join_buffer_size+4096)) + + human_readable $join_buffer_size join_buffer_sizeHR 2 + + cecho "Current join_buffer_size = $join_buffer_sizeHR $unit" + cecho "You have had $select_full_join queries where a join could not use an index properly" + + if [ $select_range_check -eq 0 ] && [ $select_full_join -eq 0 ] ; then + cecho "Your joins seem to be using indexes properly" green + fi + if [ $select_full_join -gt 0 ] ; then + print_error='true' + raise_buffer='true' + fi + if [ $select_range_check -gt 0 ] ; then + cecho "You have had $select_range_check joins without keys that check for key usage after each row" red + print_error='true' + raise_buffer='true' + fi + + ## For Debuging ## + # print_error='true' + if [ $join_buffer_size -ge 4194304 ] ; then + cecho "join_buffer_size >= 4 M" boldred + cecho "This is not advised" boldred + raise_buffer= + fi + + if [ $print_error ] ; then + if [ "$major_version" = '3.23' ] || [ "$major_version" = '4.0' ] ; then + cecho "You should enable \"log-long-format\" " + elif [ "$mysql_version_num" -gt 040100 ]; then + cecho "You should enable \"log-queries-not-using-indexes\"" + fi + cecho "Then look for non indexed joins in the slow query log." + if [ $raise_buffer ] ; then + cecho "If you are unable to optimize your queries you may want to increase your" + cecho "join_buffer_size to accommodate larger joins in one pass." + printf "\n" + cecho "Note! This script will still suggest raising the join_buffer_size when" boldred + cecho "ANY joins not using indexes are found." boldred + fi + fi + + # XXX Add better tests for join_buffer_size pending mysql bug #15088 XXX # +} + +check_tmp_tables () { + +## -- Temp Tables -- ## + + cecho "TEMP TABLES" boldblue + + mysql_status \'Created_tmp_tables\' created_tmp_tables + mysql_status \'Created_tmp_disk_tables\' created_tmp_disk_tables + mysql_variable \'tmp_table_size\' tmp_table_size + mysql_variable \'max_heap_table_size\' max_heap_table_size + + + if [ $created_tmp_tables -eq 0 ] ; then + tmp_disk_tables=0 + else + tmp_disk_tables=$((created_tmp_disk_tables*100/(created_tmp_tables+created_tmp_disk_tables))) + fi + human_readable $max_heap_table_size max_heap_table_sizeHR + cecho "Current max_heap_table_size = $max_heap_table_sizeHR $unit" + + human_readable $tmp_table_size tmp_table_sizeHR + cecho "Current tmp_table_size = $tmp_table_sizeHR $unit" + + cecho "Of $created_tmp_tables temp tables, $tmp_disk_tables% were created on disk" + if [ $tmp_table_size -gt $max_heap_table_size ] ; then + cecho "Effective in-memory tmp_table_size is limited to max_heap_table_size." yellow + fi + if [ $tmp_disk_tables -ge 25 ] ; then + cecho "Perhaps you should increase your tmp_table_size and/or max_heap_table_size" boldred + cecho "to reduce the number of disk-based temporary tables" boldred + cecho "Note! BLOB and TEXT columns are not allow in memory tables." yellow + cecho "If you are using these columns raising these values might not impact your " yellow + cecho "ratio of on disk temp tables." yellow + else + cecho "Created disk tmp tables ratio seems fine" green + fi +} + +check_open_files () { + +## -- Open Files Limit -- ## + cecho "OPEN FILES LIMIT" boldblue + + mysql_variable \'open_files_limit\' open_files_limit + mysql_status \'Open_files\' open_files + + if [ -z $open_files_limit ] || [ $open_files_limit -eq 0 ] ; then + open_files_limit=$(ulimit -n) + cant_override=1 + else + cant_override=0 + fi + cecho "Current open_files_limit = $open_files_limit files" + + open_files_ratio=$(($open_files*100/$open_files_limit)) + + cecho "The open_files_limit should typically be set to at least 2x-3x" yellow + cecho "that of table_cache if you have heavy MyISAM usage." yellow + if [ $open_files_ratio -ge 75 ] ; then + cecho "You currently have open more than 75% of your open_files_limit" boldred + if [ $cant_override -eq 1 ] ; then + cecho "You should set a higer value for ulimit -u in the mysql startup script then restart mysqld" boldred + cecho "MySQL 3.23 users : This is just a guess based upon the current shell's ulimit -u value" yellow + elif [ $cant_override -eq 0 ] ; then + cecho "You should set a higher value for open_files_limit in my.cnf" boldred + else + cecho "ERROR can't determine if mysqld override of ulimit is allowed" boldred + exit 1 + fi + else + cecho "Your open_files_limit value seems to be fine" green + fi + + + +} + +check_table_cache () { + +## -- Table Cache -- ## + + cecho "TABLE CACHE" boldblue + + mysql_variable \'datadir\' datadir + mysql_variable \'table_cache\' table_cache + + ## /* MySQL +5.1 version of table_cache */ ## + mysql_variable \'table_open_cache\' table_open_cache + mysql_variable \'table_definition_cache\' table_definition_cache + + mysql_status \'Open_tables\' open_tables + mysql_status \'Opened_tables\' opened_tables + mysql_status \'Open_table_definitions\' open_table_definitions + + table_count=$($mysql -Bse "/*!50000 SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE' */") + + if [ -z "$table_count" ] ; then + if [ "$UID" != "$socket_owner" ] && [ "$UID" != "0" ] ; then + cecho "You are not '$socket_owner' or 'root'" red + cecho "I am unable to determine the table_count!" red + else + table_count=$(find $datadir 2>&1 | grep -c .frm$) + fi + fi + if [ $table_open_cache ] ; then + table_cache=$table_open_cache + fi + + if [ $opened_tables -ne 0 ] && [ $table_cache -ne 0 ] ; then + table_cache_hit_rate=$(($open_tables*100/$opened_tables)) + table_cache_fill=$(($open_tables*100/$table_cache)) + elif [ $opened_tables -eq 0 ] && [ $table_cache -ne 0 ] ; then + table_cache_hit_rate=100 + table_cache_fill=$(($open_tables*100/$table_cache)) + else + cecho "ERROR no table_cache ?!" boldred + exit 1 + fi + if [ $table_cache ] && [ ! $table_open_cache ] ; then + cecho "Current table_cache value = $table_cache tables" + fi + if [ $table_open_cache ] ; then + cecho "Current table_open_cache = $table_open_cache tables" + cecho "Current table_definition_cache = $table_definition_cache tables" + fi + if [ $table_count ] ; then + cecho "You have a total of $table_count tables" + fi + + if [ $table_cache_fill -lt 95 ] ; then + cechon "You have " + cechon "$open_tables " green + cecho "open tables." + cecho "The table_cache value seems to be fine" green + elif [ $table_cache_hit_rate -le 85 -o $table_cache_fill -ge 95 ]; then + cechon "You have " + cechon "$open_tables " boldred + cecho "open tables." + cechon "Current table_cache hit rate is " + cecho "$table_cache_hit_rate%" boldred + cechon ", while " + cechon "$table_cache_fill% " boldred + cecho "of your table cache is in use" + cecho "You should probably increase your table_cache" red + else + cechon "Current table_cache hit rate is " + cechon "$table_cache_hit_rate%" green + cechon ", while " + cechon "$table_cache_fill% " green + cecho "of your table cache is in use" + cecho "The table cache value seems to be fine" green + fi + if [ $table_definition_cache ] && [ $table_definition_cache -le $table_count ] && [ $table_count -ge 100 ] ; then + cecho "You should probably increase your table_definition_cache value." red + fi +} + +check_table_locking () { + +## -- Table Locking -- ## + + cecho "TABLE LOCKING" boldblue + + mysql_status \'Table_locks_waited\' table_locks_waited + mysql_status \'Table_locks_immediate\' table_locks_immediate + mysql_variable \'concurrent_insert\' concurrent_insert + mysql_variable \'low_priority_updates\' low_priority_updates + if [ "$concurrent_insert" = 'ON' ]; then + concurrent_insert=1 + elif [ "$concurrent_insert" = 'OFF' ]; then + concurrent_insert=0 + fi + + cechon "Current Lock Wait ratio = " + if [ $table_locks_waited -gt 0 ]; then + immediate_locks_miss_rate=$(($table_locks_immediate/$table_locks_waited)) + cecho "1 : $immediate_locks_miss_rate" red + else + immediate_locks_miss_rate=99999 # perfect + cecho "0 : $questions" + fi + if [ $immediate_locks_miss_rate -lt 5000 ] ; then + cecho "You may benefit from selective use of InnoDB." + if [ "$low_priority_updates" = 'OFF' ] ; then + cecho "If you have long running SELECT's against MyISAM tables and perform" + cecho "frequent updates consider setting 'low_priority_updates=1'" + fi + if [ "$mysql_version_num" -gt 050000 ] && [ "$mysql_version_num" -lt 050500 ]; then + if [ $concurrent_insert -le 1 ] ; then + cecho "If you have a high concurrency of inserts on Dynamic row-length tables" + cecho "consider setting 'concurrent_insert=2'." + fi + elif [ "$mysql_version_num" -gt 050500 ] ; then + if [ "$concurrent_insert" = 'AUTO' ] || [ "$concurrent_insert" = 'NEVER' ] ; then + cecho "If you have a high concurrency of inserts on Dynamic row-length tables" + cecho "consider setting 'concurrent_insert=ALWAYS'." + fi + fi + else + cecho "Your table locking seems to be fine" green + fi +} + +check_table_scans () { + +## -- Table Scans -- ## + + cecho "TABLE SCANS" boldblue + + mysql_status \'Com_select\' com_select + mysql_status \'Handler_read_rnd_next\' read_rnd_next + mysql_variable \'read_buffer_size\' read_buffer_size + + if [ -z $read_buffer_size ] ; then + mysql_variable \'record_buffer\' read_buffer_size + fi + + human_readable $read_buffer_size read_buffer_sizeHR + cecho "Current read_buffer_size = $read_buffer_sizeHR $unit" + + if [ $com_select -gt 0 ] ; then + full_table_scans=$(($read_rnd_next/$com_select)) + cecho "Current table scan ratio = $full_table_scans : 1" + if [ $full_table_scans -ge 4000 ] && [ $read_buffer_size -le 2097152 ] ; then + cecho "You have a high ratio of sequential access requests to SELECTs" red + cechon "You may benefit from raising " red + if [ "$major_version" = '3.23' ] ; then + cechon "record_buffer " red + else + cechon "read_buffer_size " red + fi + cecho "and/or improving your use of indexes." red + elif [ $read_buffer_size -gt 8388608 ] ; then + cechon "read_buffer_size is over 8 MB " red + cecho "there is probably no need for such a large read_buffer" red + + else + cecho "read_buffer_size seems to be fine" green + fi + else + cecho "read_buffer_size seems to be fine" green + fi +} + + +check_innodb_status () { + +## -- InnoDB -- ## + + ## See http://bugs.mysql.com/59393 + + if [ "$mysql_version_num" -lt 050603 ] ; then + mysql_variable \'have_innodb\' have_innodb + fi + if [ "$mysql_version_num" -lt 050500 ] && [ "$have_innodb" = "YES" ] ; then + innodb_enabled=1 + fi + if [ "$mysql_version_num" -ge 050500 ] && [ "$mysql_version_num" -lt 050512 ] ; then + mysql_variable \'ignore_builtin_innodb\' ignore_builtin_innodb + if [ "$ignore_builtin_innodb" = "ON" ] || [ $have_innodb = "NO" ] ; then + innodb_enabled=0 + else + innodb_enabled=1 + fi + elif [ "$major_version" = '5.5' ] && [ "$mysql_version_num" -ge 050512 ] ; then + mysql_variable \'ignore_builtin_innodb\' ignore_builtin_innodb + if [ "$ignore_builtin_innodb" = "ON" ] || [ $have_innodb = "DISABLED" ] ; then + innodb_enabled=0 + else + innodb_enabled=1 + fi + elif [ "$mysql_version_num" -ge 050600 ] && [ "$mysql_version_num" -lt 050603 ] ; then + mysql_variable \'ignore_builtin_innodb\' ignore_builtin_innodb + if [ "$ignore_builtin_innodb" = "ON" ] || [ $have_innodb = "NO" ] ; then + innodb_enabled=0 + else + innodb_enabled=1 + fi + elif [ "$major_version" = '5.6' ] && [ "$mysql_version_num" -ge 050603 ] ; then + mysql_variable \'ignore_builtin_innodb\' ignore_builtin_innodb + if [ "$ignore_builtin_innodb" = "ON" ] ; then + innodb_enabled=0 + else + innodb_enabled=1 + fi + fi + if [ "$innodb_enabled" = 1 ] ; then + mysql_variable \'innodb_buffer_pool_size\' innodb_buffer_pool_size + mysql_variable \'innodb_additional_mem_pool_size\' innodb_additional_mem_pool_size + mysql_variable \'innodb_fast_shutdown\' innodb_fast_shutdown + mysql_variable \'innodb_flush_log_at_trx_commit\' innodb_flush_log_at_trx_commit + mysql_variable \'innodb_locks_unsafe_for_binlog\' innodb_locks_unsafe_for_binlog + mysql_variable \'innodb_log_buffer_size\' innodb_log_buffer_size + mysql_variable \'innodb_log_file_size\' innodb_log_file_size + mysql_variable \'innodb_log_files_in_group\' innodb_log_files_in_group + mysql_variable \'innodb_safe_binlog\' innodb_safe_binlog + mysql_variable \'innodb_thread_concurrency\' innodb_thread_concurrency + + cecho "INNODB STATUS" boldblue + innodb_indexes=$($mysql -Bse "/*!50000 SELECT IFNULL(SUM(INDEX_LENGTH),0) from information_schema.TABLES where ENGINE='InnoDB' */") + innodb_data=$($mysql -Bse "/*!50000 SELECT IFNULL(SUM(DATA_LENGTH),0) from information_schema.TABLES where ENGINE='InnoDB' */") + + if [ ! -z "$innodb_indexes" ] ; then + + mysql_status \'Innodb_buffer_pool_pages_data\' innodb_buffer_pool_pages_data + mysql_status \'Innodb_buffer_pool_pages_misc\' innodb_buffer_pool_pages_misc + mysql_status \'Innodb_buffer_pool_pages_free\' innodb_buffer_pool_pages_free + mysql_status \'Innodb_buffer_pool_pages_total\' innodb_buffer_pool_pages_total + + mysql_status \'Innodb_buffer_pool_read_ahead_seq\' innodb_buffer_pool_read_ahead_seq + mysql_status \'Innodb_buffer_pool_read_requests\' innodb_buffer_pool_read_requests + + mysql_status \'Innodb_os_log_pending_fsyncs\' innodb_os_log_pending_fsyncs + mysql_status \'Innodb_os_log_pending_writes\' innodb_os_log_pending_writes + mysql_status \'Innodb_log_waits\' innodb_log_waits + + mysql_status \'Innodb_row_lock_time\' innodb_row_lock_time + mysql_status \'Innodb_row_lock_waits\' innodb_row_lock_waits + + human_readable $innodb_indexes innodb_indexesHR + cecho "Current InnoDB index space = $innodb_indexesHR $unit" + human_readable $innodb_data innodb_dataHR + cecho "Current InnoDB data space = $innodb_dataHR $unit" + percent_innodb_buffer_pool_free=$(($innodb_buffer_pool_pages_free*100/$innodb_buffer_pool_pages_total)) + cecho "Current InnoDB buffer pool free = "$percent_innodb_buffer_pool_free" %" + + else + cecho "Cannot parse InnoDB stats prior to 5.0.x" red + $mysql -s -e "SHOW /*!50000 ENGINE */ INNODB STATUS\G" + fi + + human_readable $innodb_buffer_pool_size innodb_buffer_pool_sizeHR + cecho "Current innodb_buffer_pool_size = $innodb_buffer_pool_sizeHR $unit" + cecho "Depending on how much space your innodb indexes take up it may be safe" + cecho "to increase this value to up to 2 / 3 of total system memory" + else + cecho "No InnoDB Support Enabled!" boldred + fi +} + +total_memory_used () { + +## -- Total Memory Usage -- ## + cecho "MEMORY USAGE" boldblue + + mysql_variable \'read_buffer_size\' read_buffer_size + mysql_variable \'read_rnd_buffer_size\' read_rnd_buffer_size + mysql_variable \'sort_buffer_size\' sort_buffer_size + mysql_variable \'thread_stack\' thread_stack + mysql_variable \'max_connections\' max_connections + mysql_variable \'join_buffer_size\' join_buffer_size + mysql_variable \'tmp_table_size\' tmp_table_size + mysql_variable \'max_heap_table_size\' max_heap_table_size + mysql_variable \'log_bin\' log_bin + mysql_status \'Max_used_connections\' max_used_connections + + if [ "$major_version" = "3.23" ] ; then + mysql_variable \'record_buffer\' read_buffer_size + mysql_variable \'record_rnd_buffer\' read_rnd_buffer_size + mysql_variable \'sort_buffer\' sort_buffer_size + fi + + if [ "$log_bin" = "ON" ] ; then + mysql_variable \'binlog_cache_size\' binlog_cache_size + else + binlog_cache_size=0 + fi + + if [ $max_heap_table_size -le $tmp_table_size ] ; then + effective_tmp_table_size=$max_heap_table_size + else + effective_tmp_table_size=$tmp_table_size + fi + + + per_thread_buffers=$(echo "($read_buffer_size+$read_rnd_buffer_size+$sort_buffer_size+$thread_stack+$join_buffer_size+$binlog_cache_size)*$max_connections" | bc -l) + per_thread_max_buffers=$(echo "($read_buffer_size+$read_rnd_buffer_size+$sort_buffer_size+$thread_stack+$join_buffer_size+$binlog_cache_size)*$max_used_connections" | bc -l) + + mysql_variable \'innodb_buffer_pool_size\' innodb_buffer_pool_size + if [ -z $innodb_buffer_pool_size ] ; then + innodb_buffer_pool_size=0 + fi + + mysql_variable \'innodb_additional_mem_pool_size\' innodb_additional_mem_pool_size + if [ -z $innodb_additional_mem_pool_size ] ; then + innodb_additional_mem_pool_size=0 + fi + + mysql_variable \'innodb_log_buffer_size\' innodb_log_buffer_size + if [ -z $innodb_log_buffer_size ] ; then + innodb_log_buffer_size=0 + fi + + mysql_variable \'key_buffer_size\' key_buffer_size + + mysql_variable \'query_cache_size\' query_cache_size + if [ -z $query_cache_size ] ; then + query_cache_size=0 + fi + + global_buffers=$(echo "$innodb_buffer_pool_size+$innodb_additional_mem_pool_size+$innodb_log_buffer_size+$key_buffer_size+$query_cache_size" | bc -l) + + + max_memory=$(echo "$global_buffers+$per_thread_max_buffers" | bc -l) + total_memory=$(echo "$global_buffers+$per_thread_buffers" | bc -l) + + pct_of_sys_mem=$(echo "scale=0; $total_memory*100/$physical_memory" | bc -l) + + if [ $pct_of_sys_mem -gt 90 ] ; then + txt_color=boldred + error=1 + else + txt_color= + error=0 + fi + + human_readable $max_memory max_memoryHR + cecho "Max Memory Ever Allocated : $max_memoryHR $unit" $txt_color + human_readable $per_thread_buffers per_thread_buffersHR + cecho "Configured Max Per-thread Buffers : $per_thread_buffersHR $unit" $txt_color + human_readable $global_buffers global_buffersHR + cecho "Configured Max Global Buffers : $global_buffersHR $unit" $txt_color + human_readable $total_memory total_memoryHR + cecho "Configured Max Memory Limit : $total_memoryHR $unit" $txt_color +# human_readable $effective_tmp_table_size effective_tmp_table_sizeHR +# cecho "Plus $effective_tmp_table_sizeHR $unit per temporary table created" + human_readable $physical_memory physical_memoryHR + cecho "Physical Memory : $physical_memoryHR $unit" $txt_color + if [ $error -eq 1 ] ; then + printf "\n" + cecho "Max memory limit exceeds 90% of physical memory" $txt_color + else + cecho "Max memory limit seem to be within acceptable norms" green + fi + unset txt_color +} + +## Required Functions ## + +login_validation () { + check_for_socket # determine the socket location -- 1st login + check_for_plesk_passwords # determine the login method -- 2nd login + check_mysql_login # determine if mysql is accepting login -- 3rd login + export major_version=$($mysql -Bse "SELECT SUBSTRING_INDEX(VERSION(), '.', +2)") +# export mysql_version_num=$($mysql -Bse "SELECT LEFT(REPLACE(SUBSTRING_INDEX(VERSION(), '-', +1), '.', ''),4)" ) + export mysql_version_num=$($mysql -Bse "SELECT VERSION()" | + awk -F \. '{ printf "%02d", $1; printf "%02d", $2; printf "%02d", $3 }') + +} + +shared_info () { + export major_version=$($mysql -Bse "SELECT SUBSTRING_INDEX(VERSION(), '.', +2)") + # export mysql_version_num=$($mysql -Bse "SELECT LEFT(REPLACE(SUBSTRING_INDEX(VERSION(), '-', +1), '.', ''),4)" ) + export mysql_version_num=$($mysql -Bse "SELECT VERSION()" | + awk -F \. '{ printf "%02d", $1; printf "%02d", $2; printf "%02d", $3 }') + mysql_status \'Questions\' questions +# socket_owner=$(find -L $socket -printf '%u\n') + socket_owner=$(ls -nH $socket | awk '{ print $3 }') +} + + +get_system_info () { + + export OS=$(uname) + + # Get information for various UNIXes + if [ "$OS" = 'Darwin' ]; then + ps_socket=$(netstat -ln | awk '/mysql(.*)?\.sock/ { print $9 }' | head -1) + found_socks=$(netstat -ln | awk '/mysql(.*)?\.sock/ { print $9 }') + export physical_memory=$(sysctl -n hw.memsize) + export duflags='' + elif [ "$OS" = 'FreeBSD' ] || [ "$OS" = 'OpenBSD' ]; then + ## On FreeBSD must be root to locate sockets. + ps_socket=$(netstat -ln | awk '/mysql(.*)?\.sock/ { print $9 }' | head -1) + found_socks=$(netstat -ln | awk '/mysql(.*)?\.sock/ { print $9 }') + export physical_memory=$(sysctl -n hw.realmem) + export duflags='' + elif [ "$OS" = 'Linux' ] ; then + ## Includes SWAP + ## export physical_memory=$(free -b | grep -v buffers | awk '{ s += $2 } END { printf("%.0f\n", s ) }') + ps_socket=$(netstat -ln | awk '/mysql(.*)?\.sock/ { print $9 }' | head -1) + found_socks=$(netstat -ln | awk '/mysql(.*)?\.sock/ { print $9 }') + export physical_memory=$(awk '/^MemTotal/ { printf("%.0f", $2*1024 ) }' < /proc/meminfo) + export duflags='-b' + elif [ "$OS" = 'SunOS' ] ; then + ps_socket=$(netstat -an | awk '/mysql(.*)?.sock/ { print $5 }' | head -1) + found_socks=$(netstat -an | awk '/mysql(.*)?.sock/ { print $5 }') + export physical_memory=$(prtconf | awk '/^Memory\ size:/ { print $3*1048576 }') + fi + if [ -z $(which bc) ] ; then + echo "Error: Command line calculator 'bc' not found!" + exit + fi +} + + +## Optional Components Groups ## + +banner_info () { + shared_info + print_banner ; echo + check_mysql_version ; echo + post_uptime_warning ; echo +} + +misc () { + shared_info + check_slow_queries ; echo + check_binary_log ; echo + check_threads ; echo + check_used_connections ; echo + check_innodb_status ; echo +} + +memory () { + shared_info + total_memory_used ; echo + check_key_buffer_size ; echo + check_query_cache ; echo + check_sort_operations ; echo + check_join_operations ; echo +} + +file () { + shared_info + check_open_files ; echo + check_table_cache ; echo + check_tmp_tables ; echo + check_table_scans ; echo + check_table_locking ; echo +} + +all () { + banner_info + misc + memory + file +} + +prompt () { + prompted='true' + read -p "Username [anonymous] : " user + read -rp "Password [] : " pass + cecho " " + read -p "Socket [ /var/lib/mysql/mysql.sock ] : " socket + if [ -z $socket ] ; then + export socket='/var/lib/mysql/mysql.sock' + fi + + if [ -z $pass ] ; then + export mysql="mysql -S $socket -u$user" + export mysqladmin="mysqladmin -S $socket -u$user" + else + export mysql="mysql -S $socket -u$user -p$pass" + export mysqladmin="mysqladmin -S $socket -u$user -p$pass" + fi + + check_for_socket + check_mysql_login + + if [ $? = 1 ] ; then + exit 1 + fi + read -p "Mode to test - banner, file, misc, mem, innodb, [all] : " REPLY + if [ -z $REPLY ] ; then + REPLY='all' + fi + case $REPLY in + banner | BANNER | header | HEADER | head | HEAD) + banner_info + ;; + misc | MISC | miscelaneous ) + misc + ;; + mem | memory | MEM | MEMORY ) + memory + ;; + file | FILE | disk | DISK ) + file + ;; + innodb | INNODB ) + innodb + ;; + all | ALL ) + cecho " " + all + ;; + * ) + cecho "Invalid Mode! Valid options are 'banner', 'misc', 'memory', 'file', 'innodb' or 'all'" boldred + exit 1 + ;; + esac +} + +## Address environmental differences ## +get_system_info +# echo $ps_socket + +if [ -z "$1" ] ; then + login_validation + mode='ALL' +elif [ "$1" = "prompt" ] || [ "$1" = "PROMPT" ] ; then + mode=$1 +elif [ "$1" != "prompt" ] || [ "$1" != "PROMPT" ] ; then + login_validation + mode=$1 +fi + +case $mode in + all | ALL ) + cecho " " + all + ;; + mem | memory | MEM | MEMORY ) + cecho " " + memory + ;; + file | FILE | disk | DISK ) + cecho " " + file + ;; + banner | BANNER | header | HEADER | head | HEAD ) + banner_info + ;; + misc | MISC | miscelaneous ) + cecho " " + misc + ;; + innodb | INNODB ) + banner_info + check_innodb_status ; echo + ;; + prompt | PROMPT ) + prompt + ;; + *) + cecho "usage: $0 [ all | banner | file | innodb | memory | misc | prompt ]" boldred + exit 1 + ;; +esac