mirror of
https://github.com/percona/percona-toolkit.git
synced 2025-10-21 18:24:38 +00:00
Add critical load to MySQLStatusWaiter.pm and pt-osc. Clean up the tool's docu.
This commit is contained in:
@@ -3684,18 +3684,31 @@ use constant PTDEBUG => $ENV{PTDEBUG} || 0;
|
|||||||
|
|
||||||
sub new {
|
sub new {
|
||||||
my ( $class, %args ) = @_;
|
my ( $class, %args ) = @_;
|
||||||
my @required_args = qw(spec get_status sleep oktorun);
|
my @required_args = qw(max_spec get_status sleep oktorun);
|
||||||
foreach my $arg ( @required_args ) {
|
foreach my $arg ( @required_args ) {
|
||||||
die "I need a $arg argument" unless defined $args{$arg};
|
die "I need a $arg argument" unless defined $args{$arg};
|
||||||
}
|
}
|
||||||
|
|
||||||
my $max_val_for = _parse_spec(%args);
|
PTDEBUG && _d('Parsing spec for max thresholds');
|
||||||
|
my $max_val_for = _parse_spec(
|
||||||
|
spec => $args{max_spec},
|
||||||
|
get_status => $args{get_status},
|
||||||
|
threshold_factor => 0.2, # +20%
|
||||||
|
);
|
||||||
|
|
||||||
|
PTDEBUG && _d('Parsing spec for critical thresholds');
|
||||||
|
my $critical_val_for = _parse_spec(
|
||||||
|
spec => $args{critical_spec} || [],
|
||||||
|
get_status => $args{get_status},
|
||||||
|
threshold_factor => 1.0, # double (x2; +100%)
|
||||||
|
);
|
||||||
|
|
||||||
my $self = {
|
my $self = {
|
||||||
get_status => $args{get_status},
|
get_status => $args{get_status},
|
||||||
sleep => $args{sleep},
|
sleep => $args{sleep},
|
||||||
oktorun => $args{oktorun},
|
oktorun => $args{oktorun},
|
||||||
max_val_for => $max_val_for,
|
max_val_for => $max_val_for,
|
||||||
|
critical_val_for => $critical_val_for,
|
||||||
};
|
};
|
||||||
|
|
||||||
return bless $self, $class;
|
return bless $self, $class;
|
||||||
@@ -3709,10 +3722,8 @@ sub _parse_spec {
|
|||||||
}
|
}
|
||||||
my ($spec, $get_status) = @args{@required_args};
|
my ($spec, $get_status) = @args{@required_args};
|
||||||
|
|
||||||
if ( !@$spec ) {
|
return unless $spec && scalar @$spec;
|
||||||
PTDEBUG && _d('No spec, disabling status var waits');
|
my $threshold_factor = $args{threshold_factor} || 0.20;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
my %max_val_for;
|
my %max_val_for;
|
||||||
foreach my $var_val ( @$spec ) {
|
foreach my $var_val ( @$spec ) {
|
||||||
@@ -3721,7 +3732,7 @@ sub _parse_spec {
|
|||||||
if ( !$val ) {
|
if ( !$val ) {
|
||||||
my $init_val = $get_status->($var);
|
my $init_val = $get_status->($var);
|
||||||
PTDEBUG && _d('Initial', $var, 'value:', $init_val);
|
PTDEBUG && _d('Initial', $var, 'value:', $init_val);
|
||||||
$val = int(($init_val * .20) + $init_val);
|
$val = int(($init_val * $threshold_factor) + $init_val);
|
||||||
}
|
}
|
||||||
PTDEBUG && _d('Wait if', $var, '>=', $val);
|
PTDEBUG && _d('Wait if', $var, '>=', $val);
|
||||||
$max_val_for{$var} = $val;
|
$max_val_for{$var} = $val;
|
||||||
@@ -3735,6 +3746,11 @@ sub max_values {
|
|||||||
return $self->{max_val_for};
|
return $self->{max_val_for};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub critical_values {
|
||||||
|
my ($self) = @_;
|
||||||
|
return $self->{critical_val_for};
|
||||||
|
}
|
||||||
|
|
||||||
sub wait {
|
sub wait {
|
||||||
my ( $self, %args ) = @_;
|
my ( $self, %args ) = @_;
|
||||||
|
|
||||||
@@ -3769,6 +3785,12 @@ sub wait {
|
|||||||
foreach my $var ( sort keys %vals_too_high ) {
|
foreach my $var ( sort keys %vals_too_high ) {
|
||||||
my $val = $get_status->($var);
|
my $val = $get_status->($var);
|
||||||
PTDEBUG && _d($var, '=', $val);
|
PTDEBUG && _d($var, '=', $val);
|
||||||
|
if ( $val
|
||||||
|
&& exists $self->{critical_val_for}->{$var}
|
||||||
|
&& $val >= $self->{critical_val_for}->{$var} ) {
|
||||||
|
die "$var=$val exceeds its critical threshold "
|
||||||
|
. "$self->{critical_val_for}->{$var}\n";
|
||||||
|
}
|
||||||
if ( !$val || $val >= $self->{max_val_for}->{$var} ) {
|
if ( !$val || $val >= $self->{max_val_for}->{$var} ) {
|
||||||
$vals_too_high{$var} = $val;
|
$vals_too_high{$var} = $val;
|
||||||
}
|
}
|
||||||
@@ -5146,7 +5168,8 @@ sub main {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$sys_load = new MySQLStatusWaiter(
|
$sys_load = new MySQLStatusWaiter(
|
||||||
spec => $o->get('max-load'),
|
max_spec => $o->get('max-load'),
|
||||||
|
critical_spec => $o->get('critical-load'),
|
||||||
get_status => $get_status,
|
get_status => $get_status,
|
||||||
oktorun => sub { return $oktorun },
|
oktorun => sub { return $oktorun },
|
||||||
sleep => $sleep,
|
sleep => $sleep,
|
||||||
@@ -6547,7 +6570,7 @@ pt-online-schema-change - Perform online, non-blocking table schema changes.
|
|||||||
|
|
||||||
=head1 SYNOPSIS
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
Usage: pt-online-schema-change [OPTION...] DSN
|
Usage: pt-online-schema-change [OPTIONS] DSN
|
||||||
|
|
||||||
BARON: NOTE we should say that you ought not to use 'rename' in --alter or the
|
BARON: NOTE we should say that you ought not to use 'rename' in --alter or the
|
||||||
new table won't exist and the tool will fail.
|
new table won't exist and the tool will fail.
|
||||||
@@ -6560,20 +6583,13 @@ Change the table's engine to InnoDB:
|
|||||||
|
|
||||||
pt-online-schema-change \
|
pt-online-schema-change \
|
||||||
h=127.1,t=db.tbl \
|
h=127.1,t=db.tbl \
|
||||||
--alter "ENGINE=InnoDB" \
|
--alter "ENGINE=InnoDB"
|
||||||
--drop-old-table
|
|
||||||
|
|
||||||
Rebuild but do not alter the table, and keep the temporary table:
|
|
||||||
|
|
||||||
pt-online-schema-change h=127.1,t=db.tbl
|
|
||||||
|
|
||||||
Add column to parent table, update child table foreign key constraints:
|
Add column to parent table, update child table foreign key constraints:
|
||||||
|
|
||||||
pt-online-schema-change \
|
pt-online-schema-change \
|
||||||
h=127.1,D=db,t=parent \
|
h=127.1,D=db,t=parent \
|
||||||
--alter "ADD COLUMN (foo INT)" \
|
--alter "ADD COLUMN (foo INT)"
|
||||||
--child-tables child1,child2 \
|
|
||||||
--update-foreign-keys-method drop_swap
|
|
||||||
|
|
||||||
=head1 RISKS
|
=head1 RISKS
|
||||||
|
|
||||||
@@ -6666,13 +6682,12 @@ Here are options related to each phase:
|
|||||||
|
|
||||||
1. --alter
|
1. --alter
|
||||||
2. (none)
|
2. (none)
|
||||||
3. --chunk-size, --sleep
|
3. --chunk-size
|
||||||
4. (none)
|
4. (none)
|
||||||
5. --[no]swap-tables
|
5. --[no]swap-tables
|
||||||
6. --drop-old-table
|
6. --[no]drop-old-table
|
||||||
|
|
||||||
Options L<"--check-tables-and-exit"> and L<"--print"> are helpful to see what
|
L<"--print"> is helpful to see what the tool might do before actually doing it.
|
||||||
the tool might do before actually doing it.
|
|
||||||
|
|
||||||
=head1 REPLICATION
|
=head1 REPLICATION
|
||||||
|
|
||||||
@@ -6772,14 +6787,6 @@ replicas. If you don't want to monitor ALL replicas, but you want more than
|
|||||||
just one replica to be monitored, then use the DSN option to the
|
just one replica to be monitored, then use the DSN option to the
|
||||||
L<"--recursion-method"> option instead of this option.
|
L<"--recursion-method"> option instead of this option.
|
||||||
|
|
||||||
=item --check-tables-and-exit
|
|
||||||
|
|
||||||
Check that the table can be altered then exit; do not alter the table.
|
|
||||||
If you just want to see that the tool can/will work for the given table,
|
|
||||||
specify this option. Even if all checks pass, the tool may still encounter
|
|
||||||
problems if, for example, one of the L<"--alter"> statements uses
|
|
||||||
incorrect syntax.
|
|
||||||
|
|
||||||
=item --child-tables
|
=item --child-tables
|
||||||
|
|
||||||
type: array
|
type: array
|
||||||
@@ -6885,6 +6892,18 @@ type: Array
|
|||||||
Read this comma-separated list of config files; if specified, this must be the
|
Read this comma-separated list of config files; if specified, this must be the
|
||||||
first option on the command line.
|
first option on the command line.
|
||||||
|
|
||||||
|
=item --critical-load
|
||||||
|
|
||||||
|
type: Array; default: Threads_running=50; group: Throttle
|
||||||
|
|
||||||
|
Examine SHOW GLOBAL STATUS after every chunk, and abort if any status variables
|
||||||
|
are higher than the threshold. The option accepts a comma-separated list of
|
||||||
|
MySQL status variables to check for a threshold. An optional C<=MAX_VALUE> (or
|
||||||
|
C<:MAX_VALUE>) can follow each variable. If not given, the tool determines a
|
||||||
|
threshold by examining the current value and doubling it.
|
||||||
|
|
||||||
|
See also L<"--max-load">.
|
||||||
|
|
||||||
=item --defaults-file
|
=item --defaults-file
|
||||||
|
|
||||||
short form: -F; type: string
|
short form: -F; type: string
|
||||||
@@ -6903,7 +6922,7 @@ if there are no errors and the new table successfully takes it place.
|
|||||||
|
|
||||||
=item --dry-run
|
=item --dry-run
|
||||||
|
|
||||||
Do not create triggers, copy rows, or L<"--swap-tables">.
|
Do not create triggers, copy rows, or L<"--[no]swap-tables">.
|
||||||
|
|
||||||
=item --execute
|
=item --execute
|
||||||
|
|
||||||
@@ -7069,16 +7088,6 @@ replication lag and checksum differences, insert the values C<h=10.10.1.16> and
|
|||||||
C<h=10.10.1.17> into the table. Currently, the DSNs are ordered by id, but id
|
C<h=10.10.1.17> into the table. Currently, the DSNs are ordered by id, but id
|
||||||
and parent_id are otherwise ignored.
|
and parent_id are otherwise ignored.
|
||||||
|
|
||||||
=item --[no]swap-tables
|
|
||||||
|
|
||||||
default: yes
|
|
||||||
|
|
||||||
Swap the the original table and the new, altered table. This step
|
|
||||||
essentially completes the online schema change process by making the
|
|
||||||
temporary table with the new schema take the place of the original table.
|
|
||||||
The original tables becomes the "old table" and is dropped if
|
|
||||||
L<"--[no]drop-old-table"> is specified.
|
|
||||||
|
|
||||||
=item --retries
|
=item --retries
|
||||||
|
|
||||||
type: int; default: 3
|
type: int; default: 3
|
||||||
@@ -7099,6 +7108,17 @@ short form: -S; type: string
|
|||||||
|
|
||||||
Socket file to use for connection.
|
Socket file to use for connection.
|
||||||
|
|
||||||
|
=item --[no]swap-tables
|
||||||
|
|
||||||
|
default: yes
|
||||||
|
|
||||||
|
Swap the the original table and the new, altered table. This step
|
||||||
|
essentially completes the online schema change process by making the
|
||||||
|
temporary table with the new schema take the place of the original table.
|
||||||
|
The original tables becomes the "old table" and is dropped if
|
||||||
|
L<"--[no]drop-old-table"> is specified.
|
||||||
|
|
||||||
|
|
||||||
=item --update-foreign-keys-method
|
=item --update-foreign-keys-method
|
||||||
|
|
||||||
type: string
|
type: string
|
||||||
|
@@ -39,18 +39,31 @@ use constant PTDEBUG => $ENV{PTDEBUG} || 0;
|
|||||||
# MySQLStatusWaiter object
|
# MySQLStatusWaiter object
|
||||||
sub new {
|
sub new {
|
||||||
my ( $class, %args ) = @_;
|
my ( $class, %args ) = @_;
|
||||||
my @required_args = qw(spec get_status sleep oktorun);
|
my @required_args = qw(max_spec get_status sleep oktorun);
|
||||||
foreach my $arg ( @required_args ) {
|
foreach my $arg ( @required_args ) {
|
||||||
die "I need a $arg argument" unless defined $args{$arg};
|
die "I need a $arg argument" unless defined $args{$arg};
|
||||||
}
|
}
|
||||||
|
|
||||||
my $max_val_for = _parse_spec(%args);
|
PTDEBUG && _d('Parsing spec for max thresholds');
|
||||||
|
my $max_val_for = _parse_spec(
|
||||||
|
spec => $args{max_spec},
|
||||||
|
get_status => $args{get_status},
|
||||||
|
threshold_factor => 0.2, # +20%
|
||||||
|
);
|
||||||
|
|
||||||
|
PTDEBUG && _d('Parsing spec for critical thresholds');
|
||||||
|
my $critical_val_for = _parse_spec(
|
||||||
|
spec => $args{critical_spec} || [],
|
||||||
|
get_status => $args{get_status},
|
||||||
|
threshold_factor => 1.0, # double (x2; +100%)
|
||||||
|
);
|
||||||
|
|
||||||
my $self = {
|
my $self = {
|
||||||
get_status => $args{get_status},
|
get_status => $args{get_status},
|
||||||
sleep => $args{sleep},
|
sleep => $args{sleep},
|
||||||
oktorun => $args{oktorun},
|
oktorun => $args{oktorun},
|
||||||
max_val_for => $max_val_for,
|
max_val_for => $max_val_for,
|
||||||
|
critical_val_for => $critical_val_for,
|
||||||
};
|
};
|
||||||
|
|
||||||
return bless $self, $class;
|
return bless $self, $class;
|
||||||
@@ -73,10 +86,8 @@ sub _parse_spec {
|
|||||||
}
|
}
|
||||||
my ($spec, $get_status) = @args{@required_args};
|
my ($spec, $get_status) = @args{@required_args};
|
||||||
|
|
||||||
if ( !@$spec ) {
|
return unless $spec && scalar @$spec;
|
||||||
PTDEBUG && _d('No spec, disabling status var waits');
|
my $threshold_factor = $args{threshold_factor} || 0.20;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
my %max_val_for;
|
my %max_val_for;
|
||||||
foreach my $var_val ( @$spec ) {
|
foreach my $var_val ( @$spec ) {
|
||||||
@@ -85,7 +96,7 @@ sub _parse_spec {
|
|||||||
if ( !$val ) {
|
if ( !$val ) {
|
||||||
my $init_val = $get_status->($var);
|
my $init_val = $get_status->($var);
|
||||||
PTDEBUG && _d('Initial', $var, 'value:', $init_val);
|
PTDEBUG && _d('Initial', $var, 'value:', $init_val);
|
||||||
$val = int(($init_val * .20) + $init_val);
|
$val = int(($init_val * $threshold_factor) + $init_val);
|
||||||
}
|
}
|
||||||
PTDEBUG && _d('Wait if', $var, '>=', $val);
|
PTDEBUG && _d('Wait if', $var, '>=', $val);
|
||||||
$max_val_for{$var} = $val;
|
$max_val_for{$var} = $val;
|
||||||
@@ -101,6 +112,11 @@ sub max_values {
|
|||||||
return $self->{max_val_for};
|
return $self->{max_val_for};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub critical_values {
|
||||||
|
my ($self) = @_;
|
||||||
|
return $self->{critical_val_for};
|
||||||
|
}
|
||||||
|
|
||||||
# Sub: wait
|
# Sub: wait
|
||||||
# Wait until all variables' values are less than their permitted maximums.
|
# Wait until all variables' values are less than their permitted maximums.
|
||||||
#
|
#
|
||||||
@@ -144,6 +160,12 @@ sub wait {
|
|||||||
foreach my $var ( sort keys %vals_too_high ) {
|
foreach my $var ( sort keys %vals_too_high ) {
|
||||||
my $val = $get_status->($var);
|
my $val = $get_status->($var);
|
||||||
PTDEBUG && _d($var, '=', $val);
|
PTDEBUG && _d($var, '=', $val);
|
||||||
|
if ( $val
|
||||||
|
&& exists $self->{critical_val_for}->{$var}
|
||||||
|
&& $val >= $self->{critical_val_for}->{$var} ) {
|
||||||
|
die "$var=$val exceeds its critical threshold "
|
||||||
|
. "$self->{critical_val_for}->{$var}\n";
|
||||||
|
}
|
||||||
if ( !$val || $val >= $self->{max_val_for}->{$var} ) {
|
if ( !$val || $val >= $self->{max_val_for}->{$var} ) {
|
||||||
$vals_too_high{$var} = $val;
|
$vals_too_high{$var} = $val;
|
||||||
}
|
}
|
||||||
|
@@ -9,7 +9,7 @@ BEGIN {
|
|||||||
use strict;
|
use strict;
|
||||||
use warnings FATAL => 'all';
|
use warnings FATAL => 'all';
|
||||||
use English qw(-no_match_vars);
|
use English qw(-no_match_vars);
|
||||||
use Test::More tests => 12;
|
use Test::More tests => 14;
|
||||||
|
|
||||||
use MySQLStatusWaiter;
|
use MySQLStatusWaiter;
|
||||||
use PerconaTest;
|
use PerconaTest;
|
||||||
@@ -72,7 +72,7 @@ my $sw = new MySQLStatusWaiter(
|
|||||||
oktorun => \&oktorun,
|
oktorun => \&oktorun,
|
||||||
get_status => \&get_status,
|
get_status => \&get_status,
|
||||||
sleep => \&sleep,
|
sleep => \&sleep,
|
||||||
spec => [qw(Threads_connected Threads_running)],
|
max_spec => [qw(Threads_connected Threads_running)],
|
||||||
);
|
);
|
||||||
|
|
||||||
is_deeply(
|
is_deeply(
|
||||||
@@ -136,7 +136,7 @@ $sw = new MySQLStatusWaiter(
|
|||||||
oktorun => \&oktorun,
|
oktorun => \&oktorun,
|
||||||
get_status => \&get_status,
|
get_status => \&get_status,
|
||||||
sleep => \&sleep,
|
sleep => \&sleep,
|
||||||
spec => [qw(Threads_connected=5 Threads_running=5)],
|
max_spec => [qw(Threads_connected=5 Threads_running=5)],
|
||||||
);
|
);
|
||||||
|
|
||||||
is_deeply(
|
is_deeply(
|
||||||
@@ -178,7 +178,7 @@ $sw = new MySQLStatusWaiter(
|
|||||||
oktorun => \&oktorun,
|
oktorun => \&oktorun,
|
||||||
get_status => \&get_status,
|
get_status => \&get_status,
|
||||||
sleep => \&sleep,
|
sleep => \&sleep,
|
||||||
spec => [],
|
max_spec => [],
|
||||||
);
|
);
|
||||||
|
|
||||||
is(
|
is(
|
||||||
@@ -204,6 +204,40 @@ is(
|
|||||||
"No spec, no sleep"
|
"No spec, no sleep"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
# ############################################################################
|
||||||
|
# Critical thresholds (with static vals).
|
||||||
|
# ############################################################################
|
||||||
|
@vals = (
|
||||||
|
# first check, no wait
|
||||||
|
{ Threads_running => 1, },
|
||||||
|
{ Threads_running => 9, },
|
||||||
|
);
|
||||||
|
|
||||||
|
$sw = new MySQLStatusWaiter(
|
||||||
|
oktorun => \&oktorun,
|
||||||
|
get_status => \&get_status,
|
||||||
|
sleep => \&sleep,
|
||||||
|
max_spec => [qw(Threads_running=4)],
|
||||||
|
critical_spec => [qw(Threads_running=8)],
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
@checked = ();
|
||||||
|
$slept = 0;
|
||||||
|
$sw->wait();
|
||||||
|
|
||||||
|
is(
|
||||||
|
$slept,
|
||||||
|
0,
|
||||||
|
"Vals not critical, did not sleep"
|
||||||
|
);
|
||||||
|
|
||||||
|
throws_ok(
|
||||||
|
sub { $sw->wait(); },
|
||||||
|
qr/Threads_running=9 exceeds its critical threshold 8/,
|
||||||
|
"Die on critical threshold"
|
||||||
|
);
|
||||||
|
|
||||||
# #############################################################################
|
# #############################################################################
|
||||||
# Done.
|
# Done.
|
||||||
# #############################################################################
|
# #############################################################################
|
||||||
|
Reference in New Issue
Block a user