Merge pull request #905 from percona/release-v3.7.0

Release v3.7.0
This commit is contained in:
Sveta Smirnova
2024-12-23 16:19:03 +03:00
committed by GitHub
51 changed files with 759 additions and 73 deletions

View File

@@ -1,5 +1,13 @@
Changelog for Percona Toolkit
v3.7.0 released 2024-12-23
* Feature PT-2340: Support MySQL 8.4
* Improvement PT-2347: Improper use of sha256 hash algorithm in percona-toolkit/src/go/pt-secure-collect /encrypt.go
* Improvement PR-862: Fixed flaky tests (Thanks to Henning Pöttker for the contribution)
* Improvement PR-839: Update pt-mysql-summary (Thanks to GOKUL S for the contribution)
* Fixed bug PT-2371: pt-summary errors out with "STATUS_THP_SYSTEM: unbound variable" (Thanks to Jason Ng for the contribution)
v3.6.0 released 2024-06-12
* Feature PR-754: Port improved pt-pmp (Thanks to Alexey Stroganov for the contribution)

View File

@@ -11,7 +11,7 @@ MAKE_GOTOOLS
WriteMakefile(
NAME => 'Percona::Toolkit',
VERSION => '3.6.0',
VERSION => '3.7.0',
EXE_FILES => [
map {
(my $name = $_) =~ s/^bin.//;

View File

@@ -1364,6 +1364,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-align 3.6.0
pt-align 3.7.0
=cut

View File

@@ -45,7 +45,7 @@ BEGIN {
{
package Percona::Toolkit;
our $VERSION = '3.6.0';
our $VERSION = '3.7.0';
use strict;
use warnings FATAL => 'all';
@@ -8964,6 +8964,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-archiver 3.6.0
pt-archiver 3.7.0
=cut

View File

@@ -43,7 +43,7 @@ BEGIN {
{
package Percona::Toolkit;
our $VERSION = '3.6.0';
our $VERSION = '3.7.0';
use strict;
use warnings FATAL => 'all';
@@ -6038,6 +6038,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-config-diff 3.6.0
pt-config-diff 3.7.0
=cut

View File

@@ -42,7 +42,7 @@ BEGIN {
{
package Percona::Toolkit;
our $VERSION = '3.6.0';
our $VERSION = '3.7.0';
use strict;
use warnings FATAL => 'all';
@@ -5815,6 +5815,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-deadlock-logger 3.6.0
pt-deadlock-logger 3.7.0
=cut

View File

@@ -38,7 +38,7 @@ BEGIN {
{
package Percona::Toolkit;
our $VERSION = '3.6.0';
our $VERSION = '3.7.0';
use strict;
use warnings FATAL => 'all';
@@ -5696,6 +5696,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-diskstats 3.6.0
pt-diskstats 3.7.0
=cut

View File

@@ -39,7 +39,7 @@ BEGIN {
{
package Percona::Toolkit;
our $VERSION = '3.6.0';
our $VERSION = '3.7.0';
use strict;
use warnings FATAL => 'all';
@@ -5834,6 +5834,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-duplicate-key-checker 3.6.0
pt-duplicate-key-checker 3.7.0
=cut

View File

@@ -252,6 +252,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-eustack-resolver 3.6.0
pt-eustack-resolver 3.7.0
=cut

View File

@@ -1719,6 +1719,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-fifo-split 3.6.0
pt-fifo-split 3.7.0
=cut

View File

@@ -35,7 +35,7 @@ BEGIN {
{
package Percona::Toolkit;
our $VERSION = '3.6.0';
our $VERSION = '3.7.0';
use strict;
use warnings FATAL => 'all';
@@ -5247,6 +5247,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-find 3.6.0
pt-find 3.7.0
=cut

View File

@@ -2271,6 +2271,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-fingerprint 3.6.0
pt-fingerprint 3.7.0
=cut

View File

@@ -37,7 +37,7 @@ BEGIN {
{
package Percona::Toolkit;
our $VERSION = '3.6.0';
our $VERSION = '3.7.0';
use strict;
use warnings FATAL => 'all';
@@ -4802,6 +4802,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-fk-error-logger 3.6.0
pt-fk-error-logger 3.7.0
=cut

View File

@@ -44,7 +44,7 @@ BEGIN {
{
package Percona::Toolkit;
our $VERSION = '3.6.0';
our $VERSION = '3.7.0';
use strict;
use warnings FATAL => 'all';
@@ -7737,6 +7737,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-heartbeat 3.6.0
pt-heartbeat 3.7.0
=cut

View File

@@ -45,7 +45,7 @@ BEGIN {
{
package Percona::Toolkit;
our $VERSION = '3.6.0';
our $VERSION = '3.7.0';
use strict;
use warnings FATAL => 'all';
@@ -7764,6 +7764,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-index-usage 3.6.0
pt-index-usage 3.7.0
=cut

View File

@@ -1149,7 +1149,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-ioprofile 3.6.0
pt-ioprofile 3.7.0
=cut

View File

@@ -47,7 +47,7 @@ BEGIN {
{
package Percona::Toolkit;
our $VERSION = '3.6.0';
our $VERSION = '3.7.0';
use strict;
use warnings FATAL => 'all';
@@ -8924,6 +8924,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-kill 3.6.0
pt-kill 3.7.0
=cut

View File

@@ -825,7 +825,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-mext 3.6.0
pt-mext 3.7.0
=cut

View File

@@ -3444,7 +3444,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-mysql-summary 3.6.0
pt-mysql-summary 3.7.0
=cut

View File

@@ -56,7 +56,7 @@ BEGIN {
{
package Percona::Toolkit;
our $VERSION = '3.6.0';
our $VERSION = '3.7.0';
use strict;
use warnings FATAL => 'all';
@@ -14199,6 +14199,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-online-schema-change 3.6.0
pt-online-schema-change 3.7.0
=cut

View File

@@ -1042,7 +1042,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-pmp 3.6.0
pt-pmp 3.7.0
=cut

View File

@@ -64,7 +64,7 @@ BEGIN {
{
package Percona::Toolkit;
our $VERSION = '3.6.0';
our $VERSION = '3.7.0';
use strict;
use warnings FATAL => 'all';
@@ -17145,6 +17145,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-query-digest 3.6.0
pt-query-digest 3.7.0
=cut

View File

@@ -4777,6 +4777,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-replica-find 3.6.0
pt-replica-find 3.7.0
=cut

View File

@@ -41,7 +41,7 @@ BEGIN {
{
package Percona::Toolkit;
our $VERSION = '3.6.0';
our $VERSION = '3.7.0';
use strict;
use warnings FATAL => 'all';
@@ -6472,6 +6472,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-replica-restart 3.6.0
pt-replica-restart 3.7.0
=cut

View File

@@ -2725,6 +2725,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-show-grants 3.6.0
pt-show-grants 3.7.0
=cut

View File

@@ -1266,7 +1266,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-sift 3.6.0
pt-sift 3.7.0
=cut

View File

@@ -41,7 +41,7 @@ BEGIN {
{
package Percona::Toolkit;
our $VERSION = '3.6.0';
our $VERSION = '3.7.0';
use strict;
use warnings FATAL => 'all';
@@ -5286,6 +5286,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-slave-delay 3.6.0
pt-slave-delay 3.7.0
=cut

View File

@@ -2607,7 +2607,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-stalk 3.6.0
pt-stalk 3.7.0
=cut

View File

@@ -2808,7 +2808,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-summary 3.6.0
pt-summary 3.7.0
=cut

View File

@@ -58,7 +58,7 @@ BEGIN {
{
package Percona::Toolkit;
our $VERSION = '3.6.0';
our $VERSION = '3.7.0';
use strict;
use warnings FATAL => 'all';
@@ -14429,6 +14429,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-table-checksum 3.6.0
pt-table-checksum 3.7.0
=cut

View File

@@ -55,7 +55,7 @@ BEGIN {
{
package Percona::Toolkit;
our $VERSION = '3.6.0';
our $VERSION = '3.7.0';
use strict;
use warnings FATAL => 'all';
@@ -13416,6 +13416,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-table-sync 3.6.0
pt-table-sync 3.7.0
=cut

View File

@@ -8622,6 +8622,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-table-usage 3.6.0
pt-table-usage 3.7.0
=cut

View File

@@ -61,7 +61,7 @@ BEGIN {
{
package Percona::Toolkit;
our $VERSION = '3.6.0';
our $VERSION = '3.7.0';
use strict;
use warnings FATAL => 'all';
@@ -11555,6 +11555,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-upgrade 3.6.0
pt-upgrade 3.7.0
=cut

View File

@@ -44,7 +44,7 @@ BEGIN {
{
package Percona::Toolkit;
our $VERSION = '3.6.0';
our $VERSION = '3.7.0';
use strict;
use warnings FATAL => 'all';
@@ -6415,6 +6415,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-variable-advisor 3.6.0
pt-variable-advisor 3.7.0
=cut

View File

@@ -18,6 +18,11 @@ BEGIN {
OptionParser
DSNParser
Daemon
Lmo::Utils
Lmo::Meta
Lmo::Object
Lmo::Types
Lmo
VersionParser
));
}
@@ -2527,6 +2532,655 @@ sub _d {
# End Daemon package
# ###########################################################################
# ###########################################################################
# Lmo::Utils package
# This package is a copy without comments from the original. The original
# with comments and its test file can be found in the GitHub repository at,
# lib/Lmo/Utils.pm
# t/lib/Lmo/Utils.t
# See https://github.com/percona/percona-toolkit for more information.
# ###########################################################################
{
package Lmo::Utils;
use strict;
use warnings qw( FATAL all );
require Exporter;
our (@ISA, @EXPORT, @EXPORT_OK);
BEGIN {
@ISA = qw(Exporter);
@EXPORT = @EXPORT_OK = qw(
_install_coderef
_unimport_coderefs
_glob_for
_stash_for
);
}
{
no strict 'refs';
sub _glob_for {
return \*{shift()}
}
sub _stash_for {
return \%{ shift() . "::" };
}
}
sub _install_coderef {
my ($to, $code) = @_;
return *{ _glob_for $to } = $code;
}
sub _unimport_coderefs {
my ($target, @names) = @_;
return unless @names;
my $stash = _stash_for($target);
foreach my $name (@names) {
if ($stash->{$name} and defined(&{$stash->{$name}})) {
delete $stash->{$name};
}
}
}
1;
}
# ###########################################################################
# End Lmo::Utils package
# ###########################################################################
# ###########################################################################
# Lmo::Meta package
# This package is a copy without comments from the original. The original
# with comments and its test file can be found in the GitHub repository at,
# lib/Lmo/Meta.pm
# t/lib/Lmo/Meta.t
# See https://github.com/percona/percona-toolkit for more information.
# ###########################################################################
{
package Lmo::Meta;
use strict;
use warnings qw( FATAL all );
my %metadata_for;
sub new {
my $class = shift;
return bless { @_ }, $class
}
sub metadata_for {
my $self = shift;
my ($class) = @_;
return $metadata_for{$class} ||= {};
}
sub class { shift->{class} }
sub attributes {
my $self = shift;
return keys %{$self->metadata_for($self->class)}
}
sub attributes_for_new {
my $self = shift;
my @attributes;
my $class_metadata = $self->metadata_for($self->class);
while ( my ($attr, $meta) = each %$class_metadata ) {
if ( exists $meta->{init_arg} ) {
push @attributes, $meta->{init_arg}
if defined $meta->{init_arg};
}
else {
push @attributes, $attr;
}
}
return @attributes;
}
1;
}
# ###########################################################################
# End Lmo::Meta package
# ###########################################################################
# ###########################################################################
# Lmo::Object package
# This package is a copy without comments from the original. The original
# with comments and its test file can be found in the GitHub repository at,
# lib/Lmo/Object.pm
# t/lib/Lmo/Object.t
# See https://github.com/percona/percona-toolkit for more information.
# ###########################################################################
{
package Lmo::Object;
use strict;
use warnings qw( FATAL all );
use Carp ();
use Scalar::Util qw(blessed);
use Lmo::Meta;
use Lmo::Utils qw(_glob_for);
sub new {
my $class = shift;
my $args = $class->BUILDARGS(@_);
my $class_metadata = Lmo::Meta->metadata_for($class);
my @args_to_delete;
while ( my ($attr, $meta) = each %$class_metadata ) {
next unless exists $meta->{init_arg};
my $init_arg = $meta->{init_arg};
if ( defined $init_arg ) {
$args->{$attr} = delete $args->{$init_arg};
}
else {
push @args_to_delete, $attr;
}
}
delete $args->{$_} for @args_to_delete;
for my $attribute ( keys %$args ) {
if ( my $coerce = $class_metadata->{$attribute}{coerce} ) {
$args->{$attribute} = $coerce->($args->{$attribute});
}
if ( my $isa_check = $class_metadata->{$attribute}{isa} ) {
my ($check_name, $check_sub) = @$isa_check;
$check_sub->($args->{$attribute});
}
}
while ( my ($attribute, $meta) = each %$class_metadata ) {
next unless $meta->{required};
Carp::confess("Attribute ($attribute) is required for $class")
if ! exists $args->{$attribute}
}
my $self = bless $args, $class;
my @build_subs;
my $linearized_isa = mro::get_linear_isa($class);
for my $isa_class ( @$linearized_isa ) {
unshift @build_subs, *{ _glob_for "${isa_class}::BUILD" }{CODE};
}
my @args = %$args;
for my $sub (grep { defined($_) && exists &$_ } @build_subs) {
$sub->( $self, @args);
}
return $self;
}
sub BUILDARGS {
shift; # No need for the classname
if ( @_ == 1 && ref($_[0]) ) {
Carp::confess("Single parameters to new() must be a HASH ref, not $_[0]")
unless ref($_[0]) eq ref({});
return {%{$_[0]}} # We want a new reference, always
}
else {
return { @_ };
}
}
sub meta {
my $class = shift;
$class = Scalar::Util::blessed($class) || $class;
return Lmo::Meta->new(class => $class);
}
1;
}
# ###########################################################################
# End Lmo::Object package
# ###########################################################################
# ###########################################################################
# Lmo::Types package
# This package is a copy without comments from the original. The original
# with comments and its test file can be found in the GitHub repository at,
# lib/Lmo/Types.pm
# t/lib/Lmo/Types.t
# See https://github.com/percona/percona-toolkit for more information.
# ###########################################################################
{
package Lmo::Types;
use strict;
use warnings qw( FATAL all );
use Carp ();
use Scalar::Util qw(looks_like_number blessed);
our %TYPES = (
Bool => sub { !$_[0] || (defined $_[0] && looks_like_number($_[0]) && $_[0] == 1) },
Num => sub { defined $_[0] && looks_like_number($_[0]) },
Int => sub { defined $_[0] && looks_like_number($_[0]) && $_[0] == int($_[0]) },
Str => sub { defined $_[0] },
Object => sub { defined $_[0] && blessed($_[0]) },
FileHandle => sub { local $@; require IO::Handle; fileno($_[0]) && $_[0]->opened },
map {
my $type = /R/ ? $_ : uc $_;
$_ . "Ref" => sub { ref $_[0] eq $type }
} qw(Array Code Hash Regexp Glob Scalar)
);
sub check_type_constraints {
my ($attribute, $type_check, $check_name, $val) = @_;
( ref($type_check) eq 'CODE'
? $type_check->($val)
: (ref $val eq $type_check
|| ($val && $val eq $type_check)
|| (exists $TYPES{$type_check} && $TYPES{$type_check}->($val)))
)
|| Carp::confess(
qq<Attribute ($attribute) does not pass the type constraint because: >
. qq<Validation failed for '$check_name' with value >
. (defined $val ? Lmo::Dumper($val) : 'undef') )
}
sub _nested_constraints {
my ($attribute, $aggregate_type, $type) = @_;
my $inner_types;
if ( $type =~ /\A(ArrayRef|Maybe)\[(.*)\]\z/ ) {
$inner_types = _nested_constraints($1, $2);
}
else {
$inner_types = $TYPES{$type};
}
if ( $aggregate_type eq 'ArrayRef' ) {
return sub {
my ($val) = @_;
return unless ref($val) eq ref([]);
if ($inner_types) {
for my $value ( @{$val} ) {
return unless $inner_types->($value)
}
}
else {
for my $value ( @{$val} ) {
return unless $value && ($value eq $type
|| (Scalar::Util::blessed($value) && $value->isa($type)));
}
}
return 1;
};
}
elsif ( $aggregate_type eq 'Maybe' ) {
return sub {
my ($value) = @_;
return 1 if ! defined($value);
if ($inner_types) {
return unless $inner_types->($value)
}
else {
return unless $value eq $type
|| (Scalar::Util::blessed($value) && $value->isa($type));
}
return 1;
}
}
else {
Carp::confess("Nested aggregate types are only implemented for ArrayRefs and Maybe");
}
}
1;
}
# ###########################################################################
# End Lmo::Types package
# ###########################################################################
# ###########################################################################
# Lmo package
# This package is a copy without comments from the original. The original
# with comments and its test file can be found in the GitHub repository at,
# lib/Lmo.pm
# t/lib/Lmo.t
# See https://github.com/percona/percona-toolkit for more information.
# ###########################################################################
{
BEGIN {
$INC{"Lmo.pm"} = __FILE__;
package Lmo;
our $VERSION = '0.30_Percona'; # Forked from 0.30 of Mo.
use strict;
use warnings qw( FATAL all );
use Carp ();
use Scalar::Util qw(looks_like_number blessed);
use Lmo::Meta;
use Lmo::Object;
use Lmo::Types;
use Lmo::Utils;
my %export_for;
sub import {
warnings->import(qw(FATAL all));
strict->import();
my $caller = scalar caller(); # Caller's package
my %exports = (
extends => \&extends,
has => \&has,
with => \&with,
override => \&override,
confess => \&Carp::confess,
);
$export_for{$caller} = \%exports;
for my $keyword ( keys %exports ) {
_install_coderef "${caller}::$keyword" => $exports{$keyword};
}
if ( !@{ *{ _glob_for "${caller}::ISA" }{ARRAY} || [] } ) {
@_ = "Lmo::Object";
goto *{ _glob_for "${caller}::extends" }{CODE};
}
}
sub extends {
my $caller = scalar caller();
for my $class ( @_ ) {
_load_module($class);
}
_set_package_isa($caller, @_);
_set_inherited_metadata($caller);
}
sub _load_module {
my ($class) = @_;
(my $file = $class) =~ s{::|'}{/}g;
$file .= '.pm';
{ local $@; eval { require "$file" } } # or warn $@;
return;
}
sub with {
my $package = scalar caller();
require Role::Tiny;
for my $role ( @_ ) {
_load_module($role);
_role_attribute_metadata($package, $role);
}
Role::Tiny->apply_roles_to_package($package, @_);
}
sub _role_attribute_metadata {
my ($package, $role) = @_;
my $package_meta = Lmo::Meta->metadata_for($package);
my $role_meta = Lmo::Meta->metadata_for($role);
%$package_meta = (%$role_meta, %$package_meta);
}
sub has {
my $names = shift;
my $caller = scalar caller();
my $class_metadata = Lmo::Meta->metadata_for($caller);
for my $attribute ( ref $names ? @$names : $names ) {
my %args = @_;
my $method = ($args{is} || '') eq 'ro'
? sub {
Carp::confess("Cannot assign a value to a read-only accessor at reader ${caller}::${attribute}")
if $#_;
return $_[0]{$attribute};
}
: sub {
return $#_
? $_[0]{$attribute} = $_[1]
: $_[0]{$attribute};
};
$class_metadata->{$attribute} = ();
if ( my $type_check = $args{isa} ) {
my $check_name = $type_check;
if ( my ($aggregate_type, $inner_type) = $type_check =~ /\A(ArrayRef|Maybe)\[(.*)\]\z/ ) {
$type_check = Lmo::Types::_nested_constraints($attribute, $aggregate_type, $inner_type);
}
my $check_sub = sub {
my ($new_val) = @_;
Lmo::Types::check_type_constraints($attribute, $type_check, $check_name, $new_val);
};
$class_metadata->{$attribute}{isa} = [$check_name, $check_sub];
my $orig_method = $method;
$method = sub {
$check_sub->($_[1]) if $#_;
goto &$orig_method;
};
}
if ( my $builder = $args{builder} ) {
my $original_method = $method;
$method = sub {
$#_
? goto &$original_method
: ! exists $_[0]{$attribute}
? $_[0]{$attribute} = $_[0]->$builder
: goto &$original_method
};
}
if ( my $code = $args{default} ) {
Carp::confess("${caller}::${attribute}'s default is $code, but should be a coderef")
unless ref($code) eq 'CODE';
my $original_method = $method;
$method = sub {
$#_
? goto &$original_method
: ! exists $_[0]{$attribute}
? $_[0]{$attribute} = $_[0]->$code
: goto &$original_method
};
}
if ( my $role = $args{does} ) {
my $original_method = $method;
$method = sub {
if ( $#_ ) {
Carp::confess(qq<Attribute ($attribute) doesn't consume a '$role' role">)
unless Scalar::Util::blessed($_[1]) && eval { $_[1]->does($role) }
}
goto &$original_method
};
}
if ( my $coercion = $args{coerce} ) {
$class_metadata->{$attribute}{coerce} = $coercion;
my $original_method = $method;
$method = sub {
if ( $#_ ) {
return $original_method->($_[0], $coercion->($_[1]))
}
goto &$original_method;
}
}
_install_coderef "${caller}::$attribute" => $method;
if ( $args{required} ) {
$class_metadata->{$attribute}{required} = 1;
}
if ($args{clearer}) {
_install_coderef "${caller}::$args{clearer}"
=> sub { delete shift->{$attribute} }
}
if ($args{predicate}) {
_install_coderef "${caller}::$args{predicate}"
=> sub { exists shift->{$attribute} }
}
if ($args{handles}) {
_has_handles($caller, $attribute, \%args);
}
if (exists $args{init_arg}) {
$class_metadata->{$attribute}{init_arg} = $args{init_arg};
}
}
}
sub _has_handles {
my ($caller, $attribute, $args) = @_;
my $handles = $args->{handles};
my $ref = ref $handles;
my $kv;
if ( $ref eq ref [] ) {
$kv = { map { $_,$_ } @{$handles} };
}
elsif ( $ref eq ref {} ) {
$kv = $handles;
}
elsif ( $ref eq ref qr// ) {
Carp::confess("Cannot delegate methods based on a Regexp without a type constraint (isa)")
unless $args->{isa};
my $target_class = $args->{isa};
$kv = {
map { $_, $_ }
grep { $_ =~ $handles }
grep { !exists $Lmo::Object::{$_} && $target_class->can($_) }
grep { !$export_for{$target_class}->{$_} }
keys %{ _stash_for $target_class }
};
}
else {
Carp::confess("handles for $ref not yet implemented");
}
while ( my ($method, $target) = each %{$kv} ) {
my $name = _glob_for "${caller}::$method";
Carp::confess("You cannot overwrite a locally defined method ($method) with a delegation")
if defined &$name;
my ($target, @curried_args) = ref($target) ? @$target : $target;
*$name = sub {
my $self = shift;
my $delegate_to = $self->$attribute();
my $error = "Cannot delegate $method to $target because the value of $attribute";
Carp::confess("$error is not defined") unless $delegate_to;
Carp::confess("$error is not an object (got '$delegate_to')")
unless Scalar::Util::blessed($delegate_to) || (!ref($delegate_to) && $delegate_to->can($target));
return $delegate_to->$target(@curried_args, @_);
}
}
}
sub _set_package_isa {
my ($package, @new_isa) = @_;
my $package_isa = \*{ _glob_for "${package}::ISA" };
@{*$package_isa} = @new_isa;
}
sub _set_inherited_metadata {
my $class = shift;
my $class_metadata = Lmo::Meta->metadata_for($class);
my $linearized_isa = mro::get_linear_isa($class);
my %new_metadata;
for my $isa_class (reverse @$linearized_isa) {
my $isa_metadata = Lmo::Meta->metadata_for($isa_class);
%new_metadata = (
%new_metadata,
%$isa_metadata,
);
}
%$class_metadata = %new_metadata;
}
sub unimport {
my $caller = scalar caller();
my $target = caller;
_unimport_coderefs($target, keys %{$export_for{$caller}});
}
sub Dumper {
require Data::Dumper;
local $Data::Dumper::Indent = 0;
local $Data::Dumper::Sortkeys = 0;
local $Data::Dumper::Quotekeys = 0;
local $Data::Dumper::Terse = 1;
Data::Dumper::Dumper(@_)
}
BEGIN {
if ($] >= 5.010) {
{ local $@; require mro; }
}
else {
local $@;
eval {
require MRO::Compat;
} or do {
*mro::get_linear_isa = *mro::get_linear_isa_dfs = sub {
no strict 'refs';
my $classname = shift;
my @lin = ($classname);
my %stored;
foreach my $parent (@{"$classname\::ISA"}) {
my $plin = mro::get_linear_isa_dfs($parent);
foreach (@$plin) {
next if exists $stored{$_};
push(@lin, $_);
$stored{$_} = 1;
}
}
return \@lin;
};
}
}
}
sub override {
my ($methods, $code) = @_;
my $caller = scalar caller;
for my $method ( ref($methods) ? @$methods : $methods ) {
my $full_method = "${caller}::${method}";
*{_glob_for $full_method} = $code;
}
}
}
1;
}
# ###########################################################################
# End Lmo package
# ###########################################################################
# ###########################################################################
# VersionParser package
# This package is a copy without comments from the original. The original
@@ -3587,6 +4241,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-visual-explain 3.6.0
pt-visual-explain 3.7.0
=cut

View File

@@ -165,7 +165,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.22.4
GO_VERSION=1.23.4
if [ x"$ARCH" = "xx86_64" ]; then
GO_ARCH="amd64"
elif [ x"$ARCH" = "xaarch64" ]; then
@@ -398,7 +398,7 @@ build_rpm(){
ARCH=$(echo $(uname -m) | sed -e 's:i686:i386:g')
echo "RHEL=${RHEL}" >> percona-toolkit.properties
echo "ARCH=${ARCH}" >> percona-toolkit.properties
rpmbuild --target=x86_64 --define "version $VERSION" --define "VERSION $VERSION" --define "dist .el${RHEL}" --define "release $RPM_RELEASE.el${RHEL}" --define "_topdir ${WORKDIR}/rpmbuild" --rebuild rpmbuild/SRPMS/${SRC_RPM}
rpmbuild --target=${ARCH} --define "version $VERSION" --define "VERSION $VERSION" --define "dist .el${RHEL}" --define "release $RPM_RELEASE.el${RHEL}" --define "_topdir ${WORKDIR}/rpmbuild" --rebuild rpmbuild/SRPMS/${SRC_RPM}
return_code=$?
if [ $return_code != 0 ]; then

View File

@@ -48,9 +48,9 @@ copyright = u'2024, Percona LLC and/or its affiliates'
# built documents.
#
# The short X.Y version.
version = '3.6'
version = '3.7'
# The full version, including alpha/beta/rc tags.
release = '3.6.0'
release = '3.7.0'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.

View File

@@ -607,6 +607,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
Percona Toolkit v3.6.0 released 2024-06-12
Percona Toolkit v3.7.0 released 2024-12-19
=cut

View File

@@ -1,6 +1,26 @@
Release Notes
***************
v3.7.0 released 2024-12-23
==============================
New Feature
------------------------------------------------------------
* :jirabug:`PT-2340`: Support MySQL 8.4
Improvements
------------------------------------------------------------
* :jirabug:`PT-2347`: Improper use of sha256 hash algorithm in percona-toolkit/src/go/pt-secure-collect /encrypt.go. Note that this improvement is an **incompatible change**. pt-secure-collect now uses KDF to encrypt and decrypt user passwords. As a result, pt-secure-collect v3.7.0 cannot decrypt data collected by earlier versions and vice versa.
* `PR-862`: Fixed flaky tests (Thanks to Henning Pöttker for the contribution)
* `PR-839`: Update pt-mysql-summary (Thanks to GOKUL S for the contribution)
Bugs Fixed
------------
* :jirabug:`PT-2371`: pt-summary errors out with "STATUS_THP_SYSTEM: unbound variable" (Thanks to Jason Ng for the contribution)
v3.6.0 released 2024-06-12
==============================

5
go.mod
View File

@@ -1,7 +1,6 @@
module github.com/percona/percona-toolkit
go 1.22.4
toolchain go1.23.4
go 1.23.4
require (
github.com/AlekSi/pointer v1.2.0
@@ -61,7 +60,7 @@ require (
github.com/xdg-go/stringprep v1.0.4 // indirect
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect
github.com/yusufpapurcu/wmi v1.2.2 // indirect
golang.org/x/net v0.30.0 // indirect
golang.org/x/net v0.33.0 // indirect
golang.org/x/sync v0.10.0 // indirect
golang.org/x/sys v0.28.0 // indirect
golang.org/x/term v0.27.0 // indirect

2
go.sum
View File

@@ -148,6 +148,8 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=

View File

@@ -18,7 +18,7 @@
# ###########################################################################
package Percona::Toolkit;
our $VERSION = '3.6.0';
our $VERSION = '3.7.0';
use strict;
use warnings FATAL => 'all';

View File

@@ -16,8 +16,6 @@ sphinx-tabs
certifi>=2024.7.4 # not directly required, pinned by Snyk to avoid a vulnerability
jinja2>=3.1.4 # not directly required, pinned by Snyk to avoid a vulnerability
pygments>=2.15.0 # not directly required, pinned by Snyk to avoid a vulnerability
requests>=2.32.2 # not directly required, pinned by Snyk to avoid a vulnerability
setuptools>=70.0.0 # not directly required, pinned by Snyk to avoid a vulnerability
urllib3>=2.2.2 # not directly required, pinned by Snyk to avoid a vulnerability
zipp>=3.19.1 # not directly required, pinned by Snyk to avoid a vulnerability
requests>=2.31.0 # not directly required, pinned by Snyk to avoid a vulnerability
setuptools>=65.5.1 # not directly required, pinned by Snyk to avoid a vulnerability
idna>=3.7 # not directly required, pinned by Snyk to avoid a vulnerability

View File

@@ -40,3 +40,6 @@ binlog_format = STATEMENT
#performance-schema-instrument='wait/lock/metadata/sql/mdl=ON'
#performance-schema-instrument='transaction=ON'
secure-file-priv =
# wait_for_replica buggy on multi-threaded replica
slave-parallel-workers=0

View File

@@ -40,3 +40,6 @@ binlog_format = STATEMENT
#performance-schema-instrument='wait/lock/metadata/sql/mdl=ON'
#performance-schema-instrument='transaction=ON'
secure-file-priv =
# wait_for_replica buggy on multi-threaded replica
replica-parallel-workers=0

View File

@@ -104,7 +104,7 @@ unlike(
$output,
qr/Cannot checksum table/,
"Very small --chunk-time doesn't cause zero --chunk-size"
);
) or diag($output);
}
# #############################################################################
# Bug 921700: pt-table-checksum doesn't add --where to chunk-oversize test

View File

@@ -12,7 +12,7 @@ use English qw(-no_match_vars);
use Test::More;
#if ( !$ENV{SLOW_TESTS} ) {
# plan skip_all => "pt-table-checksum/replication_filters.t is one of the top slowest files; set SLOW_TESTS=1 to enable it.";
# plan skip_all => "pt-table-checksum/pt-1616.t is one of the top slowest files; set SLOW_TESTS=1 to enable it.";
#}
use PerconaTest;

View File

@@ -127,7 +127,7 @@ is_deeply(
[qw( sakila city )],
],
"Checksum results for 1/4 of sakila singles"
);
) or diag(Dumper($row));
$output = output(
sub { pt_table_checksum::main(@args, qw(-d sakila --resume --chunk-size 10000)) },

View File

@@ -61,7 +61,7 @@ is(
REPLACE INTO `issue_375`.`t`(`id`, `updated_at`, `foo`) VALUES ('100', '2009-09-06 15:01:23', 'cv');
",
'Simple --replicate'
);
) or diag($output);
# Note how the columns are out of order (tbl order is: id, updated_at, foo).
# This is issue http://code.google.com/p/maatkit/issues/detail?id=371

View File

@@ -146,9 +146,8 @@ like(
$replica1_dbh->do("STOP ${replica_name}");
$replica1_dbh->do("CHANGE ${source_change} TO ${source_name}_port=12345, ${source_name}_user='msandbox'");
$replica1_dbh->do("START ${replica_name}");
$replica1_dbh->do("STOP ${replica_name}");
$replica1_dbh->do("CHANGE ${source_change} TO ${source_name}_port=12345, ${source_name}_user='msandbox'");
$source_dbh->do("RESET ${source_reset}");
$replica1_dbh->do("RESET ${replica_name}");
$replica1_dbh->do("START ${replica_name}");
# #############################################################################

View File

@@ -60,7 +60,7 @@ my $t = time - $t0;
ok(
$t >= 3 && $t <= ($ENV{PERCONA_SLOW_BOX} ? 8 : 6),
"Exec queries: ran for roughly --run-time seconds"
"Exec queries: ran for roughly 3 seconds"
) or diag($output, 'Actual run time:', $t);
# Exit status 8 = --run-time expired (an no other errors/problems)