From 5038253e20e8787bd185c3288f1981d32dc0bd52 Mon Sep 17 00:00:00 2001 From: Roberto de Bem Date: Tue, 8 Oct 2024 20:21:42 -0300 Subject: [PATCH 1/2] Fixing the jemalloc report enabled --- lib/bash/report_mysql_info.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/bash/report_mysql_info.sh b/lib/bash/report_mysql_info.sh index 79315b2f2..a5f56d8a8 100644 --- a/lib/bash/report_mysql_info.sh +++ b/lib/bash/report_mysql_info.sh @@ -1283,7 +1283,7 @@ report_jemalloc_enabled() { local variables_file="$2" local GENERAL_JEMALLOC_STATUS=0 - for pid in $(grep '/mysqld ' "$instances_file" | awk '{print $1;}'); do + for pid in $(grep '/mysqld' "$instances_file" | awk '{print $1;}'); do local jemalloc_status="$(get_var "pt-summary-internal-jemalloc_enabled_for_pid_${pid}" "${variables_file}")" if [ -z $jemalloc_status ]; then continue From ab2cd9e83488ddf2a77af0f4f5f38241edad7044 Mon Sep 17 00:00:00 2001 From: Roberto de Bem Date: Tue, 8 Oct 2024 20:30:28 -0300 Subject: [PATCH 2/2] adding bin/pt-mysql-summary --- bin/pt-mysql-summary | 2539 ------------------------------------------ 1 file changed, 2539 deletions(-) diff --git a/bin/pt-mysql-summary b/bin/pt-mysql-summary index 94039a767..87699e7a9 100755 --- a/bin/pt-mysql-summary +++ b/bin/pt-mysql-summary @@ -15,41 +15,6 @@ set -u # See https://github.com/percona/percona-toolkit for more information. # ########################################################################### - -set -u - -PTFUNCNAME="" -PTDEBUG="${PTDEBUG:-""}" -EXIT_STATUS=0 - -ts() { - TS=$(date +%F-%T | tr ':-' '_') - echo "$TS $*" -} - -info() { - [ ${OPT_VERBOSE:-3} -ge 3 ] && ts "$*" -} - -log() { - [ ${OPT_VERBOSE:-3} -ge 2 ] && ts "$*" -} - -warn() { - [ ${OPT_VERBOSE:-3} -ge 1 ] && ts "$*" >&2 - EXIT_STATUS=1 -} - -die() { - ts "$*" >&2 - EXIT_STATUS=1 - exit 1 -} - -_d () { - [ "$PTDEBUG" ] && echo "# $PTFUNCNAME: $(ts "$*")" >&2 -} - # ########################################################################### # End log_warn_die package # ########################################################################### @@ -63,417 +28,6 @@ _d () { # See https://github.com/percona/percona-toolkit for more information. # ########################################################################### - - - - - -set -u - -ARGV="" # Non-option args (probably input files) -EXT_ARGV="" # Everything after -- (args for an external command) -HAVE_EXT_ARGV="" # Got --, everything else is put into EXT_ARGV -OPT_ERRS=0 # How many command line option errors -OPT_VERSION="" # If --version was specified -OPT_HELP="" # If --help was specified -OPT_ASK_PASS="" # If --ask-pass was specified -PO_DIR="" # Directory with program option spec files -GLOBAL_CONFIG=0 # We ignore non-recognized options in global configs - -usage() { - local file="$1" - - local usage="$(grep '^Usage: ' "$file")" - echo $usage - echo - echo "For more information, 'man $TOOL' or 'perldoc $file'." -} - -usage_or_errors() { - local file="$1" - local version="" - - if [ "$OPT_VERSION" ]; then - version=$(grep '^pt-[^ ]\+ [0-9]' "$file") - echo "$version" - return 1 - fi - - if [ -z $(_which perl) ]; then - echo "Perl binary required to run this tool" - return 1 - fi - - if [ "$OPT_HELP" ]; then - usage "$file" - echo - echo "Command line options:" - echo - perl -e ' - use strict; - use warnings FATAL => qw(all); - my $lcol = 20; # Allow this much space for option names. - my $rcol = 80 - $lcol; # The terminal is assumed to be 80 chars wide. - my $name; - while ( <> ) { - my $line = $_; - chomp $line; - if ( $line =~ s/^long:/ --/ ) { - $name = $line; - } - elsif ( $line =~ s/^desc:// ) { - $line =~ s/ +$//mg; - my @lines = grep { $_ } - $line =~ m/(.{0,$rcol})(?:\s+|\Z)/g; - if ( length($name) >= $lcol ) { - print $name, "\n", (q{ } x $lcol); - } - else { - printf "%-${lcol}s", $name; - } - print join("\n" . (q{ } x $lcol), @lines); - print "\n"; - } - } - ' "$PO_DIR"/* - echo - echo "Options and values after processing arguments:" - echo - ( - cd "$PO_DIR" - for opt in *; do - local varname="OPT_$(echo "$opt" | tr a-z- A-Z_)" - eval local varvalue=\$$varname - if ! grep -q "type:" "$PO_DIR/$opt" >/dev/null; then - if [ "$varvalue" -a "$varvalue" = "yes" ]; - then varvalue="TRUE" - else - varvalue="FALSE" - fi - fi - printf -- " --%-30s %s" "$opt" "${varvalue:-(No value)}" - echo - done - ) - return 1 - fi - - if [ $OPT_ERRS -gt 0 ]; then - echo - usage "$file" - return 1 - fi - - return 0 -} - -option_error() { - local err="$1" - OPT_ERRS=$(($OPT_ERRS + 1)) - echo "$err" >&2 -} - -parse_options() { - local file="$1" - shift - - ARGV="" - EXT_ARGV="" - HAVE_EXT_ARGV="" - OPT_ERRS=0 - OPT_VERSION="" - OPT_HELP="" - OPT_ASK_PASS="" - PO_DIR="$PT_TMPDIR/po" - - if [ ! -d "$PO_DIR" ]; then - mkdir "$PO_DIR" - if [ $? -ne 0 ]; then - echo "Cannot mkdir $PO_DIR" >&2 - exit 1 - fi - fi - - rm -rf "$PO_DIR"/* - if [ $? -ne 0 ]; then - echo "Cannot rm -rf $PO_DIR/*" >&2 - exit 1 - fi - - _parse_pod "$file" # Parse POD into program option (po) spec files - _eval_po # Eval po into existence with default values - - if [ $# -ge 2 ] && [ "$1" = "--config" ]; then - shift # --config - local user_config_files="$1" - shift # that ^ - local IFS="," - for user_config_file in $user_config_files; do - _parse_config_files "$user_config_file" - done - else - GLOBAL_CONFIG=1 - _parse_config_files "/etc/percona-toolkit/percona-toolkit.conf" - GLOBAL_CONFIG=0 - _parse_config_files "/etc/percona-toolkit/$TOOL.conf" - if [ "${HOME:-}" ]; then - GLOBAL_CONFIG=1 - _parse_config_files "$HOME/.percona-toolkit.conf" - GLOBAL_CONFIG=0 - _parse_config_files "$HOME/.$TOOL.conf" - fi - fi - - _parse_command_line "${@:-""}" -} - -_parse_pod() { - local file="$1" - - PO_FILE="$file" PO_DIR="$PO_DIR" perl -e ' - $/ = ""; - my $file = $ENV{PO_FILE}; - open my $fh, "<", $file or die "Cannot open $file: $!"; - while ( defined(my $para = <$fh>) ) { - next unless $para =~ m/^=head1 OPTIONS/; - while ( defined(my $para = <$fh>) ) { - last if $para =~ m/^=head1/; - chomp; - if ( $para =~ m/^=item --(\S+)/ ) { - my $opt = $1; - my $file = "$ENV{PO_DIR}/$opt"; - open my $opt_fh, ">", $file or die "Cannot open $file: $!"; - print $opt_fh "long:$opt\n"; - $para = <$fh>; - chomp; - if ( $para =~ m/^[a-z ]+:/ ) { - map { - chomp; - my ($attrib, $val) = split(/: /, $_); - print $opt_fh "$attrib:$val\n"; - } split(/; /, $para); - $para = <$fh>; - chomp; - } - my ($desc) = $para =~ m/^([^?.]+)/; - print $opt_fh "desc:$desc.\n"; - close $opt_fh; - } - } - last; - } - ' -} - -_eval_po() { - local IFS=":" - for opt_spec in "$PO_DIR"/*; do - local opt="" - local default_val="" - local neg=0 - local size=0 - while read key val; do - case "$key" in - long) - opt=$(echo $val | sed 's/-/_/g' | tr '[:lower:]' '[:upper:]') - ;; - default) - default_val="$val" - ;; - "short form") - ;; - type) - [ "$val" = "size" ] && size=1 - ;; - desc) - ;; - negatable) - if [ "$val" = "yes" ]; then - neg=1 - fi - ;; - *) - echo "Invalid attribute in $opt_spec: $line" >&2 - exit 1 - esac - done < "$opt_spec" - - if [ -z "$opt" ]; then - echo "No long attribute in option spec $opt_spec" >&2 - exit 1 - fi - - if [ $neg -eq 1 ]; then - if [ -z "$default_val" ] || [ "$default_val" != "yes" ]; then - echo "Option $opt_spec is negatable but not default: yes" >&2 - exit 1 - fi - fi - - if [ $size -eq 1 -a -n "$default_val" ]; then - default_val=$(size_to_bytes $default_val) - fi - - eval "OPT_${opt}"="$default_val" - done -} - -_parse_config_files() { - - for config_file in "${@:-""}"; do - test -f "$config_file" || continue - - while read config_opt; do - - echo "$config_opt" | grep '^[ ]*[^#]' >/dev/null 2>&1 || continue - - config_opt="$(echo "$config_opt" | sed -e 's/^ *//g' -e 's/ *$//g' -e 's/[ ]*=[ ]*/=/' -e 's/\s[ ]*#.*$//')" - - [ "$config_opt" = "" ] && continue - - echo "$config_opt" | grep -v 'version-check' >/dev/null 2>&1 || continue - - if ! [ "$HAVE_EXT_ARGV" ]; then - config_opt="--$config_opt" - fi - - _parse_command_line "$config_opt" - - done < "$config_file" - - HAVE_EXT_ARGV="" # reset for each file - - done -} - -_parse_command_line() { - local opt="" - local val="" - local next_opt_is_val="" - local opt_is_ok="" - local opt_is_negated="" - local real_opt="" - local required_arg="" - local spec="" - - for opt in "${@:-""}"; do - if [ "$opt" = "--" -o "$opt" = "----" ]; then - HAVE_EXT_ARGV=1 - continue - fi - if [ "$HAVE_EXT_ARGV" ]; then - if [ "$EXT_ARGV" ]; then - EXT_ARGV="$EXT_ARGV $opt" - else - EXT_ARGV="$opt" - fi - continue - fi - - if [ "$next_opt_is_val" ]; then - next_opt_is_val="" - if [ $# -eq 0 ] || [ $(expr "$opt" : "\-") -eq 1 ]; then - option_error "$real_opt requires a $required_arg argument" - continue - fi - val="$opt" - opt_is_ok=1 - else - if [ $(expr "$opt" : "\-") -eq 0 ]; then - if [ -z "$ARGV" ]; then - ARGV="$opt" - else - ARGV="$ARGV $opt" - fi - continue - fi - - real_opt="$opt" - - if $(echo $opt | grep '^--no[^-]' >/dev/null); then - local base_opt=$(echo $opt | sed 's/^--no//') - if [ -f "$PT_TMPDIR/po/$base_opt" ]; then - opt_is_negated=1 - opt="$base_opt" - else - opt_is_negated="" - opt=$(echo $opt | sed 's/^-*//') - fi - else - if $(echo $opt | grep '^--no-' >/dev/null); then - opt_is_negated=1 - opt=$(echo $opt | sed 's/^--no-//') - else - opt_is_negated="" - opt=$(echo $opt | sed 's/^-*//') - fi - fi - - if $(echo $opt | grep '^[a-z-][a-z-]*=' >/dev/null 2>&1); then - val="$(echo "$opt" | awk '{ st = index($0,"="); print substr($0, st+1)}')" - opt="$(echo $opt | awk -F= '{print $1}')" - fi - - if [ -f "$PT_TMPDIR/po/$opt" ]; then - spec="$PT_TMPDIR/po/$opt" - else - spec=$(grep "^short form:-$opt\$" "$PT_TMPDIR"/po/* | cut -d ':' -f 1) - if [ -z "$spec" ]; then - if [ $GLOBAL_CONFIG -eq 1 ]; then - continue - else - option_error "Unknown option: $real_opt" - fi - fi - fi - - required_arg=$(cat "$spec" | awk -F: '/^type:/{print $2}') - if [ "$required_arg" ]; then - if [ "$val" ]; then - opt_is_ok=1 - else - next_opt_is_val=1 - fi - else - if [ "$val" ]; then - option_error "Option $real_opt does not take a value" - continue - fi - if [ "$opt_is_negated" ]; then - val="" - else - val="yes" - fi - opt_is_ok=1 - fi - fi - - if [ "$opt_is_ok" ]; then - opt=$(cat "$spec" | grep '^long:' | cut -d':' -f2 | sed 's/-/_/g' | tr '[:lower:]' '[:upper:]') - - if grep "^type:size" "$spec" >/dev/null; then - val=$(size_to_bytes $val) - fi - - eval "OPT_$opt"='$val' - - opt="" - val="" - next_opt_is_val="" - opt_is_ok="" - opt_is_negated="" - real_opt="" - required_arg="" - spec="" - fi - done -} - -size_to_bytes() { - local size="$1" - echo $size | perl -ne '%f=(B=>1, K=>1_024, M=>1_048_576, G=>1_073_741_824, T=>1_099_511_627_776); m/^(\d+)([kMGT])?/i; print $1 * $f{uc($2 || "B")};' -} - # ########################################################################### # End parse_options package # ########################################################################### @@ -487,55 +41,6 @@ size_to_bytes() { # See https://github.com/percona/percona-toolkit for more information. # ########################################################################### - -set -u - -mysql_options() { - local MYSQL_ARGS="" - if [ -n "$OPT_DEFAULTS_FILE" ]; then - MYSQL_ARGS="--defaults-file=$OPT_DEFAULTS_FILE" - fi - if [ -n "$OPT_PORT" ]; then - MYSQL_ARGS="$MYSQL_ARGS --port=$OPT_PORT" - fi - if [ -n "$OPT_SOCKET" ]; then - MYSQL_ARGS="$MYSQL_ARGS --socket=$OPT_SOCKET" - fi - if [ -n "$OPT_HOST" ]; then - MYSQL_ARGS="$MYSQL_ARGS --host=$OPT_HOST" - fi - if [ -n "$OPT_USER" ]; then - MYSQL_ARGS="$MYSQL_ARGS --user=$OPT_USER" - fi - if [ -n "$OPT_ASK_PASS" ]; then - stty -echo - >&2 printf "Enter MySQL password: " - read GIVEN_PASS - stty echo - printf "\n" - MYSQL_ARGS="$MYSQL_ARGS --password=$GIVEN_PASS" - elif [ -n "$OPT_PASSWORD" ]; then - MYSQL_ARGS="$MYSQL_ARGS --password=$OPT_PASSWORD" - fi - - echo $MYSQL_ARGS -} - -arrange_mysql_options() { - local opts="$1" - - local rearranged="" - for opt in $opts; do - if [ "$(echo $opt | awk -F= '{print $1}')" = "--defaults-file" ]; then - rearranged="$opt $rearranged" - else - rearranged="$rearranged $opt" - fi - done - - echo "$rearranged" -} - # ########################################################################### # End mysql_options package # ########################################################################### @@ -549,34 +54,6 @@ arrange_mysql_options() { # See https://github.com/percona/percona-toolkit for more information. # ########################################################################### - -set -u - -PT_TMPDIR="" - -mk_tmpdir() { - local dir="${1:-""}" - - if [ -n "$dir" ]; then - if [ ! -d "$dir" ]; then - mkdir "$dir" || die "Cannot make tmpdir $dir" - fi - PT_TMPDIR="$dir" - else - local tool="${0##*/}" - local pid="$$" - PT_TMPDIR=`mktemp -d -t "${tool}.${pid}.XXXXXX"` \ - || die "Cannot make secure tmpdir" - fi -} - -rm_tmpdir() { - if [ -n "$PT_TMPDIR" ] && [ -d "$PT_TMPDIR" ]; then - rm -rf "$PT_TMPDIR" - fi - PT_TMPDIR="" -} - # ########################################################################### # End tmpdir package # ########################################################################### @@ -590,40 +67,6 @@ rm_tmpdir() { # See https://github.com/percona/percona-toolkit for more information. # ########################################################################### - -set -u - -_seq() { - local i="$1" - awk "BEGIN { for(i=1; i<=$i; i++) print i; }" -} - -_pidof() { - local cmd="$1" - if ! pidof "$cmd" 2>/dev/null; then - ps -eo pid,ucomm | awk -v comm="$cmd" '$2 == comm { print $1 }' - fi -} - -_lsof() { - local pid="$1" - if ! lsof -p $pid 2>/dev/null; then - /bin/ls -l /proc/$pid/fd 2>/dev/null - fi -} - - - -_which() { - if [ -x /usr/bin/which ]; then - /usr/bin/which "$1" 2>/dev/null | awk '{print $1}' - elif which which 1>/dev/null 2>&1; then - which "$1" 2>/dev/null | awk '{print $1}' - else - echo "$1" - fi -} - # ########################################################################### # End alt_cmds package # ########################################################################### @@ -637,85 +80,6 @@ _which() { # See https://github.com/percona/percona-toolkit for more information. # ########################################################################### - -set -u - -POSIXLY_CORRECT=1 -export POSIXLY_CORRECT - -fuzzy_formula=' - rounded = 0; - if (fuzzy_var <= 10 ) { - rounded = 1; - } - factor = 1; - while ( rounded == 0 ) { - if ( fuzzy_var <= 50 * factor ) { - fuzzy_var = sprintf("%.0f", fuzzy_var / (5 * factor)) * 5 * factor; - rounded = 1; - } - else if ( fuzzy_var <= 100 * factor) { - fuzzy_var = sprintf("%.0f", fuzzy_var / (10 * factor)) * 10 * factor; - rounded = 1; - } - else if ( fuzzy_var <= 250 * factor) { - fuzzy_var = sprintf("%.0f", fuzzy_var / (25 * factor)) * 25 * factor; - rounded = 1; - } - factor = factor * 10; - }' - -fuzz () { - awk -v fuzzy_var="$1" "BEGIN { ${fuzzy_formula} print fuzzy_var;}" -} - -fuzzy_pct () { - local pct="$(awk -v one="$1" -v two="$2" 'BEGIN{ if (two > 0) { printf "%d", one/two*100; } else {print 0} }')"; - echo "$(fuzz "${pct}")%" -} - -section () { - local str="$1" - awk -v var="${str} _" 'BEGIN { - line = sprintf("# %-60s", var); - i = index(line, "_"); - x = substr(line, i); - gsub(/[_ \t]/, "#", x); - printf("%s%s\n", substr(line, 1, i-1), x); - }' -} - -NAME_VAL_LEN=12 -name_val () { - printf "%+*s | %s\n" "${NAME_VAL_LEN}" "$1" "$2" -} - -shorten() { - local num="$1" - local prec="${2:-2}" - local div="${3:-1024}" - - echo "$num" | awk -v prec="$prec" -v div="$div" ' - { - num = $1; - unit = num >= 1125899906842624 ? "P" \ - : num >= 1099511627776 ? "T" \ - : num >= 1073741824 ? "G" \ - : num >= 1048576 ? "M" \ - : num >= 1024 ? "k" \ - : ""; - while ( num >= div ) { - num /= div; - } - printf "%.*f%s", prec, num, unit; - } - ' -} - -group_concat () { - sed -e '{H; $!d;}' -e 'x' -e 's/\n[[:space:]]*\([[:digit:]]*\)[[:space:]]*/, \1x/g' -e 's/[[:space:]][[:space:]]*/ /g' -e 's/, //' "${1}" -} - # ########################################################################### # End report_formatting package # ########################################################################### @@ -729,123 +93,6 @@ group_concat () { # See https://github.com/percona/percona-toolkit for more information. # ########################################################################### - -set -u - -CMD_FILE="$( _which file 2>/dev/null )" -CMD_NM="$( _which nm 2>/dev/null )" -CMD_OBJDUMP="$( _which objdump 2>/dev/null )" - -get_nice_of_pid () { - local pid="$1" - local niceness="$(ps -p $pid -o nice | awk '$1 !~ /[^0-9]/ {print $1; exit}')" - - if [ -n "${niceness}" ]; then - echo $niceness - else - local tmpfile="$PT_TMPDIR/nice_through_c.tmp.c" - _d "Getting the niceness from ps failed, somehow. We are about to try this:" - cat < "$tmpfile" - -int main(void) { - int priority = getpriority(PRIO_PROCESS, $pid); - if ( priority == -1 && errno == ESRCH ) { - return 1; - } - else { - printf("%d\\n", priority); - return 0; - } -} - -EOC - local c_comp=$(_which gcc) - if [ -z "${c_comp}" ]; then - c_comp=$(_which cc) - fi - _d "$tmpfile: $( cat "$tmpfile" )" - _d "$c_comp -xc \"$tmpfile\" -o \"$tmpfile\" && eval \"$tmpfile\"" - $c_comp -xc "$tmpfile" -o "$tmpfile" 2>/dev/null && eval "$tmpfile" 2>/dev/null - if [ $? -ne 0 ]; then - echo "?" - _d "Failed to get a niceness value for $pid" - fi - fi -} - -get_oom_of_pid () { - local pid="$1" - local oom_adj="" - - if [ -n "${pid}" -a -e /proc/cpuinfo ]; then - if [ -s "/proc/$pid/oom_score_adj" ]; then - oom_adj=$(cat "/proc/$pid/oom_score_adj" 2>/dev/null) - _d "For $pid, the oom value is $oom_adj, retrieved from oom_score_adj" - else - oom_adj=$(cat "/proc/$pid/oom_adj" 2>/dev/null) - _d "For $pid, the oom value is $oom_adj, retrieved from oom_adj" - fi - fi - - if [ -n "${oom_adj}" ]; then - echo "${oom_adj}" - else - echo "?" - _d "Can't find the oom value for $pid" - fi -} - -has_symbols () { - local executable="$(_which "$1")" - local has_symbols="" - - if [ "${CMD_FILE}" ] \ - && [ "$($CMD_FILE "${executable}" | grep 'not stripped' )" ]; then - has_symbols=1 - elif [ "${CMD_NM}" ] \ - || [ "${CMD_OBJDMP}" ]; then - if [ "${CMD_NM}" ] \ - && [ !"$("${CMD_NM}" -- "${executable}" 2>&1 | grep 'File format not recognized' )" ]; then - if [ -z "$( $CMD_NM -- "${executable}" 2>&1 | grep ': no symbols' )" ]; then - has_symbols=1 - fi - elif [ -z "$("${CMD_OBJDUMP}" -t -- "${executable}" | grep '^no symbols$' )" ]; then - has_symbols=1 - fi - fi - - if [ "${has_symbols}" ]; then - echo "Yes" - else - echo "No" - fi -} - -setup_data_dir () { - local existing_dir="$1" - local data_dir="" - if [ -z "$existing_dir" ]; then - mkdir "$PT_TMPDIR/data" || die "Cannot mkdir $PT_TMPDIR/data" - data_dir="$PT_TMPDIR/data" - else - if [ ! -d "$existing_dir" ]; then - mkdir "$existing_dir" || die "Cannot mkdir $existing_dir" - elif [ "$( ls -A "$existing_dir" )" ]; then - die "--save-samples directory isn't empty, halting." - fi - touch "$existing_dir/test" || die "Cannot write to $existing_dir" - rm "$existing_dir/test" || die "Cannot rm $existing_dir/test" - data_dir="$existing_dir" - fi - echo "$data_dir" -} - -get_var () { - local varname="$1" - local file="$2" - awk -v pattern="${varname}" '$1 == pattern { if (length($2)) { len = length($1); print substr($0, len+index(substr($0, len+1), $2)) } }' "${file}" -} - # ########################################################################### # End summary_common package # ########################################################################### @@ -859,307 +106,6 @@ get_var () { # See https://github.com/percona/percona-toolkit for more information. # ########################################################################### - - -CMD_MYSQL="${CMD_MYSQL:-""}" -CMD_MYSQLDUMP="${CMD_MYSQLDUMP:-""}" - -collect_mysqld_instances () { - local variables_file="$1" - - local pids="$(_pidof mysqld)" - - if [ -n "$pids" ]; then - - for pid in $pids; do - local nice="$( get_nice_of_pid $pid )" - local oom="$( get_oom_of_pid $pid )" - echo "internal::nice_of_$pid $nice" >> "$variables_file" - echo "internal::oom_of_$pid $oom" >> "$variables_file" - done - - pids="$(echo $pids | sed -e 's/ /,/g')" - ps ww -p "$pids" 2>/dev/null - else - echo "mysqld doesn't appear to be running" - fi - -} - -find_my_cnf_file() { - local file="$1" - local port="${2:-""}" - local pid_file="${3:-""}" - - local cnf_file="" - - if [ "$pid_file" ]; then - local pid=$(cat "$pid_file") - cnf_file="$(grep --max-count 1 -E "^\s*$pid\s+" "$file" \ - | awk 'BEGIN{RS=" "; FS="=";} $1 ~ /--defaults-file/ { print $2; }')" - - if [ -n "$cnf_file" ]; then - echo "$cnf_file" - return - fi - fi - - if [ "$port" ]; then - cnf_file="$(grep --max-count 1 "/mysqld.*--port=$port" "$file" \ - | awk 'BEGIN{RS=" "; FS="=";} $1 ~ /--defaults-file/ { print $2; }')" - - if [ -n "$cnf_file" ]; then - echo "$cnf_file" - return - fi - else - cnf_file="$(grep --max-count 1 '/mysqld' "$file" \ - | awk 'BEGIN{RS=" "; FS="=";} $1 ~ /--defaults-file/ { print $2; }')" - fi - - if [ -z "$cnf_file" ]; then - if [ -e "/etc/my.cnf" ]; then - cnf_file="/etc/my.cnf" - elif [ -e "/etc/mysql/my.cnf" ]; then - cnf_file="/etc/mysql/my.cnf" - elif [ -e "/var/db/mysql/my.cnf" ]; then - cnf_file="/var/db/mysql/my.cnf"; - fi - fi - - echo "$cnf_file" -} - -collect_mysql_variables () { - $CMD_MYSQL $EXT_ARGV -ss -e 'SHOW /*!40100 GLOBAL*/ VARIABLES' -} - -collect_mysql_status () { - $CMD_MYSQL $EXT_ARGV -ss -e 'SHOW /*!50000 GLOBAL*/ STATUS' -} - -collect_mysql_databases () { - $CMD_MYSQL $EXT_ARGV -ss -e 'SHOW DATABASES' 2>/dev/null -} - -collect_mysql_plugins () { - $CMD_MYSQL $EXT_ARGV -ss -e 'SHOW PLUGINS' 2>/dev/null -} - -collect_mysql_slave_status () { - $CMD_MYSQL $EXT_ARGV -ssE -e 'SHOW SLAVE STATUS' 2>/dev/null -} - -collect_mysql_innodb_status () { - $CMD_MYSQL $EXT_ARGV -ssE -e 'SHOW /*!50000 ENGINE*/ INNODB STATUS' 2>/dev/null -} - -collect_mysql_ndb_status () { - $CMD_MYSQL $EXT_ARGV -ssE -e 'show /*!50000 ENGINE*/ NDB STATUS' 2>/dev/null -} - -collect_mysql_processlist () { - $CMD_MYSQL $EXT_ARGV -ssE -e 'SHOW FULL PROCESSLIST' 2>/dev/null -} - -collect_mysql_users () { - $CMD_MYSQL $EXT_ARGV -ss -e "SELECT COUNT(*), SUM(user=''), SUM(password=''), SUM(password NOT LIKE '*%') FROM mysql.user" 2>/dev/null - if [ "$?" -ne 0 ]; then - $CMD_MYSQL $EXT_ARGV -ss -e "SELECT COUNT(*), SUM(user=''), SUM(authentication_string=''), SUM(authentication_string NOT LIKE '*%') FROM mysql.user WHERE account_locked <> 'Y' AND password_expired <> 'Y' AND authentication_string <> ''" 2>/dev/null - fi -} - -collect_mysql_roles () { - QUERY="SELECT DISTINCT User 'Role Name', if(from_user is NULL,0, 1) Active FROM mysql.user LEFT JOIN mysql.role_edges ON from_user=user WHERE account_locked='Y' AND password_expired='Y' AND authentication_string=''\G" - $CMD_MYSQL $EXT_ARGV -ss -e "$QUERY" 2>/dev/null -} - -collect_mysql_show_slave_hosts () { - $CMD_MYSQL $EXT_ARGV -ssE -e 'SHOW SLAVE HOSTS' 2>/dev/null -} - -collect_master_logs_status () { - local master_logs_file="$1" - local master_status_file="$2" - $CMD_MYSQL $EXT_ARGV -ss -e 'SHOW MASTER LOGS' > "$master_logs_file" 2>/dev/null - $CMD_MYSQL $EXT_ARGV -ss -e 'SHOW MASTER STATUS' > "$master_status_file" 2>/dev/null -} - -collect_mysql_deferred_status () { - local status_file="$1" - collect_mysql_status > "$PT_TMPDIR/defer_gatherer" - join "$status_file" "$PT_TMPDIR/defer_gatherer" -} - -collect_internal_vars () { - local mysqld_executables="${1:-""}" - - local FNV_64="" - if $CMD_MYSQL $EXT_ARGV -e "SELECT FNV_64('a')" >/dev/null 2>&1; then - FNV_64="Enabled"; - else - FNV_64="Unknown"; - fi - - local now="$($CMD_MYSQL $EXT_ARGV -ss -e 'SELECT NOW()')" - local user="$($CMD_MYSQL $EXT_ARGV -ss -e 'SELECT CURRENT_USER()')" - local trigger_count=$($CMD_MYSQL $EXT_ARGV -ss -e "SELECT COUNT(*) FROM INFORMATION_SCHEMA.TRIGGERS" 2>/dev/null) - - echo "pt-summary-internal-mysql_executable $CMD_MYSQL" - echo "pt-summary-internal-now $now" - echo "pt-summary-internal-user $user" - echo "pt-summary-internal-FNV_64 $FNV_64" - echo "pt-summary-internal-trigger_count $trigger_count" - - if [ -e "$mysqld_executables" ]; then - local i=1 - while read executable; do - echo "pt-summary-internal-mysqld_executable_${i} $(has_symbols "$executable")" - i=$(($i + 1)) - done < "$mysqld_executables" - fi - - local JEMALLOC_STATUS='' - local GENERAL_JEMALLOC_STATUS=0 - local JEMALLOC_LOCATION='' - - for pid in $(pidof mysqld); do - grep -qc jemalloc /proc/${pid}/environ || ldd $(which mysqld) 2>/dev/null | grep -qc jemalloc - jemalloc_status=$? - if [ $jemalloc_status = 1 ]; then - echo "pt-summary-internal-jemalloc_enabled_for_pid_${pid} 0" - else - echo "pt-summary-internal-jemalloc_enabled_for_pid_${pid} 1" - GENERAL_JEMALLOC_STATUS=1 - fi - done - - if [ $GENERAL_JEMALLOC_STATUS -eq 1 ]; then - JEMALLOC_LOCATION=$(find /usr/lib64/ /usr/lib/x86_64-linux-gnu /usr/lib -name "libjemalloc.*" 2>/dev/null | head -n 1) - echo "pt-summary-internal-jemalloc_location ${JEMALLOC_LOCATION}" - fi -} - -collect_keyring_plugins() { - $CMD_MYSQL $EXT_ARGV --table -ss -e "SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE 'keyring%';" -} - -collect_encrypted_tables() { - $CMD_MYSQL $EXT_ARGV --table -ss -e "SELECT TABLE_SCHEMA, TABLE_NAME, CREATE_OPTIONS FROM INFORMATION_SCHEMA.TABLES WHERE CREATE_OPTIONS LIKE '%ENCRYPTION=_Y_%';" -} - -collect_encrypted_tablespaces() { - local version="$1" - if [ "$version" '<' "8.0" ]; then - $CMD_MYSQL $EXT_ARGV --table -ss -e "SELECT SPACE, NAME, SPACE_TYPE from INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES where FLAG&8192 = 8192;" - else - $CMD_MYSQL $EXT_ARGV --table -ss -e "SELECT SPACE, NAME, SPACE_TYPE from INFORMATION_SCHEMA.INNODB_TABLESPACES where FLAG&8192 = 8192;" - fi -} - -get_mysqldump_for () { - local args="$1" - local dbtodump="${2:-"--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} --databases $(local IFS=,; echo ${dbtodump}) -} - -get_mysqldump_args () { - local file="$1" - local trg_arg="" - - if $CMD_MYSQLDUMP --help --verbose 2>&1 | grep triggers >/dev/null; then - 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 - triggers="--triggers" - fi - trg_arg="${trg_arg} ${triggers}"; - fi - echo "${trg_arg}" -} - -collect_mysqld_executables () { - local mysqld_instances="$1" - - local ps_opt="cmd=" - if [ "$(uname -s)" = "Darwin" ]; then - ps_opt="command=" - fi - - for pid in $( grep '/mysqld' "$mysqld_instances" | awk '/^.*[0-9]/{print $1}' ); do - ps -o $ps_opt -p $pid | sed -e 's/^\(.*mysqld\) .*/\1/' - done | sort -u -} - -collect_mysql_info () { - local dir="$1" - - collect_mysql_variables > "$dir/mysql-variables" - collect_mysql_status > "$dir/mysql-status" - collect_mysql_databases > "$dir/mysql-databases" - collect_mysql_plugins > "$dir/mysql-plugins" - collect_mysql_slave_status > "$dir/mysql-slave" - collect_mysql_innodb_status > "$dir/innodb-status" - collect_mysql_ndb_status > "$dir/ndb-status" - collect_mysql_processlist > "$dir/mysql-processlist" - collect_mysql_users > "$dir/mysql-users" - collect_mysql_roles > "$dir/mysql-roles" - collect_keyring_plugins > "$dir/keyring-plugins" - - collect_mysqld_instances "$dir/mysql-variables" > "$dir/mysqld-instances" - collect_mysqld_executables "$dir/mysqld-instances" > "$dir/mysqld-executables" - collect_mysql_show_slave_hosts "$dir/mysql-slave-hosts" > "$dir/mysql-slave-hosts" - - local binlog="$(get_var log_bin "$dir/mysql-variables")" - if [ "${binlog}" ]; then - collect_master_logs_status "$dir/mysql-master-logs" "$dir/mysql-master-status" - fi - - local uptime="$(get_var Uptime "$dir/mysql-status")" - local current_time="$($CMD_MYSQL $EXT_ARGV -ss -e \ - "SELECT LEFT(NOW() - INTERVAL ${uptime} SECOND, 16)")" - - local pid_file="$(get_var "pid_file" "$dir/mysql-variables")" - local pid_file_exists="" - [ -e "${pid_file}" ] && pid_file_exists=1 - echo "pt-summary-internal-pid_file_exists $pid_file_exists" >> "$dir/mysql-variables" - - local port="$(get_var port "$dir/mysql-variables")" - local cnf_file="$(find_my_cnf_file "$dir/mysqld-instances" ${port} ${pid_file})" - - [ -e "$cnf_file" ] && cat "$cnf_file" > "$dir/mysql-config-file" - - echo "pt-summary-internal-current_time $current_time" >> "$dir/mysql-variables" - echo "pt-summary-internal-Config_File_path $cnf_file" >> "$dir/mysql-variables" - collect_internal_vars "$dir/mysqld-executables" >> "$dir/mysql-variables" - - if [ "$OPT_DATABASES" -o "$OPT_ALL_DATABASES" ]; then - local trg_arg="$(get_mysqldump_args "$dir/mysql-variables")" - local dbs="${OPT_DATABASES:-""}" - get_mysqldump_for "${trg_arg}" "$dbs" > "$dir/mysqldump" - fi - - if [ "${OPT_LIST_ENCRYPTED_TABLES}" = 'yes' ]; then - local mysql_version="$(get_var version "$dir/mysql-variables")" - collect_encrypted_tables > "$dir/encrypted-tables" - collect_encrypted_tablespaces ${mysql_version} > "$dir/encrypted-tablespaces" - fi - - ( - sleep $OPT_SLEEP - collect_mysql_deferred_status "$dir/mysql-status" > "$dir/mysql-status-defer" - ) & - _d "Forked child is $!" -} - # ########################################################################### # End collect_mysql_info package # ########################################################################### @@ -1173,1491 +119,6 @@ collect_mysql_info () { # See https://github.com/percona/percona-toolkit for more information. # ########################################################################### - -set -u -POSIXLY_CORRECT=1 - -secs_to_time () { - awk -v sec="$1" 'BEGIN { - printf( "%d+%02d:%02d:%02d", sec / 86400, (sec % 86400) / 3600, (sec % 3600) / 60, sec % 60); - }' -} - -feat_on() { - local file="$1" - local varname="$2" - [ -e "$file" ] || return - - if [ "$( grep "$varname" "${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 -} - -feat_on_renamed () { - local file="$1" - shift; - - for varname in "$@"; do - local feat_on="$( feat_on "$file" $varname )" - if [ "${feat_on:-"Not Supported"}" != "Not Supported" ]; then - echo $feat_on - return - fi - done - - echo "Not Supported" -} - -get_table_cache () { - local file="$1" - - [ -e "$file" ] || return - - local table_cache="" - if [ "$( get_var 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} -} - -get_plugin_status () { - local file="$1" - local plugin="$2" - - local status="$(grep -w "$plugin" "$file" | awk '{ print $2 }')" - - echo ${status:-"Not found"} -} - - -_NO_FALSE_NEGATIVES="" -parse_mysqld_instances () { - local file="$1" - local variables_file="$2" - - local socket="" - local port="" - local datadir="" - local defaults_file="" - - [ -e "$file" ] || return - - echo " Port Data Directory Nice OOM Socket" - echo " ===== ========================== ==== === ======" - - grep '/mysqld ' "$file" | while read line; do - local pid=$(echo "$line" | awk '{print $1;}') - for word in ${line}; do - 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 - if echo "${word}" | grep -- "--defaults-file=" > /dev/null; then - defaults_file="$(echo "${word}" | cut -d= -f2)" - fi - done - - if [ -n "${defaults_file:-""}" -a -r "${defaults_file:-""}" ]; then - socket="${socket:-"$(grep "^socket\>" "$defaults_file" | tail -n1 | cut -d= -f2 | sed 's/^[ \t]*//;s/[ \t]*$//')"}" - port="${port:-"$(grep "^port\>" "$defaults_file" | tail -n1 | cut -d= -f2 | sed 's/^[ \t]*//;s/[ \t]*$//')"}" - datadir="${datadir:-"$(grep "^datadir\>" "$defaults_file" | tail -n1 | cut -d= -f2 | sed 's/^[ \t]*//;s/[ \t]*$//')"}" - fi - - local nice="$(get_var "internal::nice_of_$pid" "$variables_file")" - local oom="$(get_var "internal::oom_of_$pid" "$variables_file")" - if [ -n "${_NO_FALSE_NEGATIVES}" ]; then - nice="?" - oom="?" - fi - printf " %5s %-26s %-4s %-3s %s\n" "${port}" "${datadir}" "${nice:-"?"}" "${oom:-"?"}" "${socket}" - - defaults_file="" - socket="" - port="" - datadir="" - done -} - -get_mysql_timezone () { - local file="$1" - - [ -e "$file" ] || return - - local tz="$(get_var time_zone "${file}")" - if [ "${tz}" = "SYSTEM" ]; then - tz="$(get_var system_time_zone "${file}")" - fi - echo "${tz}" -} - -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}")" -} - -get_mysql_uptime () { - local uptime="$1" - local restart="$2" - uptime="$(secs_to_time ${uptime})" - echo "${restart} (up ${uptime})" -} - -summarize_binlogs () { - local file="$1" - - [ -e "$file" ] || return - - 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" - [ -e "$file" ] || return - awk '{printf "%d users, %d anon, %d w/o pw, %d old pw\n", $1, $2, $3, $4}' "${file}" -} - -format_binlog_filters () { - local file="$1" - [ -e "$file" ] || return - name_val "binlog_do_db" "$(cut -f3 "$file")" - name_val "binlog_ignore_db" "$(cut -f4 "$file")" -} - -format_status_variables () { - local file="$1" - [ -e "$file" ] || return - - utime1="$(awk '/Uptime /{print $2}' "$file")"; - utime2="$(awk '/Uptime /{print $3}' "$file")"; - awk " - BEGIN { - utime1 = ${utime1}; - utime2 = ${utime2}; - udays = utime1 / 86400; - udiff = utime2 - utime1; - printf(\"%-35s %11s %11s %11s\\n\", \"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 ) { - perday_format=\"%11.f\"; - persec_format=\"%11.f\"; - nowsec_format=\"%11.f\"; - if ( perday == 0 ) { perday = \"\"; perday_format=\"%11s\"; } - if ( persec == 0 ) { persec = \"\"; persec_format=\"%11s\"; } - if ( nowsec == 0 ) { nowsec = \"\"; nowsec_format=\"%11s\"; } - format=\"%-35s \" perday_format \" \" persec_format \" \" nowsec_format \"\\n\"; - printf(format, \$1, perday, persec, nowsec); - } - } - }" "$file" -} - -summarize_processlist () { - local file="$1" - - [ -e "$file" ] || return - - 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; - if ( t == \"NULL\" ) { - t = 0; - } - } - \$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_print_cnf_file () { - local file="$1" - - [ -e "$file" ] || return - - perl -n -l -e ' - my $line = $_; - if ( $line =~ /^\s*[a-zA-Z[]/ ) { - if ( $line=~/\s*(.*?)\s*=\s*(.*)\s*$/ ) { - printf("%-35s = %s\n", $1, $2) - } - elsif ( $line =~ /\s*\[/ ) { - print "\n$line" - } else { - print $line - } - }' "$file" - - while read line; do - echo $line | grep -q '!include' - if [ $? -eq 0 ]; then - clause=$(echo -n $line | tr -s ' ' | cut -d ' ' -f 1) - include=$(echo -n $line | tr -s ' ' | cut -d ' ' -f 2) - - if [ "x$include" != "x" -a -d "${include}" -a "x$clause" = 'x!includedir' ]; then - for subfile in $(find -L "$include" -type f -maxdepth 1 -name *.cnf ); do - echo "# $subfile" - pretty_print_cnf_file $subfile - done - elif [ -f "$include" -a "$clause" = '!include' ]; then - echo "# $include" - pretty_print_cnf_file $include - fi - fi - - done < "$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" - - [ -e "$file" ] || return - - 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" - - [ -e "$file" ] || return - - 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" - - [ -e "$file" ] || return - - 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" - - [ -e "$file" ] || return - - 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" - - [ -e "$file" ] || return - - 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_transaction_states () { - local file="$1" - local tmpfile="$PT_TMPDIR/find_transaction_states.tmp" - - [ -e "$file" ] || return - - awk -F, '/^---TRANSACTION/{print $2}' "${file}" \ - | sed -e 's/ [0-9]* sec.*//' \ - | sort \ - | uniq -c > "${tmpfile}" - group_concat "${tmpfile}" -} - -format_innodb_status () { - local file=$1 - - [ -e "$file" ] || return - - 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_transaction_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 -} - -format_ndb_status() { - local file=$1 - - [ -e "$file" ] || return - egrep '^[ \t]*Name:|[ \t]*Status:' $file|sed 's/^[ \t]*//g'|while read line; do echo $line; echo $line | grep '^Status:'>/dev/null && echo ; done -} - -format_keyring_plugins() { - local keyring_plugins="$1" - local encrypted_tables="$2" - - if [ -z "$keyring_plugins" ]; then - echo "No keyring plugins found" - if [ ! -z "$encrypted_tables" ]; then - echo "Warning! There are encrypted tables but keyring plugins are not loaded" - fi - else - echo "Keyring plugins:" - echo "'$keyring_plugins'" - fi -} - -format_encrypted_tables() { - local encrypted_tables="$1" - if [ ! -z "$encrypted_tables" ]; then - echo "Encrypted tables:" - echo "$encrypted_tables" - fi -} - -format_encrypted_tablespaces() { - local encrypted_tablespaces="$1" - if [ ! -z "$encrypted_tablespaces" ]; then - echo "Encrypted tablespaces:" - echo "$encrypted_tablespaces" - fi -} - -format_mysql_roles() { - local file=$1 - [ -e "$file" ] || return - cat $file -} - -format_overall_db_stats () { - local file="$1" - local tmpfile="$PT_TMPDIR/format_overall_db_stats.tmp" - - [ -e "$file" ] || return - - echo - awk ' - BEGIN { - 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/ { - 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 - awk ' - BEGIN { - 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=/ { - if (num_dbs == 0) { - num_dbs = 1; - db_seen[db] = 1; - dbs[0] = db; - } - engine=substr($2, index($2, "=") + 1); - if ( engine_seen[tolower(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 - awk ' - BEGIN { - 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/ { - 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 - awk ' - BEGIN { - 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++; - } - } - /^ `/ { - 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" - - [ -e "$file" ] || return - - name_val "Table & Index Stats" \ - "$(feat_on_renamed "$file" userstat_running userstat)" - name_val "Multiple I/O Threads" \ - "$(feat_on "$file" innodb_read_io_threads gt 1)" - - name_val "Corruption Resilient" \ - "$(feat_on_renamed "$file" innodb_pass_corrupt_table innodb_corrupt_table_action)" - - name_val "Durable Replication" \ - "$(feat_on_renamed "$file" innodb_overwrite_relay_log_info innodb_recovery_update_relay_log)" - - name_val "Import InnoDB Tables" \ - "$(feat_on_renamed "$file" innodb_expand_import innodb_import_table_from_xtrabackup)" - - name_val "Fast Server Restarts" \ - "$(feat_on_renamed "$file" innodb_auto_lru_dump innodb_buffer_pool_restore_at_startup)" - - 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_renamed "$file" enable_query_response_time_stats query_response_time_stats)" - - local smooth_flushing="$(feat_on_renamed "$file" innodb_adaptive_checkpoint innodb_adaptive_flushing_method)" - if [ "${smooth_flushing:-""}" != "Not Supported" ]; then - if [ -n "$(get_var innodb_adaptive_checkpoint "$file")" ]; then - smooth_flushing="$(feat_on "$file" "innodb_adaptive_checkpoint" ne none)" - else - smooth_flushing="$(feat_on "$file" "innodb_adaptive_flushing_method" ne native)" - fi - fi - name_val "Smooth Flushing" "$smooth_flushing" - - name_val "HandlerSocket NoSQL" \ - "$(feat_on "$file" handlersocket_port)" - name_val "Fast Hash UDFs" \ - "$(get_var "pt-summary-internal-FNV_64" "$file")" -} - -section_myisam () { - local variables_file="$1" - local status_file="$2" - - [ -e "$variables_file" -a -e "$status_file" ] || return - - 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:-0} * ${blk_size:-0})) - local unfl=$((${blk_unfl:-0} * ${blk_size:-0})) - local used=$((${buf_size:-0} - ${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" - - [ -e "$variables_file" -a -e "$status_file" ] || return - - 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:-0}" 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})) - - local transaction_isolation_var="transaction_isolation" - if [ "$version" '<' "5.7.20" ]; then # false if version >= 5.7.20 - transaction_isolation_var="tx_isolation" - fi - - 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=$(awk "BEGIN {printf \"%.2f\n\", ${log_size}*${log_file}}" ) - name_val "Log File Size" \ - "${log_file} * $(shorten ${log_size} 1) = $(shorten ${log_total} 1)" - 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 $transaction_isolation_var "$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_rocksdb () { - local variables_file="$1" - local status_file="$2" - - local NAME_VAL_LEN=32 - - [ -e "$variables_file" -a -e "$status_file" ] || return - - name_val "Block Cache Size" "$(shorten $(get_var rocksdb_block_cache_size "$variables_file") 0)" - name_val "Block Size" "$(shorten $(get_var rocksdb_block_size "$variables_file") 0)" - name_val "Bytes Per Sync" "$(shorten $(get_var rocksdb_bytes_per_sync "$variables_file") 0)" - name_val "Compaction Seq Deletes " "$(shorten $(get_var rocksdb_compaction_sequential_deletes "$variables_file") 0)" - name_val "Compaction Seq Deletes Count SD" "$(get_var rocksdb_compaction_sequential_deletes_count_sd "$variables_file")" - name_val "Compaction Seq Deletes Window" "$(shorten $(get_var rocksdb_compaction_sequential_deletes_window "$variables_file") 0)" - name_val "Default CF Options" "$(get_var rocksdb_default_cf_options "$variables_file")" - name_val "Max Background Jobs" "$(shorten $(get_var rocksdb_max_background_jobs "$variables_file") 0)" - name_val "Max Block Cache Size" "$(shorten $(get_var rocksdb_max_block_cache_size "$variables_file") 0)" - name_val "Max Block Size" "$(shorten $(get_var rocksdb_max_block_size "$variables_file") 0)" - name_val "Max Open Files" "$(shorten $(get_var rocksdb_max_open_files "$variables_file") 0)" - name_val "Max Total Wal Size" "$(shorten $(get_var rocksdb_max_total_wal_size "$variables_file") 0)" - name_val "Rate Limiter Bytes Per Second" "$(shorten $(get_var rocksdb_rate_limiter_bytes_per_sec "$variables_file") 0)" - name_val "Rate Limiter Bytes Per Sync" "$(shorten $(get_var rocksdb_bytes_per_sync "$variables_file") 0)" - name_val "Rate Limiter Wal Bytes Per Sync" "$(shorten $(get_var rocksdb_wal_bytes_per_sync "$variables_file") 0)" - name_val "Table Cache NumHardBits" "$(shorten $(get_var rocksdb_table_cache_numshardbits "$variables_file") 0)" - name_val "Wal Bytes per Sync" "$(shorten $(get_var rocksdb_wal_bytes_per_sync "$variables_file") 0)" -} - -section_noteworthy_variables () { - local file="$1" - - [ -e "$file" ] || return - - 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 -} - -_semi_sync_stats_for () { - local target="$1" - local file="$2" - - [ -e "$file" ] || return - - 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 -} - -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 -} - -section_mysqld () { - local executables_file="$1" - local variables_file="$2" - - [ -e "$executables_file" -a -e "$variables_file" ] || return - - section "MySQL Executable" - local i=1; - while read executable; do - name_val "Path to executable" "$executable" - name_val "Has symbols" "$( get_var "pt-summary-internal-mysqld_executable_${i}" "$variables_file" )" - i=$(($i + 1)) - done < "$executables_file" -} - -section_slave_hosts () { - local slave_hosts_file="$1" - - [ -e "$slave_hosts_file" ] || return - - section "Slave Hosts" - if [ -s "$slave_hosts_file" ]; then - cat "$slave_hosts_file" - else - echo "No slaves found" - fi -} - -section_mysql_files () { - local variables_file="$1" - - section "MySQL Files" - for file_name in pid_file slow_query_log_file general_log_file log_error; do - local file="$(get_var "${file_name}" "$variables_file")" - local name_out="$(echo "$file_name" | sed 'y/[a-z]/[A-Z]/')" - if [ -e "${file}" ]; then - name_val "$name_out" "$file" - name_val "${name_out} Size" "$(du "$file" | awk '{print $1}')" - else - name_val "$name_out" "(does not exist)" - fi - done -} - -section_percona_xtradb_cluster () { - local mysql_var="$1" - local mysql_status="$2" - - name_val "Cluster Name" "$(get_var "wsrep_cluster_name" "$mysql_var")" - name_val "Cluster Address" "$(get_var "wsrep_cluster_address" "$mysql_var")" - name_val "Cluster Size" "$(get_var "wsrep_cluster_size" "$mysql_status")" - name_val "Cluster Nodes" "$(get_var "wsrep_incoming_addresses" "$mysql_status")" - - name_val "Node Name" "$(get_var "wsrep_node_name" "$mysql_var")" - name_val "Node Status" "$(get_var "wsrep_cluster_status" "$mysql_status")" - - name_val "SST Method" "$(get_var "wsrep_sst_method" "$mysql_var")" - name_val "Slave Threads" "$(get_var "wsrep_slave_threads" "$mysql_var")" - - name_val "Ignore Split Brain" "$( parse_wsrep_provider_options "pc.ignore_sb" "$mysql_var" )" - name_val "Ignore Quorum" "$( parse_wsrep_provider_options "pc.ignore_quorum" "$mysql_var" )" - - name_val "gcache Size" "$( parse_wsrep_provider_options "gcache.size" "$mysql_var" )" - name_val "gcache Directory" "$( parse_wsrep_provider_options "gcache.dir" "$mysql_var" )" - name_val "gcache Name" "$( parse_wsrep_provider_options "gcache.name" "$mysql_var" )" -} - -parse_wsrep_provider_options () { - local looking_for="$1" - local mysql_var_file="$2" - - grep wsrep_provider_options "$mysql_var_file" \ - | perl -Mstrict -le ' - my $provider_opts = scalar(); - my $looking_for = $ARGV[0]; - my %opts = $provider_opts =~ /(\S+)\s*=\s*(\S*)(?:;|$)/g; - print $opts{$looking_for}; - ' "$looking_for" -} - -report_jemalloc_enabled() { - local instances_file="$1" - local variables_file="$2" - local GENERAL_JEMALLOC_STATUS=0 - - for pid in $(grep '/mysqld ' "$instances_file" | awk '{print $1;}'); do - local jemalloc_status="$(get_var "pt-summary-internal-jemalloc_enabled_for_pid_${pid}" "${variables_file}")" - if [ -z $jemalloc_status ]; then - continue - elif [ $jemalloc_status = 0 ]; then - echo "jemalloc is not enabled in mysql config for process with id ${pid}" - else - echo "jemalloc enabled in mysql config for process with id ${pid}" - GENERAL_JEMALLOC_STATUS=1 - fi - done - - if [ $GENERAL_JEMALLOC_STATUS -eq 1 ]; then - local jemalloc_location="$(get_var "pt-summary-internal-jemalloc_location" "${variables_file}")" - if [ -n "$jemalloc_location" ]; then - echo "Using jemalloc from $jemalloc_location" - else - echo "Jemalloc library not found" - fi - fi - -} - -report_mysql_summary () { - local dir="$1" - - local NAME_VAL_LEN=25 - - - 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/mysqld-instances" "$dir/mysql-variables" - - section_mysqld "$dir/mysqld-executables" "$dir/mysql-variables" - - section_slave_hosts "$dir/mysql-slave-hosts" - local user="$(get_var "pt-summary-internal-user" "$dir/mysql-variables")" - local port="$(get_var port "$dir/mysql-variables")" - local now="$(get_var "pt-summary-internal-now" "$dir/mysql-variables")" - section "Report On Port ${port}" - name_val User "${user}" - name_val Time "${now} ($(get_mysql_timezone "$dir/mysql-variables"))" - name_val Hostname "$(get_var hostname "$dir/mysql-variables")" - get_mysql_version "$dir/mysql-variables" - - local uptime="$(get_var Uptime "$dir/mysql-status")" - local current_time="$(get_var "pt-summary-internal-current_time" "$dir/mysql-variables")" - name_val Started "$(get_mysql_uptime "${uptime}" "${current_time}")" - - local num_dbs="$(grep -c . "$dir/mysql-databases")" - name_val Databases "${num_dbs}" - name_val Datadir "$(get_var datadir "$dir/mysql-variables")" - - local fuzz_procs=$(fuzz $(get_var Threads_connected "$dir/mysql-status")) - local fuzz_procr=$(fuzz $(get_var Threads_running "$dir/mysql-status")) - name_val Processes "${fuzz_procs} connected, ${fuzz_procr} running" - - local slave="" - if [ -s "$dir/mysql-slave" ]; then slave=""; else slave="not "; fi - local slavecount=$(grep -c 'Binlog Dump' "$dir/mysql-processlist") - name_val Replication "Is ${slave}a slave, has ${slavecount} slaves connected" - - - local pid_file="$(get_var "pid_file" "$dir/mysql-variables")" - local PID_EXISTS="" - if [ "$( get_var "pt-summary-internal-pid_file_exists" "$dir/mysql-variables" )" ]; then - PID_EXISTS="(exists)" - else - PID_EXISTS="(does not exist)" - fi - name_val Pidfile "${pid_file} ${PID_EXISTS}" - - section "Processlist" - summarize_processlist "$dir/mysql-processlist" - - section "Status Counters (Wait ${OPT_SLEEP} Seconds)" - wait - local noncounters_pattern="$(noncounters_pattern)" - format_status_variables "$dir/mysql-status-defer" | grep -v "${noncounters_pattern}" - - section "Table cache" - local open_tables=$(get_var "Open_tables" "$dir/mysql-status") - local table_cache=$(get_table_cache "$dir/mysql-variables") - name_val Size $table_cache - name_val Usage "$(fuzzy_pct ${open_tables} ${table_cache})" - - section "Key Percona Server features" - section_percona_server_features "$dir/mysql-variables" - - section "Percona XtraDB Cluster" - local has_wsrep="$(get_var "wsrep_on" "$dir/mysql-variables")" - if [ -n "${has_wsrep:-""}" ]; then - local wsrep_on="$(feat_on "$dir/mysql-variables" "wsrep_on")" - if [ "${wsrep_on:-""}" = "Enabled" ]; then - section_percona_xtradb_cluster "$dir/mysql-variables" "$dir/mysql-status" - else - name_val "wsrep_on" "OFF" - fi - fi - - section "Plugins" - name_val "InnoDB compression" "$(get_plugin_status "$dir/mysql-plugins" "INNODB_CMP")" - - local has_query_cache=$(get_var have_query_cache "$dir/mysql-variables") - if [ "$has_query_cache" = 'YES' ]; then - section "Query cache" - local query_cache_size=$(get_var query_cache_size "$dir/mysql-variables") - local used=$(( ${query_cache_size} - $(get_var Qcache_free_memory "$dir/mysql-status") )) - local hrat=$(fuzzy_pct $(get_var Qcache_hits "$dir/mysql-status") $(get_var Qcache_inserts "$dir/mysql-status")) - name_val query_cache_type $(get_var query_cache_type "$dir/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/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/mysql-variables" - fi - local semisync_enabled_slave="$(get_var rpl_semi_sync_slave_enabled "$dir/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/mysql-variables" - fi - fi - - section "Schema" - if [ -s "$dir/mysqldump" ] \ - && grep 'CREATE TABLE' "$dir/mysqldump" >/dev/null 2>&1; then - format_overall_db_stats "$dir/mysqldump" - elif [ ! -e "$dir/mysqldump" -a "$OPT_READ_SAMPLES" ]; then - echo "Skipping schema analysis because --read-samples $dir/mysqldump " \ - "does not exist" - elif [ -z "$OPT_DATABASES" -a -z "$OPT_ALL_DATABASES" ]; then - echo "Specify --databases or --all-databases to dump and summarize schemas" - else - echo "Skipping schema analysis due to apparent error in dump file" - fi - - section "Noteworthy Technologies" - if [ -s "$dir/mysqldump" ]; then - if grep FULLTEXT "$dir/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/mysqldump" > /dev/null; then - name_val "Geospatial Types" "Yes" - else - name_val "Geospatial Types" "No" - fi - if grep 'FOREIGN KEY' "$dir/mysqldump" > /dev/null; then - name_val "Foreign Keys" "Yes" - else - name_val "Foreign Keys" "No" - fi - if grep 'PARTITION BY' "$dir/mysqldump" > /dev/null; then - name_val "Partitioning" "Yes" - else - name_val "Partitioning" "No" - fi - if grep -e 'ENGINE=InnoDB.*ROW_FORMAT' \ - -e 'ENGINE=InnoDB.*KEY_BLOCK_SIZE' "$dir/mysqldump" > /dev/null; then - name_val "InnoDB Compression" "Yes" - else - name_val "InnoDB Compression" "No" - fi - fi - local ssl="$(get_var Ssl_accepts "$dir/mysql-status")" - if [ -n "$ssl" -a "${ssl:-0}" -gt 0 ]; then - name_val "SSL" "Yes" - else - name_val "SSL" "No" - fi - local lock_tables="$(get_var Com_lock_tables "$dir/mysql-status")" - if [ -n "$lock_tables" -a "${lock_tables:-0}" -gt 0 ]; then - name_val "Explicit LOCK TABLES" "Yes" - else - name_val "Explicit LOCK TABLES" "No" - fi - local delayed_insert="$(get_var Delayed_writes "$dir/mysql-status")" - if [ -n "$delayed_insert" -a "${delayed_insert:-0}" -gt 0 ]; then - name_val "Delayed Insert" "Yes" - else - name_val "Delayed Insert" "No" - fi - local xat="$(get_var Com_xa_start "$dir/mysql-status")" - if [ -n "$xat" -a "${xat:-0}" -gt 0 ]; then - name_val "XA Transactions" "Yes" - else - name_val "XA Transactions" "No" - fi - local ndb_cluster="$(get_var "Ndb_cluster_node_id" "$dir/mysql-status")" - if [ -n "$ndb_cluster" -a "${ndb_cluster:-0}" -gt 0 ]; then - name_val "NDB Cluster" "Yes" - else - name_val "NDB Cluster" "No" - fi - local prep=$(( $(get_var "Com_stmt_prepare" "$dir/mysql-status") + $(get_var "Com_prepare_sql" "$dir/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/mysql-status")" - if [ "${prep_count}" ]; then - name_val "Prepared statement count" "${prep_count}" - fi - - section "InnoDB" - local have_innodb="$(get_var "have_innodb" "$dir/mysql-variables")" - local innodb_version="$(get_var "innodb_version" "$dir/mysql-variables")" - if [ "${have_innodb}" = "YES" ] || [ -n "${innodb_version}" ]; then - section_innodb "$dir/mysql-variables" "$dir/mysql-status" - - if [ -s "$dir/innodb-status" ]; then - format_innodb_status "$dir/innodb-status" - fi - fi - - local has_rocksdb="$(cat $dir/mysql-plugins | grep -i 'rocksdb.*active.*storage engine')" - if [ ! -z "$has_rocksdb" ]; then - section "RocksDB" - section_rocksdb "$dir/mysql-variables" "$dir/mysql-status" - fi - - if [ -s "$dir/ndb-status" ]; then - section "NDB" - format_ndb_status "$dir/ndb-status" - fi - - section "MyISAM" - section_myisam "$dir/mysql-variables" "$dir/mysql-status" - - section "Security" - local users="$( format_users "$dir/mysql-users" )" - name_val "Users" "${users}" - name_val "Old Passwords" "$(get_var old_passwords "$dir/mysql-variables")" - - if [ -s "$dir/mysql-roles" ]; then - section "Roles" - format_mysql_roles "$dir/mysql-roles" - fi - - section "Encryption" - local keyring_plugins="" - local encrypted_tables="" - local encrypted_tablespaces="" - if [ -s "$dir/keyring-plugins" ]; then - keyring_plugins="$(cat $dir/keyring-plugins)" - fi - if [ -s "$dir/encrypted-tables" ]; then - encrypted_tables="$(cat $dir/encrypted-tables)" - fi - if [ -s "$dir/encrypted-tablespaces" ]; then - encrypted_tablespaces="$(cat $dir/encrypted-tablespaces)" - fi - - format_keyring_plugins "$keyring_plugins" "$encrypted_tables" - format_encrypted_tables "$encrypted_tables" - format_encrypted_tablespaces "$encrypted_tablespaces" - - section "Binary Logging" - - if [ -s "$dir/mysql-master-logs" ] \ - || [ -s "$dir/mysql-master-status" ]; then - summarize_binlogs "$dir/mysql-master-logs" - local format="$(get_var binlog_format "$dir/mysql-variables")" - name_val binlog_format "${format:-STATEMENT}" - name_val expire_logs_days "$(get_var expire_logs_days "$dir/mysql-variables")" - name_val sync_binlog "$(get_var sync_binlog "$dir/mysql-variables")" - name_val server_id "$(get_var server_id "$dir/mysql-variables")" - format_binlog_filters "$dir/mysql-master-status" - fi - - - section "Noteworthy Variables" - section_noteworthy_variables "$dir/mysql-variables" - - section "Configuration File" - local cnf_file="$(get_var "pt-summary-internal-Config_File_path" "$dir/mysql-variables")" - - if [ -n "${cnf_file}" ]; then - name_val "Config File" "${cnf_file}" - pretty_print_cnf_file "$dir/mysql-config-file" - else - name_val "Config File" "Cannot autodetect or find, giving up" - fi - - section "Memory management library" - report_jemalloc_enabled "$dir/mysqld-instances" "$dir/mysql-variables" - - section "The End" -} - # ########################################################################### # End report_mysql_info package # ###########################################################################