diff --git a/bin/pt-mysql-summary b/bin/pt-mysql-summary index d336f319..a94c2a0c 100755 --- a/bin/pt-mysql-summary +++ b/bin/pt-mysql-summary @@ -537,7 +537,6 @@ fuzzy_formula=' }' fuzz () { - _d "fuzz: $1" echo $1 | awk "{fuzzy_var=\$1; ${fuzzy_formula} print fuzzy_var;}" } @@ -842,6 +841,38 @@ collect_internal_vars () { echo "pt-summary-internal-symbols $has_symbols" >> "$file" } +get_mysqldump_for () { + local file="$1" + local args="$2" + local dbtodump="${3:---all-databases}" + + $CMD_MYSQLDUMP $EXT_ARGV --no-data --skip-comments \ + --skip-add-locks --skip-add-drop-table --compact \ + --skip-lock-all-tables --skip-lock-tables --skip-set-charset \ + ${args} "${dbtodump}" > "$file" +} + +get_mysqldump_args () { + local file="$1" + local trg_arg="" + + if $CMD_MYSQLDUMP --help --verbose 2>&1 | grep triggers >/dev/null; then + _d "mysqldump supports triggers" + trg_arg="--routines" + fi + + if [ "${trg_arg}" ]; then + local triggers="--skip-triggers" + local trg=$(get_var "pt-summary-internal-trigger_count" "$file" ) + if [ -n "${trg}" ] && [ "${trg}" -gt 0 ]; then + _d "We have triggers to dump" + triggers="--triggers" + fi + trg_arg="${trg_arg} ${triggers}"; + fi + echo "${trg_arg}" +} + collect_mysql_info () { local dir="$1" local prefix="${2:-percona-toolkit}" @@ -891,34 +922,30 @@ collect_mysql_info () { # End collect_mysql_info package # ########################################################################### -# ######################################################################## -# Some global setup is necessary for cross-platform compatibility, even -# when sourcing this script for testing purposes. -# ######################################################################## +# ########################################################################### +# report_mysql_info package +# This package is a copy without comments from the original. The original +# with comments and its test file can be found in the Bazaar repository at, +# lib/bash/report_mysql_info.sh +# t/lib/bash/report_mysql_info.sh +# See https://launchpad.net/percona-toolkit for more information. +# ########################################################################### -TOOL="pt-mysql-summary" -CMD_MYSQL="$(_which mysql)" -CMD_MYSQLDUMP="$( _which mysqldump )" +set -u -# Accepts a number of seconds, and outputs a d+h:m:s formatted string secs_to_time () { echo "$1" | awk '{ printf( "%d+%02d:%02d:%02d", $1 / 86400, ($1 % 86400) / 3600, ($1 % 3600) / 60, $1 % 60); }' } -# Returns true if a variable exists var_exists () { local varname="$1" local file="$2" grep "${varname}" "${file}" >/dev/null 2>&1; } -# Returns "Enabled", "Disabled", or "Not Supported" depending on whether the -# variable exists and is ON or enabled. You can pass 2nd and 3rd variables to -# control whether the variable should be 'gt' (numeric greater than) or 'eq' -# (string equal) to some value. feat_on() { local file="$1" if var_exists "$2" "${file}" ; then @@ -960,7 +987,6 @@ get_table_cache () { echo ${table_cache:-0} } -# Gets the status of a plugin, or returns "Not found" get_plugin_status () { local file="$1" local plugin="$2" @@ -970,13 +996,7 @@ get_plugin_status () { echo ${status:-"Not found"} } -# ############################################################################## -# Functions for parsing specific files and getting desired info from them. -# These are called from within main() and are separated so they can be tested -# easily. -# ############################################################################## -# Parses the output of 'ps -e -o args | grep mysqld' or 'ps auxww...' _NO_FALSE_NEGATIVES="" parse_mysqld_instances () { local file="$1" @@ -989,8 +1009,6 @@ parse_mysqld_instances () { grep '/mysqld ' "$file" | while read line; do local pid=$(echo "$line" | awk '{print $2;}') for word in ${line}; do - # Some grep doesn't have -o, so I have to pull out the words I want by - # looking at each word if echo "${word}" | grep -- "--socket=" > /dev/null; then socket="$(echo "${word}" | cut -d= -f2)" fi @@ -1011,7 +1029,6 @@ parse_mysqld_instances () { done } -# Gets the MySQL system time. Uses input from $MYSQL_VARIABLES_FILE. get_mysql_timezone () { local file="${1:-$MYSQL_VARIABLES_FILE}" local tz="$(get_var time_zone "${file}")" @@ -1021,14 +1038,12 @@ get_mysql_timezone () { echo "${tz}" } -# Gets the MySQL system version. get_mysql_version () { local file="$1" name_val Version "$(get_var version "${file}") $(get_var version_comment "${file}")" name_val "Built On" "$(get_var version_compile_os "${file}") $(get_var version_compile_machine "${file}")" } -# Gets the system start and uptime in human readable format. get_mysql_uptime () { local uptime="$1" local restart="$2" @@ -1036,11 +1051,9 @@ get_mysql_uptime () { echo "${restart} (up ${uptime})" } -# Summarizes the output of SHOW MASTER LOGS. summarize_binlogs () { local file="$1" local size="$(awk '{t += $2} END{printf "%0.f\n", t}' "$file")" -cat "$file" >> ~/bluhbluh.txt name_val "Binlogs" $(wc -l "$file") name_val "Zero-Sized" $(grep -c '\<0$' "$file") name_val "Total Size" $(shorten ${size} 1) @@ -1051,20 +1064,14 @@ format_users () { awk '{printf "%d users, %d anon, %d w/o pw, %d old pw\n", $1, $2, $3, $4}' "${file}" } -# Print out binlog_do_db and binlog_ignore_db format_binlog_filters () { local file="$1" name_val "binlog_do_db" "$(cut -f3 "$file")" name_val "binlog_ignore_db" "$(cut -f4 "$file")" } -# Takes as input a file that has two samples of SHOW STATUS, columnized next to -# each other. Outputs fuzzy-ed numbers: -# absolute, all-time per second, and per-second over the interval between the -# samples. Omits any rows that are all zeroes. format_status_variables () { local file="$1" - # First, figure out the intervals. utime1="$(awk '/Uptime /{print $2}' "$file")"; utime2="$(awk '/Uptime /{print $3}' "$file")"; awk " @@ -1106,15 +1113,6 @@ format_status_variables () { }" "$file" } -# Slices the processlist a bunch of different ways. The processlist should be -# created with the \G flag so it's vertical. -# The parsing is a bit awkward because different -# versions of awk have limitations like "too many fields on line xyz". So we -# use 'cut' to shorten the lines. We count all things into temporary variables -# for each process in the processlist, and when we hit the Info: line which -# ought to be the last line in the process, we decide what to do with the temp -# variables. If we're summarizing Command, we count everything; otherwise, only -# non-Sleep processes get counted towards the sum and max of Time. summarize_processlist () { local file="$1" for param in Command User Host db State; do @@ -1164,10 +1162,6 @@ summarize_processlist () { echo } -# Pretty-prints the my.cnf file. It's super annoying, but some *modern* -# versions of awk don't support POSIX character sets in regular -# expressions, like [[:space:]] (looking at you, Debian). So -# the below patterns contain [] and must remain that way. pretty_print_cnf_file () { local file="$1" awk ' @@ -1176,10 +1170,10 @@ pretty_print_cnf_file () { } /^ *[a-zA-Z[]/ { if (length($2)) { - gsub(/^[ ]*/, "", $1); - gsub(/^[ ]*/, "", $2); - gsub(/[ ]*$/, "", $1); - gsub(/[ ]*$/, "", $2); + gsub(/^[ ]*/, "", $1); + gsub(/^[ ]*/, "", $2); + gsub(/[ ]*$/, "", $1); + gsub(/[ ]*$/, "", $2); printf("%-35s = %s\n", $1, $2); } else if ( $0 ~ /\[/ ) { @@ -1325,7 +1319,6 @@ find_transation_states () { group_concat "${tmpfile}" } -# Summarizes various things about InnoDB status that are not easy to see by eye. format_innodb_status () { local file=$1 name_val "Checkpoint Age" "$(shorten $(find_checkpoint_age "${file}") 0)" @@ -1361,19 +1354,12 @@ format_innodb_status () { fi } -# Summarizes per-database statistics for a bunch of different things: count of -# tables, views, etc. $1 is the file name. $2 is the database name; if none, -# then there should be multiple databases. format_overall_db_stats () { local file="$1" local tmpfile="$TMPDIR/format_overall_db_stats.tmp" echo - # We keep counts of everything in an associative array keyed by db name, and - # what it is. The num_dbs counter is to ensure sort order is consistent when - # we run the awk commands following this one. awk ' BEGIN { - # In case there is no USE statement in the file. db = "{chosen}"; num_dbs = 0; } @@ -1385,7 +1371,6 @@ format_overall_db_stats () { } } /^CREATE TABLE/ { - # Handle single-DB dumps, where there is no USE statement. if (num_dbs == 0) { num_dbs = 1; db_seen[db] = 1; @@ -1430,10 +1415,8 @@ format_overall_db_stats () { tail -n +3 "$tmpfile" | sort echo - # Now do the summary of engines per DB awk ' BEGIN { - # In case there is no USE statement in the file. db = "{chosen}"; num_dbs = 0; num_engines = 0; @@ -1446,7 +1429,6 @@ format_overall_db_stats () { } } /^\) ENGINE=/ { - # Handle single-DB dumps, where there is no USE statement. if (num_dbs == 0) { num_dbs = 1; db_seen[db] = 1; @@ -1490,11 +1472,8 @@ format_overall_db_stats () { tail -n +2 "$tmpfile" | sort echo - # Now do the summary of index types per DB. Careful -- index is a reserved - # word in awk. awk ' BEGIN { - # In case there is no USE statement in the file. db = "{chosen}"; num_dbs = 0; num_idxes = 0; @@ -1507,7 +1486,6 @@ format_overall_db_stats () { } } /KEY/ { - # Handle single-DB dumps, where there is no USE statement. if (num_dbs == 0) { num_dbs = 1; db_seen[db] = 1; @@ -1563,10 +1541,8 @@ format_overall_db_stats () { tail -n +2 "$tmpfile" | sort echo - # Now do the summary of datatypes per DB awk ' BEGIN { - # In case there is no USE statement in the file. db = "{chosen}"; num_dbs = 0; num_types = 0; @@ -1579,7 +1555,6 @@ format_overall_db_stats () { } } /^ `/ { - # Handle single-DB dumps, where there is no USE statement. if (num_dbs == 0) { num_dbs = 1; db_seen[db] = 1; @@ -1656,25 +1631,7 @@ format_overall_db_stats () { echo } -_myisam () { - local variables_file="$1" - local status_file="$2" - - local buf_size=$(get_var key_buffer_size "$variables_file") - local blk_size=$(get_var key_cache_block_size "$variables_file") - local blk_unus=$(get_var Key_blocks_unused "$status_file") - local blk_unfl=$(get_var Key_blocks_not_flushed "$variables_file") - local unus=$((${blk_unus} * ${blk_size})) - local unfl=$((${blk_unfl} * ${blk_size})) - local used=$((${buf_size} - ${unus})) - - name_val "Key Cache" "$(shorten ${buf_size} 1)" - name_val "Pct Used" "$(fuzzy_pct ${used} ${buf_size})" - name_val "Unflushed" "$(fuzzy_pct ${unfl} ${buf_size})" -} - - -_percona_server_features () { +section_percona_server_features () { local file="$1" name_val "Table & Index Stats" \ "$(feat_on "$file" userstat_running)" @@ -1702,12 +1659,27 @@ _percona_server_features () { "$(get_var "pt-summary-internal-FNV_64" "$file")" } -_innodb () { +section_myisam () { + local variables_file="$1" + local status_file="$2" + + local buf_size=$(get_var key_buffer_size "$variables_file") + local blk_size=$(get_var key_cache_block_size "$variables_file") + local blk_unus=$(get_var Key_blocks_unused "$status_file") + local blk_unfl=$(get_var Key_blocks_not_flushed "$variables_file") + local unus=$((${blk_unus} * ${blk_size})) + local unfl=$((${blk_unfl} * ${blk_size})) + local used=$((${buf_size} - ${unus})) + + name_val "Key Cache" "$(shorten ${buf_size} 1)" + name_val "Pct Used" "$(fuzzy_pct ${used} ${buf_size})" + name_val "Unflushed" "$(fuzzy_pct ${unfl} ${buf_size})" +} + +section_innodb () { local variables_file="$1" local status_file="$2" - # XXX TODO I don't think this is working right. - # XXX TODO Should it use data from information_schema.plugins too? local version=$(get_var innodb_version "$variables_file") name_val Version ${version:-default} @@ -1728,7 +1700,7 @@ _innodb () { local log_file="$(get_var innodb_log_files_in_group "$variables_file")" local log_total=$(echo 1 | awk "{printf \"%.2f\n\", ${log_size}*${log_file}}" ) name_val "Log File Size" \ - "${log_file} * $(shorten ${log_size} 1) = $(shorten ${log_total} 1 1000)" + "${log_file} * $(shorten ${log_size} 1 1000) = $(shorten ${log_total} 1 1000)" name_val "Log Buffer Size" \ "$(shorten $(get_var innodb_log_buffer_size "$variables_file") 0)" name_val "Flush Method" \ @@ -1759,7 +1731,8 @@ _innodb () { "$(get_var innodb_adaptive_checkpoint "$variables_file")" } -_noteworthy_variables () { + +section_noteworthy_variables () { local file="$1" name_val "Auto-Inc Incr/Offset" "$(get_var auto_increment_increment "$file")/$(get_var auto_increment_offset "$file")" @@ -1826,9 +1799,6 @@ _semi_sync_stats_for () { fi } -# Make a pattern of things we want to omit because they aren't -# counters, they are gauges (in RRDTool terminology). Gauges are shown -# elsewhere in the output. noncounters_pattern () { local noncounters_pattern="" @@ -1861,124 +1831,12 @@ noncounters_pattern () { echo $noncounters_pattern } - -# Uses mysqldump and dumps the results to FILE. -# args and dbtodump are passed to mysqldump. -get_mysqldump_for () { - local file="$1" - local args="$2" - local dbtodump="${3:---all-databases}" - - $CMD_MYSQLDUMP $EXT_ARGV --no-data --skip-comments \ - --skip-add-locks --skip-add-drop-table --compact \ - --skip-lock-all-tables --skip-lock-tables --skip-set-charset \ - ${args} "${dbtodump}" > "$file" -} - -# Returns a string with arguments to pass to mysqldump. -# Takes one argument, which should be a -get_mysqldump_args () { - local file="$1" - local trg_arg="" - - # If mysqldump supports triggers, then add options for routines. - if $CMD_MYSQLDUMP --help --verbose 2>&1 | grep triggers >/dev/null; then - _d "mysqldump supports triggers" - trg_arg="--routines" - fi - - if [ "${trg_arg}" ]; then - # Find out if there are any triggers. If there are none, we will skip - # that option to mysqldump, because when mysqldump checks for them, it - # can take a long time, one table at a time. - local triggers="--skip-triggers" - local trg=$(get_var "pt-summary-internal-trigger_count" "$file" ) - if [ -n "${trg}" ] && [ "${trg}" -gt 0 ]; then - _d "We have triggers to dump" - triggers="--triggers" - fi - trg_arg="${trg_arg} ${triggers}"; - fi - echo "${trg_arg}" -} - -check_mysql () { - # Check that mysql and mysqldump are in PATH. If not, we're - # already dead in the water, so don't bother with cmd line opts, - # just error and exit. - [ -n "$(mysql --help 2>/dev/null)" ] \ - || die "Cannot execute mysql. Check that it is in PATH." - [ -n "$(mysqldump --help 2>/dev/null)" ] \ - || die "Cannot execute mysqldump. Check that it is in PATH." - - # Now that we have the cmd line opts, check that we can actually - # connect to MySQL. - [ -n "$(mysql $EXT_ARGV -e 'SELECT 1')" ] \ - || die "Cannot connect to MySQL. Check that MySQL is running and that the options after -- are correct." - -} - -sigtrap() { - warn "Caught signal, forcing exit" - exit $EXIT_STATUS -} - -# ############################################################################## -# The main() function is called at the end of the script. This makes it -# testable. Major bits of parsing are separated into functions for testability. -# ############################################################################## -main() { - # Prepending SIG to these doesn't work with NetBSD's sh - trap sigtrap HUP INT TERM - - local RAN_WITH="--sleep=$OPT_SLEEP --dump-schemas=$OPT_DUMP_SCHEMAS --save-data=$OPT_SAVE_DATA" - - _d "Starting $0 $RAN_WITH" - - # Begin by setting the $PATH to include some common locations that are not - # always in the $PATH, including the "sbin" locations. On SunOS systems, - # prefix the path with the location of more sophisticated utilities. - export PATH="${PATH}:/usr/local/bin:/usr/bin:/bin:/usr/libexec" - export PATH="${PATH}:/usr/mysql/bin/:/usr/local/sbin:/usr/sbin:/sbin" - export PATH="/usr/gnu/bin/:/usr/xpg4/bin/:${PATH}" - - _d "Going to use: mysql=${CMD_MYSQL} mysqldump=${CMD_MYSQLDUMP}" - - # Create the tmpdir for everything to run in - mk_tmpdir - - # Set DATA_DIR where we'll save collected data files. - local data_dir="$(setup_data_dir)" - - _d "Temp dir is [$TMPDIR], saving data in [$data_dir]" - - # ######################################################################## - # Fetch most info, leave a child in the background gathering the rest - # ######################################################################## - collect_mysql_info "${data_dir}" - - # ######################################################################## - # Format and pretty-print the data - # ######################################################################## - report_summary "${data_dir}" - - rm_tmpdir - -} - -report_summary () { +report_mysql_summary () { local dir="$1" local prefix="${2:-percona-toolkit}" - # Make sure the MYSQL_etc_FILE variables are set - setup_files "$dir" - - # Field width for name_val local NAME_VAL_LEN=25 - # ######################################################################## - # Header for the whole thing, table of discovered instances - # ######################################################################## section Percona_Toolkit_MySQL_Summary_Report name_val "System time" "`date -u +'%F %T UTC'` (local TZ: `date +'%Z %z'`)" @@ -1988,9 +1846,6 @@ report_summary () { section MySQL_Executable name_val "Has symbols" "$( get_var "pt-summary-internal-symbols" "$dir/${prefix}-mysql-variables" )" - # ######################################################################## - # General date, hostname, etc - # ######################################################################## local user="$(get_var "pt-summary-internal-user" "$dir/${prefix}-mysql-variables")" local port="$(get_var port "$dir/${prefix}-mysql-variables")" local now="$(get_var "pt-summary-internal-NOW" "$dir/${prefix}-mysql-variables")" @@ -2018,8 +1873,6 @@ report_summary () { name_val Replication "Is ${slave}a slave, has ${slavecount} slaves connected" - # TODO move this into a section with other files: error log, slow log and - # show the sizes local pid_file="$(get_var pid_file "$dir/${prefix}-mysql-variables")" local PID_EXISTS="" if [ -e "${pid_file}" ]; then @@ -2029,45 +1882,26 @@ report_summary () { fi name_val Pidfile "${pid_file} ${PID_EXISTS}" - # ######################################################################## - # Processlist, sliced several different ways - # ######################################################################## section Processlist summarize_processlist "$dir/${prefix}-mysql-processlist" - # ######################################################################## - # Queries and query plans - # ######################################################################## section "Status_Counters_(Wait_${OPT_SLEEP}_Seconds)" - # Wait for the child that was forked during collection. wait local noncounters_pattern="$(noncounters_pattern)" format_status_variables "$dir/${prefix}-mysql-status-defer" | grep -v "${noncounters_pattern}" - # ######################################################################## - # Table cache - # ######################################################################## section Table_cache local open_tables=$(get_var Open_tables "$dir/${prefix}-mysql-status") local table_cache=$(get_table_cache "$dir/${prefix}-mysql-status") name_val Size $table_cache name_val Usage "$(fuzzy_pct ${open_tables} ${table_cache})" - # ######################################################################## - # Percona Server features - # ######################################################################## section Key_Percona_Server_features - _percona_server_features "$dir/${prefix}-mysql-variables" + section_percona_server_features "$dir/${prefix}-mysql-variables" - # ######################################################################## - # Plugins - # ######################################################################## section Plugins name_val "InnoDB compression" "$(get_plugin_status "$dir/${prefix}-mysql-plugins" "INNODB_CMP")" - # ######################################################################## - # Query cache - # ######################################################################## if [ "$(get_var have_query_cache "$dir/${prefix}-mysql-variables")" ]; then section Query_cache local query_cache_size=$(get_var query_cache_size "$dir/${prefix}-mysql-variables") @@ -2095,14 +1929,8 @@ report_summary () { fi fi - # ######################################################################## - # Schema, databases, data type, other analysis. - # ######################################################################## section Schema - # Assume "no" if stdin or stdout is not a terminal, so this can be run and - # put into a file, or piped into a pager, or something else like that. local reply="n" - # But dump no matter what if they passed in something through --dump-schemas if [ -n "${OPT_DUMP_SCHEMAS}" ]; then reply="y" elif [ -t 0 -a -t 1 ]; then @@ -2112,9 +1940,7 @@ report_summary () { fi if echo "${reply:-n}" | grep -i '^y' > /dev/null ; then if [ -z "${OPT_DUMP_SCHEMAS}" ]; then - # If --dump-schemas wasn't used, ask what they want - # Find out which databases to dump echo "There are ${num_dbs} databases. Would you like to dump all, or just one?" echo -n "Type the name of the database, or press Enter to dump all of them. " local dbtodump="" @@ -2123,9 +1949,6 @@ report_summary () { get_mysqldump_for "$dir/${prefix}-mysqldump" "${trg_arg}" "${dbtodump}" fi - # Test the result by checking the file, not by the exit status, because we - # might get partway through and then die, and the info is worth analyzing - # anyway. if [ -e "$dir/${prefix}-mysqldump" -a -s "$dir/${prefix}-mysqldump" ] \ && grep 'CREATE TABLE' "$dir/${prefix}-mysqldump" >/dev/null 2>&1; then @@ -2137,9 +1960,6 @@ report_summary () { echo "Skipping schema analysis" fi - # ######################################################################## - # Noteworthy Technologies - # ######################################################################## section Noteworthy_Technologies if [ -s "$dir/${prefix}-mysqldump" ]; then if grep FULLTEXT "$dir/${prefix}-mysqldump" > /dev/null; then @@ -2199,37 +2019,24 @@ report_summary () { name_val "Prepared statement count" "${prep_count}" fi - # ######################################################################## - # InnoDB - # ######################################################################## section InnoDB local have_innodb=$(get_var have_innodb "$dir/${prefix}-mysql-variables") if [ "${have_innodb}" = "YES" ]; then - _innodb "$dir/${prefix}-mysql-variables" "$dir/${prefix}-mysql-status" + section_innodb "$dir/${prefix}-mysql-variables" "$dir/${prefix}-mysql-status" if [ -s "$dir/${prefix}-innodb-status" ]; then format_innodb_status "$dir/${prefix}-innodb-status" fi fi - # ######################################################################## - # MyISAM - # ######################################################################## section MyISAM - _myisam "$dir/${prefix}-mysql-variables" "$dir/${prefix}-mysql-status" + section_myisam "$dir/${prefix}-mysql-variables" "$dir/${prefix}-mysql-status" - # ######################################################################## - # Users & Security - # ######################################################################## section Security local users="$( format_users "$dir/${prefix}-mysql-users" )" - # XXX TODO Give it a different formatting? name_val Users "${users}" name_val "Old Passwords" "$(get_var old_passwords "$dir/${prefix}-mysql-variables")" - # ######################################################################## - # Binary Logging - # ######################################################################## section Binary_Logging if [ -s "$dir/${prefix}-mysql-master-logs" ] \ @@ -2243,18 +2050,10 @@ report_summary () { format_binlog_filters "$dir/${prefix}-mysql-master-status" fi -# Replication: seconds behind, running, filters, skip_slave_start, skip_errors, -# read_only, temp tables open, slave_net_timeout, slave_exec_mode - # ######################################################################## - # Interesting things that you just ought to know about. - # ######################################################################## section Noteworthy_Variables - _noteworthy_variables "$dir/${prefix}-mysql-variables" + section_noteworthy_variables "$dir/${prefix}-mysql-variables" - # ######################################################################## - # If there is a my.cnf in a standard location, see if we can pretty-print it. - # ######################################################################## section Configuration_File local cnf_file="$(get_var "pt-summary-internal-Config_File" "$dir/${prefix}-mysql-variables")" if [ -n "${cnf_file}" ]; then @@ -2264,10 +2063,87 @@ report_summary () { name_val "Config File" "Cannot autodetect or find, giving up" fi - # Make sure that we signal the end of the tool's output. section The_End } +# ########################################################################### +# End report_mysql_info package +# ########################################################################### + +# ######################################################################## +# Some global setup is necessary for cross-platform compatibility, even +# when sourcing this script for testing purposes. +# ######################################################################## + +TOOL="pt-mysql-summary" + +CMD_MYSQL="$(_which mysql)" +CMD_MYSQLDUMP="$( _which mysqldump )" + +check_mysql () { + # Check that mysql and mysqldump are in PATH. If not, we're + # already dead in the water, so don't bother with cmd line opts, + # just error and exit. + [ -n "$(mysql --help 2>/dev/null)" ] \ + || die "Cannot execute mysql. Check that it is in PATH." + [ -n "$(mysqldump --help 2>/dev/null)" ] \ + || die "Cannot execute mysqldump. Check that it is in PATH." + + # Now that we have the cmd line opts, check that we can actually + # connect to MySQL. + [ -n "$(mysql $EXT_ARGV -e 'SELECT 1')" ] \ + || die "Cannot connect to MySQL. Check that MySQL is running and that the options after -- are correct." + +} + +sigtrap() { + warn "Caught signal, forcing exit" + exit $EXIT_STATUS +} + +# ############################################################################## +# The main() function is called at the end of the script. This makes it +# testable. Major bits of parsing are separated into functions for testability. +# ############################################################################## +main() { + # Prepending SIG to these doesn't work with NetBSD's sh + trap sigtrap HUP INT TERM + + local RAN_WITH="--sleep=$OPT_SLEEP --dump-schemas=$OPT_DUMP_SCHEMAS --save-data=$OPT_SAVE_DATA" + + _d "Starting $0 $RAN_WITH" + + # Begin by setting the $PATH to include some common locations that are not + # always in the $PATH, including the "sbin" locations. On SunOS systems, + # prefix the path with the location of more sophisticated utilities. + export PATH="${PATH}:/usr/local/bin:/usr/bin:/bin:/usr/libexec" + export PATH="${PATH}:/usr/mysql/bin/:/usr/local/sbin:/usr/sbin:/sbin" + export PATH="/usr/gnu/bin/:/usr/xpg4/bin/:${PATH}" + + _d "Going to use: mysql=${CMD_MYSQL} mysqldump=${CMD_MYSQLDUMP}" + + # Create the tmpdir for everything to run in + mk_tmpdir + + # Set DATA_DIR where we'll save collected data files. + local data_dir="$(setup_data_dir)" + + _d "Temp dir is [$TMPDIR], saving data in [$data_dir]" + + # ######################################################################## + # Fetch most info, leave a child in the background gathering the rest + # ######################################################################## + collect_mysql_info "${data_dir}" + + # ######################################################################## + # Format and pretty-print the data + # ######################################################################## + report_mysql_summary "${data_dir}" + + rm_tmpdir + +} + # Execute the program if it was not included from another file. # This makes it possible to include without executing, and thus test. if [ "${0##*/}" = "$TOOL" ] \ diff --git a/lib/bash/collect_mysql_info.sh b/lib/bash/collect_mysql_info.sh index 7aa54dbf..e9f4f6d1 100644 --- a/lib/bash/collect_mysql_info.sh +++ b/lib/bash/collect_mysql_info.sh @@ -140,9 +140,49 @@ collect_internal_vars () { echo "pt-summary-internal-symbols $has_symbols" >> "$file" } +# Uses mysqldump and dumps the results to FILE. +# args and dbtodump are passed to mysqldump. +get_mysqldump_for () { + local file="$1" + local args="$2" + local dbtodump="${3:---all-databases}" + + $CMD_MYSQLDUMP $EXT_ARGV --no-data --skip-comments \ + --skip-add-locks --skip-add-drop-table --compact \ + --skip-lock-all-tables --skip-lock-tables --skip-set-charset \ + ${args} "${dbtodump}" > "$file" +} + +# Returns a string with arguments to pass to mysqldump. +# Takes one argument, which should be a +get_mysqldump_args () { + local file="$1" + local trg_arg="" + + # If mysqldump supports triggers, then add options for routines. + if $CMD_MYSQLDUMP --help --verbose 2>&1 | grep triggers >/dev/null; then + _d "mysqldump supports triggers" + trg_arg="--routines" + fi + + if [ "${trg_arg}" ]; then + # Find out if there are any triggers. If there are none, we will skip + # that option to mysqldump, because when mysqldump checks for them, it + # can take a long time, one table at a time. + local triggers="--skip-triggers" + local trg=$(get_var "pt-summary-internal-trigger_count" "$file" ) + if [ -n "${trg}" ] && [ "${trg}" -gt 0 ]; then + _d "We have triggers to dump" + triggers="--triggers" + fi + trg_arg="${trg_arg} ${triggers}"; + fi + echo "${trg_arg}" +} + collect_mysql_info () { local dir="$1" - local prefix="$2" + local prefix="${2:-percona-toolkit}" collect_mysqld_instances "$dir/${prefix}-mysqld-instances" diff --git a/lib/bash/report_formatting.sh b/lib/bash/report_formatting.sh index c88e8bb1..95acdb2c 100644 --- a/lib/bash/report_formatting.sh +++ b/lib/bash/report_formatting.sh @@ -51,7 +51,6 @@ fuzzy_formula=' # Does fuzzy rounding: rounds to nearest interval, but the interval gets larger # as the number gets larger. This is to make things easier to diff. fuzz () { - _d "fuzz: $1" echo $1 | awk "{fuzzy_var=\$1; ${fuzzy_formula} print fuzzy_var;}" } diff --git a/lib/bash/report_mysql_info.sh b/lib/bash/report_mysql_info.sh new file mode 100644 index 00000000..923b2cde --- /dev/null +++ b/lib/bash/report_mysql_info.sh @@ -0,0 +1,1291 @@ +# This program is copyright 2011 Percona Inc. +# Feedback and improvements are welcome. +# +# THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF +# MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation, version 2; OR the Perl Artistic License. On UNIX and similar +# systems, you can issue `man perlgpl' or `man perlartistic' to read these +# licenses. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., 59 Temple +# Place, Suite 330, Boston, MA 02111-1307 USA. +# ########################################################################### +# report_mysql_info package +# ########################################################################### + +# Package: report_mysql_info +# Report various aspects of MySQL + +set -u +POSIXLY_CORRECT=1 + +# Accepts a number of seconds, and outputs a d+h:m:s formatted string +secs_to_time () { + echo "$1" | awk '{ + printf( "%d+%02d:%02d:%02d", $1 / 86400, ($1 % 86400) / 3600, ($1 % 3600) / 60, $1 % 60); + }' +} + +# Returns true if a variable exists +var_exists () { + local varname="$1" + local file="$2" + grep "${varname}" "${file}" >/dev/null 2>&1; +} + +# Returns "Enabled", "Disabled", or "Not Supported" depending on whether the +# variable exists and is ON or enabled. You can pass 2nd and 3rd variables to +# control whether the variable should be 'gt' (numeric greater than) or 'eq' +# (string equal) to some value. +feat_on() { + local file="$1" + if var_exists "$2" "${file}" ; then + local var="$(awk "\$1 ~ /^$2$/ { print \$2 }" $file)" + if [ "${var}" = "ON" ]; then + echo "Enabled" + elif [ "${var}" = "OFF" -o "${var}" = "0" -o -z "${var}" ]; then + echo "Disabled" + elif [ "$3" = "ne" ]; then + if [ "${var}" != "$4" ]; then + echo "Enabled" + else + echo "Disabled" + fi + elif [ "$3" = "gt" ]; then + if [ "${var}" -gt "$4" ]; then + echo "Enabled" + else + echo "Disabled" + fi + elif [ "${var}" ]; then + echo "Enabled" + else + echo "Disabled" + fi + else + echo "Not Supported" + fi +} + +get_table_cache () { + local file="$1" + local table_cache="" + if var_exists table_open_cache "${file}"; then + table_cache="$(get_var table_open_cache "${file}")" + else + table_cache="$(get_var table_cache "${file}")" + fi + echo ${table_cache:-0} +} + +# Gets the status of a plugin, or returns "Not found" +get_plugin_status () { + local file="$1" + local plugin="$2" + + local status="$(grep -w "$plugin" "$file" | awk '{ print $2 }')" + + echo ${status:-"Not found"} +} + +# ############################################################################## +# Functions for parsing specific files and getting desired info from them. +# These are called from within main() and are separated so they can be tested +# easily. +# ############################################################################## + +# Parses the output of 'ps -e -o args | grep mysqld' or 'ps auxww...' +_NO_FALSE_NEGATIVES="" +parse_mysqld_instances () { + local file="$1" + local socket=${socket:-""} + local port=${port:-""} + local datadir="${datadir:-""}" + echo " Port Data Directory Nice OOM Value Socket" + echo " ===== ========================== ==== ========= ======" + + grep '/mysqld ' "$file" | while read line; do + local pid=$(echo "$line" | awk '{print $2;}') + for word in ${line}; do + # Some grep doesn't have -o, so I have to pull out the words I want by + # looking at each word + if echo "${word}" | grep -- "--socket=" > /dev/null; then + socket="$(echo "${word}" | cut -d= -f2)" + fi + if echo "${word}" | grep -- "--port=" > /dev/null; then + port="$(echo "${word}" | cut -d= -f2)" + fi + if echo "${word}" | grep -- "--datadir=" > /dev/null; then + datadir="$(echo "${word}" | cut -d= -f2)" + fi + done + local nice=$(get_nice_of_pid $pid ) + local oom=$(get_oom_of_pid $pid ) + # Only used during testing + if [ -n "${_NO_FALSE_NEGATIVES}" ]; then + nice="?" + oom="?" + fi + printf " %5s %-26s %-4s %-9s %s\n" "${port}" "${datadir}" "${nice}" "${oom}" "${socket}" + done +} + +# Gets the MySQL system time. Uses input from $MYSQL_VARIABLES_FILE. +get_mysql_timezone () { + local file="${1:-$MYSQL_VARIABLES_FILE}" + local tz="$(get_var time_zone "${file}")" + if [ "${tz}" = "SYSTEM" ]; then + tz="$(get_var system_time_zone "${file}")" + fi + echo "${tz}" +} + +# Gets the MySQL system version. +get_mysql_version () { + local file="$1" + name_val Version "$(get_var version "${file}") $(get_var version_comment "${file}")" + name_val "Built On" "$(get_var version_compile_os "${file}") $(get_var version_compile_machine "${file}")" +} + +# Gets the system start and uptime in human readable format. +get_mysql_uptime () { + local uptime="$1" + local restart="$2" + uptime="$(secs_to_time ${uptime})" + echo "${restart} (up ${uptime})" +} + +# Summarizes the output of SHOW MASTER LOGS. +summarize_binlogs () { + local file="$1" + local size="$(awk '{t += $2} END{printf "%0.f\n", t}' "$file")" + name_val "Binlogs" $(wc -l "$file") + name_val "Zero-Sized" $(grep -c '\<0$' "$file") + name_val "Total Size" $(shorten ${size} 1) +} + +format_users () { + local file="$1" + awk '{printf "%d users, %d anon, %d w/o pw, %d old pw\n", $1, $2, $3, $4}' "${file}" +} + +# Print out binlog_do_db and binlog_ignore_db +format_binlog_filters () { + local file="$1" + name_val "binlog_do_db" "$(cut -f3 "$file")" + name_val "binlog_ignore_db" "$(cut -f4 "$file")" +} + +# Takes as input a file that has two samples of SHOW STATUS, columnized next to +# each other. Outputs fuzzy-ed numbers: +# absolute, all-time per second, and per-second over the interval between the +# samples. Omits any rows that are all zeroes. +format_status_variables () { + local file="$1" + # First, figure out the intervals. + utime1="$(awk '/Uptime /{print $2}' "$file")"; + utime2="$(awk '/Uptime /{print $3}' "$file")"; + awk " + BEGIN { + utime1 = ${utime1}; + utime2 = ${utime2}; + udays = utime1 / 86400; + udiff = utime2 - utime1; + format=\"%-35s %11s %11s %11s\\n\"; + printf(format, \"Variable\", \"Per day\", \"Per second\", udiff \" secs\"); + } + \$2 ~ /^[0-9]*\$/ { + if ( \$2 > 0 && \$2 < 18446744073709551615 ) { + if ( udays > 0 ) { + fuzzy_var=\$2 / udays; + ${fuzzy_formula}; + perday=fuzzy_var; + } + if ( utime1 > 0 ) { + fuzzy_var=\$2 / utime1; + ${fuzzy_formula}; + persec=fuzzy_var; + } + if ( udiff > 0 ) { + fuzzy_var=(\$3 - \$2) / udiff; + ${fuzzy_formula}; + nowsec=fuzzy_var; + } + perday = int(perday); + persec = int(persec); + nowsec = int(nowsec); + if ( perday + persec + nowsec > 0 ) { + if ( perday == 0 ) { perday = \"\"; } + if ( persec == 0 ) { persec = \"\"; } + if ( nowsec == 0 ) { nowsec = \"\"; } + printf(format, \$1, perday, persec, nowsec); + } + } + }" "$file" +} + +# Slices the processlist a bunch of different ways. The processlist should be +# created with the \G flag so it's vertical. +# The parsing is a bit awkward because different +# versions of awk have limitations like "too many fields on line xyz". So we +# use 'cut' to shorten the lines. We count all things into temporary variables +# for each process in the processlist, and when we hit the Info: line which +# ought to be the last line in the process, we decide what to do with the temp +# variables. If we're summarizing Command, we count everything; otherwise, only +# non-Sleep processes get counted towards the sum and max of Time. +summarize_processlist () { + local file="$1" + for param in Command User Host db State; do + echo + printf ' %-30s %8s %7s %9s %9s\n' \ + "${param}" "COUNT(*)" Working "SUM(Time)" "MAX(Time)" + echo " ------------------------------" \ + "-------- ------- --------- ---------" + cut -c1-80 "$file" \ + | awk " + \$1 == \"${param}:\" { + p = substr(\$0, index(\$0, \":\") + 2); + if ( index(p, \":\") > 0 ) { + p = substr(p, 1, index(p, \":\") - 1); + } + if ( length(p) > 30 ) { + p = substr(p, 1, 30); + } + } + \$1 == \"Time:\" { + t = \$2; + } + \$1 == \"Command:\" { + c = \$2; + } + \$1 == \"Info:\" { + count[p]++; + if ( c == \"Sleep\" ) { + sleep[p]++; + } + if ( \"${param}\" == \"Command\" || c != \"Sleep\" ) { + time[p] += t; + if ( t > mtime[p] ) { mtime[p] = t; } + } + } + END { + for ( p in count ) { + fuzzy_var=count[p]-sleep[p]; ${fuzzy_formula} fuzzy_work=fuzzy_var; + fuzzy_var=count[p]; ${fuzzy_formula} fuzzy_count=fuzzy_var; + fuzzy_var=time[p]; ${fuzzy_formula} fuzzy_time=fuzzy_var; + fuzzy_var=mtime[p]; ${fuzzy_formula} fuzzy_mtime=fuzzy_var; + printf \" %-30s %8d %7d %9d %9d\n\", p, fuzzy_count, fuzzy_work, fuzzy_time, fuzzy_mtime; + } + } + " | sort + done + echo +} + +# Pretty-prints the my.cnf file. It's super annoying, but some *modern* +# versions of awk don't support POSIX character sets in regular +# expressions, like [[:space:]] (looking at you, Debian). So +# the below patterns contain [] and must remain that way. +pretty_print_cnf_file () { + local file="$1" + awk ' + BEGIN { + FS="=" + } + /^[ \t]*[a-zA-Z[]/ { + if (length($2)) { + gsub(/^[ \t]*/, "", $1); + gsub(/^[ \t]*/, "", $2); + gsub(/[ \t]*$/, "", $1); + gsub(/[ \t]*$/, "", $2); + printf("%-35s = %s\n", $1, $2); + } + else if ( $0 ~ /\[/ ) { + print ""; + print $1; + } + else { + print $1; + } + }' "$file" +} + +find_checkpoint_age() { + local file="$1" + awk ' + /Log sequence number/{ + if ( $5 ) { + lsn = $5 + ($4 * 4294967296); + } + else { + lsn = $4; + } + } + /Last checkpoint at/{ + if ( $5 ) { + print lsn - ($5 + ($4 * 4294967296)); + } + else { + print lsn - $4; + } + } + ' "$file" +} + +find_pending_io_reads() { + local file="$1" + awk ' + /Pending normal aio reads/ { + normal_aio_reads = substr($5, 1, index($5, ",")); + } + /ibuf aio reads/ { + ibuf_aio_reads = substr($4, 1, index($4, ",")); + } + /pending preads/ { + preads = $1; + } + /Pending reads/ { + reads = $3; + } + END { + printf "%d buf pool reads, %d normal AIO", reads, normal_aio_reads; + printf ", %d ibuf AIO, %d preads", ibuf_aio_reads, preads; + } + ' "${file}" +} + +find_pending_io_writes() { + local file="$1" + awk ' + /aio writes/ { + aio_writes = substr($NF, 1, index($NF, ",")); + } + /ibuf aio reads/ { + log_ios = substr($7, 1, index($7, ",")); + sync_ios = substr($10, 1, index($10, ",")); + } + /pending log writes/ { + log_writes = $1; + chkp_writes = $5; + } + /pending pwrites/ { + pwrites = $4; + } + /Pending writes:/ { + lru = substr($4, 1, index($4, ",")); + flush_list = substr($7, 1, index($7, ",")); + single_page = $NF; + } + END { + printf "%d buf pool (%d LRU, %d flush list, %d page); %d AIO, %d sync, %d log IO (%d log, %d chkp); %d pwrites", lru + flush_list + single_page, lru, flush_list, single_page, aio_writes, sync_ios, log_ios, log_writes, chkp_writes, pwrites; + } + ' "${file}" +} + +find_pending_io_flushes() { + local file="$1" + awk ' + /Pending flushes/ { + log_flushes = substr($5, 1, index($5, ";")); + buf_pool = $NF; + } + END { + printf "%d buf pool, %d log", buf_pool, log_flushes; + } + ' "${file}" +} + +summarize_undo_log_entries() { + local file="$1" + grep 'undo log entries' "${file}" \ + | sed -e 's/^.*undo log entries \([0-9]*\)/\1/' \ + | awk ' + { + count++; + sum += $1; + if ( $1 > max ) { + max = $1; + } + } + END { + printf "%d transactions, %d total undo, %d max undo\n", count, sum, max; + }' +} + +find_max_trx_time() { + local file="$1" + awk ' + BEGIN { + max = 0; + } + /^---TRANSACTION.* sec,/ { + for ( i = 0; i < 7; ++i ) { + if ( $i == "sec," ) { + j = i-1; + if ( max < $j ) { + max = $j; + } + } + } + } + END { + print max; + }' "${file}" +} + +find_transation_states () { + local file="$1" + local tmpfile="$TMPDIR/find_transation_states.tmp" + awk -F, '/^---TRANSACTION/{print $2}' "${file}" \ + | sed -e 's/ [0-9]* sec.*//' \ + | sort \ + | uniq -c > "${tmpfile}" + group_concat "${tmpfile}" +} + +# Summarizes various things about InnoDB status that are not easy to see by eye. +format_innodb_status () { + local file=$1 + name_val "Checkpoint Age" "$(shorten $(find_checkpoint_age "${file}") 0)" + name_val "InnoDB Queue" "$(awk '/queries inside/{print}' "${file}")" + name_val "Oldest Transaction" "$(find_max_trx_time "${file}") Seconds"; + name_val "History List Len" "$(awk '/History list length/{print $4}' "${file}")" + name_val "Read Views" "$(awk '/read views open inside/{print $1}' "${file}")" + name_val "Undo Log Entries" "$(summarize_undo_log_entries "${file}")" + name_val "Pending I/O Reads" "$(find_pending_io_reads "${file}")" + name_val "Pending I/O Writes" "$(find_pending_io_writes "${file}")" + name_val "Pending I/O Flushes" "$(find_pending_io_flushes "${file}")" + name_val "Transaction States" "$(find_transation_states "${file}" )" + if grep 'TABLE LOCK table' "${file}" >/dev/null ; then + echo "Tables Locked" + awk '/^TABLE LOCK table/{print $4}' "${file}" \ + | sort | uniq -c | sort -rn + fi + if grep 'has waited at' "${file}" > /dev/null ; then + echo "Semaphore Waits" + grep 'has waited at' "${file}" | cut -d' ' -f6-8 \ + | sort | uniq -c | sort -rn + fi + if grep 'reserved it in mode' "${file}" > /dev/null; then + echo "Semaphore Holders" + awk '/has reserved it in mode/{ + print substr($0, 1 + index($0, "("), index($0, ")") - index($0, "(") - 1); + }' "${file}" | sort | uniq -c | sort -rn + fi + if grep -e 'Mutex at' -e 'lock on' "${file}" >/dev/null 2>&1; then + echo "Mutexes/Locks Waited For" + grep -e 'Mutex at' -e 'lock on' "${file}" | sed -e 's/^[XS]-//' -e 's/,.*$//' \ + | sort | uniq -c | sort -rn + fi +} + +# Summarizes per-database statistics for a bunch of different things: count of +# tables, views, etc. $1 is the file name. $2 is the database name; if none, +# then there should be multiple databases. +format_overall_db_stats () { + local file="$1" + local tmpfile="$TMPDIR/format_overall_db_stats.tmp" + echo + # We keep counts of everything in an associative array keyed by db name, and + # what it is. The num_dbs counter is to ensure sort order is consistent when + # we run the awk commands following this one. + awk ' + BEGIN { + # In case there is no USE statement in the file. + db = "{chosen}"; + num_dbs = 0; + } + /^USE `.*`;$/ { + db = substr($2, 2, length($2) - 3); + if ( db_seen[db]++ == 0 ) { + dbs[num_dbs] = db; + num_dbs++; + } + } + /^CREATE TABLE/ { + # Handle single-DB dumps, where there is no USE statement. + if (num_dbs == 0) { + num_dbs = 1; + db_seen[db] = 1; + dbs[0] = db; + } + counts[db ",tables"]++; + } + /CREATE ALGORITHM=/ { + counts[db ",views"]++; + } + /03 CREATE.*03 PROCEDURE/ { + counts[db ",sps"]++; + } + /03 CREATE.*03 FUNCTION/ { + counts[db ",func"]++; + } + /03 CREATE.*03 TRIGGER/ { + counts[db ",trg"]++; + } + /FOREIGN KEY/ { + counts[db ",fk"]++; + } + /PARTITION BY/ { + counts[db ",partn"]++; + } + END { + mdb = length("Database"); + for ( i = 0; i < num_dbs; i++ ) { + if ( length(dbs[i]) > mdb ) { + mdb = length(dbs[i]); + } + } + fmt = " %-" mdb "s %6s %5s %3s %5s %5s %5s %5s\n"; + printf fmt, "Database", "Tables", "Views", "SPs", "Trigs", "Funcs", "FKs", "Partn"; + for ( i=0;i "$tmpfile" + head -n2 "$tmpfile" + tail -n +3 "$tmpfile" | sort + + echo + # Now do the summary of engines per DB + awk ' + BEGIN { + # In case there is no USE statement in the file. + db = "{chosen}"; + num_dbs = 0; + num_engines = 0; + } + /^USE `.*`;$/ { + db = substr($2, 2, length($2) - 3); + if ( db_seen[db]++ == 0 ) { + dbs[num_dbs] = db; + num_dbs++; + } + } + /^\) ENGINE=/ { + # Handle single-DB dumps, where there is no USE statement. + if (num_dbs == 0) { + num_dbs = 1; + db_seen[db] = 1; + dbs[0] = db; + } + engine=substr($2, index($2, "=") + 1); + if ( engine_seen[engine]++ == 0 ) { + engines[num_engines] = engine; + num_engines++; + } + counts[db "," engine]++; + } + END { + mdb = length("Database"); + for ( i=0;i mdb ) { + mdb = length(db); + } + } + fmt = " %-" mdb "s" + printf fmt, "Database"; + for ( i=0;i "$tmpfile" + head -n1 "$tmpfile" + tail -n +2 "$tmpfile" | sort + + echo + # Now do the summary of index types per DB. Careful -- index is a reserved + # word in awk. + awk ' + BEGIN { + # In case there is no USE statement in the file. + db = "{chosen}"; + num_dbs = 0; + num_idxes = 0; + } + /^USE `.*`;$/ { + db = substr($2, 2, length($2) - 3); + if ( db_seen[db]++ == 0 ) { + dbs[num_dbs] = db; + num_dbs++; + } + } + /KEY/ { + # Handle single-DB dumps, where there is no USE statement. + if (num_dbs == 0) { + num_dbs = 1; + db_seen[db] = 1; + dbs[0] = db; + } + idx="BTREE"; + if ( $0 ~ /SPATIAL/ ) { + idx="SPATIAL"; + } + if ( $0 ~ /FULLTEXT/ ) { + idx="FULLTEXT"; + } + if ( $0 ~ /USING RTREE/ ) { + idx="RTREE"; + } + if ( $0 ~ /USING HASH/ ) { + idx="HASH"; + } + if ( idx_seen[idx]++ == 0 ) { + idxes[num_idxes] = idx; + num_idxes++; + } + counts[db "," idx]++; + } + END { + mdb = length("Database"); + for ( i=0;i mdb ) { + mdb = length(db); + } + } + fmt = " %-" mdb "s" + printf fmt, "Database"; + for ( i=0;i "$tmpfile" + head -n1 "$tmpfile" + tail -n +2 "$tmpfile" | sort + + echo + # Now do the summary of datatypes per DB + awk ' + BEGIN { + # In case there is no USE statement in the file. + db = "{chosen}"; + num_dbs = 0; + num_types = 0; + } + /^USE `.*`;$/ { + db = substr($2, 2, length($2) - 3); + if ( db_seen[db]++ == 0 ) { + dbs[num_dbs] = db; + num_dbs++; + } + } + /^ `/ { + # Handle single-DB dumps, where there is no USE statement. + if (num_dbs == 0) { + num_dbs = 1; + db_seen[db] = 1; + dbs[0] = db; + } + str = $0; + str = substr(str, index(str, "`") + 1); + str = substr(str, index(str, "`") + 2); + if ( index(str, " ") > 0 ) { + str = substr(str, 1, index(str, " ") - 1); + } + if ( index(str, ",") > 0 ) { + str = substr(str, 1, index(str, ",") - 1); + } + if ( index(str, "(") > 0 ) { + str = substr(str, 1, index(str, "(") - 1); + } + type = str; + if ( type_seen[type]++ == 0 ) { + types[num_types] = type; + num_types++; + } + counts[db "," type]++; + } + END { + mdb = length("Database"); + for ( i=0;i mdb ) { + mdb = length(db); + } + } + fmt = " %-" mdb "s" + mtlen = 0; # max type length + for ( i=0;i mtlen ) { + mtlen = length(type); + } + } + for ( i=1;i<=mtlen;i++ ) { + printf " %-" mdb "s", ""; + for ( j=0;j length(type) ) { + ch = " "; + } + else { + ch = substr(type, i, 1); + } + printf(" %3s", ch); + } + print ""; + } + printf " %-" mdb "s", "Database"; + for ( i=0;i "$tmpfile" + local hdr=$(grep -n Database "$tmpfile" | cut -d: -f1); + head -n${hdr} "$tmpfile" + tail -n +$((${hdr} + 1)) "$tmpfile" | sort + echo +} + +section_percona_server_features () { + local file="$1" + name_val "Table & Index Stats" \ + "$(feat_on "$file" userstat_running)" + name_val "Multiple I/O Threads" \ + "$(feat_on "$file" innodb_read_io_threads gt 1)" + name_val "Corruption Resilient" \ + "$(feat_on "$file" innodb_pass_corrupt_table)" + name_val "Durable Replication" \ + "$(feat_on "$file" innodb_overwrite_relay_log_info)" + name_val "Import InnoDB Tables" \ + "$(feat_on "$file" innodb_expand_import)" + name_val "Fast Server Restarts" \ + "$(feat_on "$file" innodb_auto_lru_dump)" + name_val "Enhanced Logging" \ + "$(feat_on "$file" log_slow_verbosity ne microtime)" + name_val "Replica Perf Logging" \ + "$(feat_on "$file" log_slow_slave_statements)" + name_val "Response Time Hist." \ + "$(feat_on "$file" enable_query_response_time_stats)" + name_val "Smooth Flushing" \ + "$(feat_on "$file" innodb_adaptive_checkpoint ne none)" + name_val "HandlerSocket NoSQL" \ + "$(feat_on "$file" handlersocket_port)" + name_val "Fast Maatkit Hashes" \ + "$(get_var "pt-summary-internal-FNV_64" "$file")" +} + +section_myisam () { + local variables_file="$1" + local status_file="$2" + + local buf_size=$(get_var key_buffer_size "$variables_file") + local blk_size=$(get_var key_cache_block_size "$variables_file") + local blk_unus=$(get_var Key_blocks_unused "$status_file") + local blk_unfl=$(get_var Key_blocks_not_flushed "$variables_file") + local unus=$((${blk_unus} * ${blk_size})) + local unfl=$((${blk_unfl} * ${blk_size})) + local used=$((${buf_size} - ${unus})) + + name_val "Key Cache" "$(shorten ${buf_size} 1)" + name_val "Pct Used" "$(fuzzy_pct ${used} ${buf_size})" + name_val "Unflushed" "$(fuzzy_pct ${unfl} ${buf_size})" +} + +section_innodb () { + local variables_file="$1" + local status_file="$2" + + # XXX TODO I don't think this is working right. + # XXX TODO Should it use data from information_schema.plugins too? + local version=$(get_var innodb_version "$variables_file") + name_val Version ${version:-default} + + local bp_size="$(get_var innodb_buffer_pool_size "$variables_file")" + name_val "Buffer Pool Size" "$(shorten ${bp_size} 1)" + + local bp_pags="$(get_var Innodb_buffer_pool_pages_total "$status_file")" + local bp_free="$(get_var Innodb_buffer_pool_pages_free "$status_file")" + local bp_dirt="$(get_var Innodb_buffer_pool_pages_dirty "$status_file")" + local bp_fill=$((${bp_pags} - ${bp_free})) + name_val "Buffer Pool Fill" "$(fuzzy_pct ${bp_fill} ${bp_pags})" + name_val "Buffer Pool Dirty" "$(fuzzy_pct ${bp_dirt} ${bp_pags})" + + name_val "File Per Table" $(get_var innodb_file_per_table "$variables_file") + name_val "Page Size" $(shorten $(get_var Innodb_page_size "$status_file") 0) + + local log_size="$(get_var innodb_log_file_size "$variables_file")" + local log_file="$(get_var innodb_log_files_in_group "$variables_file")" + local log_total=$(echo 1 | awk "{printf \"%.2f\n\", ${log_size}*${log_file}}" ) + name_val "Log File Size" \ + "${log_file} * $(shorten ${log_size} 1 1000) = $(shorten ${log_total} 1 1000)" + name_val "Log Buffer Size" \ + "$(shorten $(get_var innodb_log_buffer_size "$variables_file") 0)" + name_val "Flush Method" \ + "$(get_var innodb_flush_method "$variables_file")" + name_val "Flush Log At Commit" \ + "$(get_var innodb_flush_log_at_trx_commit "$variables_file")" + name_val "XA Support" \ + "$(get_var innodb_support_xa "$variables_file")" + name_val "Checksums" \ + "$(get_var innodb_checksums "$variables_file")" + name_val "Doublewrite" \ + "$(get_var innodb_doublewrite "$variables_file")" + name_val "R/W I/O Threads" \ + "$(get_var innodb_read_io_threads "$variables_file") $(get_var innodb_write_io_threads "$variables_file")" + name_val "I/O Capacity" \ + "$(get_var innodb_io_capacity "$variables_file")" + name_val "Thread Concurrency" \ + "$(get_var innodb_thread_concurrency "$variables_file")" + name_val "Concurrency Tickets" \ + "$(get_var innodb_concurrency_tickets "$variables_file")" + name_val "Commit Concurrency" \ + "$(get_var innodb_commit_concurrency "$variables_file")" + name_val "Txn Isolation Level" \ + "$(get_var tx_isolation "$variables_file")" + name_val "Adaptive Flushing" \ + "$(get_var innodb_adaptive_flushing "$variables_file")" + name_val "Adaptive Checkpoint" \ + "$(get_var innodb_adaptive_checkpoint "$variables_file")" +} + + +section_noteworthy_variables () { + local file="$1" + + name_val "Auto-Inc Incr/Offset" "$(get_var auto_increment_increment "$file")/$(get_var auto_increment_offset "$file")" + for v in \ + default_storage_engine flush_time init_connect init_file sql_mode; + do + name_val ${v} $(get_var ${v} "$file") + done + for v in \ + join_buffer_size sort_buffer_size read_buffer_size read_rnd_buffer_size \ + bulk_insert_buffer max_heap_table_size tmp_table_size \ + max_allowed_packet thread_stack; + do + name_val ${v} $(shorten $(get_var ${v} "$file") 0) + done + for v in log log_error log_warnings log_slow_queries \ + log_queries_not_using_indexes log_slave_updates; + do + name_val ${v} $(get_var ${v} "$file") + done +} + +# +# Formats and outputs the semisyncronious replication-related variables +# +_semi_sync_stats_for () { + local target="$1" + local file="$2" + + local semisync_status="$(get_var "Rpl_semi_sync_${target}_status" "${file}" )" + local semisync_trace="$(get_var "rpl_semi_sync_${target}_trace_level" "${file}")" + + local trace_extra="" + if [ -n "${semisync_trace}" ]; then + if [ $semisync_trace -eq 1 ]; then + trace_extra="general (for example, time function failures) " + elif [ $semisync_trace -eq 16 ]; then + trace_extra="detail (more verbose information) " + elif [ $semisync_trace -eq 32 ]; then + trace_extra="net wait (more information about network waits)" + elif [ $semisync_trace -eq 64 ]; then + trace_extra="function (information about function entry and exit)" + else + trace_extra="Unknown setting" + fi + fi + + name_val "${target} semisync status" "${semisync_status}" + name_val "${target} trace level" "${semisync_trace}, ${trace_extra}" + + if [ "${target}" = "master" ]; then + name_val "${target} timeout in milliseconds" \ + "$(get_var "rpl_semi_sync_${target}_timeout" "${file}")" + name_val "${target} waits for slaves" \ + "$(get_var "rpl_semi_sync_${target}_wait_no_slave" "${file}")" + + _d "Prepend Rpl_semi_sync_master_ to the following" + for v in \ + clients net_avg_wait_time net_wait_time net_waits \ + no_times no_tx timefunc_failures tx_avg_wait_time \ + tx_wait_time tx_waits wait_pos_backtraverse \ + wait_sessions yes_tx; + do + name_val "${target} ${v}" \ + "$( get_var "Rpl_semi_sync_master_${v}" "${file}" )" + done + fi +} + +# Make a pattern of things we want to omit because they aren't +# counters, they are gauges (in RRDTool terminology). Gauges are shown +# elsewhere in the output. +noncounters_pattern () { + local noncounters_pattern="" + + for var in Compression Delayed_insert_threads Innodb_buffer_pool_pages_data \ + Innodb_buffer_pool_pages_dirty Innodb_buffer_pool_pages_free \ + Innodb_buffer_pool_pages_latched Innodb_buffer_pool_pages_misc \ + Innodb_buffer_pool_pages_total Innodb_data_pending_fsyncs \ + Innodb_data_pending_reads Innodb_data_pending_writes \ + Innodb_os_log_pending_fsyncs Innodb_os_log_pending_writes \ + Innodb_page_size Innodb_row_lock_current_waits Innodb_row_lock_time_avg \ + Innodb_row_lock_time_max Key_blocks_not_flushed Key_blocks_unused \ + Key_blocks_used Last_query_cost Max_used_connections Ndb_cluster_node_id \ + Ndb_config_from_host Ndb_config_from_port Ndb_number_of_data_nodes \ + Not_flushed_delayed_rows Open_files Open_streams Open_tables \ + Prepared_stmt_count Qcache_free_blocks Qcache_free_memory \ + Qcache_queries_in_cache Qcache_total_blocks Rpl_status \ + Slave_open_temp_tables Slave_running Ssl_cipher Ssl_cipher_list \ + Ssl_ctx_verify_depth Ssl_ctx_verify_mode Ssl_default_timeout \ + Ssl_session_cache_mode Ssl_session_cache_size Ssl_verify_depth \ + Ssl_verify_mode Ssl_version Tc_log_max_pages_used Tc_log_page_size \ + Threads_cached Threads_connected Threads_running \ + Uptime_since_flush_status; + do + if [ -z "${noncounters_pattern}" ]; then + noncounters_pattern="${var}" + else + noncounters_pattern="${noncounters_pattern}\|${var}" + fi + done + echo $noncounters_pattern +} + +report_mysql_summary () { + local dir="$1" + local prefix="${2:-percona-toolkit}" + + # Field width for name_val + local NAME_VAL_LEN=25 + + # ######################################################################## + # Header for the whole thing, table of discovered instances + # ######################################################################## + + section Percona_Toolkit_MySQL_Summary_Report + name_val "System time" "`date -u +'%F %T UTC'` (local TZ: `date +'%Z %z'`)" + section Instances + parse_mysqld_instances "$dir/${prefix}-mysqld-instances" + + section MySQL_Executable + name_val "Has symbols" "$( get_var "pt-summary-internal-symbols" "$dir/${prefix}-mysql-variables" )" + + # ######################################################################## + # General date, hostname, etc + # ######################################################################## + local user="$(get_var "pt-summary-internal-user" "$dir/${prefix}-mysql-variables")" + local port="$(get_var port "$dir/${prefix}-mysql-variables")" + local now="$(get_var "pt-summary-internal-NOW" "$dir/${prefix}-mysql-variables")" + section "Report_On_Port_${port}" + name_val User "${user}" + name_val Time "${now} ($(get_mysql_timezone "$dir/${prefix}-mysql-variables"))" + name_val Hostname "$(get_var hostname "$dir/${prefix}-mysql-variables")" + get_mysql_version "$dir/${prefix}-mysql-variables" + + local uptime="$(get_var Uptime "$dir/${prefix}-mysql-status")" + local current_time="$(get_var "pt-summary-internal-current_time" "$dir/${prefix}-mysql-status")" + name_val Started "$(get_mysql_uptime "${uptime}" "${current_time}")" + + local num_dbs="$(grep -c . "$dir/${prefix}-mysql-databases")" + name_val Databases "${num_dbs}" + name_val Datadir "$(get_var datadir "$dir/${prefix}-mysql-variables")" + + local fuzz_procs=$(fuzz $(get_var Threads_connected "$dir/${prefix}-mysql-status")) + local fuzz_procr=$(fuzz $(get_var Threads_running "$dir/${prefix}-mysql-status")) + name_val Processes "${fuzz_procs} connected, ${fuzz_procr} running" + + local slave="" + if [ -s "$dir/${prefix}-mysql-slave" ]; then slave=""; else slave="not "; fi + local slavecount=$(grep -c 'Binlog Dump' "$dir/${prefix}-mysql-processlist") + name_val Replication "Is ${slave}a slave, has ${slavecount} slaves connected" + + + # TODO move this into a section with other files: error log, slow log and + # show the sizes + local pid_file="$(get_var pid_file "$dir/${prefix}-mysql-variables")" + local PID_EXISTS="" + if [ -e "${pid_file}" ]; then + PID_EXISTS="(exists)" + else + PID_EXISTS="(does not exist)" + fi + name_val Pidfile "${pid_file} ${PID_EXISTS}" + + # ######################################################################## + # Processlist, sliced several different ways + # ######################################################################## + section Processlist + summarize_processlist "$dir/${prefix}-mysql-processlist" + + # ######################################################################## + # Queries and query plans + # ######################################################################## + section "Status_Counters_(Wait_${OPT_SLEEP}_Seconds)" + # Wait for the child that was forked during collection. + wait + local noncounters_pattern="$(noncounters_pattern)" + format_status_variables "$dir/${prefix}-mysql-status-defer" | grep -v "${noncounters_pattern}" + + # ######################################################################## + # Table cache + # ######################################################################## + section Table_cache + local open_tables=$(get_var Open_tables "$dir/${prefix}-mysql-status") + local table_cache=$(get_table_cache "$dir/${prefix}-mysql-status") + name_val Size $table_cache + name_val Usage "$(fuzzy_pct ${open_tables} ${table_cache})" + + # ######################################################################## + # Percona Server features + # ######################################################################## + section Key_Percona_Server_features + section_percona_server_features "$dir/${prefix}-mysql-variables" + + # ######################################################################## + # Plugins + # ######################################################################## + section Plugins + name_val "InnoDB compression" "$(get_plugin_status "$dir/${prefix}-mysql-plugins" "INNODB_CMP")" + + # ######################################################################## + # Query cache + # ######################################################################## + if [ "$(get_var have_query_cache "$dir/${prefix}-mysql-variables")" ]; then + section Query_cache + local query_cache_size=$(get_var query_cache_size "$dir/${prefix}-mysql-variables") + local used=$(( ${query_cache_size} - $(get_var Qcache_free_memory "$dir/${prefix}-mysql-status") )) + local hrat=$(fuzzy_pct $(get_var Qcache_hits "$dir/${prefix}-mysql-status") $(get_var Qcache_inserts "$dir/${prefix}-mysql-status")) + name_val query_cache_type $(get_var query_cache_type "$dir/${prefix}-mysql-variables") + name_val Size "$(shorten ${query_cache_size} 1)" + name_val Usage "$(fuzzy_pct ${used} ${query_cache_size})" + name_val HitToInsertRatio "${hrat}" + fi + + local semisync_enabled_master="$(get_var rpl_semi_sync_master_enabled "$dir/${prefix}-mysql-variables")" + if [ -n "${semisync_enabled_master}" ]; then + section Semisynchronous_Replication + if [ "$semisync_enabled_master" = "OFF" -o "$semisync_enabled_master" = "0" -o -z "$semisync_enabled_master" ]; then + name_val "Master" "Disabled" + else + _semi_sync_stats_for "master" "$dir/${prefix}-mysql-variables" + fi + local semisync_enabled_slave="$(get_var rpl_semi_sync_slave_enabled "$dir/${prefix}-mysql-variables")" + if [ "$semisync_enabled_slave" = "OFF" -o "$semisync_enabled_slave" = "0" -o -z "$semisync_enabled_slave" ]; then + name_val "Slave" "Disabled" + else + _semi_sync_stats_for "slave" "$dir/${prefix}-mysql-variables" + fi + fi + + # ######################################################################## + # Schema, databases, data type, other analysis. + # ######################################################################## + section Schema + # Assume "no" if stdin or stdout is not a terminal, so this can be run and + # put into a file, or piped into a pager, or something else like that. + local reply="n" + # But dump no matter what if they passed in something through --dump-schemas + if [ -n "${OPT_DUMP_SCHEMAS}" ]; then + reply="y" + elif [ -t 0 -a -t 1 ]; then + echo -n "Would you like to mysqldump -d the schema and analyze it? y/n " + read reply + reply=${reply:-n} + fi + if echo "${reply:-n}" | grep -i '^y' > /dev/null ; then + if [ -z "${OPT_DUMP_SCHEMAS}" ]; then + # If --dump-schemas wasn't used, ask what they want + + # Find out which databases to dump + echo "There are ${num_dbs} databases. Would you like to dump all, or just one?" + echo -n "Type the name of the database, or press Enter to dump all of them. " + local dbtodump="" + read dbtodump + local trg_arg="$( get_mysqldump_args "$dir/${prefix}-mysql-variables" )" + get_mysqldump_for "$dir/${prefix}-mysqldump" "${trg_arg}" "${dbtodump}" + fi + + # Test the result by checking the file, not by the exit status, because we + # might get partway through and then die, and the info is worth analyzing + # anyway. + + if [ -e "$dir/${prefix}-mysqldump" -a -s "$dir/${prefix}-mysqldump" ] \ + && grep 'CREATE TABLE' "$dir/${prefix}-mysqldump" >/dev/null 2>&1; then + format_overall_db_stats "$dir/${prefix}-mysqldump" + else + warn "Skipping schema analysis due to apparent error in dump file" + fi + else + echo "Skipping schema analysis" + fi + + # ######################################################################## + # Noteworthy Technologies + # ######################################################################## + section Noteworthy_Technologies + if [ -s "$dir/${prefix}-mysqldump" ]; then + if grep FULLTEXT "$dir/${prefix}-mysqldump" > /dev/null; then + name_val "Full Text Indexing" Yes + else + name_val "Full Text Indexing" No + fi + if grep 'GEOMETRY\|POINT\|LINESTRING\|POLYGON' "$dir/${prefix}-mysqldump" > /dev/null; then + name_val "Geospatial Types" Yes + else + name_val "Geospatial Types" No + fi + if grep 'FOREIGN KEY' "$dir/${prefix}-mysqldump" > /dev/null; then + name_val "Foreign Keys" Yes + else + name_val "Foreign Keys" No + fi + if grep 'PARTITION BY' "$dir/${prefix}-mysqldump" > /dev/null; then + name_val "Partitioning" Yes + else + name_val "Partitioning" No + fi + fi + if [ "$(get_var Ssl_accepts "$dir/${prefix}-mysql-status")" -gt 0 ]; then + name_val "SSL" Yes + else + name_val "SSL" No + fi + if [ "$(get_var Com_lock_tables "$dir/${prefix}-mysql-status")" -gt 0 ]; then + name_val "Explicit LOCK TABLES" Yes + else + name_val "Explicit LOCK TABLES" No + fi + if [ "$(get_var Delayed_writes "$dir/${prefix}-mysql-status")" -gt 0 ]; then + name_val "Delayed Insert" Yes + else + name_val "Delayed Insert" No + fi + if [ "$(get_var Com_xa_start "$dir/${prefix}-mysql-status")" -gt 0 ]; then + name_val "XA Transactions" Yes + else + name_val "XA Transactions" No + fi + if [ "$(get_var Ndb_cluster_node_id "$dir/${prefix}-mysql-status")" -gt 0 ]; then + name_val "NDB Cluster" Yes + else + name_val "NDB Cluster" No + fi + local prep=$(( $(get_var Com_stmt_prepare "$dir/${prefix}-mysql-status") + $(get_var Com_prepare_sql "$dir/${prefix}-mysql-status") )) + if [ "${prep}" -gt 0 ]; then + name_val "Prepared Statements" Yes + else + name_val "Prepared Statements" No + fi + local prep_count="$(get_var Prepared_stmt_count "$dir/${prefix}-mysql-status")" + if [ "${prep_count}" ]; then + name_val "Prepared statement count" "${prep_count}" + fi + + # ######################################################################## + # InnoDB + # ######################################################################## + section InnoDB + local have_innodb=$(get_var have_innodb "$dir/${prefix}-mysql-variables") + if [ "${have_innodb}" = "YES" ]; then + section_innodb "$dir/${prefix}-mysql-variables" "$dir/${prefix}-mysql-status" + + if [ -s "$dir/${prefix}-innodb-status" ]; then + format_innodb_status "$dir/${prefix}-innodb-status" + fi + fi + + # ######################################################################## + # MyISAM + # ######################################################################## + section MyISAM + section_myisam "$dir/${prefix}-mysql-variables" "$dir/${prefix}-mysql-status" + + # ######################################################################## + # Users & Security + # ######################################################################## + section Security + local users="$( format_users "$dir/${prefix}-mysql-users" )" + # XXX TODO Give it a different formatting? + name_val Users "${users}" + name_val "Old Passwords" "$(get_var old_passwords "$dir/${prefix}-mysql-variables")" + + # ######################################################################## + # Binary Logging + # ######################################################################## + section Binary_Logging + + if [ -s "$dir/${prefix}-mysql-master-logs" ] \ + || [ -s "$dir/${prefix}-mysql-master-status" ]; then + summarize_binlogs "$dir/${prefix}-mysql-master-logs" + local format="$(get_var binlog_format "$dir/${prefix}-mysql-variables")" + name_val binlog_format "${format:-STATEMENT}" + name_val expire_logs_days $(get_var expire_logs_days "$dir/${prefix}-mysql-variables") + name_val sync_binlog $(get_var sync_binlog "$dir/${prefix}-mysql-variables") + name_val server_id $(get_var server_id "$dir/${prefix}-mysql-variables") + format_binlog_filters "$dir/${prefix}-mysql-master-status" + fi + +# Replication: seconds behind, running, filters, skip_slave_start, skip_errors, +# read_only, temp tables open, slave_net_timeout, slave_exec_mode + + # ######################################################################## + # Interesting things that you just ought to know about. + # ######################################################################## + section Noteworthy_Variables + section_noteworthy_variables "$dir/${prefix}-mysql-variables" + + # ######################################################################## + # If there is a my.cnf in a standard location, see if we can pretty-print it. + # ######################################################################## + section Configuration_File + local cnf_file="$(get_var "pt-summary-internal-Config_File" "$dir/${prefix}-mysql-variables")" + if [ -n "${cnf_file}" ]; then + name_val "Config File" "${cnf_file}" + pretty_print_cnf_file "${cnf_file}" + else + name_val "Config File" "Cannot autodetect or find, giving up" + fi + + # Make sure that we signal the end of the tool's output. + section The_End +} + +# ########################################################################### +# End report_mysql_info package +# ########################################################################### diff --git a/t/lib/bash/collect_mysql_info.t b/t/lib/bash/collect_mysql_info.t new file mode 120000 index 00000000..edb04c13 --- /dev/null +++ b/t/lib/bash/collect_mysql_info.t @@ -0,0 +1 @@ +../../../util/test-bash-functions \ No newline at end of file diff --git a/t/lib/bash/report_formatting.sh b/t/lib/bash/report_formatting.sh index 1f55167e..a61edd3e 100644 --- a/t/lib/bash/report_formatting.sh +++ b/t/lib/bash/report_formatting.sh @@ -85,6 +85,11 @@ is \ "A | B" \ "name_val and NAME_VAL_LEN work" +# fuzz + +is $(fuzz 11) "10" "fuzz 11" +is $(fuzz 49) "50" "fuzz 49" + # ########################################################################### # Done # ########################################################################### diff --git a/t/lib/bash/report_formatting.t b/t/lib/bash/report_formatting.t new file mode 120000 index 00000000..edb04c13 --- /dev/null +++ b/t/lib/bash/report_formatting.t @@ -0,0 +1 @@ +../../../util/test-bash-functions \ No newline at end of file diff --git a/t/lib/bash/report_mysql_info.sh b/t/lib/bash/report_mysql_info.sh new file mode 100644 index 00000000..267606a3 --- /dev/null +++ b/t/lib/bash/report_mysql_info.sh @@ -0,0 +1,711 @@ +#!/usr/bin/env bash + +plan 29 + +. "$LIB_DIR/alt_cmds.sh" +. "$LIB_DIR/log_warn_die.sh" +. "$LIB_DIR/summary_common.sh" +. "$LIB_DIR/report_formatting.sh" +. "$LIB_DIR/report_mysql_info.sh" + +TMPDIR="$TEST_TMPDIR" +PATH="$PATH:$PERCONA_TOOLKIT_SANDBOX/bin" +TOOL="pt-mysql-summary" + +samples="$PERCONA_TOOLKIT_BRANCH/t/pt-mysql-summary/samples" +NAME_VAL_LEN=20 +# ########################################################################### +# table_cache +# ########################################################################### + +rm $TMPDIR/table_cache_tests 2>/dev/null +touch $TMPDIR/table_cache_tests + +is \ + $(get_table_cache "$TMPDIR/table_cache_tests") \ + 0 \ + "0 if neither table_cache nor table_open_cache are present" + +cat < $TMPDIR/table_cache_tests +table_cache 5 +table_open_cache 4 +EOF + +is \ + $(get_table_cache "$TMPDIR/table_cache_tests") \ + 4 \ + "If there's a table_open_cache present, uses that" + +cat < $TMPDIR/table_cache_tests +table_cache 5 +EOF + +is \ + $(get_table_cache "$TMPDIR/table_cache_tests") \ + 5 \ + "Otherwise, defaults to table_cache" + +# ########################################################################### +# summarize_processlist +# ########################################################################### + +cat < $TMPDIR/expected + + Command COUNT(*) Working SUM(Time) MAX(Time) + ------------------------------ -------- ------- --------- --------- + Binlog Dump 1 1 9000000 9000000 + Connect 2 2 6000000 5000000 + Query 2 2 0 0 + Sleep 150 0 150000 20000 + + User COUNT(*) Working SUM(Time) MAX(Time) + ------------------------------ -------- ------- --------- --------- + acjcxx 4 0 0 0 + aecac 1 0 0 0 + babeecc 20 0 0 0 + centous 2 0 0 0 + crcpcpc 2 0 0 0 + crgcp4c 3 0 0 0 + eanecj 30 1 0 0 + ebace 10 0 0 0 + etace 80 0 0 0 + goate 8 0 0 0 + qjveec 1 0 0 0 + repl 1 1 9000000 9000000 + root 1 1 0 0 + system user 2 2 6000000 5000000 + + Host COUNT(*) Working SUM(Time) MAX(Time) + ------------------------------ -------- ------- --------- --------- + 10.14.82.196 6 0 0 0 + 10.14.82.202 20 0 0 0 + 10.17.85.100 9 0 0 0 + 10.17.85.74 1 1 9000000 9000000 + 10.17.85.86 35 0 0 0 + 10.17.85.88 5 0 0 0 + 10.17.85.90 10 0 0 0 + 10.36.34.66 35 1 0 0 + 2 2 6000000 5000000 + localhost 1 1 0 0 + someserver.woozle.com11 1 0 0 0 + someserver.woozle.com14 1 0 0 0 + someserver.woozle.com 40 0 0 0 + + db COUNT(*) Working SUM(Time) MAX(Time) + ------------------------------ -------- ------- --------- --------- + aetecjc 175 1 0 0 + NULL 4 4 15000000 9000000 + + State COUNT(*) Working SUM(Time) MAX(Time) + ------------------------------ -------- ------- --------- --------- + 150 0 0 0 + Has read all relay log; waitin 1 1 300000 300000 + Has sent all binlog to slave; 1 1 9000000 9000000 + NULL 2 2 0 0 + Waiting for master to send eve 1 1 5000000 5000000 + +EOF + +summarize_processlist "$samples/processlist-001.txt" > "$TMPDIR/got" +no_diff "$TMPDIR/got" "$TMPDIR/expected" "summarize_processlist" + + +# ########################################################################### +# summarize_binlogs +# ########################################################################### +NAME_VAL_LEN=25 +cat < "$TMPDIR/expected" + Binlogs | 20 + Zero-Sized | 3 + Total Size | 6.5G +EOF + +summarize_binlogs "$samples/mysql-master-logs-001.txt" > "$TMPDIR/got" +no_diff "$TMPDIR/expected" "$TMPDIR/got" "summarize_binlogs" + +# ########################################################################### +# Reporting semisync replication +# ########################################################################### + +cat < "$TMPDIR/expected" + master semisync status | 0 + master trace level | 32, net wait (more information about network waits) +master timeout in milliseconds | 10000 + master waits for slaves | ON + master clients | 0 + master net_avg_wait_time | 0 + master net_wait_time | 0 + master net_waits | 0 + master no_times | 0 + master no_tx | 0 + master timefunc_failures | 0 + master tx_avg_wait_time | 0 + master tx_wait_time | 0 + master tx_waits | 0 +master wait_pos_backtraverse | 0 + master wait_sessions | 0 + master yes_tx | 0 +EOF + +_semi_sync_stats_for "master" "$samples/mysql-variables-with-semisync.txt" > "$TMPDIR/got" +no_diff "$TMPDIR/expected" "$TMPDIR/got" "semisync replication" + +# ########################################################################### +# pretty_print_cnf_file +# ########################################################################### + +cat < $TMPDIR/expected + +[mysqld] +datadir = /mnt/data/mysql +socket = /mnt/data/mysql/mysql.sock +old_passwords = 1 +ssl-key = /opt/mysql.pdns/.cert/server-key.pem +ssl-cert = /opt/mysql.pdns/.cert/server-cert.pem +ssl-ca = /opt/mysql.pdns/.cert/ca-cert.pem +innodb_buffer_pool_size = 16M +innodb_flush_method = O_DIRECT +innodb_log_file_size = 64M +innodb_log_buffer_size = 1M +innodb_flush_log_at_trx_commit = 2 +innodb_file_per_table = 1 +ssl = 1 +server-id = 1 +log-bin = sl1-bin + +[mysql.server] +user = mysql +basedir = /mnt/data + +[mysqld_safe] +log-error = /var/log/mysqld.log +pid-file = /var/run/mysqld/mysqld.pid + +[mysql] + +[xtrabackup] +target-dir = /data/backup +EOF + +pretty_print_cnf_file "$samples/my.cnf-001.txt" > "$TMPDIR/got" +no_diff "$TMPDIR/got" "$TMPDIR/expected" "pretty_print_cnf_file" + + +# TODO BUG NUMBER# +cp "$samples/my.cnf-001.txt" "$TMPDIR/test_pretty_print_cnf_file" +echo "some_var_yadda=0" >> "$TMPDIR/test_pretty_print_cnf_file" +echo "some_var_yadda = 0" >> "$TMPDIR/expected" + +pretty_print_cnf_file "$TMPDIR/test_pretty_print_cnf_file" > "$TMPDIR/got" +no_diff "$TMPDIR/got" "$TMPDIR/expected" "pretty_print_cnf_file, bug XXXXXX" + + +# ########################################################################### +# plugin_status +# ########################################################################### + +cat < $TMPDIR/plugins +binlog ACTIVE STORAGE ENGINE NULL GPL +partition ACTIVE STORAGE ENGINE NULL GPL +ARCHIVE ACTIVE STORAGE ENGINE NULL GPL +BLACKHOLE ACTIVE STORAGE ENGINE NULL GPL +CSV ACTIVE STORAGE ENGINE NULL GPL +FEDERATED DISABLED STORAGE ENGINE NULL GPL +MEMORY ACTIVE STORAGE ENGINE NULL GPL +InnoDB ACTIVE STORAGE ENGINE NULL GPL +MyISAM ACTIVE STORAGE ENGINE NULL GPL +MRG_MYISAM ACTIVE STORAGE ENGINE NULL GPL +EOF + +is \ + "$(get_plugin_status $TMPDIR/plugins InnoDB )" \ + "ACTIVE" \ + "Sanity test, finds InnoDB as active" + +is \ + "$(get_plugin_status $TMPDIR/plugins some_plugin_that_doesnt_exist )" \ + "Not found" \ + "Doesn't find a nonexistent plugin" + +echo "INNODB_CMP ACTIVE" >> $TMPDIR/plugins +is \ + "$(get_plugin_status $TMPDIR/plugins "INNODB_CMP" )" \ + "ACTIVE" + +cat < $TMPDIR/plugins +binlog ACTIVE STORAGE ENGINE NULL GPL +mysql_native_password ACTIVE AUTHENTICATION NULL GPL +mysql_old_password ACTIVE AUTHENTICATION NULL GPL +MRG_MYISAM ACTIVE STORAGE ENGINE NULL GPL +MyISAM ACTIVE STORAGE ENGINE NULL GPL +CSV ACTIVE STORAGE ENGINE NULL GPL +MEMORY ACTIVE STORAGE ENGINE NULL GPL +FEDERATED DISABLED STORAGE ENGINE NULL GPL +ARCHIVE ACTIVE STORAGE ENGINE NULL GPL +BLACKHOLE ACTIVE STORAGE ENGINE NULL GPL +InnoDB ACTIVE STORAGE ENGINE NULL GPL +INNODB_TRX ACTIVE INFORMATION SCHEMA NULL GPL +INNODB_LOCKS ACTIVE INFORMATION SCHEMA NULL GPL +INNODB_LOCK_WAITS ACTIVE INFORMATION SCHEMA NULL GPL +INNODB_CMP ACTIVE INFORMATION SCHEMA NULL GPL +INNODB_CMP_RESET ACTIVE INFORMATION SCHEMA NULL GPL +INNODB_CMPMEM ACTIVE INFORMATION SCHEMA NULL GPL +INNODB_CMPMEM_RESET ACTIVE INFORMATION SCHEMA NULL GPL +PERFORMANCE_SCHEMA ACTIVE STORAGE ENGINE NULL GPL +partition ACTIVE STORAGE ENGINE NULL GPL +EOF + +is \ + "$(get_plugin_status $TMPDIR/plugins "INNODB_CMP" )" \ + "ACTIVE" \ + "Doesn't get confused by multiple plugins with the same prefix" + +# ########################################################################### +# parse_mysqld_instances +# ########################################################################### + +_NO_FALSE_NEGATIVES=1 + +cat < $TMPDIR/expected + Port Data Directory Nice OOM Value Socket + ===== ========================== ==== ========= ====== + 3306 /var/lib/mysql ? ? /var/run/mysqld/mysqld.sock + 12345 /tmp/12345/data ? ? /tmp/12345/mysql_sandbox12345.sock + 12346 /tmp/12346/data ? ? /tmp/12346/mysql_sandbox12346.sock +EOF +parse_mysqld_instances "$samples/ps-mysqld-001.txt" > "$TMPDIR/got" +no_diff "$TMPDIR/got" "$TMPDIR/expected" "ps-mysqld-001.txt" + +cat < "$TMPDIR/expected" + Port Data Directory Nice OOM Value Socket + ===== ========================== ==== ========= ====== + /var/lib/mysql ? ? /var/lib/mysql/mysql.sock +EOF +parse_mysqld_instances "$samples/ps-mysqld-002.txt" > "$TMPDIR/got" +no_diff "$TMPDIR/got" "$TMPDIR/expected" "ps-mysqld-002.txt" + +#parse_mysqld_instances +cat < $TMPDIR/expected + Port Data Directory Nice OOM Value Socket + ===== ========================== ==== ========= ====== + 3306 /mnt/data-store/mysql/data ? ? /tmp/mysql.sock +EOF +parse_mysqld_instances "$samples/ps-mysqld-003.txt" > "$TMPDIR/got" +no_diff "$TMPDIR/got" "$TMPDIR/expected" "ps-mysqld-003.txt" + +cat < "$TMPDIR/expected" + Port Data Directory Nice OOM Value Socket + ===== ========================== ==== ========= ====== + /var/db/mysql ? ? +EOF + +cat < "$TMPDIR/in" +mysql 767 0.0 0.9 3492 1100 v0 I 3:01PM 0:00.07 /bin/sh /usr/local/bin/mysqld_safe --defaults-extra-file=/var/db/mysql/my.cnf --user=mysql --datadir=/var/db/mysql --pid-file=/var/db/mysql/freebsd.hsd1.va.comcast.net..pid +mysql 818 0.0 17.4 45292 20584 v0 I 3:01PM 0:02.28 /usr/local/libexec/mysqld --defaults-extra-file=/var/db/mysql/my.cnf --basedir=/usr/local --datadir=/var/db/mysql --user=mysql --log-error=/var/db/mysql/freebsd.hsd1.va.comcast.net..err --pid-file=/var/db/mysql/freebsd.hsd1.va.comcast.net..pid +EOF +parse_mysqld_instances "$TMPDIR/in" > "$TMPDIR/got" +no_diff "$TMPDIR/got" "$TMPDIR/expected" + +# ########################################################################### +# get_mysql_* +# ########################################################################### +NAME_VAL_LEN=20 + +cp $samples/mysql-variables-001.txt $TMPDIR/percona-toolkit-mysql-variables +is \ + $(get_mysql_timezone "$TMPDIR/percona-toolkit-mysql-variables") \ + "EDT" \ + "get_mysql_timezone" + +cat < $TMPDIR/expected +2010-05-27 11:38 (up 0+02:08:52) +EOF +cp $samples/mysql-status-001.txt $TMPDIR/percona-toolkit-mysql-status +uptime="$(get_var Uptime $TMPDIR/percona-toolkit-mysql-status)" +current_time="$(echo -e "2010-05-27 11:38\n")" +get_mysql_uptime "${uptime}" "${current_time}" > $TMPDIR/got +no_diff "$TMPDIR/got" "$TMPDIR/expected" "get_mysql_uptime" + +cat < $TMPDIR/expected + Version | 5.0.51a-24+lenny2 (Debian) + Built On | debian-linux-gnu i486 +EOF +cp "$samples/mysql-variables-001.txt" "$TMPDIR/percona-toolkit-mysql-variables" +get_mysql_version "$TMPDIR/percona-toolkit-mysql-variables" > "$TMPDIR/got" +no_diff "$TMPDIR/got" "$TMPDIR/expected" "get_mysql_version" + +# ########################################################################### +# format_status_variables +# ########################################################################### + +cat < "$TMPDIR/expected" +Variable Per day Per second 5 secs +Bytes_received 8000000 100 +Bytes_sent 35000000 400 +Com_admin_commands 20 +Com_change_db 1000 +Com_delete 8000 +Com_insert 8000 +Com_lock_tables 200 +Com_replace 1250 +Com_select 22500 +Com_set_option 22500 +Com_show_binlogs 10 +Com_show_create_db 400 +Com_show_create_table 7000 +Com_show_databases 125 +Com_show_fields 7000 +Com_show_innodb_status 300 +Com_show_open_tables 10 +Com_show_processlist 300 +Com_show_slave_status 300 +Com_show_status 350 +Com_show_storage_engines 10 +Com_show_tables 400 +Com_show_triggers 7000 +Com_show_variables 450 +Com_truncate 300 +Com_unlock_tables 250 +Com_update 900 +Connections 2500 +Created_tmp_disk_tables 15000 +Created_tmp_files 60 +Created_tmp_tables 22500 +Flush_commands 10 +Handler_delete 8000 +Handler_read_first 2250 +Handler_read_key 30000 +Handler_read_next 15000 +Handler_read_rnd 9000 +Handler_read_rnd_next 300000 3 +Handler_update 17500 +Handler_write 250000 2 +Innodb_buffer_pool_pages_data 225 +Innodb_buffer_pool_pages_free 5000 +Innodb_buffer_pool_pages_total 6000 +Innodb_buffer_pool_read_ahead_rnd 10 +Innodb_buffer_pool_read_requests 2250 +Innodb_buffer_pool_reads 150 +Innodb_data_fsyncs 35 +Innodb_data_read 30000000 350 +Innodb_data_reads 300 +Innodb_data_writes 35 +Innodb_data_written 17500 +Innodb_log_writes 10 +Innodb_os_log_fsyncs 35 +Innodb_os_log_written 6000 +Innodb_page_size 175000 2 +Innodb_pages_read 225 +Key_blocks_unused 150000 1 +Key_blocks_used 175 +Key_read_requests 100000 1 +Key_reads 600 +Key_write_requests 70000 +Key_writes 17500 +Max_used_connections 45 +Open_files 1500 +Open_tables 700 +Opened_tables 15000 +Qcache_free_blocks 80 +Qcache_free_memory 175000000 2250 +Qcache_hits 8000 +Qcache_inserts 20000 +Qcache_not_cached 10000 +Qcache_queries_in_cache 225 +Qcache_total_blocks 600 +Questions 100000 1 +Select_scan 25000 +Sort_rows 8000 +Sort_scan 300 +Table_locks_immediate 50000 17500 +Table_locks_waited 10 1 +Threads_cached 35 +Threads_connected 10 +Threads_created 45 +Threads_running 10 +Uptime 90000 1 1 +Uptime_since_flush_status 90000 1 +EOF + +join $samples/mysql-status-00{1,2}.txt > "$TMPDIR/in" +format_status_variables "$TMPDIR/in" > "$TMPDIR/got" +no_diff "$TMPDIR/got" "$TMPDIR/expected" "format_status_variables" + +# ########################################################################### +# format_overall_db_stats +# ########################################################################### + +cat < $TMPDIR/expected + + Database Tables Views SPs Trigs Funcs FKs Partn + mysql 17 + sakila 17 7 3 6 3 22 1 + + Database MyISAM InnoDB + mysql 17 + sakila 2 15 + + Database BTREE FULLTEXT + mysql 24 + sakila 63 1 + + c t s e t s i t b l b v d y d m + h i e n i m n e l o i a a e e e + a m t u n a t x o n g r t a c d + r e m y l t b g i c e r i i + s i l b n h t m u + t n i l t a i a m + a t n o r m l i + m t b e n + p t + Database === === === === === === === === === === === === === === === === + mysql 38 5 5 69 2 3 16 2 4 1 2 + sakila 1 15 1 3 19 26 3 4 1 45 4 1 7 2 + +EOF +format_overall_db_stats $samples/mysql-schema-001.txt > $TMPDIR/got +no_diff $TMPDIR/got $TMPDIR/expected + + +cat < $TMPDIR/expected + + Database Tables Views SPs Trigs Funcs FKs Partn + {chosen} 1 + + Database InnoDB + {chosen} 1 + + Database BTREE + {chosen} 2 + + t v + i a + n r + y c + i h + n a + t r + Database === === + {chosen} 1 1 + +EOF +format_overall_db_stats $samples/mysql-schema-002.txt > $TMPDIR/got +no_diff $TMPDIR/got $TMPDIR/expected + +# ########################################################################### +# format_innodb_status +# ########################################################################### + +# ############################################################################ +TEST_NAME="innodb-status.001.txt" +# ############################################################################ +cat < $TMPDIR/expected + Checkpoint Age | 619k + InnoDB Queue | 0 queries inside InnoDB, 0 queries in queue + Oldest Transaction | 3 Seconds + History List Len | 255 + Read Views | 23 + Undo Log Entries | 0 transactions, 0 total undo, 0 max undo + Pending I/O Reads | 14 buf pool reads, 6 normal AIO, 0 ibuf AIO, 23 preads + Pending I/O Writes | 63 buf pool (63 LRU, 0 flush list, 0 page); 0 AIO, 0 sync, 0 log IO (1 log, 0 chkp); 0 pwrites + Pending I/O Flushes | 0 buf pool, 1 log + Transaction States | 1xACTIVE +Semaphore Waits + 69 btr/btr0cur.c line 457 + 47 btr/btr0cur.c line 523 + 17 trx/trx0trx.c line 1621 + 12 row/row0sel.c line 3549 + 4 lock/lock0lock.c line 4944 + 3 lock/lock0lock.c line 5316 + 2 lock/lock0lock.c line 3224 + 2 btr/btr0sea.c line 1032 + 1 trx/trx0trx.c line 738 + 1 row/row0sel.c line 4574 + 1 lock/lock0lock.c line 5163 + 1 lock/lock0lock.c line 3249 + 1 ./include/btr0btr.ic line 53 + 1 fsp/fsp0fsp.c line 3395 + 1 btr/btr0cur.c line 672 + 1 btr/btr0cur.c line 450 +Semaphore Holders + 66 thread id 139960165583184 + 45 thread id 139960567171408 + 4 thread id 139960404199760 + 1 thread id 139961215367504 + 1 thread id 139960969292112 + 1 thread id 139960676096336 +Mutexes/Locks Waited For + 65 lock on RW-latch at 0x905d33d0 '&new_index->lock' + 45 lock on RW-latch at 0x7f4bedbf8810 '&block->lock' + 30 Mutex at 0xf89ab0 '&kernel_mutex' + 15 lock on RW-latch at 0x90075530 '&btr_search_latch' + 4 lock on RW-latch at 0x90a42ca0 '&new_index->lock' + 1 lock on RW-latch at 0x90fe1c80 '&new_index->lock' + 1 lock on RW-latch at 0x90078f10 '&space->latch' + 1 lock on RW-latch at 0x7f4c0d3abba8 '&block->lock' + 1 lock on RW-latch at 0x7f4bfc558040 '&block->lock' + 1 lock on RW-latch at 0x7f4bd0a8c8d0 '&block->lock' +EOF + +format_innodb_status $samples/innodb-status.001.txt > $TMPDIR/got +no_diff $TMPDIR/got $TMPDIR/expected + +# ############################################################################ +TEST_NAME="innodb-status.002.txt" +# ############################################################################ +cat <<'EOF' > $TMPDIR/expected + Checkpoint Age | 348M + InnoDB Queue | 0 queries inside InnoDB, 0 queries in queue + Oldest Transaction | 4 Seconds + History List Len | 426 + Read Views | 583 + Undo Log Entries | 71 transactions, 247 total undo, 46 max undo + Pending I/O Reads | 0 buf pool reads, 0 normal AIO, 0 ibuf AIO, 0 preads + Pending I/O Writes | 0 buf pool (0 LRU, 0 flush list, 0 page); 0 AIO, 0 sync, 0 log IO (0 log, 0 chkp); 0 pwrites + Pending I/O Flushes | 0 buf pool, 0 log + Transaction States | 1xACTIVE, 70xACTIVE (PREPARED) +Tables Locked + 62 `citydb`.`player_buildings` + 46 `citydb`.`players` + 22 `citydb`.`city_grid` + 17 `citydb`.`player_stats` + 6 `citydb`.`player_contracts` + 1 `citydb`.`player_achievements` +Semaphore Waits + 23 trx/trx0undo.c line 1796 + 10 trx/trx0trx.c line 1888 + 8 trx/trx0trx.c line 1033 + 7 trx/trx0trx.c line 738 + 1 lock/lock0lock.c line 3770 + 1 ./include/log0log.ic line 322 +Mutexes/Locks Waited For + 33 Mutex at 0x2abf68b76a18 '&rseg->mutex' + 16 Mutex at 0x48ace40 '&kernel_mutex' + 1 Mutex at 0x2abf68b6c0d0 '&log_sys->mutex' +EOF + +format_innodb_status $samples/innodb-status.002.txt > $TMPDIR/got +no_diff $TMPDIR/got $TMPDIR/expected + +# ############################################################################ +TEST_NAME="innodb-status.003.txt" +# ############################################################################ +cat <<'EOF' > $TMPDIR/expected + Checkpoint Age | 0 + InnoDB Queue | 0 queries inside InnoDB, 0 queries in queue + Oldest Transaction | 35 Seconds + History List Len | 11 + Read Views | 1 + Undo Log Entries | 0 transactions, 0 total undo, 0 max undo + Pending I/O Reads | 0 buf pool reads, 0 normal AIO, 0 ibuf AIO, 0 preads + Pending I/O Writes | 0 buf pool (0 LRU, 0 flush list, 0 page); 0 AIO, 0 sync, 0 log IO (0 log, 0 chkp); 0 pwrites + Pending I/O Flushes | 0 buf pool, 0 log + Transaction States | 1xACTIVE, 1xnot started +Tables Locked + 1 `test`.`t` +EOF + +format_innodb_status $samples/innodb-status.003.txt > $TMPDIR/got +no_diff $TMPDIR/got $TMPDIR/expected + +# ############################################################################ +TEST_NAME="innodb-status.004.txt" +# ############################################################################ +cat <<'EOF' > $TMPDIR/expected + Checkpoint Age | 93M + InnoDB Queue | 9 queries inside InnoDB, 0 queries in queue + Oldest Transaction | 263 Seconds + History List Len | 1282 + Read Views | 10 + Undo Log Entries | 3 transactions, 276797 total undo, 153341 max undo + Pending I/O Reads | 50 buf pool reads, 48 normal AIO, 0 ibuf AIO, 2 preads + Pending I/O Writes | 0 buf pool (0 LRU, 0 flush list, 0 page); 0 AIO, 0 sync, 0 log IO (0 log, 0 chkp); 0 pwrites + Pending I/O Flushes | 0 buf pool, 0 log + Transaction States | 9xACTIVE, 57xnot started +Semaphore Waits + 3 row/row0sel.c line 3495 + 2 btr/btr0sea.c line 1024 + 1 btr/btr0sea.c line 1170 + 1 btr/btr0cur.c line 443 + 1 btr/btr0cur.c line 1501 +Semaphore Holders + 7 thread id 1220999488 + 1 thread id 1229429056 +Mutexes/Locks Waited For + 7 lock on RW-latch at 0x2aaab42120b8 created in file btr/btr0sea.c line 139 + 1 lock on RW-latch at 0x2ab2c679a550 created in file buf/buf0buf.c line 550 +EOF + +format_innodb_status $samples/innodb-status.004.txt > $TMPDIR/got +no_diff $TMPDIR/got $TMPDIR/expected + + +# ########################################################################### +# section_innodb +# ########################################################################### + +test_format_innodb () { + local NAME_VAL_LEN=25 + cat < $TMPDIR/expected + Version | 1.0.17-13.2 + Buffer Pool Size | 128.0M + Buffer Pool Fill | 1% + Buffer Pool Dirty | 0% + File Per Table | OFF + Page Size | 16k + Log File Size | 2 * 1.5G = 3.0G + Log Buffer Size | 8M + Flush Method | 0 + Flush Log At Commit | 1 + XA Support | ON + Checksums | ON + Doublewrite | ON + R/W I/O Threads | 4 4 + I/O Capacity | 200 + Thread Concurrency | 0 + Concurrency Tickets | 500 + Commit Concurrency | 0 + Txn Isolation Level | REPEATABLE-READ + Adaptive Flushing | OFF + Adaptive Checkpoint | estimate +EOF + + section_innodb $samples/temp001/percona-toolkit-mysql-variables $samples/temp001/percona-toolkit-mysql-status > $TMPDIR/got + no_diff $TMPDIR/expected $TMPDIR/got +} + +test_format_innodb + + +# ########################################################################### +# format_innodb_filters +# ########################################################################### + +format_innodb_filters_test () { + local NAME_VAL_LEN=20 + + cat < $TMPDIR/expected + binlog_do_db | foo + binlog_ignore_db | mysql,test +EOF + + format_binlog_filters $samples/mysql-show-master-status-001.txt > $TMPDIR/got + no_diff $TMPDIR/got $TMPDIR/expected +} + +format_innodb_filters_test + +# ########################################################################### +# report_mysql_summary +# ########################################################################### + +OPT_SLEEP=1 +OPT_DUMP_SCHEMAS="mysql" +NAME_VAL_LEN=25 +_NO_FALSE_NEGATIVES=1 +report_mysql_summary "$samples/tempdir" "percona-toolkit" | tail -n+3 > $TMPDIR/got +no_diff "$TMPDIR/got" "$samples/expected_result_report_summary.txt" + +# ########################################################################### +# Done +# ########################################################################### diff --git a/t/lib/bash/report_mysql_info.t b/t/lib/bash/report_mysql_info.t new file mode 120000 index 00000000..edb04c13 --- /dev/null +++ b/t/lib/bash/report_mysql_info.t @@ -0,0 +1 @@ +../../../util/test-bash-functions \ No newline at end of file diff --git a/t/pt-mysql-summary/find_my_cnf_file.sh b/t/pt-mysql-summary/find_my_cnf_file.sh deleted file mode 100644 index 37712fcb..00000000 --- a/t/pt-mysql-summary/find_my_cnf_file.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env bash - -TESTS=4 -TMPDIR=$TEST_TMPDIR - -TEST_NAME="ps-mysqld-001.txt" -res=$(find_my_cnf_file samples/ps-mysqld-001.txt) -is "$res" "/tmp/12345/my.sandbox.cnf" - -TEST_NAME="ps-mysqld-001.txt with port" -res=$(find_my_cnf_file samples/ps-mysqld-001.txt 12346) -is "$res" "/tmp/12346/my.sandbox.cnf" - -TEST_NAME="ps-mysqld-004.txt" -res=$(find_my_cnf_file samples/ps-mysqld-004.txt) -is "$res" "/var/lib/mysql/my.cnf" - -TEST_NAME="ps-mysqld-004.txt with port" -res=$(find_my_cnf_file samples/ps-mysqld-004.txt 12345) -is "$res" "/var/lib/mysql/my.cnf" diff --git a/t/pt-mysql-summary/format_binlog_filters.sh b/t/pt-mysql-summary/format_binlog_filters.sh deleted file mode 100644 index 441599bb..00000000 --- a/t/pt-mysql-summary/format_binlog_filters.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash - -TEST=1 -TMPDIR=$TEST_TMPDIR - -NAME_VAL_LEN=20 - -cat < $TMPDIR/expected - binlog_do_db | foo - binlog_ignore_db | mysql,test -EOF - -format_binlog_filters samples/mysql-show-master-status-001.txt > $TMPDIR/got -no_diff $TMPDIR/got $TMPDIR/expected diff --git a/t/pt-mysql-summary/format_innodb.sh b/t/pt-mysql-summary/format_innodb.sh deleted file mode 100644 index 1dc5e149..00000000 --- a/t/pt-mysql-summary/format_innodb.sh +++ /dev/null @@ -1,36 +0,0 @@ -#/bin/bash - -TESTS=1 -TMPDIR=$TEST_TMPDIR - -test_format_innodb () { - local NAME_VAL_LEN=25 - cat < $TMPDIR/expected - Version | 1.0.17-13.2 - Buffer Pool Size | 128.0M - Buffer Pool Fill | 1% - Buffer Pool Dirty | 0% - File Per Table | OFF - Page Size | 16k - Log File Size | 2 * 1.5G = 3.1G - Log Buffer Size | 8M - Flush Method | 0 - Flush Log At Commit | 1 - XA Support | ON - Checksums | ON - Doublewrite | ON - R/W I/O Threads | 4 4 - I/O Capacity | 200 - Thread Concurrency | 0 - Concurrency Tickets | 500 - Commit Concurrency | 0 - Txn Isolation Level | REPEATABLE-READ - Adaptive Flushing | OFF - Adaptive Checkpoint | estimate -EOF - - _innodb samples/temp001/percona-toolkit-mysql-variables samples/temp001/percona-toolkit-mysql-status > $TMPDIR/got - no_diff $TMPDIR/expected $TMPDIR/got -} - -test_format_innodb diff --git a/t/pt-mysql-summary/format_innodb_status.sh b/t/pt-mysql-summary/format_innodb_status.sh deleted file mode 100644 index 24cee4d5..00000000 --- a/t/pt-mysql-summary/format_innodb_status.sh +++ /dev/null @@ -1,147 +0,0 @@ -#!/usr/bin/env bash - -TESTS=4 -TMPDIR=$TEST_TMPDIR - -# ############################################################################ -TEST_NAME="innodb-status.001.txt" -# ############################################################################ -cat < $TMPDIR/expected - Checkpoint Age | 619k - InnoDB Queue | 0 queries inside InnoDB, 0 queries in queue - Oldest Transaction | 3 Seconds - History List Len | 255 - Read Views | 23 - Undo Log Entries | 0 transactions, 0 total undo, 0 max undo - Pending I/O Reads | 14 buf pool reads, 6 normal AIO, 0 ibuf AIO, 23 preads - Pending I/O Writes | 63 buf pool (63 LRU, 0 flush list, 0 page); 0 AIO, 0 sync, 0 log IO (1 log, 0 chkp); 0 pwrites - Pending I/O Flushes | 0 buf pool, 1 log - Transaction States | 1xACTIVE -Semaphore Waits - 69 btr/btr0cur.c line 457 - 47 btr/btr0cur.c line 523 - 17 trx/trx0trx.c line 1621 - 12 row/row0sel.c line 3549 - 4 lock/lock0lock.c line 4944 - 3 lock/lock0lock.c line 5316 - 2 lock/lock0lock.c line 3224 - 2 btr/btr0sea.c line 1032 - 1 trx/trx0trx.c line 738 - 1 row/row0sel.c line 4574 - 1 lock/lock0lock.c line 5163 - 1 lock/lock0lock.c line 3249 - 1 ./include/btr0btr.ic line 53 - 1 fsp/fsp0fsp.c line 3395 - 1 btr/btr0cur.c line 672 - 1 btr/btr0cur.c line 450 -Semaphore Holders - 66 thread id 139960165583184 - 45 thread id 139960567171408 - 4 thread id 139960404199760 - 1 thread id 139961215367504 - 1 thread id 139960969292112 - 1 thread id 139960676096336 -Mutexes/Locks Waited For - 65 lock on RW-latch at 0x905d33d0 '&new_index->lock' - 45 lock on RW-latch at 0x7f4bedbf8810 '&block->lock' - 30 Mutex at 0xf89ab0 '&kernel_mutex' - 15 lock on RW-latch at 0x90075530 '&btr_search_latch' - 4 lock on RW-latch at 0x90a42ca0 '&new_index->lock' - 1 lock on RW-latch at 0x90fe1c80 '&new_index->lock' - 1 lock on RW-latch at 0x90078f10 '&space->latch' - 1 lock on RW-latch at 0x7f4c0d3abba8 '&block->lock' - 1 lock on RW-latch at 0x7f4bfc558040 '&block->lock' - 1 lock on RW-latch at 0x7f4bd0a8c8d0 '&block->lock' -EOF - -format_innodb_status samples/innodb-status.001.txt > $TMPDIR/got -no_diff $TMPDIR/got $TMPDIR/expected - -# ############################################################################ -TEST_NAME="innodb-status.002.txt" -# ############################################################################ -cat <<'EOF' > $TMPDIR/expected - Checkpoint Age | 348M - InnoDB Queue | 0 queries inside InnoDB, 0 queries in queue - Oldest Transaction | 4 Seconds - History List Len | 426 - Read Views | 583 - Undo Log Entries | 71 transactions, 247 total undo, 46 max undo - Pending I/O Reads | 0 buf pool reads, 0 normal AIO, 0 ibuf AIO, 0 preads - Pending I/O Writes | 0 buf pool (0 LRU, 0 flush list, 0 page); 0 AIO, 0 sync, 0 log IO (0 log, 0 chkp); 0 pwrites - Pending I/O Flushes | 0 buf pool, 0 log - Transaction States | 1xACTIVE, 70xACTIVE (PREPARED) -Tables Locked - 62 `citydb`.`player_buildings` - 46 `citydb`.`players` - 22 `citydb`.`city_grid` - 17 `citydb`.`player_stats` - 6 `citydb`.`player_contracts` - 1 `citydb`.`player_achievements` -Semaphore Waits - 23 trx/trx0undo.c line 1796 - 10 trx/trx0trx.c line 1888 - 8 trx/trx0trx.c line 1033 - 7 trx/trx0trx.c line 738 - 1 lock/lock0lock.c line 3770 - 1 ./include/log0log.ic line 322 -Mutexes/Locks Waited For - 33 Mutex at 0x2abf68b76a18 '&rseg->mutex' - 16 Mutex at 0x48ace40 '&kernel_mutex' - 1 Mutex at 0x2abf68b6c0d0 '&log_sys->mutex' -EOF - -format_innodb_status samples/innodb-status.002.txt > $TMPDIR/got -no_diff $TMPDIR/got $TMPDIR/expected - -# ############################################################################ -TEST_NAME="innodb-status.003.txt" -# ############################################################################ -cat <<'EOF' > $TMPDIR/expected - Checkpoint Age | 0k - InnoDB Queue | 0 queries inside InnoDB, 0 queries in queue - Oldest Transaction | 35 Seconds - History List Len | 11 - Read Views | 1 - Undo Log Entries | 0 transactions, 0 total undo, 0 max undo - Pending I/O Reads | 0 buf pool reads, 0 normal AIO, 0 ibuf AIO, 0 preads - Pending I/O Writes | 0 buf pool (0 LRU, 0 flush list, 0 page); 0 AIO, 0 sync, 0 log IO (0 log, 0 chkp); 0 pwrites - Pending I/O Flushes | 0 buf pool, 0 log - Transaction States | 1xACTIVE, 1xnot started -Tables Locked - 1 `test`.`t` -EOF - -format_innodb_status samples/innodb-status.003.txt > $TMPDIR/got -no_diff $TMPDIR/got $TMPDIR/expected - -# ############################################################################ -TEST_NAME="innodb-status.004.txt" -# ############################################################################ -cat <<'EOF' > $TMPDIR/expected - Checkpoint Age | 93M - InnoDB Queue | 9 queries inside InnoDB, 0 queries in queue - Oldest Transaction | 263 Seconds - History List Len | 1282 - Read Views | 10 - Undo Log Entries | 3 transactions, 276797 total undo, 153341 max undo - Pending I/O Reads | 50 buf pool reads, 48 normal AIO, 0 ibuf AIO, 2 preads - Pending I/O Writes | 0 buf pool (0 LRU, 0 flush list, 0 page); 0 AIO, 0 sync, 0 log IO (0 log, 0 chkp); 0 pwrites - Pending I/O Flushes | 0 buf pool, 0 log - Transaction States | 9xACTIVE, 57xnot started -Semaphore Waits - 3 row/row0sel.c line 3495 - 2 btr/btr0sea.c line 1024 - 1 btr/btr0sea.c line 1170 - 1 btr/btr0cur.c line 443 - 1 btr/btr0cur.c line 1501 -Semaphore Holders - 7 thread id 1220999488 - 1 thread id 1229429056 -Mutexes/Locks Waited For - 7 lock on RW-latch at 0x2aaab42120b8 created in file btr/btr0sea.c line 139 - 1 lock on RW-latch at 0x2ab2c679a550 created in file buf/buf0buf.c line 550 -EOF - -format_innodb_status samples/innodb-status.004.txt > $TMPDIR/got -no_diff $TMPDIR/got $TMPDIR/expected diff --git a/t/pt-mysql-summary/format_overall_db_stats.sh b/t/pt-mysql-summary/format_overall_db_stats.sh deleted file mode 100644 index 93ea9c40..00000000 --- a/t/pt-mysql-summary/format_overall_db_stats.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/bin/bash - -TESTS=2 -TMPDIR=$TEST_TMPDIR - -cat < $TMPDIR/expected - - Database Tables Views SPs Trigs Funcs FKs Partn - mysql 17 - sakila 17 7 3 6 3 22 1 - - Database MyISAM InnoDB - mysql 17 - sakila 2 15 - - Database BTREE FULLTEXT - mysql 24 - sakila 63 1 - - c t s e t s i t b l b v d y d m - h i e n i m n e l o i a a e e e - a m t u n a t x o n g r t a c d - r e m y l t b g i c e r i i - s i l b n h t m u - t n i l t a i a m - a t n o r m l i - m t b e n - p t - Database === === === === === === === === === === === === === === === === - mysql 38 5 5 69 2 3 16 2 4 1 2 - sakila 1 15 1 3 19 26 3 4 1 45 4 1 7 2 - -EOF -format_overall_db_stats samples/mysql-schema-001.txt > $TMPDIR/got -no_diff $TMPDIR/got $TMPDIR/expected - - -cat < $TMPDIR/expected - - Database Tables Views SPs Trigs Funcs FKs Partn - {chosen} 1 - - Database InnoDB - {chosen} 1 - - Database BTREE - {chosen} 2 - - t v - i a - n r - y c - i h - n a - t r - Database === === - {chosen} 1 1 - -EOF -format_overall_db_stats samples/mysql-schema-002.txt > $TMPDIR/got -no_diff $TMPDIR/got $TMPDIR/expected diff --git a/t/pt-mysql-summary/format_status_variables.sh b/t/pt-mysql-summary/format_status_variables.sh deleted file mode 100644 index 5bee86e5..00000000 --- a/t/pt-mysql-summary/format_status_variables.sh +++ /dev/null @@ -1,97 +0,0 @@ -#!/bin/bash - -TESTS=1 -TMPDIR=$TEST_TMPDIR - -cat < $TMPDIR/expected -Variable Per day Per second 5 secs -Bytes_received 8000000 100 -Bytes_sent 35000000 400 -Com_admin_commands 20 -Com_change_db 1000 -Com_delete 8000 -Com_insert 8000 -Com_lock_tables 200 -Com_replace 1250 -Com_select 22500 -Com_set_option 22500 -Com_show_binlogs 10 -Com_show_create_db 400 -Com_show_create_table 7000 -Com_show_databases 125 -Com_show_fields 7000 -Com_show_innodb_status 300 -Com_show_open_tables 10 -Com_show_processlist 300 -Com_show_slave_status 300 -Com_show_status 350 -Com_show_storage_engines 10 -Com_show_tables 400 -Com_show_triggers 7000 -Com_show_variables 450 -Com_truncate 300 -Com_unlock_tables 250 -Com_update 900 -Connections 2500 -Created_tmp_disk_tables 15000 -Created_tmp_files 60 -Created_tmp_tables 22500 -Flush_commands 10 -Handler_delete 8000 -Handler_read_first 2250 -Handler_read_key 30000 -Handler_read_next 15000 -Handler_read_rnd 9000 -Handler_read_rnd_next 300000 3 -Handler_update 17500 -Handler_write 250000 2 -Innodb_buffer_pool_pages_data 225 -Innodb_buffer_pool_pages_free 5000 -Innodb_buffer_pool_pages_total 6000 -Innodb_buffer_pool_read_ahead_rnd 10 -Innodb_buffer_pool_read_requests 2250 -Innodb_buffer_pool_reads 150 -Innodb_data_fsyncs 35 -Innodb_data_read 30000000 350 -Innodb_data_reads 300 -Innodb_data_writes 35 -Innodb_data_written 17500 -Innodb_log_writes 10 -Innodb_os_log_fsyncs 35 -Innodb_os_log_written 6000 -Innodb_page_size 175000 2 -Innodb_pages_read 225 -Key_blocks_unused 150000 1 -Key_blocks_used 175 -Key_read_requests 100000 1 -Key_reads 600 -Key_write_requests 70000 -Key_writes 17500 -Max_used_connections 45 -Open_files 1500 -Open_tables 700 -Opened_tables 15000 -Qcache_free_blocks 80 -Qcache_free_memory 175000000 2250 -Qcache_hits 8000 -Qcache_inserts 20000 -Qcache_not_cached 10000 -Qcache_queries_in_cache 225 -Qcache_total_blocks 600 -Questions 100000 1 -Select_scan 25000 -Sort_rows 8000 -Sort_scan 300 -Table_locks_immediate 50000 17500 -Table_locks_waited 10 1 -Threads_cached 35 -Threads_connected 10 -Threads_created 45 -Threads_running 10 -Uptime 90000 1 1 -Uptime_since_flush_status 90000 1 -EOF - -join samples/mysql-status-00{1,2}.txt > $TMPDIR/in -format_status_variables $TMPDIR/in > $TMPDIR/got -no_diff $TMPDIR/got $TMPDIR/expected diff --git a/t/pt-mysql-summary/fuzz.sh b/t/pt-mysql-summary/fuzz.sh deleted file mode 100644 index 6c1d2871..00000000 --- a/t/pt-mysql-summary/fuzz.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -TESTS=1 -TMPDIR=$TEST_TMPDIR - -TEST_NAME="fuzz 49" -is $(fuzz 49) "50" diff --git a/t/pt-mysql-summary/get_mysql_info.sh b/t/pt-mysql-summary/get_mysql_info.sh deleted file mode 100644 index edbc0333..00000000 --- a/t/pt-mysql-summary/get_mysql_info.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash - -TESTS=3 -TMPDIR=$TEST_TMPDIR - -TEST_NAME="get_mysql_timezone" -cp samples/mysql-variables-001.txt $TMPDIR/percona-toolkit-mysql-variables -is $(get_mysql_timezone "$TMPDIR/percona-toolkit-mysql-variables") "EDT" - -TEST_NAME="get_mysql_uptime" -cat < $TMPDIR/expected -2010-05-27 11:38 (up 0+02:08:52) -EOF -cp samples/mysql-status-001.txt $TMPDIR/percona-toolkit-mysql-status -local uptime="$(get_var Uptime $TMPDIR/percona-toolkit-mysql-status)" -local current_time="$(echo -e "2010-05-27 11:38\n")" -get_mysql_uptime "${uptime}" "${current_time}" > $TMPDIR/got -no_diff $TMPDIR/got $TMPDIR/expected - -TEST_NAME="get_mysql_version" -cat < $TMPDIR/expected - Version | 5.0.51a-24+lenny2 (Debian) - Built On | debian-linux-gnu i486 -EOF -cp samples/mysql-variables-001.txt $TMPDIR/percona-toolkit-mysql-variables -get_mysql_version $TMPDIR/percona-toolkit-mysql-variables > $TMPDIR/got -no_diff $TMPDIR/got $TMPDIR/expected diff --git a/t/pt-mysql-summary/parse_mysqld_instances.sh b/t/pt-mysql-summary/parse_mysqld_instances.sh deleted file mode 100644 index 7a4e9e8f..00000000 --- a/t/pt-mysql-summary/parse_mysqld_instances.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/bash - -TESTS=4 -TMPDIR=$TEST_TMPDIR - -_NO_FALSE_NEGATIVES=1 - -TEST_NAME="ps-mysqld-001.txt" -cat < $TMPDIR/expected - Port Data Directory Nice OOM Value Socket - ===== ========================== ==== ========= ====== - 3306 /var/lib/mysql ? ? /var/run/mysqld/mysqld.sock - 12345 /tmp/12345/data ? ? /tmp/12345/mysql_sandbox12345.sock - 12346 /tmp/12346/data ? ? /tmp/12346/mysql_sandbox12346.sock -EOF -parse_mysqld_instances samples/ps-mysqld-001.txt > $TMPDIR/got -no_diff $TMPDIR/got $TMPDIR/expected - -TEST_NAME="ps-mysqld-002.txt" -cat < $TMPDIR/expected - Port Data Directory Nice OOM Value Socket - ===== ========================== ==== ========= ====== - /var/lib/mysql ? ? /var/lib/mysql/mysql.sock -EOF -parse_mysqld_instances samples/ps-mysqld-002.txt > $TMPDIR/got -no_diff $TMPDIR/got $TMPDIR/expected - -TEST_NAME="ps-mysqld-003.txt" -#parse_mysqld_instances -cat < $TMPDIR/expected - Port Data Directory Nice OOM Value Socket - ===== ========================== ==== ========= ====== - 3306 /mnt/data-store/mysql/data ? ? /tmp/mysql.sock -EOF -parse_mysqld_instances samples/ps-mysqld-003.txt > $TMPDIR/got -no_diff $TMPDIR/got $TMPDIR/expected - -cat < $TMPDIR/expected - Port Data Directory Nice OOM Value Socket - ===== ========================== ==== ========= ====== - /var/db/mysql ? ? -EOF - -cat < $TMPDIR/in -mysql 767 0.0 0.9 3492 1100 v0 I 3:01PM 0:00.07 /bin/sh /usr/local/bin/mysqld_safe --defaults-extra-file=/var/db/mysql/my.cnf --user=mysql --datadir=/var/db/mysql --pid-file=/var/db/mysql/freebsd.hsd1.va.comcast.net..pid -mysql 818 0.0 17.4 45292 20584 v0 I 3:01PM 0:02.28 /usr/local/libexec/mysqld --defaults-extra-file=/var/db/mysql/my.cnf --basedir=/usr/local --datadir=/var/db/mysql --user=mysql --log-error=/var/db/mysql/freebsd.hsd1.va.comcast.net..err --pid-file=/var/db/mysql/freebsd.hsd1.va.comcast.net..pid -EOF -parse_mysqld_instances $TMPDIR/in > $TMPDIR/got -no_diff $TMPDIR/got $TMPDIR/expected diff --git a/t/pt-mysql-summary/plugin_status.sh b/t/pt-mysql-summary/plugin_status.sh deleted file mode 100644 index 6312c54d..00000000 --- a/t/pt-mysql-summary/plugin_status.sh +++ /dev/null @@ -1,60 +0,0 @@ -#!/bin/bash - -TESTS=4 -TMPDIR=$TEST_TMPDIR - -cat < $TMPDIR/plugins -binlog ACTIVE STORAGE ENGINE NULL GPL -partition ACTIVE STORAGE ENGINE NULL GPL -ARCHIVE ACTIVE STORAGE ENGINE NULL GPL -BLACKHOLE ACTIVE STORAGE ENGINE NULL GPL -CSV ACTIVE STORAGE ENGINE NULL GPL -FEDERATED DISABLED STORAGE ENGINE NULL GPL -MEMORY ACTIVE STORAGE ENGINE NULL GPL -InnoDB ACTIVE STORAGE ENGINE NULL GPL -MyISAM ACTIVE STORAGE ENGINE NULL GPL -MRG_MYISAM ACTIVE STORAGE ENGINE NULL GPL -EOF - -is \ - "$(get_plugin_status $TMPDIR/plugins InnoDB )" \ - "ACTIVE" \ - "Sanity test, finds InnoDB as active" - -is \ - "$(get_plugin_status $TMPDIR/plugins some_plugin_that_doesnt_exist )" \ - "Not found" \ - "Doesn't find a nonexistent plugin" - -echo "INNODB_CMP ACTIVE" >> $TMPDIR/plugins -is \ - "$(get_plugin_status $TMPDIR/plugins "INNODB_CMP" )" \ - "ACTIVE" - -cat < $TMPDIR/plugins -binlog ACTIVE STORAGE ENGINE NULL GPL -mysql_native_password ACTIVE AUTHENTICATION NULL GPL -mysql_old_password ACTIVE AUTHENTICATION NULL GPL -MRG_MYISAM ACTIVE STORAGE ENGINE NULL GPL -MyISAM ACTIVE STORAGE ENGINE NULL GPL -CSV ACTIVE STORAGE ENGINE NULL GPL -MEMORY ACTIVE STORAGE ENGINE NULL GPL -FEDERATED DISABLED STORAGE ENGINE NULL GPL -ARCHIVE ACTIVE STORAGE ENGINE NULL GPL -BLACKHOLE ACTIVE STORAGE ENGINE NULL GPL -InnoDB ACTIVE STORAGE ENGINE NULL GPL -INNODB_TRX ACTIVE INFORMATION SCHEMA NULL GPL -INNODB_LOCKS ACTIVE INFORMATION SCHEMA NULL GPL -INNODB_LOCK_WAITS ACTIVE INFORMATION SCHEMA NULL GPL -INNODB_CMP ACTIVE INFORMATION SCHEMA NULL GPL -INNODB_CMP_RESET ACTIVE INFORMATION SCHEMA NULL GPL -INNODB_CMPMEM ACTIVE INFORMATION SCHEMA NULL GPL -INNODB_CMPMEM_RESET ACTIVE INFORMATION SCHEMA NULL GPL -PERFORMANCE_SCHEMA ACTIVE STORAGE ENGINE NULL GPL -partition ACTIVE STORAGE ENGINE NULL GPL -EOF - -is \ - "$(get_plugin_status $TMPDIR/plugins "INNODB_CMP" )" \ - "ACTIVE" \ - "Doesn't get confused by multiple plugins with the same prefix" diff --git a/t/pt-mysql-summary/pretty_print_cnf_file.sh b/t/pt-mysql-summary/pretty_print_cnf_file.sh deleted file mode 100644 index 0ef0dfcd..00000000 --- a/t/pt-mysql-summary/pretty_print_cnf_file.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/bash - -TESTS=2 -TMPDIR=$TEST_TMPDIR - -cat < $TMPDIR/expected - -[mysqld] -datadir = /mnt/data/mysql -socket = /mnt/data/mysql/mysql.sock -old_passwords = 1 -ssl-key = /opt/mysql.pdns/.cert/server-key.pem -ssl-cert = /opt/mysql.pdns/.cert/server-cert.pem -ssl-ca = /opt/mysql.pdns/.cert/ca-cert.pem -innodb_buffer_pool_size = 16M -innodb_flush_method = O_DIRECT -innodb_log_file_size = 64M -innodb_log_buffer_size = 1M -innodb_flush_log_at_trx_commit = 2 -innodb_file_per_table = 1 -ssl = 1 -server-id = 1 -log-bin = sl1-bin - -[mysql.server] -user = mysql -basedir = /mnt/data - -[mysqld_safe] -log-error = /var/log/mysqld.log -pid-file = /var/run/mysqld/mysqld.pid - -[mysql] - -[xtrabackup] -target-dir = /data/backup -EOF - -pretty_print_cnf_file samples/my.cnf-001.txt > $TMPDIR/got -no_diff $TMPDIR/got $TMPDIR/expected - - -# TODO BUG NUMBER# -cp samples/my.cnf-001.txt $TMPDIR/test_pretty_print_cnf_file -echo "some_var_yadda=0" >> $TMPDIR/test_pretty_print_cnf_file -echo "some_var_yadda = 0" >> $TMPDIR/expected - -pretty_print_cnf_file $TMPDIR/test_pretty_print_cnf_file > $TMPDIR/got -no_diff $TMPDIR/got $TMPDIR/expected diff --git a/t/pt-mysql-summary/pt-mysql-summary.t b/t/pt-mysql-summary/pt-mysql-summary.t index e6c10f7c..44b52130 100644 --- a/t/pt-mysql-summary/pt-mysql-summary.t +++ b/t/pt-mysql-summary/pt-mysql-summary.t @@ -13,11 +13,8 @@ use English qw(-no_match_vars); use PerconaTest; my ($tool) = $PROGRAM_NAME =~ m/([\w-]+)\.t$/; -push @ARGV, "$trunk/t/$tool/*.sh" unless @ARGV; -system("$trunk/util/test-bash-functions $trunk/bin/$tool @ARGV"); -require Test::More; -Test::More->import( tests => 3 ); +use Test::More tests => 3; use File::Temp qw( tempdir ); local $ENV{PTDEBUG} = ""; @@ -38,7 +35,7 @@ my @files = glob("$dir/*"); is( scalar @files, - 13, + 12, "And leaves all files in there" ); diff --git a/t/pt-mysql-summary/report_summary.sh b/t/pt-mysql-summary/report_summary.sh deleted file mode 100644 index 5b7bf4b0..00000000 --- a/t/pt-mysql-summary/report_summary.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash - -TESTS=1 -TMPDIR=$TEST_TMPDIR - -TEST_NAME="report_summary" -OPT_SLEEP=1 -OPT_DUMP_SCHEMAS="mysql" -NAME_VAL_LEN=25 -_NO_FALSE_NEGATIVES=1 -report_summary "samples/tempdir" "percona-toolkit" | tail -n+3 > $TMPDIR/got -no_diff "$TMPDIR/got" "samples/expected_result_report_summary.txt" diff --git a/t/pt-mysql-summary/semisync_stats.sh b/t/pt-mysql-summary/semisync_stats.sh deleted file mode 100644 index ab12e17e..00000000 --- a/t/pt-mysql-summary/semisync_stats.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash - -TEST=3 -TMPDIR=$TEST_TMPDIR - -cat < $TMPDIR/expected - master semisync status | 0 - master trace level | 32, net wait (more information about network waits) -master timeout in milliseconds | 10000 - master waits for slaves | ON - master clients | 0 - master net_avg_wait_time | 0 - master net_wait_time | 0 - master net_waits | 0 - master no_times | 0 - master no_tx | 0 - master timefunc_failures | 0 - master tx_avg_wait_time | 0 - master tx_wait_time | 0 - master tx_waits | 0 -master wait_pos_backtraverse | 0 - master wait_sessions | 0 - master yes_tx | 0 -EOF - -_semi_sync_stats_for "master" samples/mysql-variables-with-semisync.txt > $TMPDIR/got -no_diff $TMPDIR/expected $TMPDIR/got diff --git a/t/pt-mysql-summary/summarize_binlogs.sh b/t/pt-mysql-summary/summarize_binlogs.sh deleted file mode 100644 index 2df2446d..00000000 --- a/t/pt-mysql-summary/summarize_binlogs.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -TESTS=1 -TMPDIR=$TEST_TMPDIR - -cat < $TMPDIR/expected - Binlogs | 20 - Zero-Sized | 3 - Total Size | 6.5G -EOF - -summarize_binlogs samples/mysql-master-logs-001.txt > $TMPDIR/got -no_diff $TMPDIR/expected $TMPDIR/got diff --git a/t/pt-mysql-summary/summarize_processlist.sh b/t/pt-mysql-summary/summarize_processlist.sh deleted file mode 100644 index c67798c9..00000000 --- a/t/pt-mysql-summary/summarize_processlist.sh +++ /dev/null @@ -1,64 +0,0 @@ -#!/bin/bash - -TESTS=1 -TMPDIR=$TEST_TMPDIR - -cat < $TMPDIR/expected - - Command COUNT(*) Working SUM(Time) MAX(Time) - ------------------------------ -------- ------- --------- --------- - Binlog Dump 1 1 9000000 9000000 - Connect 2 2 6000000 5000000 - Query 2 2 0 0 - Sleep 150 0 150000 20000 - - User COUNT(*) Working SUM(Time) MAX(Time) - ------------------------------ -------- ------- --------- --------- - acjcxx 4 0 0 0 - aecac 1 0 0 0 - babeecc 20 0 0 0 - centous 2 0 0 0 - crcpcpc 2 0 0 0 - crgcp4c 3 0 0 0 - eanecj 30 1 0 0 - ebace 10 0 0 0 - etace 80 0 0 0 - goate 8 0 0 0 - qjveec 1 0 0 0 - repl 1 1 9000000 9000000 - root 1 1 0 0 - system user 2 2 6000000 5000000 - - Host COUNT(*) Working SUM(Time) MAX(Time) - ------------------------------ -------- ------- --------- --------- - 10.14.82.196 6 0 0 0 - 10.14.82.202 20 0 0 0 - 10.17.85.100 9 0 0 0 - 10.17.85.74 1 1 9000000 9000000 - 10.17.85.86 35 0 0 0 - 10.17.85.88 5 0 0 0 - 10.17.85.90 10 0 0 0 - 10.36.34.66 35 1 0 0 - 2 2 6000000 5000000 - localhost 1 1 0 0 - someserver.woozle.com11 1 0 0 0 - someserver.woozle.com14 1 0 0 0 - someserver.woozle.com 40 0 0 0 - - db COUNT(*) Working SUM(Time) MAX(Time) - ------------------------------ -------- ------- --------- --------- - aetecjc 175 1 0 0 - NULL 4 4 15000000 9000000 - - State COUNT(*) Working SUM(Time) MAX(Time) - ------------------------------ -------- ------- --------- --------- - 150 0 0 0 - Has read all relay log; waitin 1 1 300000 300000 - Has sent all binlog to slave; 1 1 9000000 9000000 - NULL 2 2 0 0 - Waiting for master to send eve 1 1 5000000 5000000 - -EOF - -summarize_processlist samples/processlist-001.txt > $TMPDIR/got -no_diff $TMPDIR/got $TMPDIR/expected diff --git a/t/pt-mysql-summary/table_cache.sh b/t/pt-mysql-summary/table_cache.sh deleted file mode 100644 index 624fc896..00000000 --- a/t/pt-mysql-summary/table_cache.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash - -TEST=3 -TMPDIR=$TEST_TMPDIR - -touch $TMPDIR/table_cache_tests - -is \ - $(get_table_cache "$TMPDIR/table_cache_tests") \ - 0 \ - "0 if neither table_cache nor table_open_cache are present" - -cat < $TMPDIR/table_cache_tests -table_cache 5 -table_open_cache 4 -EOF - -is \ - $(get_table_cache "$TMPDIR/table_cache_tests") \ - 4 \ - "If there's a table_open_cache present, uses that" - -cat < $TMPDIR/table_cache_tests -table_cache 5 -EOF - -is \ - $(get_table_cache "$TMPDIR/table_cache_tests") \ - 5 \ - "Otherwise, defaults to table_cache"