mirror of
https://github.com/percona/percona-toolkit.git
synced 2025-09-01 18:25:59 +00:00

- Adjusted tools and tests which fail due to fixed update-modules command - Adjsted t/pt-table-checksum/basics.t test for 8.0
646 lines
17 KiB
Perl
646 lines
17 KiB
Perl
# This program is copyright 2010-2011 Percona Ireland Ltd.
|
|
# Feedback and improvements are welcome.
|
|
#
|
|
# THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
|
|
# WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
|
# MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify it under
|
|
# the terms of the GNU General Public License as published by the Free Software
|
|
# Foundation, version 2; OR the Perl Artistic License. On UNIX and similar
|
|
# systems, you can issue `man perlgpl' or `man perlartistic' to read these
|
|
# licenses.
|
|
#
|
|
# You should have received a copy of the GNU General Public License along with
|
|
# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
|
# Place, Suite 330, Boston, MA 02111-1307 USA.
|
|
# ###########################################################################
|
|
# VariableAdvisorRules package
|
|
# ###########################################################################
|
|
{
|
|
# Package: VariableAdvisorRules
|
|
# VariableAdvisorRules specifies rules for checking MySQL variables.
|
|
package VariableAdvisorRules;
|
|
use base 'AdvisorRules';
|
|
|
|
use strict;
|
|
use warnings FATAL => 'all';
|
|
use English qw(-no_match_vars);
|
|
use constant PTDEBUG => $ENV{PTDEBUG} || 0;
|
|
|
|
sub new {
|
|
my ( $class, %args ) = @_;
|
|
my $self = $class->SUPER::new(%args);
|
|
@{$self->{rules}} = $self->get_rules();
|
|
PTDEBUG && _d(scalar @{$self->{rules}}, "rules");
|
|
return $self;
|
|
}
|
|
|
|
# Each rules is a hashref with two keys:
|
|
# * id Unique PREFIX.NUMBER for the rule.
|
|
# * code Coderef to check rule, returns true if the rule matches.
|
|
sub get_rules {
|
|
return
|
|
{
|
|
id => 'auto_increment',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
my $vars = $args{variables};
|
|
return unless defined $vars->{auto_increment_increment}
|
|
&& defined $vars->{auto_increment_offset};
|
|
return $vars->{auto_increment_increment} != 1
|
|
|| $vars->{auto_increment_offset} != 1 ? 1 : 0;
|
|
},
|
|
},
|
|
{
|
|
id => 'concurrent_insert',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
# MySQL 5.5 has named values.
|
|
# http://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html
|
|
# https://bugs.launchpad.net/percona-toolkit/+bug/898138
|
|
if ( $args{variables}->{concurrent_insert}
|
|
&& $args{variables}->{concurrent_insert} =~ m/[^\d]/ ) {
|
|
return $args{variables}->{concurrent_insert} eq 'ALWAYS' ? 1 : 0;
|
|
}
|
|
return _var_gt($args{variables}->{concurrent_insert}, 1);
|
|
},
|
|
},
|
|
{
|
|
id => 'connect_timeout',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_gt($args{variables}->{connect_timeout}, 10);
|
|
},
|
|
},
|
|
{
|
|
id => 'debug',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return $args{variables}->{debug} ? 1 : 0;
|
|
},
|
|
},
|
|
{
|
|
id => 'delay_key_write',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_seq($args{variables}->{delay_key_write}, "ON");
|
|
},
|
|
},
|
|
{
|
|
id => 'flush',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_seq($args{variables}->{flush}, "ON");
|
|
},
|
|
},
|
|
{
|
|
id => 'flush_time',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_gt($args{variables}->{flush_time}, 0);
|
|
},
|
|
},
|
|
{
|
|
id => 'have_bdb',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_seq($args{variables}->{have_bdb}, 'YES');
|
|
},
|
|
},
|
|
{
|
|
id => 'init_connect',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return $args{variables}->{init_connect} ? 1 : 0;
|
|
},
|
|
},
|
|
{
|
|
id => 'init_file',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return $args{variables}->{init_file} ? 1 : 0;
|
|
},
|
|
},
|
|
{
|
|
id => 'init_slave',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return $args{variables}->{init_slave} ? 1 : 0;
|
|
},
|
|
},
|
|
{
|
|
id => 'init_replica',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return $args{variables}->{init_replica} ? 1 : 0;
|
|
},
|
|
},
|
|
{
|
|
id => 'innodb_additional_mem_pool_size',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_gt($args{variables}->{innodb_additional_mem_pool_size},
|
|
20 * 1_048_576); # 20M
|
|
},
|
|
},
|
|
{
|
|
id => 'innodb_buffer_pool_size',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_eq($args{variables}->{innodb_buffer_pool_size},
|
|
128 * 1_048_576); # 128M
|
|
},
|
|
},
|
|
{
|
|
id => 'innodb_checksums',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_sneq($args{variables}->{innodb_checksums}, "ON");
|
|
},
|
|
},
|
|
{
|
|
id => 'innodb_doublewrite',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_sneq($args{variables}->{innodb_doublewrite}, "ON");
|
|
},
|
|
},
|
|
{
|
|
id => 'innodb_fast_shutdown',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_neq($args{variables}->{innodb_fast_shutdown}, 1);
|
|
},
|
|
},
|
|
{
|
|
id => 'innodb_flush_log_at_trx_commit-1',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_neq($args{variables}->{innodb_flush_log_at_trx_commit}, 1);
|
|
},
|
|
},
|
|
{
|
|
id => 'innodb_flush_log_at_trx_commit-2',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_eq($args{variables}->{innodb_flush_log_at_trx_commit}, 0);
|
|
},
|
|
},
|
|
{
|
|
id => 'innodb_force_recovery',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_gt($args{variables}->{innodb_force_recovery}, 0);
|
|
},
|
|
},
|
|
{
|
|
id => 'innodb_lock_wait_timeout',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_gt($args{variables}->{innodb_lock_wait_timeout}, 50);
|
|
},
|
|
},
|
|
{
|
|
id => 'innodb_log_buffer_size',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_gt($args{variables}->{innodb_log_buffer_size},
|
|
64 * 1_048_576); # 64M
|
|
},
|
|
},
|
|
{
|
|
id => 'innodb_log_file_size',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_eq($args{variables}->{innodb_log_file_size},
|
|
48 * 1_048_576); # 48M
|
|
},
|
|
},
|
|
{
|
|
id => 'innodb_max_dirty_pages_pct',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
my $mysql_version = $args{mysql_version};
|
|
return 0 unless $mysql_version;
|
|
return _var_lt($args{variables}->{innodb_max_dirty_pages_pct},
|
|
($mysql_version < '5.5' ? 90 : 75));
|
|
},
|
|
},
|
|
{
|
|
id => 'key_buffer_size',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_eq($args{variables}->{key_buffer_size},
|
|
8 * 1_048_576); # 8M
|
|
},
|
|
},
|
|
{
|
|
id => 'large_pages',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_seq($args{variables}->{large_pages}, "ON");
|
|
},
|
|
},
|
|
{
|
|
id => 'locked_in_memory',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_seq($args{variables}->{locked_in_memory}, "ON");
|
|
},
|
|
},
|
|
{
|
|
id => 'log_warnings-1',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_eq($args{variables}->{log_warnings}, 0);
|
|
},
|
|
},
|
|
{
|
|
id => 'log_warnings-2',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_eq($args{variables}->{log_warnings}, 1);
|
|
},
|
|
},
|
|
{
|
|
id => 'low_priority_updates',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_seq($args{variables}->{low_priority_updates}, "ON");
|
|
},
|
|
},
|
|
{
|
|
id => 'max_binlog_size',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_lt($args{variables}->{max_binlog_size},
|
|
1 * 1_073_741_824); # 1G
|
|
},
|
|
},
|
|
{
|
|
id => 'max_connect_errors',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_eq($args{variables}->{max_connect_errors}, 10);
|
|
},
|
|
},
|
|
{
|
|
id => 'max_connections',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_gt($args{variables}->{max_connections}, 1_000);
|
|
},
|
|
},
|
|
|
|
{
|
|
id => 'myisam_repair_threads',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_gt($args{variables}->{myisam_repair_threads}, 1);
|
|
},
|
|
},
|
|
{
|
|
id => 'old_passwords',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_seq($args{variables}->{old_passwords}, "ON");
|
|
},
|
|
},
|
|
{
|
|
id => 'optimizer_prune_level',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_lt($args{variables}->{optimizer_prune_level}, 1);
|
|
},
|
|
},
|
|
{
|
|
id => 'port',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_neq($args{variables}->{port}, 3306);
|
|
},
|
|
},
|
|
{
|
|
id => 'query_cache_size-1',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_gt($args{variables}->{query_cache_size},
|
|
128 * 1_048_576); # 128M
|
|
},
|
|
},
|
|
{
|
|
id => 'query_cache_size-2',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_gt($args{variables}->{query_cache_size},
|
|
512 * 1_048_576); # 512M
|
|
},
|
|
},
|
|
{
|
|
id => 'query_cache_size-3',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_neq($args{variables}->{query_cache_size}, 0);
|
|
},
|
|
},
|
|
{
|
|
id => 'read_buffer_size-1',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_neq($args{variables}->{read_buffer_size}, 131_072);
|
|
},
|
|
},
|
|
{
|
|
id => 'read_buffer_size-2',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_gt($args{variables}->{read_buffer_size},
|
|
8 * 1_048_576); # 8M
|
|
},
|
|
},
|
|
{
|
|
id => 'read_rnd_buffer_size-1',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_neq($args{variables}->{read_rnd_buffer_size}, 262_144);
|
|
},
|
|
},
|
|
{
|
|
id => 'read_rnd_buffer_size-2',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_gt($args{variables}->{read_rnd_buffer_size},
|
|
4 * 1_048_576); # 4M
|
|
},
|
|
},
|
|
{
|
|
id => 'relay_log_space_limit',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_gt($args{variables}->{relay_log_space_limit}, 0);
|
|
},
|
|
},
|
|
|
|
{
|
|
id => 'slave_net_timeout',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_gt($args{variables}->{slave_net_timeout}, 60);
|
|
},
|
|
},
|
|
{
|
|
id => 'replica_net_timeout',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_gt($args{variables}->{replica_net_timeout}, 60);
|
|
},
|
|
},
|
|
{
|
|
id => 'slave_skip_errors',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return $args{variables}->{slave_skip_errors}
|
|
&& $args{variables}->{slave_skip_errors} ne 'OFF' ? 1 : 0;
|
|
},
|
|
},
|
|
{
|
|
id => 'replica_skip_errors',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return $args{variables}->{replica_skip_errors}
|
|
&& $args{variables}->{replica_skip_errors} ne 'OFF' ? 1 : 0;
|
|
},
|
|
},
|
|
{
|
|
id => 'sort_buffer_size-1',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_neq($args{variables}->{sort_buffer_size}, 2_097_144);
|
|
},
|
|
},
|
|
{
|
|
id => 'sort_buffer_size-2',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_gt($args{variables}->{sort_buffer_size},
|
|
4 * 1_048_576); # 4M
|
|
},
|
|
},
|
|
{
|
|
id => 'sql_notes',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_seq($args{variables}->{sql_notes}, "OFF");
|
|
},
|
|
},
|
|
{
|
|
id => 'sync_frm',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_sneq($args{variables}->{sync_frm}, "ON");
|
|
},
|
|
},
|
|
{
|
|
id => 'tx_isolation-1',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_sneq($args{variables}->{tx_isolation}, "REPEATABLE-READ");
|
|
},
|
|
},
|
|
{
|
|
id => 'tx_isolation-2',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return
|
|
_var_sneq($args{variables}->{tx_isolation}, "REPEATABLE-READ")
|
|
&& _var_sneq($args{variables}->{tx_isolation}, "READ-COMMITTED")
|
|
? 1 : 0;
|
|
},
|
|
},
|
|
{
|
|
id => 'expire_logs_days',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_eq($args{variables}->{expire_logs_days}, 0)
|
|
&& _var_seq($args{variables}->{log_bin}, "ON");
|
|
},
|
|
},
|
|
{
|
|
id => 'innodb_file_io_threads',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_neq($args{variables}->{innodb_file_io_threads}, 4)
|
|
&& $OSNAME ne 'MSWin32' ? 1 : 0;
|
|
},
|
|
},
|
|
{
|
|
id => 'innodb_data_file_path',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return
|
|
($args{variables}->{innodb_data_file_path} || '') =~ m/autoextend/
|
|
? 1 : 0;
|
|
},
|
|
},
|
|
{
|
|
id => 'innodb_flush_method',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_sneq($args{variables}->{innodb_flush_method}, 'O_DIRECT')
|
|
&& $OSNAME ne 'MSWin32' ? 1 : 0;
|
|
},
|
|
},
|
|
{
|
|
id => 'innodb_locks_unsafe_for_binlog',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_seq($args{variables}->{innodb_locks_unsafe_for_binlog},
|
|
"ON") && _var_seq($args{variables}->{log_bin}, "ON");
|
|
},
|
|
},
|
|
{
|
|
id => 'innodb_support_xa',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_sneq($args{variables}->{innodb_support_xa}, "ON")
|
|
&& _var_seq($args{variables}->{log_bin}, "ON");
|
|
},
|
|
},
|
|
{
|
|
id => 'log_bin',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_sneq($args{variables}->{log_bin}, "ON");
|
|
},
|
|
},
|
|
{
|
|
id => 'log_output',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return ($args{variables}->{log_output} || '') =~ m/TABLE/i ? 1 : 0;
|
|
},
|
|
},
|
|
{
|
|
id => 'max_relay_log_size',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_gt($args{variables}->{max_relay_log_size}, 0)
|
|
&& _var_lt($args{variables}->{max_relay_log_size},
|
|
1 * 1_073_741_824) ? 1 : 0;
|
|
},
|
|
},
|
|
{
|
|
id => 'myisam_recover_options',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return _var_seq($args{variables}->{myisam_recover_options}, "OFF")
|
|
|| _var_seq($args{variables}->{myisam_recover_options}, "DEFAULT")
|
|
? 1 : 0;
|
|
},
|
|
},
|
|
{
|
|
id => 'storage_engine',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return 0 unless $args{variables}->{storage_engine};
|
|
return $args{variables}->{storage_engine} !~ m/InnoDB/i ? 1 : 0;
|
|
},
|
|
},
|
|
{
|
|
id => 'sync_binlog',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return
|
|
_var_seq($args{variables}->{log_bin}, "ON")
|
|
&& ( _var_eq($args{variables}->{sync_binlog}, 0)
|
|
|| _var_gt($args{variables}->{sync_binlog}, 1)) ? 1 : 0;
|
|
},
|
|
},
|
|
{
|
|
id => 'tmp_table_size',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
return ($args{variables}->{tmp_table_size} || 0)
|
|
> ($args{variables}->{max_heap_table_size} || 0) ? 1 : 0;
|
|
},
|
|
},
|
|
{
|
|
id => 'old mysql version',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
my $mysql_version = $args{mysql_version};
|
|
return 0 unless $mysql_version;
|
|
return 1 if ($mysql_version == '3' && $mysql_version < '3.23' )
|
|
|| ($mysql_version == '4' && $mysql_version < '4.1.20')
|
|
|| ($mysql_version == '5.0' && $mysql_version < '5.0.37')
|
|
|| ($mysql_version == '5.1' && $mysql_version < '5.1.30')
|
|
|| ($mysql_version == '5.5' && $mysql_version < '5.5.8')
|
|
|| ($mysql_version == '5.6' && $mysql_version < '5.6.10')
|
|
|| ($mysql_version == '5.7' && $mysql_version < '5.7.9')
|
|
|| ($mysql_version == '8.0' && $mysql_version < '8.0.11')
|
|
;
|
|
return 0;
|
|
},
|
|
},
|
|
{
|
|
id => 'end-of-life mysql version',
|
|
code => sub {
|
|
my ( %args ) = @_;
|
|
my $mysql_version = $args{mysql_version};
|
|
return 0 unless $mysql_version;
|
|
return $mysql_version < '8.0' ? 1 : 0; # 8.x
|
|
},
|
|
},
|
|
};
|
|
|
|
sub _var_gt {
|
|
my ($var, $val) = @_;
|
|
return 0 unless defined $var;
|
|
return $var > $val ? 1 : 0;
|
|
}
|
|
|
|
sub _var_lt {
|
|
my ($var, $val) = @_;
|
|
return 0 unless defined $var;
|
|
return $var < $val ? 1 : 0;
|
|
}
|
|
|
|
sub _var_eq {
|
|
my ($var, $val) = @_;
|
|
return 0 unless defined $var;
|
|
return $var == $val ? 1 : 0;
|
|
}
|
|
|
|
sub _var_neq {
|
|
my ($var, $val) = @_;
|
|
return 0 unless defined $var;
|
|
return _var_eq($var, $val) ? 0 : 1;
|
|
}
|
|
|
|
sub _var_seq {
|
|
my ($var, $val) = @_;
|
|
return 0 unless defined $var;
|
|
return $var eq $val ? 1 : 0;
|
|
}
|
|
|
|
sub _var_sneq {
|
|
my ($var, $val) = @_;
|
|
return 0 unless defined $var;
|
|
return _var_seq($var, $val) ? 0 : 1;
|
|
}
|
|
|
|
sub _d {
|
|
my ($package, undef, $line) = caller 0;
|
|
@_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
|
|
map { defined $_ ? $_ : 'undef' }
|
|
@_;
|
|
print STDERR "# $package:$line $PID ", join(' ', @_), "\n";
|
|
}
|
|
|
|
1;
|
|
}
|
|
# ###########################################################################
|
|
# End VariableAdvisorRules package
|
|
# ###########################################################################
|