Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 34 additions & 13 deletions bin/pt-mysql-summary
Original file line number Diff line number Diff line change
Expand Up @@ -2140,11 +2140,22 @@ section_innodb () {
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)"
local redo_capacity="$(get_var innodb_redo_log_capacity "$variables_file")"
if [ -n "${redo_capacity}" ] && [ "${redo_capacity}" -gt 0 ] 2>/dev/null; then
name_val "Log File Size" "$(shorten ${redo_capacity} 1)"
else
local log_size="$(get_var innodb_log_file_size "$variables_file")"
local log_file="$(get_var innodb_log_files_in_group "$variables_file")"
if [ -n "${log_size}" ] && [ -n "${log_file}" ]; then
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)"
elif [ -n "${log_size}" ]; then
name_val "Log File Size" "$(shorten ${log_size} 1)"
else
name_val "Log File Size" "Unknown"
fi
fi
name_val "Log Buffer Size" \
"$(shorten $(get_var innodb_log_buffer_size "$variables_file") 0)"
name_val "Flush Method" \
Expand Down Expand Up @@ -2729,13 +2740,15 @@ TOOL="pt-mysql-summary"
[ "$CMD_MYSQLDUMP" ] || CMD_MYSQLDUMP="$( _which mysqldump )"

check_mysql () {
# Check that mysql and mysqldump are in PATH. If not, we're
# already dead in the water, so don't bother with cmd line opts,
# just error and exit.
# mysql is always required for live collection.
[ -n "$(${CMD_MYSQL} --help 2>/dev/null)" ] \
|| die "Cannot execute mysql. Check that it is in PATH."
[ -n "$(${CMD_MYSQLDUMP} --help 2>/dev/null)" ] \
|| die "Cannot execute mysqldump. Check that it is in PATH."

# mysqldump is only used for the optional schema analysis.
if [ -n "$OPT_DATABASES" ] || [ -n "$OPT_ALL_DATABASES" ]; then
[ -n "$(${CMD_MYSQLDUMP} --help 2>/dev/null)" ] \
|| die "Cannot execute mysqldump. Check that it is in PATH."
fi

# Now that we have the cmd line opts, check that we can actually
# connect to MySQL.
Expand All @@ -2761,9 +2774,8 @@ main() {
local MYSQL_ARGS="$(mysql_options)"
EXT_ARGV="$(arrange_mysql_options "$EXT_ARGV $MYSQL_ARGS")"

# Check if mysql and mysqldump are there, otherwise bail out early.
# But don't if they passed in --read-samples, since we don't need
# a connection then.
# Check the required client programs, unless --read-samples was used
# and no live connection is needed.
[ "$OPT_READ_SAMPLES" ] || check_mysql

local RAN_WITH="--sleep=$OPT_SLEEP --databases=$OPT_DATABASES --save-samples=$OPT_SAVE_SAMPLES"
Expand Down Expand Up @@ -3157,6 +3169,15 @@ engine. The buffer pool fill percent and dirty percent are fuzzy-rounded. The
last few lines are derived from the output of SHOW INNODB STATUS. It is likely
that this output will change in the future to become more useful.

The C<Log File Size> line above shows C<count * per-file = total>, which is how
it is reported on servers exposing C<innodb_log_file_size> and
C<innodb_log_files_in_group>. MySQL 8.0.30 replaced both with a single
C<innodb_redo_log_capacity> and MySQL 9.0 removed them, so on those versions the
line shows that capacity as a bare total instead. MariaDB 10.5 dropped
C<innodb_log_files_in_group> without adding a capacity variable, so there the
line shows C<innodb_log_file_size> as a bare total. When none of these variables
is available the line reads C<Unknown>.

# MyISAM #####################################################
Key Cache | 16.0M
Pct Used | 10%
Expand Down
2 changes: 1 addition & 1 deletion config/scripts/pt_builder.sh
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ install_go() {
#rm -rf /usr/local/go /usr/local/go1.8 /usr/local/go1.9
#mv go1.9 /usr/local/
#ln -s /usr/local/go1.9 /usr/local/go
GO_VERSION=1.26.2
GO_VERSION=1.26.5
if [ x"$ARCH" = "xx86_64" ]; then
GO_ARCH="amd64"
elif [ x"$ARCH" = "xaarch64" ]; then
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/percona/percona-toolkit

go 1.26.4
go 1.26.5

require (
github.com/AlekSi/pointer v1.2.0
Expand Down
26 changes: 21 additions & 5 deletions lib/bash/report_mysql_info.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1027,11 +1027,27 @@ section_innodb () {
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)"
local redo_capacity="$(get_var innodb_redo_log_capacity "$variables_file")"
if [ -n "${redo_capacity}" ] && [ "${redo_capacity}" -gt 0 ] 2>/dev/null; then
# MySQL 8.0.30 and newer manage redo files dynamically and expose their
# total capacity instead of the legacy file size/count variables.
name_val "Log File Size" "$(shorten ${redo_capacity} 1)"
else
local log_size="$(get_var innodb_log_file_size "$variables_file")"
local log_file="$(get_var innodb_log_files_in_group "$variables_file")"
if [ -n "${log_size}" ] && [ -n "${log_file}" ]; then
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)"
elif [ -n "${log_size}" ]; then
# MariaDB 10.5 dropped innodb_log_files_in_group and never had
# innodb_redo_log_capacity, leaving innodb_log_file_size as the total.
# Report it rather than discarding a size the server does expose.
name_val "Log File Size" "$(shorten ${log_size} 1)"
else
name_val "Log File Size" "Unknown"
Comment on lines +1036 to +1048

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requiring both log_size and log_file means a server that exposes only innodb_log_file_size now reports Unknown, discarding a value it actually has. Verified by driving section_innodb with innodb_log_files_in_group stripped and no innodb_redo_log_capacity present:

Log File Size | Unknown

That combination is MariaDB 10.5+, which dropped innodb_log_files_in_group and never had innodb_redo_log_capacity. The old code wasn't correct there either — it emitted a malformed * 92.0M = — so this isn't a clean regression, but it trades garbage for no information instead of for the number. Defaulting the multiplier costs one line:

Suggested change
local log_size="$(get_var innodb_log_file_size "$variables_file")"
local log_file="$(get_var innodb_log_files_in_group "$variables_file")"
if [ -n "${log_size}" ] && [ -n "${log_file}" ]; then
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)"
else
name_val "Log File Size" "Unknown"
local log_size="$(get_var innodb_log_file_size "$variables_file")"
local log_file="$(get_var innodb_log_files_in_group "$variables_file")"
if [ -n "${log_size}" ]; then
[ -n "${log_file}" ] || log_file=1
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)"
else
name_val "Log File Size" "Unknown"

Worth confirming whether MariaDB is in scope for pt-mysql-summary at all — there are no MariaDB samples under t/pt-mysql-summary/samples/, so CI wouldn't catch it either way.

fi
fi
name_val "Log Buffer Size" \
"$(shorten $(get_var innodb_log_buffer_size "$variables_file") 0)"
name_val "Flush Method" \
Expand Down
64 changes: 63 additions & 1 deletion t/lib/bash/report_mysql_info.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env bash

plan 47
plan 51

. "$LIB_DIR/alt_cmds.sh"
. "$LIB_DIR/log_warn_die.sh"
Expand Down Expand Up @@ -681,6 +681,68 @@ EOF

test_format_innodb

# Drives section_innodb against one InnoDB redo log variable layout and compares
# only the "Log File Size" line.
# $1 test name
# $2 expected value
# $3 extended regex of variables to drop from the temp001 sample, or ""
# $4.. "name\tvalue" lines to append
# get_var prints every matching line, so anything appended here must also be
# named in $3 - a duplicate would make it return two values.
test_format_innodb_log_size () {
local test_name="$1"
local expected="$2"
local strip="$3"
shift 3

local NAME_VAL_LEN=25
local vars="$PT_TMPDIR/mysql-variables-log-size"

if [ -n "$strip" ]; then
grep -vE "$strip" "$samples/temp001/mysql-variables" > "$vars"
else
cp "$samples/temp001/mysql-variables" "$vars"
fi
local line
for line in "$@"; do
printf '%b\n' "$line" >> "$vars"
done

cat <<EOF > $PT_TMPDIR/expected
Log File Size | $expected
EOF

section_innodb "$vars" "$samples/temp001/mysql-status" \
| grep "Log File Size" > "$PT_TMPDIR/got"
no_diff "$PT_TMPDIR/got" "$PT_TMPDIR/expected" "$test_name"
}

# MySQL 8.0.30 through 8.4: the capacity and both legacy variables are present,
# so this pins the precedence - the capacity is what the server actually honours.
test_format_innodb_log_size \
"Format InnoDB redo log capacity" "100.0M" \
'^innodb_redo_log_capacity' \
'innodb_redo_log_capacity\t104857600'

# MySQL 9.x: the legacy variables were removed, only the capacity remains. This
# is the layout the MySQL 9.7 work is actually about.
test_format_innodb_log_size \
"Format InnoDB redo log capacity without legacy variables" "100.0M" \
'^innodb_log_file_size|^innodb_log_files_in_group|^innodb_redo_log_capacity' \
'innodb_redo_log_capacity\t104857600'

# MariaDB 10.5+: innodb_log_files_in_group was dropped and the redo capacity
# never existed, so innodb_log_file_size alone is the total.
test_format_innodb_log_size \
"Format InnoDB log file size without a file count" "96.0M" \
'^innodb_log_file_size|^innodb_log_files_in_group|^innodb_redo_log_capacity' \
'innodb_log_file_size\t100663296'

# No redo size variable of any spelling: say so rather than print a malformed one.
test_format_innodb_log_size \
"Format InnoDB log file size when unknown" "Unknown" \
'^innodb_log_file_size|^innodb_log_files_in_group|^innodb_redo_log_capacity'

# ###########################################################################
# format_innodb_filters
# ###########################################################################
Expand Down
35 changes: 35 additions & 0 deletions t/pt-mysql-summary/pt-mysql-summary.t
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,41 @@ ok(

undef($dir); # rm the dir because CLEANUP => 1

#
# mysqldump is optional without schema analysis
#

my $env_without_mysqldump = qq\CMD_MYSQL="$ENV{PERCONA_TOOLKIT_SANDBOX}/bin/mysql" CMD_MYSQLDUMP="/nonexistent/mysqldump" LC_NUMERIC=POSIX\;
my $out_without_mysqldump = `$env_without_mysqldump $trunk/bin/$tool --sleep 1 -- --defaults-file=/tmp/12345/my.sandbox.cnf 2>&1`;
my $status_without_mysqldump = $CHILD_ERROR;

is(
$status_without_mysqldump,
0,
"mysqldump is not required without schema analysis"
);

unlike(
$out_without_mysqldump,
qr/Cannot execute mysqldump/,
"default summary does not report missing mysqldump"
);

my $schema_out_without_mysqldump = `$env_without_mysqldump $trunk/bin/$tool --sleep 1 --databases mysql -- --defaults-file=/tmp/12345/my.sandbox.cnf 2>&1`;
my $schema_status_without_mysqldump = $CHILD_ERROR;

isnt(
$schema_status_without_mysqldump,
0,
"mysqldump is required for schema analysis"
);

like(
$schema_out_without_mysqldump,
qr/Cannot execute mysqldump/,
"schema analysis reports missing mysqldump"
);

#
# --databases
#
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ Specify --databases or --all-databases to dump and summarize schemas
Buffer Pool Dirty | 10%
File Per Table | ON
Page Size | 16k
Log File Size | 2 * 5.0M = 10.0M
Log File Size | 100.0M
Log Buffer Size | 16M
Flush Method | fsync
Flush Log At Commit | 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ Specify --databases or --all-databases to dump and summarize schemas
Buffer Pool Dirty | 0%
File Per Table | ON
Page Size | 16k
Log File Size | 2 * 5.0M = 10.0M
Log File Size | 100.0M
Log Buffer Size | 16M
Flush Method | fsync
Flush Log At Commit | 1
Expand Down
Loading