mirror of
https://github.com/percona/percona-toolkit.git
synced 2025-12-12 02:00:49 +08:00
Compare commits
60 Commits
PT-2479-RN
...
test_jenki
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6d1479df59 | ||
|
|
8e519885b5 | ||
|
|
c6c352023a | ||
|
|
fea3cea697 | ||
|
|
38d8bf5050 | ||
|
|
d835d8c4f4 | ||
|
|
70bd9164f8 | ||
|
|
2b350d908e | ||
|
|
ba4f650fad | ||
|
|
b6df68eb35 | ||
|
|
8121bf7468 | ||
|
|
242454184a | ||
|
|
48842df48b | ||
|
|
c864a9195b | ||
|
|
49b4293207 | ||
|
|
1b1fc5ba35 | ||
|
|
1f2b9e4cb7 | ||
|
|
c13714ebd8 | ||
|
|
5dbef38fa1 | ||
|
|
95588dd76e | ||
|
|
dcc1cff519 | ||
|
|
eed2c43dcc | ||
|
|
6ab67f79bf | ||
|
|
7987420976 | ||
|
|
836d097797 | ||
|
|
f3a2f9d2fe | ||
|
|
032eac7dc0 | ||
|
|
e9475fccd5 | ||
|
|
c44a5c2aa7 | ||
|
|
f46112d74c | ||
|
|
06b08ff9bb | ||
|
|
d784831e68 | ||
|
|
247bc246fb | ||
|
|
602a87f438 | ||
|
|
8979200e8f | ||
|
|
cccfbd9f47 | ||
|
|
2301bf9956 | ||
|
|
7a26991fb3 | ||
|
|
d016effd18 | ||
|
|
de72fb9bbc | ||
|
|
0289a1a6b4 | ||
|
|
f9452ef406 | ||
|
|
e60f742f36 | ||
|
|
527ba7ef33 | ||
|
|
64ced79f7d | ||
|
|
84889adbfb | ||
|
|
ea8fc17dbc | ||
|
|
11e73c8b60 | ||
|
|
fb1f5be339 | ||
|
|
bfeaa98379 | ||
|
|
f72d9c9637 | ||
|
|
b07dd2792d | ||
|
|
b2e25133e0 | ||
|
|
de69a69076 | ||
|
|
919970abe9 | ||
|
|
cdc24c10f0 | ||
|
|
66d20ae6da | ||
|
|
68a4540a3d | ||
|
|
cd36511b52 | ||
|
|
1a3f42acb1 |
2
.github/workflows/libmodulesupdated.yml
vendored
2
.github/workflows/libmodulesupdated.yml
vendored
@@ -11,6 +11,6 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: true
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
- name: run util/check_bin_md5sum
|
||||
run: ./util/check_bin_md5sum
|
||||
|
||||
2
.github/workflows/spelling.yml
vendored
2
.github/workflows/spelling.yml
vendored
@@ -20,5 +20,5 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 1
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
- uses: crate-ci/typos@master
|
||||
|
||||
6
.github/workflows/toolkit.yml
vendored
6
.github/workflows/toolkit.yml
vendored
@@ -15,10 +15,10 @@ jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: '1.24'
|
||||
- name: Build
|
||||
@@ -36,7 +36,7 @@ jobs:
|
||||
vuln-type: 'os,library'
|
||||
severity: 'CRITICAL,HIGH'
|
||||
- name: Upload a Build Artifact
|
||||
uses: actions/upload-artifact@v4.6.2
|
||||
uses: actions/upload-artifact@v5.0.0
|
||||
with:
|
||||
name: binaries
|
||||
path: bin/*
|
||||
|
||||
26
Changelog
26
Changelog
@@ -1,31 +1,5 @@
|
||||
Changelog for Percona Toolkit
|
||||
|
||||
v3.7.1 released 2025-09-
|
||||
|
||||
* Feature PT-2052: Tools should default to unbuffered stdout/stderr
|
||||
* Feature PT-2289: Allow pt-stalk do disable ps-lock-transactions data collection via parameter
|
||||
* Improvement PT-2015: pt-config-diff does not sort variable flags
|
||||
* Improvement PT-2440: Support for MariaDB 10.5
|
||||
* Improvement PT-2453: Add -skip-pod-summary for pt-k8s-debug-collector
|
||||
* Improvement PT-2459: Mention "pt" repo for percona-toolkit installation
|
||||
* Improvement PT-2465: Fix Regex pattern search on version 3.7.0 for mariadb based DBs
|
||||
* Fixed bug PT-2014: pt-config-diff does not honor case insensitivity flag
|
||||
* Fixed bug PT-2129: pt-online-schem-change and other tools fail on non-readable version check file
|
||||
* Fixed bug PT-2305: pt-online-schema-change should error if server is a slave in row based replication
|
||||
* Fixed bug PT-2322: pt-mysql-summary does not detect jemalloc.
|
||||
* Fixed bug PT-2346: t/pt-table-sync/specify_column_or_index.t fails with 5.7
|
||||
* Fixed bug PT-2356: Every next run of pt-online-schema-change will result in an error and create a new table that won’t be cleaned up
|
||||
* Fixed bug PT-2401: pt-online-schema-change 'table does not exist' on macos
|
||||
* Fixed bug PT-2418: pt-online-schema-change 3.7.0 lost data when exe alter xxx rename column xxx
|
||||
* Fixed bug PT-2424: Typo in pt-table-checksum error message "--resume and --no-empty-replicate-table are mutually exclusive"
|
||||
* Fixed bug PT-2425: pt-table-sync performs case sensitive match for mariadb
|
||||
* Fixed bug PT-2435: t/pt-online-schema-change/pt-1717-resume.t fails after PT-2355 fix
|
||||
* Fixed bug PT-2451: VersionParser/MariaDB checks are incompatible with mixed-case version_comment mariadb variable
|
||||
* Fixed bug PT-2467: t/pt-show-grants/basics.t t/pt-table-checksum/basics.t t/pt-table-sync/filters.t t/pt-upgrade/diff_rows.t fail with the latest PT
|
||||
* Fixed bug PT-2469: version_cmp is binary file
|
||||
* Fixed bug PT-2470: pt-table-sync supports recursion methods dsn and cluster but documentation does not mention it
|
||||
* Fixed bug PT-2471: Link to the repository documentation is broken
|
||||
|
||||
v3.7.0-2 released 2025-05-14
|
||||
|
||||
This release addresses multiple security vulnerabilities reported in Percona Toolkit version 3.7.0, including issues related to the `libxml2` component (CVE-2024-56171, CVE-2025-24928), `openssl` (CVE-2024-12797), and `krb5` (CVE-2022-37967).
|
||||
|
||||
20
Makefile.PL
20
Makefile.PL
@@ -11,22 +11,18 @@ MAKE_GOTOOLS
|
||||
|
||||
WriteMakefile(
|
||||
NAME => 'Percona::Toolkit',
|
||||
VERSION => '3.7.1',
|
||||
EXE_FILES => [
|
||||
map {
|
||||
(my $name = $_) =~ s/^bin.//;
|
||||
my $file_name = $_;
|
||||
if ( ( $file_name !~ m/mongo/ ) || ( $file_name !~ m/pg/ ) || ( $file_name !~ m/pt-stalk/ ) || ( $file_name !~ m/pt-k8s/ ) ) {
|
||||
$_;
|
||||
}
|
||||
} <bin/*>
|
||||
],
|
||||
VERSION => '3.7.0-2',
|
||||
EXE_FILES => [ <bin/*> ],
|
||||
MAN1PODS => {
|
||||
'docs/percona-toolkit.pod' => 'blib/man1/percona-toolkit.1p',
|
||||
map {
|
||||
(my $name = $_) =~ s/^bin.//;
|
||||
my $file_name = $_;
|
||||
if ( ( $file_name !~ m/mongo/ ) || ( $file_name !~ m/pg/ ) || ( $file_name !~ m/pt-stalk/ ) || ( $file_name !~ m/pt-k8s/ ) ) {
|
||||
if ( $file_name =~ m/(mongo|pg|galera|k8s|secure)/ ) {
|
||||
# We have to put empty line here to avoid the MAN1PODS hash corruption
|
||||
'' => '',
|
||||
}
|
||||
else {
|
||||
$_ => "blib/man1/$name.1p";
|
||||
}
|
||||
} <bin/*>
|
||||
@@ -37,4 +33,4 @@ WriteMakefile(
|
||||
DBI => 1.46,
|
||||
DBD::mysql => 3.0000_0,
|
||||
},
|
||||
);
|
||||
);
|
||||
|
||||
@@ -3735,11 +3735,17 @@ sub get_replicas {
|
||||
}
|
||||
);
|
||||
} elsif ( $methods->[0] =~ m/^dsn=/i ) {
|
||||
my @required_args = qw(dsn);
|
||||
foreach my $arg ( @required_args ) {
|
||||
die "I need a $arg argument" unless $args{$arg};
|
||||
}
|
||||
my ($dsn) = @args{@required_args};
|
||||
(my $dsn_table_dsn = join ",", @$methods) =~ s/^dsn=//i;
|
||||
$replicas = $self->get_cxn_from_dsn_table(
|
||||
%args,
|
||||
dsn_table_dsn => $dsn_table_dsn,
|
||||
wait_no_die => $args{'wait_no_die'},
|
||||
parent => $dsn,
|
||||
);
|
||||
}
|
||||
elsif ( $methods->[0] =~ m/none/i ) {
|
||||
@@ -4506,11 +4512,11 @@ sub reset_known_replication_threads {
|
||||
|
||||
sub get_cxn_from_dsn_table {
|
||||
my ($self, %args) = @_;
|
||||
my @required_args = qw(dsn_table_dsn make_cxn);
|
||||
my @required_args = qw(dsn_table_dsn make_cxn parent);
|
||||
foreach my $arg ( @required_args ) {
|
||||
die "I need a $arg argument" unless $args{$arg};
|
||||
}
|
||||
my ($dsn_table_dsn, $make_cxn) = @args{@required_args};
|
||||
my ($dsn_table_dsn, $make_cxn, $parent) = @args{@required_args};
|
||||
PTDEBUG && _d('DSN table DSN:', $dsn_table_dsn);
|
||||
|
||||
my $dp = $self->{DSNParser};
|
||||
@@ -4556,7 +4562,7 @@ sub get_cxn_from_dsn_table {
|
||||
}
|
||||
push @cxn, $lcxn;
|
||||
} else {
|
||||
push @cxn, $make_cxn->(dsn_string => $dsn_string);
|
||||
push @cxn, $make_cxn->(dsn_string => $dsn_string, parent => $parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,11 +191,17 @@ sub get_replicas {
|
||||
}
|
||||
);
|
||||
} elsif ( $methods->[0] =~ m/^dsn=/i ) {
|
||||
my @required_args = qw(dsn);
|
||||
foreach my $arg ( @required_args ) {
|
||||
die "I need a $arg argument" unless $args{$arg};
|
||||
}
|
||||
my ($dsn) = @args{@required_args};
|
||||
(my $dsn_table_dsn = join ",", @$methods) =~ s/^dsn=//i;
|
||||
$replicas = $self->get_cxn_from_dsn_table(
|
||||
%args,
|
||||
dsn_table_dsn => $dsn_table_dsn,
|
||||
wait_no_die => $args{'wait_no_die'},
|
||||
parent => $dsn,
|
||||
);
|
||||
}
|
||||
elsif ( $methods->[0] =~ m/none/i ) {
|
||||
@@ -962,11 +968,11 @@ sub reset_known_replication_threads {
|
||||
|
||||
sub get_cxn_from_dsn_table {
|
||||
my ($self, %args) = @_;
|
||||
my @required_args = qw(dsn_table_dsn make_cxn);
|
||||
my @required_args = qw(dsn_table_dsn make_cxn parent);
|
||||
foreach my $arg ( @required_args ) {
|
||||
die "I need a $arg argument" unless $args{$arg};
|
||||
}
|
||||
my ($dsn_table_dsn, $make_cxn) = @args{@required_args};
|
||||
my ($dsn_table_dsn, $make_cxn, $parent) = @args{@required_args};
|
||||
PTDEBUG && _d('DSN table DSN:', $dsn_table_dsn);
|
||||
|
||||
my $dp = $self->{DSNParser};
|
||||
@@ -1012,7 +1018,7 @@ sub get_cxn_from_dsn_table {
|
||||
}
|
||||
push @cxn, $lcxn;
|
||||
} else {
|
||||
push @cxn, $make_cxn->(dsn_string => $dsn_string);
|
||||
push @cxn, $make_cxn->(dsn_string => $dsn_string, parent => $parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
14
bin/pt-kill
14
bin/pt-kill
@@ -4009,11 +4009,17 @@ sub get_replicas {
|
||||
}
|
||||
);
|
||||
} elsif ( $methods->[0] =~ m/^dsn=/i ) {
|
||||
my @required_args = qw(dsn);
|
||||
foreach my $arg ( @required_args ) {
|
||||
die "I need a $arg argument" unless $args{$arg};
|
||||
}
|
||||
my ($dsn) = @args{@required_args};
|
||||
(my $dsn_table_dsn = join ",", @$methods) =~ s/^dsn=//i;
|
||||
$replicas = $self->get_cxn_from_dsn_table(
|
||||
%args,
|
||||
dsn_table_dsn => $dsn_table_dsn,
|
||||
wait_no_die => $args{'wait_no_die'},
|
||||
parent => $dsn,
|
||||
);
|
||||
}
|
||||
elsif ( $methods->[0] =~ m/none/i ) {
|
||||
@@ -4780,11 +4786,11 @@ sub reset_known_replication_threads {
|
||||
|
||||
sub get_cxn_from_dsn_table {
|
||||
my ($self, %args) = @_;
|
||||
my @required_args = qw(dsn_table_dsn make_cxn);
|
||||
my @required_args = qw(dsn_table_dsn make_cxn parent);
|
||||
foreach my $arg ( @required_args ) {
|
||||
die "I need a $arg argument" unless $args{$arg};
|
||||
}
|
||||
my ($dsn_table_dsn, $make_cxn) = @args{@required_args};
|
||||
my ($dsn_table_dsn, $make_cxn, $parent) = @args{@required_args};
|
||||
PTDEBUG && _d('DSN table DSN:', $dsn_table_dsn);
|
||||
|
||||
my $dp = $self->{DSNParser};
|
||||
@@ -4830,7 +4836,7 @@ sub get_cxn_from_dsn_table {
|
||||
}
|
||||
push @cxn, $lcxn;
|
||||
} else {
|
||||
push @cxn, $make_cxn->(dsn_string => $dsn_string);
|
||||
push @cxn, $make_cxn->(dsn_string => $dsn_string, parent => $parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8731,7 +8737,7 @@ type: string; default: Query
|
||||
|
||||
group: Actions
|
||||
|
||||
Comma sepatated list of commands that will be watched/killed if they ran for
|
||||
Comma separated list of commands that will be watched/killed if they ran for
|
||||
more than L<"--busy-time"> seconds. Default: C<Query>
|
||||
|
||||
By default, L<"--busy-time"> kills only C<Query> commands but in some cases, it
|
||||
|
||||
@@ -4300,11 +4300,17 @@ sub get_replicas {
|
||||
}
|
||||
);
|
||||
} elsif ( $methods->[0] =~ m/^dsn=/i ) {
|
||||
my @required_args = qw(dsn);
|
||||
foreach my $arg ( @required_args ) {
|
||||
die "I need a $arg argument" unless $args{$arg};
|
||||
}
|
||||
my ($dsn) = @args{@required_args};
|
||||
(my $dsn_table_dsn = join ",", @$methods) =~ s/^dsn=//i;
|
||||
$replicas = $self->get_cxn_from_dsn_table(
|
||||
%args,
|
||||
dsn_table_dsn => $dsn_table_dsn,
|
||||
wait_no_die => $args{'wait_no_die'},
|
||||
parent => $dsn,
|
||||
);
|
||||
}
|
||||
elsif ( $methods->[0] =~ m/none/i ) {
|
||||
@@ -5071,11 +5077,11 @@ sub reset_known_replication_threads {
|
||||
|
||||
sub get_cxn_from_dsn_table {
|
||||
my ($self, %args) = @_;
|
||||
my @required_args = qw(dsn_table_dsn make_cxn);
|
||||
my @required_args = qw(dsn_table_dsn make_cxn parent);
|
||||
foreach my $arg ( @required_args ) {
|
||||
die "I need a $arg argument" unless $args{$arg};
|
||||
}
|
||||
my ($dsn_table_dsn, $make_cxn) = @args{@required_args};
|
||||
my ($dsn_table_dsn, $make_cxn, $parent) = @args{@required_args};
|
||||
PTDEBUG && _d('DSN table DSN:', $dsn_table_dsn);
|
||||
|
||||
my $dp = $self->{DSNParser};
|
||||
@@ -5121,7 +5127,7 @@ sub get_cxn_from_dsn_table {
|
||||
}
|
||||
push @cxn, $lcxn;
|
||||
} else {
|
||||
push @cxn, $make_cxn->(dsn_string => $dsn_string);
|
||||
push @cxn, $make_cxn->(dsn_string => $dsn_string, parent => $parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11211,7 +11217,7 @@ sub get_unique_index_fields {
|
||||
$clean .= $suffix;
|
||||
|
||||
my $fields = [];
|
||||
my $fields_re = qr/\s(?:(?:(?:PRIMARY|UNIQUE)\s+(?:INDEX|KEY|))|UNIQUE)\s*(?:.*?)\s*\((.*?)\)/i;
|
||||
my $fields_re = qr/\s(?:(?:(?:PRIMARY|UNIQUE)\s+(?:INDEX|KEY))|UNIQUE)\s*(?:[^\s]*?)\s*\((.*?)\)/i;
|
||||
|
||||
while($clean =~ /$fields_re/g) {
|
||||
push @$fields, [ split /\s*,\s*/, $1 ];
|
||||
@@ -11668,7 +11674,7 @@ sub check_orig_table {
|
||||
Cxn => $cxn,
|
||||
tbl => $orig_tbl,
|
||||
chunk_size => $o->get('chunk-size'),
|
||||
chunk_indx => $o->get('chunk-index'),
|
||||
chunk_index => $o->get('chunk-index'),
|
||||
OptionParser => $o,
|
||||
TableParser => $tp,
|
||||
);
|
||||
@@ -13512,7 +13518,7 @@ New rows will use the user defined default value if specified for the column.
|
||||
=item --only-same-schema-fks
|
||||
|
||||
Check foreigns keys only on tables on the same schema than the original table.
|
||||
This option is dangerous since if you have FKs refenrencing tables in other
|
||||
This option is dangerous since if you have FKs referencing tables in other
|
||||
schemas, they won't be detected.
|
||||
|
||||
|
||||
|
||||
@@ -6239,7 +6239,7 @@ sub _get_value {
|
||||
unless $found_value;
|
||||
}
|
||||
else {
|
||||
die "Event does not have attribute $attrib and there are no alterantes";
|
||||
die "Event does not have attribute $attrib and there are no alternates";
|
||||
}
|
||||
|
||||
return $value;
|
||||
@@ -10606,11 +10606,17 @@ sub get_replicas {
|
||||
}
|
||||
);
|
||||
} elsif ( $methods->[0] =~ m/^dsn=/i ) {
|
||||
my @required_args = qw(dsn);
|
||||
foreach my $arg ( @required_args ) {
|
||||
die "I need a $arg argument" unless $args{$arg};
|
||||
}
|
||||
my ($dsn) = @args{@required_args};
|
||||
(my $dsn_table_dsn = join ",", @$methods) =~ s/^dsn=//i;
|
||||
$replicas = $self->get_cxn_from_dsn_table(
|
||||
%args,
|
||||
dsn_table_dsn => $dsn_table_dsn,
|
||||
wait_no_die => $args{'wait_no_die'},
|
||||
parent => $dsn,
|
||||
);
|
||||
}
|
||||
elsif ( $methods->[0] =~ m/none/i ) {
|
||||
@@ -11377,11 +11383,11 @@ sub reset_known_replication_threads {
|
||||
|
||||
sub get_cxn_from_dsn_table {
|
||||
my ($self, %args) = @_;
|
||||
my @required_args = qw(dsn_table_dsn make_cxn);
|
||||
my @required_args = qw(dsn_table_dsn make_cxn parent);
|
||||
foreach my $arg ( @required_args ) {
|
||||
die "I need a $arg argument" unless $args{$arg};
|
||||
}
|
||||
my ($dsn_table_dsn, $make_cxn) = @args{@required_args};
|
||||
my ($dsn_table_dsn, $make_cxn, $parent) = @args{@required_args};
|
||||
PTDEBUG && _d('DSN table DSN:', $dsn_table_dsn);
|
||||
|
||||
my $dp = $self->{DSNParser};
|
||||
@@ -11427,7 +11433,7 @@ sub get_cxn_from_dsn_table {
|
||||
}
|
||||
push @cxn, $lcxn;
|
||||
} else {
|
||||
push @cxn, $make_cxn->(dsn_string => $dsn_string);
|
||||
push @cxn, $make_cxn->(dsn_string => $dsn_string, parent => $parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2338,11 +2338,17 @@ sub get_replicas {
|
||||
}
|
||||
);
|
||||
} elsif ( $methods->[0] =~ m/^dsn=/i ) {
|
||||
my @required_args = qw(dsn);
|
||||
foreach my $arg ( @required_args ) {
|
||||
die "I need a $arg argument" unless $args{$arg};
|
||||
}
|
||||
my ($dsn) = @args{@required_args};
|
||||
(my $dsn_table_dsn = join ",", @$methods) =~ s/^dsn=//i;
|
||||
$replicas = $self->get_cxn_from_dsn_table(
|
||||
%args,
|
||||
dsn_table_dsn => $dsn_table_dsn,
|
||||
wait_no_die => $args{'wait_no_die'},
|
||||
parent => $dsn,
|
||||
);
|
||||
}
|
||||
elsif ( $methods->[0] =~ m/none/i ) {
|
||||
@@ -3109,11 +3115,11 @@ sub reset_known_replication_threads {
|
||||
|
||||
sub get_cxn_from_dsn_table {
|
||||
my ($self, %args) = @_;
|
||||
my @required_args = qw(dsn_table_dsn make_cxn);
|
||||
my @required_args = qw(dsn_table_dsn make_cxn parent);
|
||||
foreach my $arg ( @required_args ) {
|
||||
die "I need a $arg argument" unless $args{$arg};
|
||||
}
|
||||
my ($dsn_table_dsn, $make_cxn) = @args{@required_args};
|
||||
my ($dsn_table_dsn, $make_cxn, $parent) = @args{@required_args};
|
||||
PTDEBUG && _d('DSN table DSN:', $dsn_table_dsn);
|
||||
|
||||
my $dp = $self->{DSNParser};
|
||||
@@ -3159,7 +3165,7 @@ sub get_cxn_from_dsn_table {
|
||||
}
|
||||
push @cxn, $lcxn;
|
||||
} else {
|
||||
push @cxn, $make_cxn->(dsn_string => $dsn_string);
|
||||
push @cxn, $make_cxn->(dsn_string => $dsn_string, parent => $parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2752,11 +2752,17 @@ sub get_replicas {
|
||||
}
|
||||
);
|
||||
} elsif ( $methods->[0] =~ m/^dsn=/i ) {
|
||||
my @required_args = qw(dsn);
|
||||
foreach my $arg ( @required_args ) {
|
||||
die "I need a $arg argument" unless $args{$arg};
|
||||
}
|
||||
my ($dsn) = @args{@required_args};
|
||||
(my $dsn_table_dsn = join ",", @$methods) =~ s/^dsn=//i;
|
||||
$replicas = $self->get_cxn_from_dsn_table(
|
||||
%args,
|
||||
dsn_table_dsn => $dsn_table_dsn,
|
||||
wait_no_die => $args{'wait_no_die'},
|
||||
parent => $dsn,
|
||||
);
|
||||
}
|
||||
elsif ( $methods->[0] =~ m/none/i ) {
|
||||
@@ -3523,11 +3529,11 @@ sub reset_known_replication_threads {
|
||||
|
||||
sub get_cxn_from_dsn_table {
|
||||
my ($self, %args) = @_;
|
||||
my @required_args = qw(dsn_table_dsn make_cxn);
|
||||
my @required_args = qw(dsn_table_dsn make_cxn parent);
|
||||
foreach my $arg ( @required_args ) {
|
||||
die "I need a $arg argument" unless $args{$arg};
|
||||
}
|
||||
my ($dsn_table_dsn, $make_cxn) = @args{@required_args};
|
||||
my ($dsn_table_dsn, $make_cxn, $parent) = @args{@required_args};
|
||||
PTDEBUG && _d('DSN table DSN:', $dsn_table_dsn);
|
||||
|
||||
my $dp = $self->{DSNParser};
|
||||
@@ -3573,7 +3579,7 @@ sub get_cxn_from_dsn_table {
|
||||
}
|
||||
push @cxn, $lcxn;
|
||||
} else {
|
||||
push @cxn, $make_cxn->(dsn_string => $dsn_string);
|
||||
push @cxn, $make_cxn->(dsn_string => $dsn_string, parent => $parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
120
bin/pt-stalk
120
bin/pt-stalk
@@ -971,8 +971,10 @@ collect_mysql_data_one() {
|
||||
fi
|
||||
fi
|
||||
|
||||
$CMD_MYSQLADMIN $EXT_ARGV ext -i$OPT_SLEEP_COLLECT -c$cnt >>"$d/$p-mysqladmin" &
|
||||
mysqladmin_pid=$!
|
||||
if ! _should_skip "mysqladmin"; then
|
||||
$CMD_MYSQLADMIN $EXT_ARGV ext -i$OPT_SLEEP_COLLECT -c$cnt >>"$d/$p-mysqladmin" &
|
||||
mysqladmin_pid=$!
|
||||
fi
|
||||
|
||||
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/')
|
||||
@@ -1014,18 +1016,25 @@ collect_system_data() {
|
||||
|
||||
collect_mysql_data_loop() {
|
||||
|
||||
|
||||
if ! _should_skip "processlist"; then
|
||||
(echo $ts; $CMD_MYSQL $EXT_ARGV -e "SHOW FULL PROCESSLIST\G") \
|
||||
>> "$d/$p-processlist" &
|
||||
(echo $ts; $CMD_MYSQL $EXT_ARGV -e "SELECT * FROM performance_schema.threads\G") \
|
||||
>> "$d/$p-threads" &
|
||||
|
||||
if [ "$have_lock_waits_table" ]; then
|
||||
(echo $ts; lock_waits "$d/lock_waits.running") >>"$d/$p-lock-waits" &
|
||||
(echo $ts; transactions) >>"$d/$p-transactions" &
|
||||
fi
|
||||
|
||||
if [ "${mysql_version}" '>' "5.6" ] && [ $ps_instrumentation_enabled == "yes" ]; then
|
||||
(echo $ts; $CMD_MYSQL $EXT_ARGV -e "SELECT * FROM performance_schema.threads\G") \
|
||||
>> "$d/$p-threads" &
|
||||
|
||||
if [ "$have_lock_waits_table" ]; then
|
||||
if ! _should_skip "lock-waits"; then
|
||||
(echo $ts; lock_waits "$d/lock_waits.running") >>"$d/$p-lock-waits" &
|
||||
fi
|
||||
if ! _should_skip "transactions"; then
|
||||
(echo $ts; transactions) >>"$d/$p-transactions" &
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "${mysql_version}" '>' "5.6" ] && [ $ps_instrumentation_enabled == "yes" ] \
|
||||
&& ! _should_skip "ps-locks-transactions"; then
|
||||
ps_locks_transactions "$d/$p-ps-locks-transactions"
|
||||
fi
|
||||
|
||||
@@ -1252,20 +1261,22 @@ innodb_status() {
|
||||
|
||||
local innostat=""
|
||||
|
||||
$CMD_MYSQL $EXT_ARGV -e "SHOW /*!40100 ENGINE*/ INNODB STATUS\G" \
|
||||
>> "$d/$p-innodbstatus$n"
|
||||
grep "END OF INNODB" "$d/$p-innodbstatus$n" >/dev/null || {
|
||||
if [ -d /proc -a -d /proc/$mysqld_pid ]; then
|
||||
for fd in /proc/$mysqld_pid/fd/*; do
|
||||
file $fd | grep deleted >/dev/null && {
|
||||
grep 'INNODB' $fd >/dev/null && {
|
||||
cat $fd > "$d/$p-innodbstatus$n"
|
||||
break
|
||||
if ! _should_skip "innodbstatus"; then
|
||||
$CMD_MYSQL $EXT_ARGV -e "SHOW /*!40100 ENGINE*/ INNODB STATUS\G" \
|
||||
>> "$d/$p-innodbstatus$n"
|
||||
grep "END OF INNODB" "$d/$p-innodbstatus$n" >/dev/null || {
|
||||
if [ -d /proc -a -d /proc/$mysqld_pid ]; then
|
||||
for fd in /proc/$mysqld_pid/fd/*; do
|
||||
file $fd | grep deleted >/dev/null && {
|
||||
grep 'INNODB' $fd >/dev/null && {
|
||||
cat $fd > "$d/$p-innodbstatus$n"
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
done
|
||||
fi
|
||||
}
|
||||
done
|
||||
fi
|
||||
}
|
||||
fi
|
||||
}
|
||||
|
||||
rocksdb_status() {
|
||||
@@ -1274,7 +1285,7 @@ rocksdb_status() {
|
||||
has_rocksdb=`$CMD_MYSQL $EXT_ARGV -e "SHOW ENGINES" | grep -i 'rocksdb'`
|
||||
exit_code=$?
|
||||
|
||||
if [ $exit_code -eq 0 ]; then
|
||||
if [ $exit_code -eq 0 ] && ! _should_skip "rocksdbstatus"; then
|
||||
$CMD_MYSQL $EXT_ARGV -e "SHOW ENGINE ROCKSDB STATUS\G" \
|
||||
>> "$d/$p-rocksdbstatus$n" || rm -f "$d/$p-rocksdbstatus$n"
|
||||
fi
|
||||
@@ -1356,20 +1367,34 @@ collect_mysql_variables() {
|
||||
echo -e "\n$sql\n" >> $outfile
|
||||
$CMD_MYSQL $EXT_ARGV -e "$sql" >> $outfile
|
||||
|
||||
sql="select * from performance_schema.variables_by_thread order by thread_id, variable_name;"
|
||||
echo -e "\n$sql\n" >> $outfile
|
||||
$CMD_MYSQL $EXT_ARGV -e "$sql" >> $outfile
|
||||
if ! _should_skip "thread-variables"; then
|
||||
sql="select * from performance_schema.variables_by_thread order by thread_id, variable_name;"
|
||||
echo -e "\n$sql\n" >> $outfile
|
||||
$CMD_MYSQL $EXT_ARGV -e "$sql" >> $outfile
|
||||
|
||||
sql="select * from performance_schema.user_variables_by_thread order by thread_id, variable_name;"
|
||||
echo -e "\n$sql\n" >> $outfile
|
||||
$CMD_MYSQL $EXT_ARGV -e "$sql" >> $outfile
|
||||
sql="select * from performance_schema.user_variables_by_thread order by thread_id, variable_name;"
|
||||
echo -e "\n$sql\n" >> $outfile
|
||||
$CMD_MYSQL $EXT_ARGV -e "$sql" >> $outfile
|
||||
|
||||
sql="select * from performance_schema.status_by_thread order by thread_id, variable_name; "
|
||||
echo -e "\n$sql\n" >> $outfile
|
||||
$CMD_MYSQL $EXT_ARGV -e "$sql" >> $outfile
|
||||
sql="select * from performance_schema.status_by_thread order by thread_id, variable_name; "
|
||||
echo -e "\n$sql\n" >> $outfile
|
||||
$CMD_MYSQL $EXT_ARGV -e "$sql" >> $outfile
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
_should_skip() {
|
||||
local name=$1
|
||||
|
||||
for item in "${OPT_SKIP_COLLECTION[@]}"; do
|
||||
if [ "$item" == "$name" ]; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
# ###########################################################################
|
||||
# End collect package
|
||||
# ###########################################################################
|
||||
@@ -1524,7 +1549,7 @@ purge_samples() {
|
||||
local retention_size="$4"
|
||||
|
||||
# Delete collect files which more than --retention-time days old.
|
||||
if [ -n "$OPT_PREFIX" ]; then
|
||||
if [ -n "${OPT_PREFIX:-}" ]; then
|
||||
find "$dir" -maxdepth 1 -type f -mtime +$retention_time -name "$OPT_PREFIX-*" -exec rm -f '{}' \;
|
||||
else
|
||||
find "$dir" -maxdepth 1 -type f -mtime +$retention_time -regextype posix-egrep -regex "$dir/[0-9]{4}(_[0-9]{2}){5}-.*" -exec rm -f '{}' \;
|
||||
@@ -1723,10 +1748,6 @@ stalk() {
|
||||
main() {
|
||||
trap sigtrap SIGHUP SIGINT SIGTERM
|
||||
|
||||
if [ "$OPT_SYSTEM_ONLY" ] && [ "$OPT_MYSQL_ONLY" ]; then
|
||||
log 'Both options --system-only and --mysql-only specified, collecting only disk-space, hostname, output, and trigger metrics';
|
||||
fi
|
||||
|
||||
# Note: $$ is the parent's PID, but we're a child proc.
|
||||
# Bash 4 has $BASHPID but we can't rely on that. Consequently,
|
||||
# we don't know our own PID. See the usage of $! below.
|
||||
@@ -1770,6 +1791,10 @@ if [ "${0##*/}" = "$TOOL" ] \
|
||||
mk_tmpdir
|
||||
parse_options "$0" "${@:-""}"
|
||||
|
||||
if [ "$OPT_SYSTEM_ONLY" ] && [ "$OPT_MYSQL_ONLY" ]; then
|
||||
log 'Both options --system-only and --mysql-only specified, collecting only disk-space, hostname, output, and trigger metrics';
|
||||
fi
|
||||
|
||||
# Verify and set TRIGGER_FUNCTION based on --function.
|
||||
if ! set_trg_func "$OPT_FUNCTION"; then
|
||||
option_error "Invalid --function value: $OPT_FUNCTION"
|
||||
@@ -1784,6 +1809,19 @@ if [ "${0##*/}" = "$TOOL" ] \
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$OPT_SKIP_COLLECTION" ]; then
|
||||
supported_skips=( "ps-locks-transactions" "thread-variables" "innodbstatus" "lock-waits" "mysqladmin" "processlist" "rocksdbstatus" "transactions" )
|
||||
IFS=',' read -ra skips <<< "$OPT_SKIP_COLLECTION"
|
||||
OPT_SKIP_COLLECTION=("${skips[@]}")
|
||||
for skip in "${skips[@]}"; do
|
||||
echo "$supported_skips" | grep -q "$skip"
|
||||
if ! [[ " ${supported_skips[@]} " =~ " ${skip} " ]]; then
|
||||
log "Invalid --skip-collection value: $skip, exiting."
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ -z "$OPT_STALK" -a "$OPT_COLLECT" ]; then
|
||||
# Not stalking; do immediate collect once.
|
||||
OPT_CYCLES=0
|
||||
@@ -2391,6 +2429,12 @@ How long to sleep between collection loop cycles. This is useful with
|
||||
C<--no-stalk> to do long collections. For example, to collect data every
|
||||
minute for an hour, specify: C<--no-stalk --run-time 3600 --sleep-collect 60>.
|
||||
|
||||
=item --skip-collection
|
||||
|
||||
type: array
|
||||
|
||||
A comma-separated list of collection types to skip. Valid values are: C<"ps-locks-transactions,thread-variables,innodbstatus,lock-waits,mysqladmin,processlist,rocksdbstatus,transactions">.
|
||||
|
||||
=item --socket
|
||||
|
||||
short form: -S; type: string
|
||||
|
||||
@@ -5255,11 +5255,17 @@ sub get_replicas {
|
||||
}
|
||||
);
|
||||
} elsif ( $methods->[0] =~ m/^dsn=/i ) {
|
||||
my @required_args = qw(dsn);
|
||||
foreach my $arg ( @required_args ) {
|
||||
die "I need a $arg argument" unless $args{$arg};
|
||||
}
|
||||
my ($dsn) = @args{@required_args};
|
||||
(my $dsn_table_dsn = join ",", @$methods) =~ s/^dsn=//i;
|
||||
$replicas = $self->get_cxn_from_dsn_table(
|
||||
%args,
|
||||
dsn_table_dsn => $dsn_table_dsn,
|
||||
wait_no_die => $args{'wait_no_die'},
|
||||
parent => $dsn,
|
||||
);
|
||||
}
|
||||
elsif ( $methods->[0] =~ m/none/i ) {
|
||||
@@ -6026,11 +6032,11 @@ sub reset_known_replication_threads {
|
||||
|
||||
sub get_cxn_from_dsn_table {
|
||||
my ($self, %args) = @_;
|
||||
my @required_args = qw(dsn_table_dsn make_cxn);
|
||||
my @required_args = qw(dsn_table_dsn make_cxn parent);
|
||||
foreach my $arg ( @required_args ) {
|
||||
die "I need a $arg argument" unless $args{$arg};
|
||||
}
|
||||
my ($dsn_table_dsn, $make_cxn) = @args{@required_args};
|
||||
my ($dsn_table_dsn, $make_cxn, $parent) = @args{@required_args};
|
||||
PTDEBUG && _d('DSN table DSN:', $dsn_table_dsn);
|
||||
|
||||
my $dp = $self->{DSNParser};
|
||||
@@ -6076,7 +6082,7 @@ sub get_cxn_from_dsn_table {
|
||||
}
|
||||
push @cxn, $lcxn;
|
||||
} else {
|
||||
push @cxn, $make_cxn->(dsn_string => $dsn_string);
|
||||
push @cxn, $make_cxn->(dsn_string => $dsn_string, parent => $parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11820,7 +11826,7 @@ sub main {
|
||||
}
|
||||
}
|
||||
|
||||
# Restore origin QRT pligin state
|
||||
# Restore origin QRT plugin state
|
||||
if ($o->get('disable-qrt-plugin')) {
|
||||
eval {
|
||||
if ($original_qrt_plugin_source_status) {
|
||||
@@ -12591,7 +12597,7 @@ sub create_repl_table {
|
||||
#
|
||||
# Required Arguments:
|
||||
# * tbl - Standard tbl hashref
|
||||
# * sth - Sth with EXLAIN <statement>
|
||||
# * sth - Sth with EXPLAIN <statement>
|
||||
# * vals - Values for sth, if any
|
||||
#
|
||||
# Returns:
|
||||
|
||||
@@ -6785,11 +6785,17 @@ sub get_replicas {
|
||||
}
|
||||
);
|
||||
} elsif ( $methods->[0] =~ m/^dsn=/i ) {
|
||||
my @required_args = qw(dsn);
|
||||
foreach my $arg ( @required_args ) {
|
||||
die "I need a $arg argument" unless $args{$arg};
|
||||
}
|
||||
my ($dsn) = @args{@required_args};
|
||||
(my $dsn_table_dsn = join ",", @$methods) =~ s/^dsn=//i;
|
||||
$replicas = $self->get_cxn_from_dsn_table(
|
||||
%args,
|
||||
dsn_table_dsn => $dsn_table_dsn,
|
||||
wait_no_die => $args{'wait_no_die'},
|
||||
parent => $dsn,
|
||||
);
|
||||
}
|
||||
elsif ( $methods->[0] =~ m/none/i ) {
|
||||
@@ -7556,11 +7562,11 @@ sub reset_known_replication_threads {
|
||||
|
||||
sub get_cxn_from_dsn_table {
|
||||
my ($self, %args) = @_;
|
||||
my @required_args = qw(dsn_table_dsn make_cxn);
|
||||
my @required_args = qw(dsn_table_dsn make_cxn parent);
|
||||
foreach my $arg ( @required_args ) {
|
||||
die "I need a $arg argument" unless $args{$arg};
|
||||
}
|
||||
my ($dsn_table_dsn, $make_cxn) = @args{@required_args};
|
||||
my ($dsn_table_dsn, $make_cxn, $parent) = @args{@required_args};
|
||||
PTDEBUG && _d('DSN table DSN:', $dsn_table_dsn);
|
||||
|
||||
my $dp = $self->{DSNParser};
|
||||
@@ -7606,7 +7612,7 @@ sub get_cxn_from_dsn_table {
|
||||
}
|
||||
push @cxn, $lcxn;
|
||||
} else {
|
||||
push @cxn, $make_cxn->(dsn_string => $dsn_string);
|
||||
push @cxn, $make_cxn->(dsn_string => $dsn_string, parent => $parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6082,7 +6082,7 @@ as tmp_table_size.
|
||||
severity: warn
|
||||
|
||||
These are the recommended minimum version for each major release: 3.23, 4.1.20,
|
||||
5.0.37, 5.1.30, 5.5.8, 5.6.10, 5.7.9, 8.0.11. This optiion does not complain
|
||||
5.0.37, 5.1.30, 5.5.8, 5.6.10, 5.7.9, 8.0.11. This option does not complain
|
||||
about Innovation releases.
|
||||
|
||||
=item end-of-life mysql version
|
||||
|
||||
@@ -240,28 +240,11 @@ install_deps() {
|
||||
export DEBIAN_VERSION=$(lsb_release -sc)
|
||||
export ARCH=$(echo $(uname -m) | sed -e 's:i686:i386:g')
|
||||
apt-get -y install gnupg2
|
||||
apt-get update || true
|
||||
ENV export DEBIAN_FRONTEND=noninteractive
|
||||
apt-get update
|
||||
if [ $DEBIAN_VERSION = buster ]; then
|
||||
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 0E98404D386FA1D9
|
||||
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 6ED0E7B82643E131
|
||||
until DEBIAN_FRONTEND=noninteractive apt-get update --allow-releaseinfo-change; do
|
||||
echo "waiting"
|
||||
sleep 1
|
||||
done
|
||||
fi
|
||||
if [ $DEBIAN_VERSION = bionic -o $DEBIAN_VERSION = focal -o $DEBIAN_VERSION = bullseye -o $DEBIAN_VERSION = buster -o $DEBIAN_VERSION = bookworm -o $DEBIAN_VERSION = jammy -o $DEBIAN_VERSION = xenial -o $DEBIAN_VERSION = noble ]; then
|
||||
until apt-get update; do
|
||||
echo "waiting"
|
||||
sleep 1
|
||||
done
|
||||
DEBIAN_FRONTEND=noninteractive apt-get update
|
||||
until DEBIAN_FRONTEND=noninteractive apt-get -y install build-essential devscripts debconf debhelper perl; do
|
||||
echo "waiting"
|
||||
sleep 1
|
||||
done
|
||||
fi
|
||||
DEBIAN_FRONTEND=noninteractive apt-get update
|
||||
until DEBIAN_FRONTEND=noninteractive apt-get -y install build-essential devscripts debconf debhelper perl; do
|
||||
echo "waiting"
|
||||
sleep 1
|
||||
done
|
||||
install_go
|
||||
#update_pat
|
||||
fi
|
||||
|
||||
@@ -50,7 +50,7 @@ copyright = u'2025, Percona LLC and/or its affiliates'
|
||||
# The short X.Y version.
|
||||
version = '3.7'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '3.7.1'
|
||||
release = '3.7.0-2'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
||||
@@ -1,44 +1,6 @@
|
||||
Release Notes
|
||||
***************
|
||||
|
||||
v3.7.1 released 2025-09-
|
||||
==============================
|
||||
|
||||
New Features
|
||||
------------------------------------------------------------
|
||||
|
||||
* :jirabug:`PT-2052`: Tools should default to unbuffered stdout/stderr
|
||||
* :jirabug:`PT-2289`: Allow pt-stalk do disable ps-lock-transactions data collection via parameter
|
||||
|
||||
Improvements
|
||||
------------------------------------------------------------
|
||||
|
||||
* :jirabug:`PT-2015`: pt-config-diff does not sort variable flags
|
||||
* :jirabug:`PT-2440`: Support for MariaDB 10.5
|
||||
* :jirabug:`PT-2453`: Add -skip-pod-summary for pt-k8s-debug-collector
|
||||
* :jirabug:`PT-2459`: Mention "pt" repo for percona-toolkit installation
|
||||
* :jirabug:`PT-2465`: Fix Regex pattern search on version 3.7.0 for mariadb based DBs
|
||||
|
||||
Bugs Fixed
|
||||
------------
|
||||
|
||||
* :jirabug:`PT-2014`: pt-config-diff does not honor case insensitivity flag
|
||||
* :jirabug:`PT-2129`: pt-online-schem-change and other tools fail on non-readable version check file
|
||||
* :jirabug:`PT-2305`: pt-online-schema-change should error if server is a slave in row based replication
|
||||
* :jirabug:`PT-2322`: pt-mysql-summary does not detect jemalloc.
|
||||
* :jirabug:`PT-2346`: t/pt-table-sync/specify_column_or_index.t fails with 5.7
|
||||
* :jirabug:`PT-2356`: Every next run of pt-online-schema-change will result in an error and create a new table that won’t be cleaned up
|
||||
* :jirabug:`PT-2401`: pt-online-schema-change 'table does not exist' on macos
|
||||
* :jirabug:`PT-2418`: pt-online-schema-change 3.7.0 lost data when exe alter xxx rename column xxx
|
||||
* :jirabug:`PT-2424`: Typo in pt-table-checksum error message "--resume and --no-empty-replicate-table are mutually exclusive"
|
||||
* :jirabug:`PT-2425`: pt-table-sync performs case sensitive match for mariadb
|
||||
* :jirabug:`PT-2435`: t/pt-online-schema-change/pt-1717-resume.t fails after PT-2355 fix
|
||||
* :jirabug:`PT-2451`: VersionParser/MariaDB checks are incompatible with mixed-case version_comment mariadb variable
|
||||
* :jirabug:`PT-2467`: t/pt-show-grants/basics.t t/pt-table-checksum/basics.t t/pt-table-sync/filters.t t/pt-upgrade/diff_rows.t fail with the latest PT
|
||||
* :jirabug:`PT-2469`: version_cmp is binary file
|
||||
* :jirabug:`PT-2470`: pt-table-sync supports recursion methods dsn and cluster but documentation does not mention it
|
||||
* :jirabug:`PT-2471`: Link to the repository documentation is broken
|
||||
|
||||
v3.7.0-2 released 2025-05-14
|
||||
==============================
|
||||
|
||||
|
||||
20
go.mod
20
go.mod
@@ -9,7 +9,7 @@ require (
|
||||
github.com/Ladicle/tabwriter v1.0.0
|
||||
github.com/Masterminds/semver v1.5.0
|
||||
github.com/alecthomas/kingpin v2.2.6+incompatible
|
||||
github.com/alecthomas/kong v1.12.1
|
||||
github.com/alecthomas/kong v1.13.0
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
|
||||
github.com/go-ini/ini v1.67.0
|
||||
github.com/golang/mock v1.6.0
|
||||
@@ -28,12 +28,12 @@ require (
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/stretchr/testify v1.11.1
|
||||
github.com/xlab/treeprint v1.2.0
|
||||
go.mongodb.org/mongo-driver v1.17.4
|
||||
golang.org/x/crypto v0.41.0
|
||||
go.mongodb.org/mongo-driver v1.17.6
|
||||
golang.org/x/crypto v0.45.0
|
||||
golang.org/x/exp v0.0.0-20230321023759-10a507213a29
|
||||
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
k8s.io/api v0.34.0
|
||||
k8s.io/api v0.34.2
|
||||
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397
|
||||
)
|
||||
|
||||
@@ -62,14 +62,14 @@ require (
|
||||
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||
go.yaml.in/yaml/v2 v2.4.2 // indirect
|
||||
golang.org/x/net v0.42.0 // indirect
|
||||
golang.org/x/sync v0.16.0 // indirect
|
||||
golang.org/x/sys v0.35.0 // indirect
|
||||
golang.org/x/term v0.34.0 // indirect
|
||||
golang.org/x/text v0.28.0 // indirect
|
||||
golang.org/x/net v0.47.0 // indirect
|
||||
golang.org/x/sync v0.18.0 // indirect
|
||||
golang.org/x/sys v0.38.0 // indirect
|
||||
golang.org/x/term v0.37.0 // indirect
|
||||
golang.org/x/text v0.31.0 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
k8s.io/apimachinery v0.34.0 // indirect
|
||||
k8s.io/apimachinery v0.34.2 // indirect
|
||||
k8s.io/klog/v2 v2.130.1 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
|
||||
sigs.k8s.io/randfill v1.0.0 // indirect
|
||||
|
||||
44
go.sum
44
go.sum
@@ -8,10 +8,10 @@ github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8v
|
||||
github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
|
||||
github.com/alecthomas/kingpin v2.2.6+incompatible h1:5svnBTFgJjZvGKyYBtMB0+m5wvrbUHiqye8wRJMlnYI=
|
||||
github.com/alecthomas/kingpin v2.2.6+incompatible/go.mod h1:59OFYbFVLKQKq+mqrL6Rw5bR0c3ACQaawgXx0QYndlE=
|
||||
github.com/alecthomas/kong v1.12.1 h1:iq6aMJDcFYP9uFrLdsiZQ2ZMmcshduyGv4Pek0MQPW0=
|
||||
github.com/alecthomas/kong v1.12.1/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU=
|
||||
github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc=
|
||||
github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
|
||||
github.com/alecthomas/kong v1.13.0 h1:5e/7XC3ugvhP1DQBmTS+WuHtCbcv44hsohMgcvVxSrA=
|
||||
github.com/alecthomas/kong v1.13.0/go.mod h1:wrlbXem1CWqUV5Vbmss5ISYhsVPkBb1Yo7YKJghju2I=
|
||||
github.com/alecthomas/repr v0.5.2 h1:SU73FTI9D1P5UNtvseffFSGmdNci/O6RsqzeXJtP0Qs=
|
||||
github.com/alecthomas/repr v0.5.2/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc=
|
||||
@@ -123,16 +123,16 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
|
||||
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
go.mongodb.org/mongo-driver v1.17.4 h1:jUorfmVzljjr0FLzYQsGP8cgN/qzzxlY9Vh0C9KFXVw=
|
||||
go.mongodb.org/mongo-driver v1.17.4/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ=
|
||||
go.mongodb.org/mongo-driver v1.17.6 h1:87JUG1wZfWsr6rIz3ZmpH90rL5tea7O3IHuSwHUpsss=
|
||||
go.mongodb.org/mongo-driver v1.17.6/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ=
|
||||
go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
|
||||
go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
|
||||
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
|
||||
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
|
||||
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
|
||||
golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug=
|
||||
golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
@@ -146,15 +146,15 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=
|
||||
golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8=
|
||||
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
|
||||
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
|
||||
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=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
|
||||
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
|
||||
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -170,18 +170,18 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
|
||||
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4=
|
||||
golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw=
|
||||
golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
|
||||
golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
|
||||
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
|
||||
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
|
||||
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
@@ -205,10 +205,10 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
k8s.io/api v0.34.0 h1:L+JtP2wDbEYPUeNGbeSa/5GwFtIA662EmT2YSLOkAVE=
|
||||
k8s.io/api v0.34.0/go.mod h1:YzgkIzOOlhl9uwWCZNqpw6RJy9L2FK4dlJeayUoydug=
|
||||
k8s.io/apimachinery v0.34.0 h1:eR1WO5fo0HyoQZt1wdISpFDffnWOvFLOOeJ7MgIv4z0=
|
||||
k8s.io/apimachinery v0.34.0/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw=
|
||||
k8s.io/api v0.34.2 h1:fsSUNZhV+bnL6Aqrp6O7lMTy6o5x2C4XLjnh//8SLYY=
|
||||
k8s.io/api v0.34.2/go.mod h1:MMBPaWlED2a8w4RSeanD76f7opUoypY8TFYkSM+3XHw=
|
||||
k8s.io/apimachinery v0.34.2 h1:zQ12Uk3eMHPxrsbUJgNF8bTauTVR2WgqJsTmwTE/NW4=
|
||||
k8s.io/apimachinery v0.34.2/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw=
|
||||
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
||||
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y=
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
{
|
||||
# Package: Diskstats
|
||||
# This package implements most of the logic in the old shell pt-diskstats;
|
||||
# it parses data from /proc/diskstats, calculcates deltas, and prints those.
|
||||
# it parses data from /proc/diskstats, calculates deltas, and prints those.
|
||||
|
||||
package Diskstats;
|
||||
|
||||
|
||||
@@ -1193,7 +1193,7 @@ sub _get_value {
|
||||
unless $found_value;
|
||||
}
|
||||
else {
|
||||
die "Event does not have attribute $attrib and there are no alterantes";
|
||||
die "Event does not have attribute $attrib and there are no alternates";
|
||||
}
|
||||
|
||||
return $value;
|
||||
|
||||
@@ -108,11 +108,19 @@ sub get_replicas {
|
||||
}
|
||||
);
|
||||
} elsif ( $methods->[0] =~ m/^dsn=/i ) {
|
||||
my @required_args = qw(dsn);
|
||||
foreach my $arg ( @required_args ) {
|
||||
die "I need a $arg argument" unless $args{$arg};
|
||||
}
|
||||
my ($dsn) = @args{@required_args};
|
||||
(my $dsn_table_dsn = join ",", @$methods) =~ s/^dsn=//i;
|
||||
$replicas = $self->get_cxn_from_dsn_table(
|
||||
%args,
|
||||
dsn_table_dsn => $dsn_table_dsn,
|
||||
wait_no_die => $args{'wait_no_die'},
|
||||
# We will set current source server as a parent
|
||||
# until https://perconadev.atlassian.net/browse/PT-2496 is implemented
|
||||
parent => $dsn,
|
||||
);
|
||||
}
|
||||
elsif ( $methods->[0] =~ m/none/i ) {
|
||||
@@ -1061,11 +1069,11 @@ sub reset_known_replication_threads {
|
||||
|
||||
sub get_cxn_from_dsn_table {
|
||||
my ($self, %args) = @_;
|
||||
my @required_args = qw(dsn_table_dsn make_cxn);
|
||||
my @required_args = qw(dsn_table_dsn make_cxn parent);
|
||||
foreach my $arg ( @required_args ) {
|
||||
die "I need a $arg argument" unless $args{$arg};
|
||||
}
|
||||
my ($dsn_table_dsn, $make_cxn) = @args{@required_args};
|
||||
my ($dsn_table_dsn, $make_cxn, $parent) = @args{@required_args};
|
||||
PTDEBUG && _d('DSN table DSN:', $dsn_table_dsn);
|
||||
|
||||
my $dp = $self->{DSNParser};
|
||||
@@ -1111,7 +1119,7 @@ sub get_cxn_from_dsn_table {
|
||||
}
|
||||
push @cxn, $lcxn;
|
||||
} else {
|
||||
push @cxn, $make_cxn->(dsn_string => $dsn_string);
|
||||
push @cxn, $make_cxn->(dsn_string => $dsn_string, parent => $parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1254,7 +1254,7 @@ sub remove_functions {
|
||||
# GROUP BY and ORDER BY specify a list of identifiers.
|
||||
#
|
||||
# Parameters:
|
||||
# $idents - Arrayref of indentifiers
|
||||
# $idents - Arrayref of identifiers
|
||||
#
|
||||
# Returns:
|
||||
# Arrayref of hashes with each identifier's parts, depending on what kind
|
||||
|
||||
@@ -79,8 +79,8 @@ sub new {
|
||||
#
|
||||
# TCP requests and responses form "sessions", which can be in one of these
|
||||
# statuses:
|
||||
# [Q]uerying - The remote host is sending the query to the server.
|
||||
# [R]esponding - The server is replying back to the remote host.
|
||||
# Querying - The remote host is sending the query to the server.
|
||||
# Responding - The server is replying back to the remote host.
|
||||
sub parse_event {
|
||||
my ( $self, %args ) = @_;
|
||||
my @required_args = qw(next_event tell);
|
||||
|
||||
@@ -178,7 +178,7 @@ sub parse_event {
|
||||
# Otherwise, we need to compute the running sums and keep looping.
|
||||
else {
|
||||
if ( $self->{in_prg} ) {
|
||||
# $self->{current_ts} is intitially 0, which would seem likely to
|
||||
# $self->{current_ts} is initially 0, which would seem likely to
|
||||
# skew this computation. But $self->{in_prg} will be 0 also, and
|
||||
# $self->{current_ts} will get set immediately after this, so
|
||||
# anytime this if() block runs, it'll be OK.
|
||||
|
||||
@@ -460,7 +460,7 @@ sub pingback {
|
||||
|
||||
# If the server has suggestions for items, it sends them back in
|
||||
# the same format: ITEM:TYPE:SUGGESTION\n. ITEM:TYPE is mostly for
|
||||
# debugging; the tool just repports the suggestions.
|
||||
# debugging; the tool just reports the suggestions.
|
||||
$items = parse_server_response(
|
||||
response => $response->{content},
|
||||
split_vars => 0,
|
||||
|
||||
@@ -243,8 +243,10 @@ collect_mysql_data_one() {
|
||||
# get and keep a connection to the database; in troubled times
|
||||
# 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" &
|
||||
mysqladmin_pid=$!
|
||||
if ! _should_skip "mysqladmin"; then
|
||||
$CMD_MYSQLADMIN $EXT_ARGV ext -i$OPT_SLEEP_COLLECT -c$cnt >>"$d/$p-mysqladmin" &
|
||||
mysqladmin_pid=$!
|
||||
fi
|
||||
|
||||
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/')
|
||||
@@ -289,18 +291,25 @@ collect_mysql_data_loop() {
|
||||
|
||||
# SHOW FULL PROCESSLIST duplicates information in performance_schema.threads we collecting now
|
||||
# Keeping it for backward compatibility and may remove in the future
|
||||
|
||||
if ! _should_skip "processlist"; then
|
||||
(echo $ts; $CMD_MYSQL $EXT_ARGV -e "SHOW FULL PROCESSLIST\G") \
|
||||
>> "$d/$p-processlist" &
|
||||
(echo $ts; $CMD_MYSQL $EXT_ARGV -e "SELECT * FROM performance_schema.threads\G") \
|
||||
>> "$d/$p-threads" &
|
||||
|
||||
if [ "$have_lock_waits_table" ]; then
|
||||
(echo $ts; lock_waits "$d/lock_waits.running") >>"$d/$p-lock-waits" &
|
||||
(echo $ts; transactions) >>"$d/$p-transactions" &
|
||||
fi
|
||||
|
||||
if [ "${mysql_version}" '>' "5.6" ] && [ $ps_instrumentation_enabled == "yes" ]; then
|
||||
(echo $ts; $CMD_MYSQL $EXT_ARGV -e "SELECT * FROM performance_schema.threads\G") \
|
||||
>> "$d/$p-threads" &
|
||||
|
||||
if [ "$have_lock_waits_table" ]; then
|
||||
if ! _should_skip "lock-waits"; then
|
||||
(echo $ts; lock_waits "$d/lock_waits.running") >>"$d/$p-lock-waits" &
|
||||
fi
|
||||
if ! _should_skip "transactions"; then
|
||||
(echo $ts; transactions) >>"$d/$p-transactions" &
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "${mysql_version}" '>' "5.6" ] && [ $ps_instrumentation_enabled == "yes" ] \
|
||||
&& ! _should_skip "ps-locks-transactions"; then
|
||||
ps_locks_transactions "$d/$p-ps-locks-transactions"
|
||||
fi
|
||||
|
||||
@@ -538,20 +547,22 @@ innodb_status() {
|
||||
|
||||
local innostat=""
|
||||
|
||||
$CMD_MYSQL $EXT_ARGV -e "SHOW /*!40100 ENGINE*/ INNODB STATUS\G" \
|
||||
>> "$d/$p-innodbstatus$n"
|
||||
grep "END OF INNODB" "$d/$p-innodbstatus$n" >/dev/null || {
|
||||
if [ -d /proc -a -d /proc/$mysqld_pid ]; then
|
||||
for fd in /proc/$mysqld_pid/fd/*; do
|
||||
file $fd | grep deleted >/dev/null && {
|
||||
grep 'INNODB' $fd >/dev/null && {
|
||||
cat $fd > "$d/$p-innodbstatus$n"
|
||||
break
|
||||
if ! _should_skip "innodbstatus"; then
|
||||
$CMD_MYSQL $EXT_ARGV -e "SHOW /*!40100 ENGINE*/ INNODB STATUS\G" \
|
||||
>> "$d/$p-innodbstatus$n"
|
||||
grep "END OF INNODB" "$d/$p-innodbstatus$n" >/dev/null || {
|
||||
if [ -d /proc -a -d /proc/$mysqld_pid ]; then
|
||||
for fd in /proc/$mysqld_pid/fd/*; do
|
||||
file $fd | grep deleted >/dev/null && {
|
||||
grep 'INNODB' $fd >/dev/null && {
|
||||
cat $fd > "$d/$p-innodbstatus$n"
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
done
|
||||
fi
|
||||
}
|
||||
done
|
||||
fi
|
||||
}
|
||||
fi
|
||||
}
|
||||
|
||||
rocksdb_status() {
|
||||
@@ -560,7 +571,7 @@ rocksdb_status() {
|
||||
has_rocksdb=`$CMD_MYSQL $EXT_ARGV -e "SHOW ENGINES" | grep -i 'rocksdb'`
|
||||
exit_code=$?
|
||||
|
||||
if [ $exit_code -eq 0 ]; then
|
||||
if [ $exit_code -eq 0 ] && ! _should_skip "rocksdbstatus"; then
|
||||
$CMD_MYSQL $EXT_ARGV -e "SHOW ENGINE ROCKSDB STATUS\G" \
|
||||
>> "$d/$p-rocksdbstatus$n" || rm -f "$d/$p-rocksdbstatus$n"
|
||||
fi
|
||||
@@ -646,20 +657,34 @@ collect_mysql_variables() {
|
||||
echo -e "\n$sql\n" >> $outfile
|
||||
$CMD_MYSQL $EXT_ARGV -e "$sql" >> $outfile
|
||||
|
||||
sql="select * from performance_schema.variables_by_thread order by thread_id, variable_name;"
|
||||
echo -e "\n$sql\n" >> $outfile
|
||||
$CMD_MYSQL $EXT_ARGV -e "$sql" >> $outfile
|
||||
if ! _should_skip "thread-variables"; then
|
||||
sql="select * from performance_schema.variables_by_thread order by thread_id, variable_name;"
|
||||
echo -e "\n$sql\n" >> $outfile
|
||||
$CMD_MYSQL $EXT_ARGV -e "$sql" >> $outfile
|
||||
|
||||
sql="select * from performance_schema.user_variables_by_thread order by thread_id, variable_name;"
|
||||
echo -e "\n$sql\n" >> $outfile
|
||||
$CMD_MYSQL $EXT_ARGV -e "$sql" >> $outfile
|
||||
sql="select * from performance_schema.user_variables_by_thread order by thread_id, variable_name;"
|
||||
echo -e "\n$sql\n" >> $outfile
|
||||
$CMD_MYSQL $EXT_ARGV -e "$sql" >> $outfile
|
||||
|
||||
sql="select * from performance_schema.status_by_thread order by thread_id, variable_name; "
|
||||
echo -e "\n$sql\n" >> $outfile
|
||||
$CMD_MYSQL $EXT_ARGV -e "$sql" >> $outfile
|
||||
sql="select * from performance_schema.status_by_thread order by thread_id, variable_name; "
|
||||
echo -e "\n$sql\n" >> $outfile
|
||||
$CMD_MYSQL $EXT_ARGV -e "$sql" >> $outfile
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
_should_skip() {
|
||||
local name=$1
|
||||
|
||||
for item in "${OPT_SKIP_COLLECTION[@]}"; do
|
||||
if [ "$item" == "$name" ]; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
# ###########################################################################
|
||||
# End collect package
|
||||
# ###########################################################################
|
||||
|
||||
@@ -208,7 +208,7 @@ func main() {
|
||||
if err != nil {
|
||||
log.Infof("cannot check version updates: %s", err.Error())
|
||||
} else if advice != "" {
|
||||
log.Infof(advice)
|
||||
log.Infof("%s", advice)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -373,24 +373,6 @@ func getHostInfo(ctx context.Context, client *mongo.Client) (*hostInfo, error) {
|
||||
return nil, errors.Wrap(err, "GetHostInfo.hostInfo")
|
||||
}
|
||||
|
||||
cmdOpts := proto.CommandLineOptions{}
|
||||
query := primitive.D{{Key: "getCmdLineOpts", Value: 1}}
|
||||
err := client.Database("admin").RunCommand(ctx, query).Decode(&cmdOpts)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "cannot get command line options")
|
||||
}
|
||||
|
||||
ss := proto.ServerStatus{}
|
||||
query = primitive.D{{Key: "serverStatus", Value: 1}}
|
||||
if err := client.Database("admin").RunCommand(ctx, query).Decode(&ss); err != nil {
|
||||
return nil, errors.Wrap(err, "GetHostInfo.serverStatus")
|
||||
}
|
||||
|
||||
pi := procInfo{}
|
||||
if err := getProcInfo(int32(ss.Pid), &pi); err != nil {
|
||||
pi.Error = err
|
||||
}
|
||||
|
||||
nodeType, _ := getNodeType(ctx, client)
|
||||
procCount, _ := countMongodProcesses()
|
||||
|
||||
@@ -398,24 +380,41 @@ func getHostInfo(ctx context.Context, client *mongo.Client) (*hostInfo, error) {
|
||||
Hostname: hi.System.Hostname,
|
||||
HostOsType: hi.Os.Type,
|
||||
HostSystemCPUArch: hi.System.CpuArch,
|
||||
DBPath: "", // Sets default. It will be overridden later if necessary
|
||||
|
||||
ProcessName: ss.Process,
|
||||
ProcProcessCount: procCount,
|
||||
Version: ss.Version,
|
||||
NodeType: nodeType,
|
||||
|
||||
ProcPath: pi.Path,
|
||||
ProcUserName: pi.UserName,
|
||||
ProcCreateTime: pi.CreateTime,
|
||||
CmdlineArgs: cmdOpts.Argv,
|
||||
}
|
||||
if ss.Repl != nil {
|
||||
i.ReplicasetName = ss.Repl.SetName
|
||||
ProcProcessCount: procCount,
|
||||
NodeType: nodeType,
|
||||
CmdlineArgs: nil,
|
||||
}
|
||||
|
||||
if cmdOpts.Parsed.Storage.DbPath != "" {
|
||||
i.DBPath = cmdOpts.Parsed.Storage.DbPath
|
||||
var cmdOpts proto.CommandLineOptions
|
||||
query := primitive.D{{Key: "getCmdLineOpts", Value: 1}}
|
||||
err := client.Database("admin").RunCommand(ctx, query).Decode(&cmdOpts)
|
||||
if err == nil {
|
||||
if len(cmdOpts.Argv) > 0 {
|
||||
i.CmdlineArgs = cmdOpts.Argv
|
||||
}
|
||||
if cmdOpts.Parsed.Storage.DbPath != "" {
|
||||
i.DBPath = cmdOpts.Parsed.Storage.DbPath
|
||||
}
|
||||
}
|
||||
|
||||
var ss proto.ServerStatus
|
||||
query = primitive.D{{Key: "serverStatus", Value: 1}}
|
||||
err = client.Database("admin").RunCommand(ctx, query).Decode(&ss)
|
||||
if err == nil {
|
||||
i.ProcessName = ss.Process
|
||||
i.Version = ss.Version
|
||||
if ss.Repl != nil {
|
||||
i.ReplicasetName = ss.Repl.SetName
|
||||
}
|
||||
|
||||
pi := procInfo{}
|
||||
if err := getProcInfo(int32(ss.Pid), &pi); err != nil {
|
||||
pi.Error = err
|
||||
} else {
|
||||
i.ProcPath = pi.Path
|
||||
i.ProcUserName = pi.UserName
|
||||
i.ProcCreateTime = pi.CreateTime
|
||||
}
|
||||
}
|
||||
|
||||
return i, nil
|
||||
|
||||
@@ -8,9 +8,9 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/pborman/getopt"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
tu "github.com/percona/percona-toolkit/src/go/internal/testutils"
|
||||
"github.com/percona/percona-toolkit/src/go/mongolib/proto"
|
||||
)
|
||||
|
||||
func TestGetHostInfo(t *testing.T) {
|
||||
@@ -49,6 +49,18 @@ func TestGetHostInfo(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetHostInfoResult(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
client, err := tu.TestClient(ctx, tu.MongoDBShard1PrimaryPort)
|
||||
require.NoError(t, err, "cannot get a new MongoDB client")
|
||||
|
||||
host, err := getHostInfo(ctx, client)
|
||||
require.NoError(t, err, "getHostInfo error")
|
||||
require.NotEmpty(t, host)
|
||||
}
|
||||
|
||||
func TestClusterWideInfo(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
@@ -85,16 +97,6 @@ func TestClusterWideInfo(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func addToCounters(ss proto.ServerStatus, increment int64) proto.ServerStatus {
|
||||
ss.Opcounters.Command += increment
|
||||
ss.Opcounters.Delete += increment
|
||||
ss.Opcounters.GetMore += increment
|
||||
ss.Opcounters.Insert += increment
|
||||
ss.Opcounters.Query += increment
|
||||
ss.Opcounters.Update += increment
|
||||
return ss
|
||||
}
|
||||
|
||||
func TestParseArgs(t *testing.T) {
|
||||
tests := []struct {
|
||||
args []string
|
||||
|
||||
@@ -694,6 +694,7 @@ my $slaves = $ms->get_replicas(
|
||||
$cxn->connect();
|
||||
return $cxn;
|
||||
},
|
||||
dsn => 'F=/tmp/12345/my.sandbox.cnf',
|
||||
);
|
||||
|
||||
is_deeply(
|
||||
|
||||
@@ -26,7 +26,7 @@ ok(
|
||||
no_diff(
|
||||
"$cmd -- cat $sample/mext-001.txt",
|
||||
"t/pt-mext/samples/mext-001-result.txt",
|
||||
post_pipe => "LOCALE=C sort -k1,1",
|
||||
post_pipe => "LOCALE=en_US.utf8 LANG=en_US.UTF-8 sort -k1,1",
|
||||
),
|
||||
"mext-001"
|
||||
) or diag($test_diff);
|
||||
@@ -35,7 +35,7 @@ ok(
|
||||
no_diff(
|
||||
"$cmd -r -- cat $sample/mext-002.txt",
|
||||
"t/pt-mext/samples/mext-002-result.txt",
|
||||
post_pipe => "LOCALE=C sort -k1,1",
|
||||
post_pipe => "LOCALE=en_US.utf8 LANG=en_US.UTF-8 sort -k1,1",
|
||||
),
|
||||
"mext-002 -r"
|
||||
) or diag($test_diff);
|
||||
@@ -44,6 +44,7 @@ ok(
|
||||
no_diff(
|
||||
"$cmd -- cat $sample/pt-130-in.txt",
|
||||
"t/pt-mext/samples/pt-130-out.txt",
|
||||
post_pipe => "LOCALE=en_US.utf8 LANG=en_US.UTF-8 sort -k1,1",
|
||||
),
|
||||
"having rsa key",
|
||||
) or diag($test_diff);
|
||||
|
||||
@@ -26,7 +26,7 @@ require "$trunk/bin/pt-online-schema-change";
|
||||
my $dp = new DSNParser(opts=>$dsn_opts);
|
||||
my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
|
||||
my $source_dbh = $sb->get_dbh_for('source');
|
||||
my $source_dsn = 'h=127.1,P=12345,u=msandbox,p=msandbox';
|
||||
my $source_dsn = 'h=127.1,P=12345,u=msandbox,p=msandbox,s=1';
|
||||
|
||||
if ( !$source_dbh ) {
|
||||
plan skip_all => 'Cannot connect to sandbox source';
|
||||
|
||||
@@ -192,8 +192,9 @@ like(
|
||||
},
|
||||
);
|
||||
|
||||
diag($output);
|
||||
$output =~ /.*Chunk: (\d+)\n/ms;
|
||||
my $last_chunk = int($1);
|
||||
my $last_chunk = int($1) or diag($output);
|
||||
|
||||
ok(
|
||||
$last_chunk * $chunk_size + int($copied_rows) == $num_rows,
|
||||
|
||||
@@ -26,7 +26,7 @@ require "$trunk/bin/pt-online-schema-change";
|
||||
my $dp = new DSNParser(opts=>$dsn_opts);
|
||||
my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
|
||||
my $source_dbh = $sb->get_dbh_for('source');
|
||||
my $source_dsn = 'h=127.1,P=12345,u=msandbox,p=msandbox';
|
||||
my $source_dsn = 'h=127.1,P=12345,u=msandbox,p=msandbox,s=1';
|
||||
|
||||
if ( !$source_dbh ) {
|
||||
plan skip_all => 'Cannot connect to sandbox source';
|
||||
|
||||
@@ -8,6 +8,6 @@ CREATE TABLE `dsns` (
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;
|
||||
|
||||
INSERT INTO `dsns` VALUES (1, NULL, "F=/home/sveta/src/percona/percona-toolkit/t/pt-archiver/samples/pt-191-replica1.cnf,P=12346,h=127.0.0.1,u=root,p=msandbox,s=1");
|
||||
INSERT INTO `dsns` VALUES (2, NULL, "F=/home/sveta/src/percona/percona-toolkit/t/pt-archiver/samples/pt-191-replica2.cnf,P=12347,h=127.0.0.1,u=root,p=msandbox,s=1");
|
||||
INSERT INTO `dsns` VALUES (1, NULL, "F=t/pt-archiver/samples/pt-191-replica1.cnf,P=12346,h=127.0.0.1,u=root,p=msandbox,s=1");
|
||||
INSERT INTO `dsns` VALUES (2, NULL, "F=t/pt-archiver/samples/pt-191-replica2.cnf,P=12347,h=127.0.0.1,u=root,p=msandbox,s=1");
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ while ( my $file = readdir $dh ) {
|
||||
(my $outfile = $file) =~ s/\.in/.out/;
|
||||
ok(
|
||||
no_diff(
|
||||
"$trunk/bin/pt-pmp $sample/$file",
|
||||
"LOCALE=en_US.utf8 LANG=en_US.UTF-8 $trunk/bin/pt-pmp $sample/$file",
|
||||
"t/pt-pmp/samples/$outfile",
|
||||
),
|
||||
"$file"
|
||||
@@ -31,7 +31,7 @@ closedir $dh;
|
||||
|
||||
ok(
|
||||
no_diff(
|
||||
"$trunk/bin/pt-pmp -l 2 $sample/stacktrace003.in",
|
||||
"LOCALE=en_US.utf8 LANG=en_US.UTF-8 $trunk/bin/pt-pmp -l 2 $sample/stacktrace003.in",
|
||||
"t/pt-pmp/samples/stacktrace003-limit2.out",
|
||||
),
|
||||
"Limit 2 (stacktrace003-limit2.out)"
|
||||
@@ -39,7 +39,7 @@ ok(
|
||||
|
||||
ok(
|
||||
no_diff(
|
||||
"$trunk/bin/pt-pmp -d eu $sample/stacktrace006-eu.in",
|
||||
"LOCALE=en_US.utf8 LANG=en_US.UTF-8 $trunk/bin/pt-pmp -d eu $sample/stacktrace006-eu.in",
|
||||
"t/pt-pmp/samples/stacktrace006-eu-deu.out",
|
||||
),
|
||||
"eu-stack dump read correctly if option -d eu specified"
|
||||
@@ -47,7 +47,7 @@ ok(
|
||||
|
||||
ok(
|
||||
no_diff(
|
||||
"$trunk/bin/pt-pmp -d pteu $sample/stacktrace006-pteu.in",
|
||||
"LOCALE=en_US.utf8 LANG=en_US.UTF-8 $trunk/bin/pt-pmp -d pteu $sample/stacktrace006-pteu.in",
|
||||
"t/pt-pmp/samples/stacktrace006-pteu-dpteu.out",
|
||||
),
|
||||
"pt-eustack-resolver dump read correctly if option -d pteu specified"
|
||||
|
||||
262
t/pt-stalk/pt-2289.t
Normal file
262
t/pt-stalk/pt-2289.t
Normal file
@@ -0,0 +1,262 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
BEGIN {
|
||||
die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n"
|
||||
unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH};
|
||||
unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib";
|
||||
};
|
||||
|
||||
use strict;
|
||||
use warnings FATAL => 'all';
|
||||
use threads;
|
||||
use English qw(-no_match_vars);
|
||||
use Test::More;
|
||||
use Time::HiRes qw(sleep);
|
||||
|
||||
use PerconaTest;
|
||||
use DSNParser;
|
||||
use Sandbox;
|
||||
require VersionParser;
|
||||
|
||||
my $dp = new DSNParser(opts=>$dsn_opts);
|
||||
my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
|
||||
my $dbh = $sb->get_dbh_for('source');
|
||||
|
||||
if ( !$dbh ) {
|
||||
plan skip_all => 'Cannot connect to sandbox source';
|
||||
}
|
||||
|
||||
my $cnf = "/tmp/12345/my.sandbox.cnf";
|
||||
my $pid_file = "/tmp/pt-stalk.pid.$PID";
|
||||
my $log_file = "/tmp/pt-stalk.log.$PID";
|
||||
my $dest = "/tmp/pt-stalk.collect.$PID";
|
||||
my $int_file = "/tmp/pt-stalk-after-interval-sleep";
|
||||
my $pid;
|
||||
my $output;
|
||||
my $retval;
|
||||
|
||||
sub cleanup {
|
||||
diag(`rm $pid_file $log_file $int_file 2>/dev/null`);
|
||||
diag(`rm -rf $dest 2>/dev/null`);
|
||||
}
|
||||
|
||||
# ###########################################################################
|
||||
# Test that it collects all data when no --skip-collection is given.
|
||||
# ###########################################################################
|
||||
|
||||
cleanup();
|
||||
|
||||
# We need these to collect lock-waits
|
||||
sub start_thread_pt_1897_1 {
|
||||
# this must run in a thread because we need to have an active session
|
||||
# with open transaction
|
||||
my ($dsn_opts) = @_;
|
||||
my $dp = new DSNParser(opts=>$dsn_opts);
|
||||
my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
|
||||
my $dbh = $sb->get_dbh_for('source');
|
||||
$sb->load_file('source', "t/pt-stalk/samples/PT-1897-1.sql");
|
||||
}
|
||||
my $thr1 = threads->create('start_thread_pt_1897_1', $dsn_opts);
|
||||
$thr1->detach();
|
||||
threads->yield();
|
||||
sleep 1;
|
||||
|
||||
sub start_thread_pt_1897_2 {
|
||||
# this must run in a thread because we need to have an active session
|
||||
# with waiting transaction
|
||||
my ($dsn_opts) = @_;
|
||||
my $dp = new DSNParser(opts=>$dsn_opts);
|
||||
my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
|
||||
my $dbh = $sb->get_dbh_for('source');
|
||||
$sb->load_file('source', "t/pt-stalk/samples/PT-1897-2.sql");
|
||||
}
|
||||
my $thr2 = threads->create('start_thread_pt_1897_2', $dsn_opts);
|
||||
$thr2->detach();
|
||||
threads->yield();
|
||||
|
||||
$retval = system("$trunk/bin/pt-stalk --no-stalk --pid $pid_file --log $log_file --dest $dest --iterations 1 -- --defaults-file=$cnf >$log_file 2>&1");
|
||||
|
||||
sleep 35;
|
||||
PerconaTest::kill_program(pid_file => $pid_file);
|
||||
|
||||
is(
|
||||
$retval >> 8,
|
||||
0,
|
||||
"Parent exit 0"
|
||||
);
|
||||
|
||||
ok(
|
||||
-d $dest,
|
||||
"Creates --dest (collect) dir"
|
||||
);
|
||||
|
||||
# ps-locks-transactions,thread-variables,innodbstatus,lock-waits,mysqladmin,processlist,rocksdbstatus,transactions
|
||||
ok(
|
||||
glob("$dest/*-ps-locks-transactions"),
|
||||
"Collects *-ps-locks-transactions"
|
||||
) or diag(`ls $dest`);
|
||||
|
||||
ok(
|
||||
glob("$dest/*-innodbstatus*"),
|
||||
"Collects *-innodbstatus*"
|
||||
) or diag(`ls $dest`);
|
||||
|
||||
ok(
|
||||
glob("$dest/*-lock-waits"),
|
||||
"Collects *-lock-waits"
|
||||
) or diag(`ls $dest`);
|
||||
|
||||
ok(
|
||||
glob("$dest/*-mysqladmin"),
|
||||
"Collects *-mysqladmin"
|
||||
) or diag(`ls $dest`);
|
||||
|
||||
ok(
|
||||
glob("$dest/*-processlist"),
|
||||
"Collects *-processlist"
|
||||
) or diag(`ls $dest`);
|
||||
|
||||
ok(
|
||||
glob("$dest/*-transactions"),
|
||||
"Collects *-transactions"
|
||||
) or diag(`ls $dest`);
|
||||
|
||||
# thread-variables
|
||||
ok(
|
||||
glob("$dest/*-variables"),
|
||||
"Collects *-variables"
|
||||
) or diag(`ls $dest`);
|
||||
|
||||
$output = `cat $dest/*-variables 2>/dev/null`;
|
||||
like(
|
||||
$output,
|
||||
qr/select \* from performance_schema\.variables_by_thread/,
|
||||
"Thread variables collected"
|
||||
); # or diag($output);
|
||||
|
||||
SKIP: {
|
||||
skip "These tests require MyRocks", 1 if ( !$sb->has_engine('source', 'ROCKSDB') ) ;
|
||||
|
||||
# rocksdbstatus
|
||||
ok(
|
||||
glob("$dest/*-rocksdbstatus*"),
|
||||
"Collects *-rocksdbstatus"
|
||||
) or diag(`ls $dest`);
|
||||
|
||||
cleanup();
|
||||
|
||||
$retval = system("$trunk/bin/pt-stalk --no-stalk --pid $pid_file --log $log_file --dest $dest --iterations 1 --skip-collection rocksdbstatus -- --defaults-file=$cnf >$log_file 2>&1");
|
||||
|
||||
sleep 5;
|
||||
PerconaTest::kill_program(pid_file => $pid_file);
|
||||
|
||||
ok(
|
||||
! glob("$dest/*-rocksdbstatus*"),
|
||||
"Does not collect *-rocksdbstatus"
|
||||
) or diag(`ls $dest`);
|
||||
}
|
||||
|
||||
cleanup();
|
||||
|
||||
$retval = system("$trunk/bin/pt-stalk --no-stalk --pid $pid_file --log $log_file --dest $dest --iterations 1 --skip-collection processlist -- --defaults-file=$cnf >$log_file 2>&1");
|
||||
|
||||
sleep 5;
|
||||
PerconaTest::kill_program(pid_file => $pid_file);
|
||||
|
||||
ok(
|
||||
! glob("$dest/*-processlist"),
|
||||
"Does not collect *-processlist"
|
||||
) or diag(`ls $dest`);
|
||||
|
||||
cleanup();
|
||||
|
||||
$retval = system("$trunk/bin/pt-stalk --no-stalk --pid $pid_file --log $log_file --dest $dest --iterations 1 --skip-collection ps-locks-transactions,thread-variables,innodbstatus,mysqladmin,processlist,transactions -- --defaults-file=$cnf >$log_file 2>&1");
|
||||
|
||||
sleep 5;
|
||||
PerconaTest::kill_program(pid_file => $pid_file);
|
||||
|
||||
ok(
|
||||
! glob("$dest/*-ps-locks-transactions"),
|
||||
"Does not collect *-ps-locks-transactions"
|
||||
) or diag(`ls $dest`);
|
||||
|
||||
ok(
|
||||
glob("$dest/*-variables"),
|
||||
"Collects *-variables"
|
||||
) or diag(`ls $dest`);
|
||||
|
||||
$output = `cat $dest/*-variables 2>/dev/null`;
|
||||
unlike(
|
||||
$output,
|
||||
qr/select \* from performance_schema\.variables_by_thread/,
|
||||
"Thread variables not collected"
|
||||
); # or diag($output);
|
||||
|
||||
ok(
|
||||
! glob("$dest/*-innodbstatus"),
|
||||
"Does not collect *-innodbstatus"
|
||||
) or diag(`ls $dest`);
|
||||
|
||||
ok(
|
||||
! glob("$dest/*-mysqladmin"),
|
||||
"Does not collect *-mysqladmin"
|
||||
) or diag(`ls $dest`);
|
||||
|
||||
ok(
|
||||
! glob("$dest/*-processlist"),
|
||||
"Does not collect *-processlist"
|
||||
) or diag(`ls $dest`);
|
||||
|
||||
ok(
|
||||
! glob("$dest/*-transactions"),
|
||||
"Does not collect *-transactions"
|
||||
) or diag(`ls $dest`);
|
||||
|
||||
#Unsupported skip-collection value
|
||||
cleanup();
|
||||
|
||||
$retval = system("$trunk/bin/pt-stalk --no-stalk --pid $pid_file --log $log_file --dest $dest --iterations 1 --skip-collection ps-locks-transactions,thread-variables,innodbstatus,mysqladmin,processlist,transaction -- --defaults-file=$cnf >$log_file 2>&1");
|
||||
|
||||
sleep 5;
|
||||
PerconaTest::kill_program(pid_file => $pid_file);
|
||||
|
||||
is(
|
||||
$retval >> 8,
|
||||
1,
|
||||
"Parent exit 1 on unsupported --skip-collection value"
|
||||
);
|
||||
|
||||
like(
|
||||
`cat $log_file`,
|
||||
qr/Invalid --skip-collection value: transaction, exiting./,
|
||||
"Rejects unsupported --skip-collection value"
|
||||
);
|
||||
|
||||
cleanup();
|
||||
|
||||
$retval = system("$trunk/bin/pt-stalk --no-stalk --pid $pid_file --log $log_file --dest $dest --iterations 1 --skip-collection 'mysqladmin and' -- --defaults-file=$cnf >$log_file 2>&1");
|
||||
|
||||
sleep 5;
|
||||
PerconaTest::kill_program(pid_file => $pid_file);
|
||||
|
||||
is(
|
||||
$retval >> 8,
|
||||
1,
|
||||
"Parent exit 1 on unsupported --skip-collection value"
|
||||
);
|
||||
|
||||
like(
|
||||
`cat $log_file`,
|
||||
qr/Invalid --skip-collection value: mysqladmin and, exiting./,
|
||||
"Rejects unsupported --skip-collection value"
|
||||
);
|
||||
|
||||
# #############################################################################
|
||||
# Done.
|
||||
# #############################################################################
|
||||
|
||||
cleanup();
|
||||
diag(`rm -rf $dest 2>/dev/null`);
|
||||
$sb->wipe_clean($dbh);
|
||||
ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
|
||||
done_testing;
|
||||
@@ -393,18 +393,16 @@ my $tempdir = tempdir( CLEANUP => 1 );
|
||||
|
||||
my $script = <<"EOT";
|
||||
. $trunk/bin/pt-stalk
|
||||
purge_samples $tempdir 10000 2>&1
|
||||
purge_samples $tempdir 10000 0 0 2>&1
|
||||
EOT
|
||||
|
||||
$output = `$script`;
|
||||
$output = `bash -c "$script"`;
|
||||
|
||||
unlike(
|
||||
$output,
|
||||
qr/\Qfind: warning: you have specified the -depth option/,
|
||||
"Bug 942114: no bad find usage"
|
||||
);
|
||||
|
||||
|
||||
# ###########################################################################
|
||||
# Test that it handles floating point values
|
||||
# ###########################################################################
|
||||
|
||||
@@ -11,6 +11,7 @@ use warnings FATAL => 'all';
|
||||
use English qw(-no_match_vars);
|
||||
use Test::More;
|
||||
use Time::Local;
|
||||
use Data::Dumper;
|
||||
|
||||
use PerconaTest;
|
||||
use Sandbox;
|
||||
@@ -20,10 +21,11 @@ my $dp = new DSNParser(opts=>$dsn_opts);
|
||||
my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
|
||||
my $dbh = $sb->get_dbh_for('source');
|
||||
|
||||
my $output = `$trunk/bin/pt-table-checksum h=127.1,P=12345,u=msandbox,p=msandbox --set-vars innodb_lock_wait_timeout=3 --chunk-size=50 -d sakila --buffer-stdout 2>&1 | tee | ts '%m-%dT%H:%M:%S'`;
|
||||
my $output = `$trunk/bin/pt-table-checksum h=127.1,P=12345,u=msandbox,p=msandbox,s=1 --set-vars innodb_lock_wait_timeout=3 --chunk-size=50 -d sakila --buffer-stdout 2>&1 | tee | ts '%m-%dT%H:%M:%S'`;
|
||||
|
||||
my @lines = split(/\n/, $output);
|
||||
my @times = ( $lines[3] =~ m/\d\d-\d\dT\d\d:\d\d:\d\d/g );
|
||||
diag(Dumper(@times));
|
||||
|
||||
is(
|
||||
scalar(@times),
|
||||
@@ -41,7 +43,7 @@ cmp_ok(
|
||||
"Print delay is expected for the buffered output"
|
||||
) or diag($output);
|
||||
|
||||
$output = `$trunk/bin/pt-table-checksum h=127.1,P=12345,u=msandbox,p=msandbox --set-vars innodb_lock_wait_timeout=3 --chunk-size=50 -d sakila 2>&1 | tee | ts '%m-%dT%H:%M:%S'`;
|
||||
$output = `$trunk/bin/pt-table-checksum h=127.1,P=12345,u=msandbox,p=msandbox,s=1 --set-vars innodb_lock_wait_timeout=3 --chunk-size=50 -d sakila 2>&1 | tee | ts '%m-%dT%H:%M:%S'`;
|
||||
|
||||
@lines = split(/\n/, $output);
|
||||
@times = ( $lines[3] =~ m/\d\d-\d\dT\d\d:\d\d:\d\d/g );
|
||||
@@ -62,7 +64,7 @@ cmp_ok(
|
||||
"STDOUT is buffered by default"
|
||||
) or diag($output);
|
||||
|
||||
$output = `$trunk/bin/pt-table-checksum h=127.1,P=12345,u=msandbox,p=msandbox --set-vars innodb_lock_wait_timeout=3 --chunk-size=50 -d sakila --no-buffer-stdout 2>&1 | tee | ts '%m-%dT%H:%M:%S'`;
|
||||
$output = `$trunk/bin/pt-table-checksum h=127.1,P=12345,u=msandbox,p=msandbox,s=1 --set-vars innodb_lock_wait_timeout=3 --chunk-size=50 -d sakila --no-buffer-stdout 2>&1 | tee | ts '%m-%dT%H:%M:%S'`;
|
||||
|
||||
@lines = split(/\n/, $output);
|
||||
@times = ( $lines[3] =~ m/\d\d-\d\dT\d\d:\d\d:\d\d/g );
|
||||
@@ -83,7 +85,7 @@ cmp_ok(
|
||||
"Print delay is not expected when buffering is disabled"
|
||||
) or diag($output);
|
||||
|
||||
$output = `$trunk/bin/pt-table-checksum h=127.1,P=12345,u=msandbox,p=msandbox --set-vars innodb_lock_wait_timeout=3 --chunk-size=50 -d sakila --nobuffer-stdout 2>&1 | tee | ts '%m-%dT%H:%M:%S'`;
|
||||
$output = `$trunk/bin/pt-table-checksum h=127.1,P=12345,u=msandbox,p=msandbox,s=1 --set-vars innodb_lock_wait_timeout=3 --chunk-size=50 -d sakila --nobuffer-stdout 2>&1 | tee | ts '%m-%dT%H:%M:%S'`;
|
||||
|
||||
@lines = split(/\n/, $output);
|
||||
@times = ( $lines[3] =~ m/\d\d-\d\dT\d\d:\d\d:\d\d/g );
|
||||
|
||||
69
t/pt-table-checksum/pt-2250.t
Normal file
69
t/pt-table-checksum/pt-2250.t
Normal file
@@ -0,0 +1,69 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
BEGIN {
|
||||
die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n"
|
||||
unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH};
|
||||
unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib";
|
||||
};
|
||||
|
||||
use strict;
|
||||
use warnings FATAL => 'all';
|
||||
use English qw(-no_match_vars);
|
||||
use Test::More;
|
||||
|
||||
use PerconaTest;
|
||||
use Sandbox;
|
||||
require "$trunk/bin/pt-table-checksum";
|
||||
|
||||
my $dp = new DSNParser(opts=>$dsn_opts);
|
||||
my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
|
||||
my $dbh = $sb->get_dbh_for('source');
|
||||
|
||||
if ( !$dbh ) {
|
||||
plan skip_all => 'Cannot connect to sandbox source';
|
||||
}
|
||||
else {
|
||||
plan tests => 3;
|
||||
}
|
||||
|
||||
# The sandbox servers run with lock_wait_timeout=3 and it's not dynamic
|
||||
# so we need to specify --set-vars innodb_lock_wait_timeout=3 else the tool will die.
|
||||
# And --max-load "" prevents waiting for status variables.
|
||||
my @args = (qw(--set-vars innodb_lock_wait_timeout=3), '--max-load', '');
|
||||
my ($output, $exit_code);
|
||||
|
||||
$sb->create_dbs($dbh, [qw(test)]);
|
||||
$sb->load_file('source', 't/lib/samples/tables/issue-388.sql', 'test');
|
||||
|
||||
$sb->load_file('source', "t/pt-table-checksum/samples/pt-2250_dsns.sql");
|
||||
$dbh->do("insert into test.foo values (null, 'john, smith')");
|
||||
|
||||
($output, $exit_code) = full_output(
|
||||
sub {
|
||||
pt_table_checksum::main(
|
||||
@args,
|
||||
'h=127.1,P=12345,u=msandbox,p=msandbox',
|
||||
qw(-d test),
|
||||
"--recursion-method=dsn=F=t/pt-archiver/samples/pt-191.cnf,D=dsns,t=dsns,h=127.0.0.1,P=12345,u=msandbox,p=msandbox")
|
||||
},
|
||||
stderr => 1,
|
||||
);
|
||||
|
||||
is(
|
||||
$exit_code,
|
||||
0,
|
||||
"No error for recursion method dsn"
|
||||
) or diag($output);
|
||||
|
||||
unlike(
|
||||
$output,
|
||||
qr/Can't connect to local MySQL server/,
|
||||
'No error message for recursion method dsn'
|
||||
) or diag($output);
|
||||
|
||||
# #############################################################################
|
||||
# Done.
|
||||
# #############################################################################
|
||||
$sb->wipe_clean($dbh);
|
||||
ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
|
||||
exit;
|
||||
@@ -294,7 +294,7 @@ if ( -x "$ENV{PERCONA_TOOLKIT_SANDBOX}/bin/mysqlbinlog" ) {
|
||||
chomp $mysqlbinlog;
|
||||
}
|
||||
|
||||
$output = `$mysqlbinlog /tmp/12345/data/$row->{file} --start-position=$row->{position} | grep 'use ' | grep -v '^# Warning' | grep -v 'pseudo_replica_mode' | sort -u | sed -e 's/\`//g'`;
|
||||
$output = `$mysqlbinlog /tmp/12345/data/$row->{file} --start-position=$row->{position} | grep 'use ' | grep -v '^# Warning' | grep -v 'pseudo_replica_mode' | LOCALE=en_US.utf8 LANG=en_US.UTF-8 sort -u | sed -e 's/\`//g'`;
|
||||
|
||||
my $use_dbs = "use mysql/*!*/;
|
||||
use percona/*!*/;
|
||||
@@ -317,7 +317,7 @@ $row = $source_dbh->selectrow_hashref("show ${source_status} status");
|
||||
|
||||
pt_table_checksum::main(@args, qw(--quiet --replicate-database percona));
|
||||
|
||||
$output = `$mysqlbinlog /tmp/12345/data/$row->{file} --start-position=$row->{position} | grep 'use ' | grep -v '^# Warning' | grep -v 'pseudo_replica_mode' | sort -u | sed -e 's/\`//g'`;
|
||||
$output = `$mysqlbinlog /tmp/12345/data/$row->{file} --start-position=$row->{position} | grep 'use ' | grep -v '^# Warning' | grep -v 'pseudo_replica_mode' | LOCALE=en_US.utf8 LANG=en_US.UTF-8 sort -u | sed -e 's/\`//g'`;
|
||||
|
||||
is(
|
||||
$output,
|
||||
|
||||
13
t/pt-table-checksum/samples/pt-2250_dsns.sql
Normal file
13
t/pt-table-checksum/samples/pt-2250_dsns.sql
Normal file
@@ -0,0 +1,13 @@
|
||||
CREATE DATABASE IF NOT EXISTS dsns;
|
||||
USE dsns;
|
||||
DROP TABLE IF EXISTS `dsns`;
|
||||
CREATE TABLE `dsns` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`parent_id` int(11) DEFAULT NULL,
|
||||
`dsn` varchar(255) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;
|
||||
|
||||
INSERT INTO `dsns` VALUES (1, NULL, "P=12346,h=127.0.0.1,u=msandbox,p=msandbox");
|
||||
INSERT INTO `dsns` VALUES (2, NULL, "P=12347,h=127.0.0.1,u=msandbox,p=msandbox");
|
||||
|
||||
Reference in New Issue
Block a user