mirror of
https://github.com/percona/percona-toolkit.git
synced 2025-09-02 02:34:19 +00:00
PT-2037 - option --system-only for pt-stalk
This commit: 1. Moves all changes to the proper place: lib/bash/collect.sh 2. Refactors pt-stalk so it is more modular 3. Places fix for PT-1734 into the right place: lib/bash/collect.sh 4. Fixes tests for PT-1336
This commit is contained in:
541
bin/pt-stalk
541
bin/pt-stalk
@@ -9,10 +9,10 @@ set -u
|
||||
# ###########################################################################
|
||||
# log_warn_die 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,
|
||||
# with comments and its test file can be found in the GitHub repository at,
|
||||
# lib/bash/log_warn_die.sh
|
||||
# t/lib/bash/log_warn_die.sh
|
||||
# See https://launchpad.net/percona-toolkit for more information.
|
||||
# See https://github.com/percona/percona-toolkit for more information.
|
||||
# ###########################################################################
|
||||
|
||||
|
||||
@@ -57,10 +57,10 @@ _d () {
|
||||
# ###########################################################################
|
||||
# subshell 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,
|
||||
# with comments and its test file can be found in the GitHub repository at,
|
||||
# lib/bash/subshell.sh
|
||||
# t/lib/bash/subshell.sh
|
||||
# See https://launchpad.net/percona-toolkit for more information.
|
||||
# See https://github.com/percona/percona-toolkit for more information.
|
||||
# ###########################################################################
|
||||
|
||||
|
||||
@@ -109,10 +109,10 @@ kill_all_subshells() {
|
||||
# ###########################################################################
|
||||
# parse_options 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,
|
||||
# with comments and its test file can be found in the GitHub repository at,
|
||||
# lib/bash/parse_options.sh
|
||||
# t/lib/bash/parse_options.sh
|
||||
# See https://launchpad.net/percona-toolkit for more information.
|
||||
# See https://github.com/percona/percona-toolkit for more information.
|
||||
# ###########################################################################
|
||||
|
||||
|
||||
@@ -121,16 +121,14 @@ kill_all_subshells() {
|
||||
|
||||
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
|
||||
OPT_MYSQL_ONLY="" # If --mysql-only was specified
|
||||
OPT_SYSTEM_ONLY="" # If --system-only was specified
|
||||
PO_DIR="" # Directory with program option spec files
|
||||
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
|
||||
|
||||
usage() {
|
||||
local file="$1"
|
||||
@@ -336,7 +334,7 @@ _eval_po() {
|
||||
*)
|
||||
echo "Invalid attribute in $opt_spec: $line" >&2
|
||||
exit 1
|
||||
esac
|
||||
esac
|
||||
done < "$opt_spec"
|
||||
|
||||
if [ -z "$opt" ]; then
|
||||
@@ -460,7 +458,6 @@ _parse_command_line() {
|
||||
else
|
||||
spec=$(grep "^short form:-$opt\$" "$PT_TMPDIR"/po/* | cut -d ':' -f 1)
|
||||
if [ -z "$spec" ]; then
|
||||
option_error "Unknown option: $real_opt"
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
@@ -476,7 +473,7 @@ _parse_command_line() {
|
||||
if [ "$val" ]; then
|
||||
option_error "Option $real_opt does not take a value"
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
if [ "$opt_is_negated" ]; then
|
||||
val=""
|
||||
else
|
||||
@@ -519,10 +516,10 @@ size_to_bytes() {
|
||||
# ###########################################################################
|
||||
# mysql_options 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,
|
||||
# with comments and its test file can be found in the GitHub repository at,
|
||||
# lib/bash/mysql_options.sh
|
||||
# t/lib/bash/mysql_options.sh
|
||||
# See https://launchpad.net/percona-toolkit for more information.
|
||||
# See https://github.com/percona/percona-toolkit for more information.
|
||||
# ###########################################################################
|
||||
|
||||
|
||||
@@ -545,16 +542,23 @@ mysql_options() {
|
||||
if [ -n "$OPT_USER" ]; then
|
||||
MYSQL_ARGS="$MYSQL_ARGS --user=$OPT_USER"
|
||||
fi
|
||||
if [ -n "$OPT_PASSWORD" ]; then
|
||||
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
|
||||
@@ -563,7 +567,7 @@ arrange_mysql_options() {
|
||||
rearranged="$rearranged $opt"
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
echo "$rearranged"
|
||||
}
|
||||
|
||||
@@ -574,10 +578,10 @@ arrange_mysql_options() {
|
||||
# ###########################################################################
|
||||
# tmpdir 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,
|
||||
# with comments and its test file can be found in the GitHub repository at,
|
||||
# lib/bash/tmpdir.sh
|
||||
# t/lib/bash/tmpdir.sh
|
||||
# See https://launchpad.net/percona-toolkit for more information.
|
||||
# See https://github.com/percona/percona-toolkit for more information.
|
||||
# ###########################################################################
|
||||
|
||||
|
||||
@@ -615,10 +619,10 @@ rm_tmpdir() {
|
||||
# ###########################################################################
|
||||
# alt_cmds 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,
|
||||
# with comments and its test file can be found in the GitHub repository at,
|
||||
# lib/bash/alt_cmds.sh
|
||||
# t/lib/bash/alt_cmds.sh
|
||||
# See https://launchpad.net/percona-toolkit for more information.
|
||||
# See https://github.com/percona/percona-toolkit for more information.
|
||||
# ###########################################################################
|
||||
|
||||
|
||||
@@ -662,10 +666,10 @@ _which() {
|
||||
# ###########################################################################
|
||||
# safeguards 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,
|
||||
# with comments and its test file can be found in the GitHub repository at,
|
||||
# lib/bash/safeguards.sh
|
||||
# t/lib/bash/safeguards.sh
|
||||
# See https://launchpad.net/percona-toolkit for more information.
|
||||
# See https://github.com/percona/percona-toolkit for more information.
|
||||
# ###########################################################################
|
||||
|
||||
|
||||
@@ -718,10 +722,10 @@ check_disk_space() {
|
||||
# ###########################################################################
|
||||
# daemon 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,
|
||||
# with comments and its test file can be found in the GitHub repository at,
|
||||
# lib/bash/daemon.sh
|
||||
# t/lib/bash/daemon.sh
|
||||
# See https://launchpad.net/percona-toolkit for more information.
|
||||
# See https://github.com/percona/percona-toolkit for more information.
|
||||
# ###########################################################################
|
||||
|
||||
|
||||
@@ -767,10 +771,10 @@ remove_pid_file() {
|
||||
# ###########################################################################
|
||||
# collect 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,
|
||||
# with comments and its test file can be found in the GitHub repository at,
|
||||
# lib/bash/collect.sh
|
||||
# t/lib/bash/collect.sh
|
||||
# See https://launchpad.net/percona-toolkit for more information.
|
||||
# See https://github.com/percona/percona-toolkit for more information.
|
||||
# ###########################################################################
|
||||
|
||||
|
||||
@@ -796,139 +800,40 @@ CMD_DMESG="${CMD_DMESG:-"$(_which dmesg)"}"
|
||||
collect() {
|
||||
local d="$1" # directory to save results in
|
||||
local p="$2" # prefix for each result file
|
||||
local cnt=$(($OPT_RUN_TIME / $OPT_SLEEP_COLLECT))
|
||||
|
||||
local cnt=$(($OPT_RUN_TIME / $OPT_SLEEP_COLLECT))
|
||||
|
||||
if [ ! "$OPT_SYSTEM_ONLY" ]; then
|
||||
local mysqld_pid=""
|
||||
if [ ! "$OPT_MYSQL_ONLY" ]; then
|
||||
mysqld_pid=$(_pidof mysqld | awk '{print $1; exit;}')
|
||||
fi
|
||||
|
||||
if [ "$CMD_PMAP" -a "$mysqld_pid" ]; then
|
||||
if $CMD_PMAP --help 2>&1 | grep -- -x >/dev/null 2>&1 ; then
|
||||
$CMD_PMAP -x $mysqld_pid > "$d/$p-pmap"
|
||||
else
|
||||
$CMD_PMAP $mysqld_pid > "$d/$p-pmap"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$CMD_GDB" -a "$OPT_COLLECT_GDB" -a "$mysqld_pid" ]; then
|
||||
$CMD_GDB \
|
||||
-ex "set pagination 0" \
|
||||
-ex "thread apply all bt" \
|
||||
--batch -p $mysqld_pid \
|
||||
>> "$d/$p-stacktrace"
|
||||
fi
|
||||
|
||||
collect_mysql_variables "$d/$p-variables" &
|
||||
sleep .5
|
||||
|
||||
local mysql_version="$(awk '/^version[^_]/{print substr($2,1,3)}' "$d/$p-variables")"
|
||||
|
||||
local mysql_error_log="$(awk '/^log_error/{print $2}' "$d/$p-variables")"
|
||||
if [ -z "$mysql_error_log" -a "$mysqld_pid" ]; then
|
||||
mysql_error_log="$(ls -l /proc/$mysqld_pid/fd | awk '/ 2 ->/{print $NF}')"
|
||||
fi
|
||||
|
||||
local mysql_version=""
|
||||
local mysql_error_log=""
|
||||
local tail_error_log_pid=""
|
||||
if [ "$mysql_error_log" -a ! "$OPT_MYSQL_ONLY" ]; then
|
||||
log "The MySQL error log seems to be $mysql_error_log"
|
||||
tail -f "$mysql_error_log" >"$d/$p-log_error" &
|
||||
tail_error_log_pid=$!
|
||||
|
||||
$CMD_MYSQLADMIN $EXT_ARGV debug
|
||||
else
|
||||
log "Could not find the MySQL error log"
|
||||
fi
|
||||
if [ "${mysql_version}" '>' "5.1" ]; then
|
||||
local mutex="SHOW ENGINE INNODB MUTEX"
|
||||
else
|
||||
local mutex="SHOW MUTEX STATUS"
|
||||
fi
|
||||
innodb_status 1
|
||||
tokudb_status 1
|
||||
rocksdb_status 1
|
||||
|
||||
$CMD_MYSQL $EXT_ARGV -e "$mutex" >> "$d/$p-mutex-status1" &
|
||||
open_tables >> "$d/$p-opentables1" &
|
||||
|
||||
local tcpdump_pid=""
|
||||
if [ "$CMD_TCPDUMP" -a "$OPT_COLLECT_TCPDUMP" ]; then
|
||||
local port=$(awk '/^port/{print $2}' "$d/$p-variables")
|
||||
if [ "$port" ]; then
|
||||
$CMD_TCPDUMP -i any -s 4096 -w "$d/$p-tcpdump" port ${port} &
|
||||
tcpdump_pid=$!
|
||||
fi
|
||||
fi
|
||||
|
||||
local have_lock_waits_table=""
|
||||
local have_oprofile=""
|
||||
if [ "$CMD_OPCONTROL" -a "$OPT_COLLECT_OPROFILE" ]; then
|
||||
if $CMD_OPCONTROL --init; then
|
||||
$CMD_OPCONTROL --start --no-vmlinux
|
||||
have_oprofile="yes"
|
||||
fi
|
||||
elif [ "$CMD_STRACE" -a "$OPT_COLLECT_STRACE" -a "$mysqld_pid" ]; then
|
||||
$CMD_STRACE -T -s 0 -f -p $mysqld_pid -o "$d/$p-strace" &
|
||||
local strace_pid=$!
|
||||
fi
|
||||
local mysqladmin_pid=""
|
||||
local mutex=""
|
||||
local tcpdump_pid=""
|
||||
local ps_instrumentation_enabled=""
|
||||
|
||||
collect_mysql_data_one
|
||||
fi
|
||||
|
||||
if [ ! "$OPT_MYSQL_ONLY" ]; then
|
||||
system_stats $d $p $cnt
|
||||
fi
|
||||
|
||||
if [ ! "$OPT_SYSTEM_ONLY" ]; then
|
||||
$CMD_MYSQLADMIN $EXT_ARGV ext -i$OPT_SLEEP_COLLECT -c$cnt >>"$d/$p-mysqladmin" &
|
||||
local mysqladmin_pid=$!
|
||||
fi
|
||||
|
||||
if [ ! "$OPT_SYSTEM_ONLY" ]; then
|
||||
local have_lock_waits_table=""
|
||||
$CMD_MYSQL $EXT_ARGV -e "SHOW TABLES FROM INFORMATION_SCHEMA" \
|
||||
| grep -i "INNODB_LOCK_WAITS" >/dev/null 2>&1
|
||||
if [ $? -eq 0 ]; then
|
||||
have_lock_waits_table="yes"
|
||||
fi
|
||||
fi
|
||||
collect_system_data
|
||||
fi
|
||||
|
||||
log "Loop start: $(date +'TS %s.%N %F %T')"
|
||||
local start_time=$(date +'%s')
|
||||
local curr_time=$start_time
|
||||
if [ ! "$OPT_SYSTEM_ONLY" ]; then
|
||||
local ps_instrumentation_enabled=$($CMD_MYSQL $EXT_ARGV -e 'SELECT ENABLED FROM performance_schema.setup_instruments WHERE NAME = "transaction";' \
|
||||
| sed "2q;d" | sed 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/')
|
||||
|
||||
if [ $ps_instrumentation_enabled != "yes" ]; then
|
||||
log "Performance Schema instrumentation is disabled"
|
||||
fi
|
||||
fi
|
||||
local ts="$(date +"TS %s.%N %F %T")"
|
||||
|
||||
while [ $((curr_time - start_time)) -lt $OPT_RUN_TIME ]; do
|
||||
if [ ! "$OPT_MYSQL_ONLY" ]; then
|
||||
check_disk_space_loop $d $p
|
||||
|
||||
sleep $(date +'%s.%N' | awk "{print $OPT_SLEEP_COLLECT - (\$1 % $OPT_SLEEP_COLLECT)}")
|
||||
local ts="$(date +"TS %s.%N %F %T")"
|
||||
|
||||
system_stats_loop $d $p $ts
|
||||
collect_system_data_loop
|
||||
fi
|
||||
|
||||
if [ ! "$OPT_SYSTEM_ONLY" ]; then
|
||||
(echo $ts; $CMD_MYSQL $EXT_ARGV -e "SHOW FULL PROCESSLIST\G") \
|
||||
>> "$d/$p-processlist" &
|
||||
if [ "$have_lock_waits_table" ]; then
|
||||
(echo $ts; lock_waits) >>"$d/$p-lock-waits" &
|
||||
(echo $ts; transactions) >>"$d/$p-transactions" &
|
||||
fi
|
||||
|
||||
if [ "${mysql_version}" '>' "5.6" ] && [ $ps_instrumentation_enabled == "yes" ]; then
|
||||
ps_locks_transactions "$d/$p-ps-locks-transactions"
|
||||
fi
|
||||
|
||||
if [ "${mysql_version}" '>' "5.6" ]; then
|
||||
(echo $ts; ps_prepared_statements) >> "$d/$p-prepared-statements" &
|
||||
fi
|
||||
|
||||
slave_status "$d/$p-slave-status" "${mysql_version}"
|
||||
collect_mysql_data_loop
|
||||
fi
|
||||
|
||||
curr_time=$(date +'%s')
|
||||
@@ -936,56 +841,11 @@ collect() {
|
||||
log "Loop end: $(date +'TS %s.%N %F %T')"
|
||||
|
||||
if [ ! "$OPT_SYSTEM_ONLY" ]; then
|
||||
if [ "$have_oprofile" ]; then
|
||||
$CMD_OPCONTROL --stop
|
||||
$CMD_OPCONTROL --dump
|
||||
|
||||
local oprofiled_pid=$(_pidof oprofiled | awk '{print $1; exit;}')
|
||||
if [ "$oprofiled_pid" ]; then
|
||||
kill $oprofiled_pid
|
||||
else
|
||||
warn "Cannot kill oprofiled because its PID cannot be determined"
|
||||
fi
|
||||
|
||||
$CMD_OPCONTROL --save=pt_collect_$p
|
||||
|
||||
local mysqld_path=$(_which mysqld);
|
||||
if [ "$mysqld_path" -a -f "$mysqld_path" ]; then
|
||||
$CMD_OPREPORT \
|
||||
--demangle=smart \
|
||||
--symbols \
|
||||
--merge tgid \
|
||||
session:pt_collect_$p \
|
||||
"$mysqld_path" \
|
||||
> "$d/$p-opreport"
|
||||
else
|
||||
log "oprofile data saved to pt_collect_$p; you should be able" \
|
||||
"to get a report by running something like 'opreport" \
|
||||
"--demangle=smart --symbols --merge tgid session:pt_collect_$p" \
|
||||
"/path/to/mysqld'" \
|
||||
> "$d/$p-opreport"
|
||||
fi
|
||||
elif [ "$CMD_STRACE" -a "$OPT_COLLECT_STRACE" ]; then
|
||||
kill -s 2 $strace_pid
|
||||
sleep 1
|
||||
kill -s 15 $strace_pid
|
||||
[ "$mysqld_pid" ] && kill -s 18 $mysqld_pid
|
||||
fi
|
||||
|
||||
innodb_status 2
|
||||
tokudb_status 2
|
||||
rocksdb_status 2
|
||||
|
||||
$CMD_MYSQL $EXT_ARGV -e "$mutex" >> "$d/$p-mutex-status2" &
|
||||
open_tables >> "$d/$p-opentables2" &
|
||||
|
||||
kill $mysqladmin_pid
|
||||
[ "$tail_error_log_pid" ] && kill $tail_error_log_pid
|
||||
[ "$tcpdump_pid" ] && kill $tcpdump_pid
|
||||
|
||||
hostname > "$d/$p-hostname"
|
||||
collect_mysql_data_two
|
||||
fi
|
||||
|
||||
hostname > "$d/$p-hostname"
|
||||
|
||||
wait_for_subshells $OPT_RUN_TIME
|
||||
kill_all_subshells
|
||||
for file in "$d/$p-"*; do
|
||||
@@ -996,83 +856,227 @@ collect() {
|
||||
done
|
||||
}
|
||||
|
||||
system_stats() {
|
||||
local d="$1"
|
||||
local p="$2"
|
||||
local cnt="$3"
|
||||
collect_mysql_data_one() {
|
||||
if [ ! "$OPT_MYSQL_ONLY" ]; then
|
||||
port=$($CMD_MYSQL $EXT_ARGV -ss -e 'SELECT @@port')
|
||||
mysqld_pid=$(lsof -i ":${port}" | grep -i listen | cut -f 3 -d" ")
|
||||
fi
|
||||
|
||||
if [ "$CMD_PMAP" -a "$mysqld_pid" ]; then
|
||||
if $CMD_PMAP --help 2>&1 | grep -- -x >/dev/null 2>&1 ; then
|
||||
$CMD_PMAP -x $mysqld_pid > "$d/$p-pmap"
|
||||
else
|
||||
$CMD_PMAP $mysqld_pid > "$d/$p-pmap"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$CMD_GDB" -a "$OPT_COLLECT_GDB" -a "$mysqld_pid" ]; then
|
||||
$CMD_GDB \
|
||||
-ex "set pagination 0" \
|
||||
-ex "thread apply all bt" \
|
||||
--batch -p $mysqld_pid \
|
||||
>> "$d/$p-stacktrace"
|
||||
fi
|
||||
|
||||
collect_mysql_variables "$d/$p-variables" &
|
||||
sleep .5
|
||||
|
||||
mysql_version="$(awk '/^version[^_]/{print substr($2,1,3)}' "$d/$p-variables")"
|
||||
|
||||
mysql_error_log="$(awk '/^log_error\s/{print $2}' "$d/$p-variables")"
|
||||
if [ -z "$mysql_error_log" -a "$mysqld_pid" ]; then
|
||||
log $mysqld_pid
|
||||
mysql_error_log="$(ls -l /proc/$mysqld_pid/fd | awk '/ 2 ->/{print $NF}')"
|
||||
fi
|
||||
|
||||
if [ "$mysql_error_log" -a ! "$OPT_MYSQL_ONLY" ]; then
|
||||
log "The MySQL error log seems to be $mysql_error_log"
|
||||
tail -f "$mysql_error_log" >"$d/$p-log_error" &
|
||||
tail_error_log_pid=$!
|
||||
|
||||
$CMD_MYSQLADMIN $EXT_ARGV debug
|
||||
else
|
||||
log "Could not find the MySQL error log"
|
||||
fi
|
||||
if [ "${mysql_version}" '>' "5.1" ]; then
|
||||
mutex="SHOW ENGINE INNODB MUTEX"
|
||||
else
|
||||
mutex="SHOW MUTEX STATUS"
|
||||
fi
|
||||
innodb_status 1
|
||||
tokudb_status 1
|
||||
rocksdb_status 1
|
||||
|
||||
$CMD_MYSQL $EXT_ARGV -e "$mutex" >> "$d/$p-mutex-status1" &
|
||||
open_tables >> "$d/$p-opentables1" &
|
||||
|
||||
if [ "$CMD_TCPDUMP" -a "$OPT_COLLECT_TCPDUMP" ]; then
|
||||
local port=$(awk '/^port/{print $2}' "$d/$p-variables")
|
||||
if [ "$port" ]; then
|
||||
$CMD_TCPDUMP -i any -s 4096 -w "$d/$p-tcpdump" port ${port} &
|
||||
tcpdump_pid=$!
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$CMD_OPCONTROL" -a "$OPT_COLLECT_OPROFILE" ]; then
|
||||
if $CMD_OPCONTROL --init; then
|
||||
$CMD_OPCONTROL --start --no-vmlinux
|
||||
have_oprofile="yes"
|
||||
fi
|
||||
elif [ "$CMD_STRACE" -a "$OPT_COLLECT_STRACE" -a "$mysqld_pid" ]; then
|
||||
$CMD_STRACE -T -s 0 -f -p $mysqld_pid -o "$d/$p-strace" &
|
||||
local strace_pid=$!
|
||||
fi
|
||||
|
||||
$CMD_MYSQL $EXT_ARGV -e "SHOW TABLES FROM INFORMATION_SCHEMA" \
|
||||
| grep -i "INNODB_LOCK_WAITS" >/dev/null 2>&1
|
||||
if [ $? -eq 0 ]; then
|
||||
have_lock_waits_table="yes"
|
||||
fi
|
||||
|
||||
$CMD_MYSQLADMIN $EXT_ARGV ext -i$OPT_SLEEP_COLLECT -c$cnt >>"$d/$p-mysqladmin" &
|
||||
mysqladmin_pid=$!
|
||||
|
||||
ps_instrumentation_enabled=$($CMD_MYSQL $EXT_ARGV -e 'SELECT ENABLED FROM performance_schema.setup_instruments WHERE NAME = "transaction";' \
|
||||
| sed "2q;d" | sed 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/')
|
||||
|
||||
if [ $ps_instrumentation_enabled != "yes" ]; then
|
||||
log "Performance Schema instrumentation is disabled"
|
||||
fi
|
||||
}
|
||||
|
||||
collect_system_data() {
|
||||
ps -eaF >> "$d/$p-ps" &
|
||||
top -bn${OPT_RUN_TIME} >> "$d/$p-top" &
|
||||
|
||||
if [ ! "$OPT_SYSTEM_ONLY" ]; then
|
||||
[ "$mysqld_pid" ] && _lsof $mysqld_pid >> "$d/$p-lsof" &
|
||||
[ "$mysqld_pid" ] && _lsof $mysqld_pid >> "$d/$p-lsof" &
|
||||
|
||||
if [ "$CMD_SYSCTL" ]; then
|
||||
$CMD_SYSCTL -a >> "$d/$p-sysctl" &
|
||||
fi
|
||||
|
||||
if [ "$CMD_SYSCTL" ]; then
|
||||
$CMD_SYSCTL -a >> "$d/$p-sysctl" &
|
||||
fi
|
||||
if [ "$CMD_DMESG" ]; then
|
||||
local UPTIME=`cat /proc/uptime | awk '{ print $1 }'`
|
||||
local START_TIME=$(echo "$UPTIME 60" | awk '{print ($1 - $2)}')
|
||||
$CMD_DMESG | perl -ne 'm/\[\s*(\d+)\./; if ($1 > '${START_TIME}') { print }' >> "$d/$p-dmesg" &
|
||||
fi
|
||||
|
||||
if [ "$CMD_DMESG" ]; then
|
||||
local UPTIME=`cat /proc/uptime | awk '{ print $1 }'`
|
||||
local START_TIME=$(echo "$UPTIME 60" | awk '{print ($1 - $2)}')
|
||||
$CMD_DMESG | perl -ne 'm/\[\s*(\d+)\./; if ($1 > '${START_TIME}') { print }' >> "$d/$p-dmesg" &
|
||||
fi
|
||||
|
||||
if [ "$CMD_VMSTAT" ]; then
|
||||
$CMD_VMSTAT $OPT_SLEEP_COLLECT $cnt >> "$d/$p-vmstat" &
|
||||
$CMD_VMSTAT $OPT_RUN_TIME 2 >> "$d/$p-vmstat-overall" &
|
||||
fi
|
||||
if [ "$CMD_IOSTAT" ]; then
|
||||
$CMD_IOSTAT -dx $OPT_SLEEP_COLLECT $cnt >> "$d/$p-iostat" &
|
||||
$CMD_IOSTAT -dx $OPT_RUN_TIME 2 >> "$d/$p-iostat-overall" &
|
||||
fi
|
||||
if [ "$CMD_MPSTAT" ]; then
|
||||
$CMD_MPSTAT -P ALL $OPT_SLEEP_COLLECT $cnt >> "$d/$p-mpstat" &
|
||||
$CMD_MPSTAT -P ALL $OPT_RUN_TIME 1 >> "$d/$p-mpstat-overall" &
|
||||
fi
|
||||
if [ "$CMD_VMSTAT" ]; then
|
||||
$CMD_VMSTAT $OPT_SLEEP_COLLECT $cnt >> "$d/$p-vmstat" &
|
||||
$CMD_VMSTAT $OPT_RUN_TIME 2 >> "$d/$p-vmstat-overall" &
|
||||
fi
|
||||
if [ "$CMD_IOSTAT" ]; then
|
||||
$CMD_IOSTAT -dx $OPT_SLEEP_COLLECT $cnt >> "$d/$p-iostat" &
|
||||
$CMD_IOSTAT -dx $OPT_RUN_TIME 2 >> "$d/$p-iostat-overall" &
|
||||
fi
|
||||
if [ "$CMD_MPSTAT" ]; then
|
||||
$CMD_MPSTAT -P ALL $OPT_SLEEP_COLLECT $cnt >> "$d/$p-mpstat" &
|
||||
$CMD_MPSTAT -P ALL $OPT_RUN_TIME 1 >> "$d/$p-mpstat-overall" &
|
||||
fi
|
||||
}
|
||||
|
||||
check_disk_space_loop() {
|
||||
local d="$1"
|
||||
local p="$2"
|
||||
collect_mysql_data_loop() {
|
||||
(echo $ts; $CMD_MYSQL $EXT_ARGV -e "SHOW FULL PROCESSLIST\G") \
|
||||
>> "$d/$p-processlist" &
|
||||
if [ "$have_lock_waits_table" ]; then
|
||||
(echo $ts; lock_waits) >>"$d/$p-lock-waits" &
|
||||
(echo $ts; transactions) >>"$d/$p-transactions" &
|
||||
fi
|
||||
|
||||
disk_space $d > $d/$p-disk-space
|
||||
check_disk_space \
|
||||
$d/$p-disk-space \
|
||||
"$OPT_DISK_BYTES_FREE" \
|
||||
"$OPT_DISK_PCT_FREE" \
|
||||
|| break
|
||||
if [ "${mysql_version}" '>' "5.6" ] && [ $ps_instrumentation_enabled == "yes" ]; then
|
||||
ps_locks_transactions "$d/$p-ps-locks-transactions"
|
||||
fi
|
||||
|
||||
if [ "${mysql_version}" '>' "5.6" ]; then
|
||||
(echo $ts; ps_prepared_statements) >> "$d/$p-prepared-statements" &
|
||||
fi
|
||||
|
||||
slave_status "$d/$p-slave-status" "${mysql_version}"
|
||||
}
|
||||
|
||||
system_stats_loop() {
|
||||
local d="$1"
|
||||
local p="$2"
|
||||
local ts="$3"
|
||||
collect_system_data_loop() {
|
||||
disk_space $d > $d/$p-disk-space
|
||||
check_disk_space \
|
||||
$d/$p-disk-space \
|
||||
"$OPT_DISK_BYTES_FREE" \
|
||||
"$OPT_DISK_PCT_FREE" \
|
||||
|| break
|
||||
|
||||
if [ -d "/proc" ]; then
|
||||
if [ -f "/proc/diskstats" ]; then
|
||||
(echo $ts; cat /proc/diskstats) >> "$d/$p-diskstats" &
|
||||
fi
|
||||
if [ -f "/proc/stat" ]; then
|
||||
(echo $ts; cat /proc/stat) >> "$d/$p-procstat" &
|
||||
fi
|
||||
if [ -f "/proc/vmstat" ]; then
|
||||
(echo $ts; cat /proc/vmstat) >> "$d/$p-procvmstat" &
|
||||
fi
|
||||
if [ -f "/proc/meminfo" ]; then
|
||||
(echo $ts; cat /proc/meminfo) >> "$d/$p-meminfo" &
|
||||
fi
|
||||
if [ -f "/proc/slabinfo" ]; then
|
||||
(echo $ts; cat /proc/slabinfo) >> "$d/$p-slabinfo" &
|
||||
fi
|
||||
if [ -f "/proc/interrupts" ]; then
|
||||
(echo $ts; cat /proc/interrupts) >> "$d/$p-interrupts" &
|
||||
fi
|
||||
fi
|
||||
(echo $ts; df -k) >> "$d/$p-df" &
|
||||
(echo $ts; netstat -antp) >> "$d/$p-netstat" &
|
||||
(echo $ts; netstat -s) >> "$d/$p-netstat_s" &
|
||||
sleep $(date +'%s.%N' | awk "{print $OPT_SLEEP_COLLECT - (\$1 % $OPT_SLEEP_COLLECT)}")
|
||||
ts="$(date +"TS %s.%N %F %T")"
|
||||
|
||||
if [ -d "/proc" ]; then
|
||||
if [ -f "/proc/diskstats" ]; then
|
||||
(echo $ts; cat /proc/diskstats) >> "$d/$p-diskstats" &
|
||||
fi
|
||||
if [ -f "/proc/stat" ]; then
|
||||
(echo $ts; cat /proc/stat) >> "$d/$p-procstat" &
|
||||
fi
|
||||
if [ -f "/proc/vmstat" ]; then
|
||||
(echo $ts; cat /proc/vmstat) >> "$d/$p-procvmstat" &
|
||||
fi
|
||||
if [ -f "/proc/meminfo" ]; then
|
||||
(echo $ts; cat /proc/meminfo) >> "$d/$p-meminfo" &
|
||||
fi
|
||||
if [ -f "/proc/slabinfo" ]; then
|
||||
(echo $ts; cat /proc/slabinfo) >> "$d/$p-slabinfo" &
|
||||
fi
|
||||
if [ -f "/proc/interrupts" ]; then
|
||||
(echo $ts; cat /proc/interrupts) >> "$d/$p-interrupts" &
|
||||
fi
|
||||
fi
|
||||
(echo $ts; df -k) >> "$d/$p-df" &
|
||||
(echo $ts; netstat -antp) >> "$d/$p-netstat" &
|
||||
(echo $ts; netstat -s) >> "$d/$p-netstat_s" &
|
||||
}
|
||||
|
||||
collect_mysql_data_two() {
|
||||
if [ "$have_oprofile" ]; then
|
||||
$CMD_OPCONTROL --stop
|
||||
$CMD_OPCONTROL --dump
|
||||
|
||||
local oprofiled_pid=$(_pidof oprofiled | awk '{print $1; exit;}')
|
||||
if [ "$oprofiled_pid" ]; then
|
||||
kill $oprofiled_pid
|
||||
else
|
||||
warn "Cannot kill oprofiled because its PID cannot be determined"
|
||||
fi
|
||||
|
||||
$CMD_OPCONTROL --save=pt_collect_$p
|
||||
|
||||
local mysqld_path=$(_which mysqld);
|
||||
if [ "$mysqld_path" -a -f "$mysqld_path" ]; then
|
||||
$CMD_OPREPORT \
|
||||
--demangle=smart \
|
||||
--symbols \
|
||||
--merge tgid \
|
||||
session:pt_collect_$p \
|
||||
"$mysqld_path" \
|
||||
> "$d/$p-opreport"
|
||||
else
|
||||
log "oprofile data saved to pt_collect_$p; you should be able" \
|
||||
"to get a report by running something like 'opreport" \
|
||||
"--demangle=smart --symbols --merge tgid session:pt_collect_$p" \
|
||||
"/path/to/mysqld'" \
|
||||
> "$d/$p-opreport"
|
||||
fi
|
||||
elif [ "$CMD_STRACE" -a "$OPT_COLLECT_STRACE" ]; then
|
||||
kill -s 2 $strace_pid
|
||||
sleep 1
|
||||
kill -s 15 $strace_pid
|
||||
[ "$mysqld_pid" ] && kill -s 18 $mysqld_pid
|
||||
fi
|
||||
|
||||
innodb_status 2
|
||||
tokudb_status 2
|
||||
rocksdb_status 2
|
||||
|
||||
$CMD_MYSQL $EXT_ARGV -e "$mutex" >> "$d/$p-mutex-status2" &
|
||||
open_tables >> "$d/$p-opentables2" &
|
||||
|
||||
[ "$mysqladmin_pid" ] && kill $mysqladmin_pid
|
||||
[ "$tail_error_log_pid" ] && kill $tail_error_log_pid
|
||||
[ "$tcpdump_pid" ] && kill $tcpdump_pid
|
||||
}
|
||||
|
||||
open_tables() {
|
||||
@@ -1126,8 +1130,13 @@ transactions() {
|
||||
tokudb_status() {
|
||||
local n=$1
|
||||
|
||||
$CMD_MYSQL $EXT_ARGV -e "SHOW ENGINE TOKUDB STATUS\G" \
|
||||
>> "$d/$p-tokudbstatus$n" || rm -f "$d/$p-tokudbstatus$n"
|
||||
has_tokudb=`$CMD_MYSQL $EXT_ARGV -e "SHOW ENGINES" | grep -i 'tokudb'`
|
||||
exit_code=$?
|
||||
|
||||
if [ $exit_code -eq 0 ]; then
|
||||
$CMD_MYSQL $EXT_ARGV -e "SHOW ENGINE TOKUDB STATUS\G" \
|
||||
>> "$d/$p-tokudbstatus$n" || rm -f "$d/$p-tokudbstatus$n"
|
||||
fi
|
||||
}
|
||||
|
||||
innodb_status() {
|
||||
@@ -1210,11 +1219,11 @@ slave_status() {
|
||||
echo -e "\n$sql\n" >> $outfile
|
||||
$CMD_MYSQL $EXT_ARGV -e "$sql" >> $outfile
|
||||
|
||||
sql="SELECT * FROM replication_connection_status\G"
|
||||
sql="SELECT * FROM performance_schema.replication_connection_status\G"
|
||||
echo -e "\n$sql\n" >> $outfile
|
||||
$CMD_MYSQL $EXT_ARGV -e "$sql" >> $outfile
|
||||
|
||||
sql="SELECT * FROM replication_applier_status JOIN replication_applier_status_by_coordinator USING(channel_name)\G"
|
||||
sql="SELECT * FROM performance_schema.replication_applier_status JOIN performance_schema.replication_applier_status_by_coordinator USING(channel_name)\G"
|
||||
echo -e "\n$sql\n" >> $outfile
|
||||
$CMD_MYSQL $EXT_ARGV -e "$sql" >> $outfile
|
||||
fi
|
||||
|
@@ -49,10 +49,77 @@ collect() {
|
||||
local d="$1" # directory to save results in
|
||||
local p="$2" # prefix for each result file
|
||||
|
||||
local mysqld_pid=""
|
||||
local cnt=$(($OPT_RUN_TIME / $OPT_SLEEP_COLLECT))
|
||||
|
||||
if [ ! "$OPT_SYSTEM_ONLY" ]; then
|
||||
local mysqld_pid=""
|
||||
local mysql_version=""
|
||||
local mysql_error_log=""
|
||||
local tail_error_log_pid=""
|
||||
local have_lock_waits_table=""
|
||||
local have_oprofile=""
|
||||
local mysqladmin_pid=""
|
||||
local mutex=""
|
||||
local tcpdump_pid=""
|
||||
local ps_instrumentation_enabled=""
|
||||
|
||||
collect_mysql_data_one
|
||||
fi
|
||||
|
||||
# Grab a few general things first. Background all of these so we can start
|
||||
# them all up as quickly as possible.
|
||||
if [ ! "$OPT_MYSQL_ONLY" ]; then
|
||||
collect_system_data
|
||||
fi
|
||||
|
||||
# This loop gathers data for the rest of the duration, and defines the time
|
||||
# of the whole job.
|
||||
log "Loop start: $(date +'TS %s.%N %F %T')"
|
||||
local start_time=$(date +'%s')
|
||||
local curr_time=$start_time
|
||||
local ts="$(date +"TS %s.%N %F %T")"
|
||||
|
||||
while [ $((curr_time - start_time)) -lt $OPT_RUN_TIME ]; do
|
||||
if [ ! "$OPT_MYSQL_ONLY" ]; then
|
||||
collect_system_data_loop
|
||||
fi
|
||||
|
||||
if [ ! "$OPT_SYSTEM_ONLY" ]; then
|
||||
collect_mysql_data_loop
|
||||
fi
|
||||
|
||||
curr_time=$(date +'%s')
|
||||
done
|
||||
log "Loop end: $(date +'TS %s.%N %F %T')"
|
||||
|
||||
if [ ! "$OPT_SYSTEM_ONLY" ]; then
|
||||
collect_mysql_data_two
|
||||
fi
|
||||
|
||||
# Finally, record what system we collected this data from.
|
||||
hostname > "$d/$p-hostname"
|
||||
|
||||
# Remove "empty" files, i.e. ones that are truly empty or
|
||||
# just contain timestamp lines. When a command above fails,
|
||||
# it may leave an empty file. But first wait another --run-time
|
||||
# seconds for any slow process to finish:
|
||||
# https://bugs.launchpad.net/percona-toolkit/+bug/1047701
|
||||
wait_for_subshells $OPT_RUN_TIME
|
||||
kill_all_subshells
|
||||
for file in "$d/$p-"*; do
|
||||
# If there's not at least 1 line that's not a TS,
|
||||
# then the file is empty.
|
||||
if [ -z "$(grep -v '^TS ' --max-count 10 "$file")" ]; then
|
||||
log "Removing empty file $file";
|
||||
rm "$file"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
collect_mysql_data_one() {
|
||||
# Get pidof mysqld.
|
||||
if [ ! "$OPT_MYSQL_ONLY" ]; then
|
||||
port=$(mysql -ss -e 'SELECT @@port')
|
||||
port=$($CMD_MYSQL $EXT_ARGV -ss -e 'SELECT @@port')
|
||||
mysqld_pid=$(lsof -i ":${port}" | grep -i listen | cut -f 3 -d" ")
|
||||
fi
|
||||
|
||||
@@ -84,16 +151,16 @@ collect() {
|
||||
|
||||
# Get the major.minor version number. Version 3.23 doesn't matter for our
|
||||
# purposes, and other releases have x.x.x* version conventions so far.
|
||||
local mysql_version="$(awk '/^version[^_]/{print substr($2,1,3)}' "$d/$p-variables")"
|
||||
mysql_version="$(awk '/^version[^_]/{print substr($2,1,3)}' "$d/$p-variables")"
|
||||
|
||||
# Is MySQL logging its errors to a file? If so, tail that file.
|
||||
local mysql_error_log="$(awk '/^log_error/{print $2}' "$d/$p-variables")"
|
||||
mysql_error_log="$(awk '/^log_error\s/{print $2}' "$d/$p-variables")"
|
||||
if [ -z "$mysql_error_log" -a "$mysqld_pid" ]; then
|
||||
log $mysqld_pid
|
||||
# Try getting it from the open filehandle...
|
||||
mysql_error_log="$(ls -l /proc/$mysqld_pid/fd | awk '/ 2 ->/{print $NF}')"
|
||||
fi
|
||||
|
||||
local tail_error_log_pid=""
|
||||
if [ "$mysql_error_log" -a ! "$OPT_MYSQL_ONLY" ]; then
|
||||
log "The MySQL error log seems to be $mysql_error_log"
|
||||
tail -f "$mysql_error_log" >"$d/$p-log_error" &
|
||||
@@ -108,9 +175,9 @@ collect() {
|
||||
# Get a sample of these right away, so we can get these without interaction
|
||||
# with the other commands we're about to run.
|
||||
if [ "${mysql_version}" '>' "5.1" ]; then
|
||||
local mutex="SHOW ENGINE INNODB MUTEX"
|
||||
mutex="SHOW ENGINE INNODB MUTEX"
|
||||
else
|
||||
local mutex="SHOW MUTEX STATUS"
|
||||
mutex="SHOW MUTEX STATUS"
|
||||
fi
|
||||
innodb_status 1
|
||||
tokudb_status 1
|
||||
@@ -120,7 +187,6 @@ collect() {
|
||||
open_tables >> "$d/$p-opentables1" &
|
||||
|
||||
# If TCP dumping is specified, start that on the server's port.
|
||||
local tcpdump_pid=""
|
||||
if [ "$CMD_TCPDUMP" -a "$OPT_COLLECT_TCPDUMP" ]; then
|
||||
local port=$(awk '/^port/{print $2}' "$d/$p-variables")
|
||||
if [ "$port" ]; then
|
||||
@@ -131,7 +197,6 @@ collect() {
|
||||
|
||||
# Next, start oprofile gathering data during the whole rest of this process.
|
||||
# The --init should be a no-op if it has already been init-ed.
|
||||
local have_oprofile=""
|
||||
if [ "$CMD_OPCONTROL" -a "$OPT_COLLECT_OPROFILE" ]; then
|
||||
if $CMD_OPCONTROL --init; then
|
||||
$CMD_OPCONTROL --start --no-vmlinux
|
||||
@@ -143,38 +208,11 @@ collect() {
|
||||
local strace_pid=$!
|
||||
fi
|
||||
|
||||
# Grab a few general things first. Background all of these so we can start
|
||||
# them all up as quickly as possible.
|
||||
if [ ! "$OPT_MYSQL_ONLY" ]; then
|
||||
ps -eaF >> "$d/$p-ps" &
|
||||
top -bn${OPT_RUN_TIME} >> "$d/$p-top" &
|
||||
|
||||
[ "$mysqld_pid" ] && _lsof $mysqld_pid >> "$d/$p-lsof" &
|
||||
|
||||
if [ "$CMD_SYSCTL" ]; then
|
||||
$CMD_SYSCTL -a >> "$d/$p-sysctl" &
|
||||
fi
|
||||
|
||||
# collect dmesg events from 60 seconds ago until present
|
||||
if [ "$CMD_DMESG" ]; then
|
||||
local UPTIME=`cat /proc/uptime | awk '{ print $1 }'`
|
||||
local START_TIME=$(echo "$UPTIME 60" | awk '{print ($1 - $2)}')
|
||||
$CMD_DMESG | perl -ne 'm/\[\s*(\d+)\./; if ($1 > '${START_TIME}') { print }' >> "$d/$p-dmesg" &
|
||||
fi
|
||||
|
||||
local cnt=$(($OPT_RUN_TIME / $OPT_SLEEP_COLLECT))
|
||||
if [ "$CMD_VMSTAT" ]; then
|
||||
$CMD_VMSTAT $OPT_SLEEP_COLLECT $cnt >> "$d/$p-vmstat" &
|
||||
$CMD_VMSTAT $OPT_RUN_TIME 2 >> "$d/$p-vmstat-overall" &
|
||||
fi
|
||||
if [ "$CMD_IOSTAT" ]; then
|
||||
$CMD_IOSTAT -dx $OPT_SLEEP_COLLECT $cnt >> "$d/$p-iostat" &
|
||||
$CMD_IOSTAT -dx $OPT_RUN_TIME 2 >> "$d/$p-iostat-overall" &
|
||||
fi
|
||||
if [ "$CMD_MPSTAT" ]; then
|
||||
$CMD_MPSTAT -P ALL $OPT_SLEEP_COLLECT $cnt >> "$d/$p-mpstat" &
|
||||
$CMD_MPSTAT -P ALL $OPT_RUN_TIME 1 >> "$d/$p-mpstat-overall" &
|
||||
fi
|
||||
$CMD_MYSQL $EXT_ARGV -e "SHOW TABLES FROM INFORMATION_SCHEMA" \
|
||||
| grep -i "INNODB_LOCK_WAITS" >/dev/null 2>&1
|
||||
if [ $? -eq 0 ]; then
|
||||
have_lock_waits_table="yes"
|
||||
fi
|
||||
|
||||
# Collect multiple snapshots of the status variables. We use
|
||||
# mysqladmin -c even though it is buggy and won't stop on its
|
||||
@@ -183,92 +221,110 @@ collect() {
|
||||
# the database tends to exceed max_connections, so reconnecting
|
||||
# in the loop tends not to work very well.
|
||||
$CMD_MYSQLADMIN $EXT_ARGV ext -i$OPT_SLEEP_COLLECT -c$cnt >>"$d/$p-mysqladmin" &
|
||||
local mysqladmin_pid=$!
|
||||
fi
|
||||
mysqladmin_pid=$!
|
||||
|
||||
local have_lock_waits_table=""
|
||||
$CMD_MYSQL $EXT_ARGV -e "SHOW TABLES FROM INFORMATION_SCHEMA" \
|
||||
| grep -i "INNODB_LOCK_WAITS" >/dev/null 2>&1
|
||||
if [ $? -eq 0 ]; then
|
||||
have_lock_waits_table="yes"
|
||||
fi
|
||||
|
||||
# This loop gathers data for the rest of the duration, and defines the time
|
||||
# of the whole job.
|
||||
log "Loop start: $(date +'TS %s.%N %F %T')"
|
||||
local start_time=$(date +'%s')
|
||||
local curr_time=$start_time
|
||||
local ps_instrumentation_enabled=$($CMD_MYSQL $EXT_ARGV -e 'SELECT ENABLED FROM performance_schema.setup_instruments WHERE NAME = "transaction";' \
|
||||
ps_instrumentation_enabled=$($CMD_MYSQL $EXT_ARGV -e 'SELECT ENABLED FROM performance_schema.setup_instruments WHERE NAME = "transaction";' \
|
||||
| sed "2q;d" | sed 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/')
|
||||
|
||||
if [ $ps_instrumentation_enabled != "yes" ]; then
|
||||
log "Performance Schema instrumentation is disabled"
|
||||
fi
|
||||
}
|
||||
|
||||
while [ $((curr_time - start_time)) -lt $OPT_RUN_TIME ]; do
|
||||
if [ ! "$OPT_MYSQL_ONLY" ]; then
|
||||
# We check the disk, but don't exit, because we need to stop jobs if we
|
||||
# need to exit.
|
||||
disk_space $d > $d/$p-disk-space
|
||||
check_disk_space \
|
||||
$d/$p-disk-space \
|
||||
"$OPT_DISK_BYTES_FREE" \
|
||||
"$OPT_DISK_PCT_FREE" \
|
||||
|| break
|
||||
collect_system_data() {
|
||||
ps -eaF >> "$d/$p-ps" &
|
||||
top -bn${OPT_RUN_TIME} >> "$d/$p-top" &
|
||||
|
||||
# Sleep between collect cycles.
|
||||
# Synchronize ourselves onto the clock tick, so the sleeps are 1-second
|
||||
sleep $(date +'%s.%N' | awk "{print $OPT_SLEEP_COLLECT - (\$1 % $OPT_SLEEP_COLLECT)}")
|
||||
local ts="$(date +"TS %s.%N %F %T")"
|
||||
[ "$mysqld_pid" ] && _lsof $mysqld_pid >> "$d/$p-lsof" &
|
||||
|
||||
# #####################################################################
|
||||
# Collect data for this cycle.
|
||||
# #####################################################################
|
||||
if [ -d "/proc" ]; then
|
||||
if [ -f "/proc/diskstats" ]; then
|
||||
(echo $ts; cat /proc/diskstats) >> "$d/$p-diskstats" &
|
||||
fi
|
||||
if [ -f "/proc/stat" ]; then
|
||||
(echo $ts; cat /proc/stat) >> "$d/$p-procstat" &
|
||||
fi
|
||||
if [ -f "/proc/vmstat" ]; then
|
||||
(echo $ts; cat /proc/vmstat) >> "$d/$p-procvmstat" &
|
||||
fi
|
||||
if [ -f "/proc/meminfo" ]; then
|
||||
(echo $ts; cat /proc/meminfo) >> "$d/$p-meminfo" &
|
||||
fi
|
||||
if [ -f "/proc/slabinfo" ]; then
|
||||
(echo $ts; cat /proc/slabinfo) >> "$d/$p-slabinfo" &
|
||||
fi
|
||||
if [ -f "/proc/interrupts" ]; then
|
||||
(echo $ts; cat /proc/interrupts) >> "$d/$p-interrupts" &
|
||||
fi
|
||||
fi
|
||||
(echo $ts; df -k) >> "$d/$p-df" &
|
||||
(echo $ts; netstat -antp) >> "$d/$p-netstat" &
|
||||
(echo $ts; netstat -s) >> "$d/$p-netstat_s" &
|
||||
if [ "$CMD_SYSCTL" ]; then
|
||||
$CMD_SYSCTL -a >> "$d/$p-sysctl" &
|
||||
fi
|
||||
|
||||
# collect dmesg events from 60 seconds ago until present
|
||||
if [ "$CMD_DMESG" ]; then
|
||||
local UPTIME=`cat /proc/uptime | awk '{ print $1 }'`
|
||||
local START_TIME=$(echo "$UPTIME 60" | awk '{print ($1 - $2)}')
|
||||
$CMD_DMESG | perl -ne 'm/\[\s*(\d+)\./; if ($1 > '${START_TIME}') { print }' >> "$d/$p-dmesg" &
|
||||
fi
|
||||
|
||||
if [ "$CMD_VMSTAT" ]; then
|
||||
$CMD_VMSTAT $OPT_SLEEP_COLLECT $cnt >> "$d/$p-vmstat" &
|
||||
$CMD_VMSTAT $OPT_RUN_TIME 2 >> "$d/$p-vmstat-overall" &
|
||||
fi
|
||||
if [ "$CMD_IOSTAT" ]; then
|
||||
$CMD_IOSTAT -dx $OPT_SLEEP_COLLECT $cnt >> "$d/$p-iostat" &
|
||||
$CMD_IOSTAT -dx $OPT_RUN_TIME 2 >> "$d/$p-iostat-overall" &
|
||||
fi
|
||||
if [ "$CMD_MPSTAT" ]; then
|
||||
$CMD_MPSTAT -P ALL $OPT_SLEEP_COLLECT $cnt >> "$d/$p-mpstat" &
|
||||
$CMD_MPSTAT -P ALL $OPT_RUN_TIME 1 >> "$d/$p-mpstat-overall" &
|
||||
fi
|
||||
}
|
||||
|
||||
collect_mysql_data_loop() {
|
||||
(echo $ts; $CMD_MYSQL $EXT_ARGV -e "SHOW FULL PROCESSLIST\G") \
|
||||
>> "$d/$p-processlist" &
|
||||
if [ "$have_lock_waits_table" ]; then
|
||||
(echo $ts; lock_waits) >>"$d/$p-lock-waits" &
|
||||
(echo $ts; transactions) >>"$d/$p-transactions" &
|
||||
fi
|
||||
|
||||
if [ "${mysql_version}" '>' "5.6" ] && [ $ps_instrumentation_enabled == "yes" ]; then
|
||||
ps_locks_transactions "$d/$p-ps-locks-transactions"
|
||||
fi
|
||||
|
||||
if [ "${mysql_version}" '>' "5.6" ]; then
|
||||
(echo $ts; ps_prepared_statements) >> "$d/$p-prepared-statements" &
|
||||
fi
|
||||
|
||||
slave_status "$d/$p-slave-status" "${mysql_version}"
|
||||
}
|
||||
|
||||
collect_system_data_loop() {
|
||||
# We check the disk, but don't exit, because we need to stop jobs if we
|
||||
# need to exit.
|
||||
disk_space $d > $d/$p-disk-space
|
||||
check_disk_space \
|
||||
$d/$p-disk-space \
|
||||
"$OPT_DISK_BYTES_FREE" \
|
||||
"$OPT_DISK_PCT_FREE" \
|
||||
|| break
|
||||
|
||||
# Sleep between collect cycles.
|
||||
# Synchronize ourselves onto the clock tick, so the sleeps are 1-second
|
||||
sleep $(date +'%s.%N' | awk "{print $OPT_SLEEP_COLLECT - (\$1 % $OPT_SLEEP_COLLECT)}")
|
||||
ts="$(date +"TS %s.%N %F %T")"
|
||||
|
||||
# #####################################################################
|
||||
# Collect data for this cycle.
|
||||
# #####################################################################
|
||||
if [ -d "/proc" ]; then
|
||||
if [ -f "/proc/diskstats" ]; then
|
||||
(echo $ts; cat /proc/diskstats) >> "$d/$p-diskstats" &
|
||||
fi
|
||||
(echo $ts; $CMD_MYSQL $EXT_ARGV -e "SHOW FULL PROCESSLIST\G") \
|
||||
>> "$d/$p-processlist" &
|
||||
if [ "$have_lock_waits_table" ]; then
|
||||
(echo $ts; lock_waits) >>"$d/$p-lock-waits" &
|
||||
(echo $ts; transactions) >>"$d/$p-transactions" &
|
||||
if [ -f "/proc/stat" ]; then
|
||||
(echo $ts; cat /proc/stat) >> "$d/$p-procstat" &
|
||||
fi
|
||||
|
||||
if [ "${mysql_version}" '>' "5.6" ] && [ $ps_instrumentation_enabled == "yes" ]; then
|
||||
ps_locks_transactions "$d/$p-ps-locks-transactions"
|
||||
if [ -f "/proc/vmstat" ]; then
|
||||
(echo $ts; cat /proc/vmstat) >> "$d/$p-procvmstat" &
|
||||
fi
|
||||
|
||||
if [ "${mysql_version}" '>' "5.6" ]; then
|
||||
(echo $ts; ps_prepared_statements) >> "$d/$p-prepared-statements" &
|
||||
if [ -f "/proc/meminfo" ]; then
|
||||
(echo $ts; cat /proc/meminfo) >> "$d/$p-meminfo" &
|
||||
fi
|
||||
if [ -f "/proc/slabinfo" ]; then
|
||||
(echo $ts; cat /proc/slabinfo) >> "$d/$p-slabinfo" &
|
||||
fi
|
||||
if [ -f "/proc/interrupts" ]; then
|
||||
(echo $ts; cat /proc/interrupts) >> "$d/$p-interrupts" &
|
||||
fi
|
||||
fi
|
||||
(echo $ts; df -k) >> "$d/$p-df" &
|
||||
(echo $ts; netstat -antp) >> "$d/$p-netstat" &
|
||||
(echo $ts; netstat -s) >> "$d/$p-netstat_s" &
|
||||
}
|
||||
|
||||
slave_status "$d/$p-slave-status" "${mysql_version}"
|
||||
|
||||
curr_time=$(date +'%s')
|
||||
done
|
||||
log "Loop end: $(date +'TS %s.%N %F %T')"
|
||||
|
||||
collect_mysql_data_two() {
|
||||
if [ "$have_oprofile" ]; then
|
||||
$CMD_OPCONTROL --stop
|
||||
$CMD_OPCONTROL --dump
|
||||
@@ -316,28 +372,9 @@ collect() {
|
||||
open_tables >> "$d/$p-opentables2" &
|
||||
|
||||
# Kill backgrounded tasks.
|
||||
kill $mysqladmin_pid
|
||||
[ "$mysqladmin_pid" ] && kill $mysqladmin_pid
|
||||
[ "$tail_error_log_pid" ] && kill $tail_error_log_pid
|
||||
[ "$tcpdump_pid" ] && kill $tcpdump_pid
|
||||
|
||||
# Finally, record what system we collected this data from.
|
||||
hostname > "$d/$p-hostname"
|
||||
|
||||
# Remove "empty" files, i.e. ones that are truly empty or
|
||||
# just contain timestamp lines. When a command above fails,
|
||||
# it may leave an empty file. But first wait another --run-time
|
||||
# seconds for any slow process to finish:
|
||||
# https://bugs.launchpad.net/percona-toolkit/+bug/1047701
|
||||
wait_for_subshells $OPT_RUN_TIME
|
||||
kill_all_subshells
|
||||
for file in "$d/$p-"*; do
|
||||
# If there's not at least 1 line that's not a TS,
|
||||
# then the file is empty.
|
||||
if [ -z "$(grep -v '^TS ' --max-count 10 "$file")" ]; then
|
||||
log "Removing empty file $file";
|
||||
rm "$file"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
open_tables() {
|
||||
@@ -391,8 +428,13 @@ transactions() {
|
||||
tokudb_status() {
|
||||
local n=$1
|
||||
|
||||
$CMD_MYSQL $EXT_ARGV -e "SHOW ENGINE TOKUDB STATUS\G" \
|
||||
>> "$d/$p-tokudbstatus$n" || rm -f "$d/$p-tokudbstatus$n"
|
||||
has_tokudb=`$CMD_MYSQL $EXT_ARGV -e "SHOW ENGINES" | grep -i 'tokudb'`
|
||||
exit_code=$?
|
||||
|
||||
if [ $exit_code -eq 0 ]; then
|
||||
$CMD_MYSQL $EXT_ARGV -e "SHOW ENGINE TOKUDB STATUS\G" \
|
||||
>> "$d/$p-tokudbstatus$n" || rm -f "$d/$p-tokudbstatus$n"
|
||||
fi
|
||||
}
|
||||
|
||||
innodb_status() {
|
||||
@@ -475,11 +517,11 @@ slave_status() {
|
||||
echo -e "\n$sql\n" >> $outfile
|
||||
$CMD_MYSQL $EXT_ARGV -e "$sql" >> $outfile
|
||||
|
||||
sql="SELECT * FROM replication_connection_status\G"
|
||||
sql="SELECT * FROM performance_schema.replication_connection_status\G"
|
||||
echo -e "\n$sql\n" >> $outfile
|
||||
$CMD_MYSQL $EXT_ARGV -e "$sql" >> $outfile
|
||||
|
||||
sql="SELECT * FROM replication_applier_status JOIN replication_applier_status_by_coordinator USING(channel_name)\G"
|
||||
sql="SELECT * FROM performance_schema.replication_applier_status JOIN performance_schema.replication_applier_status_by_coordinator USING(channel_name)\G"
|
||||
echo -e "\n$sql\n" >> $outfile
|
||||
$CMD_MYSQL $EXT_ARGV -e "$sql" >> $outfile
|
||||
fi
|
||||
|
@@ -542,13 +542,13 @@ $retval = system("$trunk/bin/pt-stalk --no-stalk --run-time 2 --sleep 2 --dest $
|
||||
|
||||
PerconaTest::wait_until(sub { !-f $pid_file });
|
||||
|
||||
$output = `du -s $dest | wc -l`;
|
||||
$output = `ls -l $dest | wc -l`;
|
||||
|
||||
$retval = system("$trunk/bin/pt-stalk --no-stalk --run-time 2 --dest $dest --retention-count 1 --pid $pid_file --iterations 1 -- --defaults-file=$cnf >$log_file 2>&1");
|
||||
|
||||
PerconaTest::wait_until(sub { !-f $pid_file });
|
||||
|
||||
$output = $output - `du -s $dest | wc -l`;
|
||||
$output = $output - `ls -l $dest | wc -l`;
|
||||
|
||||
is(
|
||||
$output,
|
||||
|
@@ -72,19 +72,19 @@ replace_pkg_in_tool() {
|
||||
if [ "$tool_lang" = "perl" ]; then
|
||||
echo "# $pkg 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,
|
||||
# with comments and its test file can be found in the GitHub repository at,
|
||||
# lib/$pkg_file_base.pm
|
||||
# t/lib/$pkg_file_base.t
|
||||
# See https://launchpad.net/percona-toolkit for more information.
|
||||
# See https://github.com/percona/percona-toolkit for more information.
|
||||
# ###########################################################################
|
||||
{" >> $tmp_file
|
||||
else
|
||||
echo "# $pkg 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,
|
||||
# with comments and its test file can be found in the GitHub repository at,
|
||||
# lib/bash/$pkg.sh
|
||||
# t/lib/bash/$pkg.sh
|
||||
# See https://launchpad.net/percona-toolkit for more information.
|
||||
# See https://github.com/percona/percona-toolkit for more information.
|
||||
# ###########################################################################
|
||||
" >> $tmp_file
|
||||
fi
|
||||
|
Reference in New Issue
Block a user