mirror of
https://github.com/percona/percona-toolkit.git
synced 2025-09-09 18:30:16 +00:00
Merge branch '3.x' into galera-log-explainer
This commit is contained in:
15
.editorconfig
Normal file
15
.editorconfig
Normal file
@@ -0,0 +1,15 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[{*.pm,bin/*}]
|
||||
indent_size = 3
|
||||
|
||||
[*.go]
|
||||
indent_style = tab
|
4
.github/workflows/toolkit.yml
vendored
4
.github/workflows/toolkit.yml
vendored
@@ -25,9 +25,9 @@ jobs:
|
||||
run: cd src/go; make linux-amd64; cd ../../
|
||||
|
||||
- name: Build the Docker image
|
||||
run: echo "FROM oraclelinux:9-slim" > Dockerfile; echo "COPY bin/* /usr/bin/" >> Dockerfile; docker build . --file Dockerfile --tag percona-toolkit:${{ github.sha }}
|
||||
run: echo "FROM oraclelinux:9-slim" > Dockerfile; echo "RUN microdnf -y update" >> Dockerfile; echo "COPY bin/* /usr/bin/" >> Dockerfile; docker build . --file Dockerfile --tag percona-toolkit:${{ github.sha }}
|
||||
- name: Run Trivy vulnerability scanner
|
||||
uses: aquasecurity/trivy-action@0.12.0
|
||||
uses: aquasecurity/trivy-action@0.14.0
|
||||
with:
|
||||
image-ref: 'percona-toolkit:${{ github.sha }}'
|
||||
format: 'table'
|
||||
|
22
Makefile.PL
22
Makefile.PL
@@ -1,20 +1,38 @@
|
||||
use ExtUtils::MakeMaker;
|
||||
use ExtUtils::MY;
|
||||
|
||||
sub MY::postamble {
|
||||
return <<'MAKE_GOTOOLS';
|
||||
gotools:
|
||||
cd src/go && $(MAKE) build
|
||||
|
||||
MAKE_GOTOOLS
|
||||
}
|
||||
|
||||
WriteMakefile(
|
||||
NAME => 'Percona::Toolkit',
|
||||
VERSION => '3.5.5',
|
||||
EXE_FILES => [ <bin/*> ],
|
||||
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/*>
|
||||
],
|
||||
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/ ) ) {
|
||||
if ( ( $file_name !~ m/mongo/ ) || ( $file_name !~ m/pg/ ) || ( $file_name !~ m/pt-stalk/ ) || ( $file_name !~ m/pt-k8s/ ) ) {
|
||||
$_ => "blib/man1/$name.1p";
|
||||
}
|
||||
} <bin/*>
|
||||
},
|
||||
MAN3PODS => {}, # man(3) pages are for C libs
|
||||
depend => {manifypods => gotools},
|
||||
PREREQ_PM => {
|
||||
DBI => 1.46,
|
||||
DBD::mysql => 3.0000_0,
|
||||
|
@@ -6401,7 +6401,7 @@ sub main {
|
||||
$tp->get_create_table( $dbh, $table->{D}, $table->{t} ));
|
||||
|
||||
if ( $o->get('check-charset') ) {
|
||||
my $sql = 'SELECT CONCAT(/*!40100 @@session.character_set_connection, */ "")';
|
||||
my $sql = 'SELECT CONCAT(/*!40100 @@session.character_set_connection, */ \'\')';
|
||||
PTDEBUG && _d($sql);
|
||||
my ($dbh_charset) = $table->{dbh}->selectrow_array($sql);
|
||||
|
||||
@@ -6786,8 +6786,8 @@ sub main {
|
||||
}
|
||||
|
||||
my $charset = $got_charset || '';
|
||||
if ($charset eq 'utf8') {
|
||||
$charset = ":$charset";
|
||||
if ($charset =~ m/utf8/) {
|
||||
$charset = ":utf8";
|
||||
}
|
||||
elsif ($charset) {
|
||||
eval { require Encode }
|
||||
@@ -7343,9 +7343,11 @@ sub do_with_retries {
|
||||
$success = $OUT_OF_RETRIES;
|
||||
}
|
||||
$get_sth->finish;
|
||||
if ( $dst && $dst->{dbh} ) {
|
||||
trace('rollback', sub {
|
||||
$dst->{dbh}->rollback;
|
||||
});
|
||||
}
|
||||
trace('rollback', sub {
|
||||
$src->{dbh}->rollback;
|
||||
});
|
||||
|
@@ -957,9 +957,9 @@ collect_mysql_processlist () {
|
||||
}
|
||||
|
||||
collect_mysql_users () {
|
||||
$CMD_MYSQL $EXT_ARGV -ss -e 'SELECT COUNT(*), SUM(user=""), SUM(password=""), SUM(password NOT LIKE "*%") FROM mysql.user' 2>/dev/null
|
||||
$CMD_MYSQL $EXT_ARGV -ss -e "SELECT COUNT(*), SUM(user=''), SUM(password=''), SUM(password NOT LIKE '*%') FROM mysql.user" 2>/dev/null
|
||||
if [ "$?" -ne 0 ]; then
|
||||
$CMD_MYSQL $EXT_ARGV -ss -e 'SELECT COUNT(*), SUM(user=""), SUM(authentication_string=""), SUM(authentication_string NOT LIKE "*%") FROM mysql.user WHERE account_locked <> "Y" AND password_expired <> "Y" AND authentication_string <> ""' 2>/dev/null
|
||||
$CMD_MYSQL $EXT_ARGV -ss -e "SELECT COUNT(*), SUM(user=''), SUM(authentication_string=''), SUM(authentication_string NOT LIKE '*%') FROM mysql.user WHERE account_locked <> 'Y' AND password_expired <> 'Y' AND authentication_string <> ''" 2>/dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -989,7 +989,7 @@ collect_internal_vars () {
|
||||
local mysqld_executables="${1:-""}"
|
||||
|
||||
local FNV_64=""
|
||||
if $CMD_MYSQL $EXT_ARGV -e 'SELECT FNV_64("a")' >/dev/null 2>&1; then
|
||||
if $CMD_MYSQL $EXT_ARGV -e "SELECT FNV_64('a')" >/dev/null 2>&1; then
|
||||
FNV_64="Enabled";
|
||||
else
|
||||
FNV_64="Unknown";
|
||||
@@ -1035,7 +1035,7 @@ collect_internal_vars () {
|
||||
}
|
||||
|
||||
collect_keyring_plugins() {
|
||||
$CMD_MYSQL $EXT_ARGV --table -ss -e 'SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE "keyring%";'
|
||||
$CMD_MYSQL $EXT_ARGV --table -ss -e "SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE 'keyring%';"
|
||||
}
|
||||
|
||||
collect_encrypted_tables() {
|
||||
|
@@ -3470,11 +3470,29 @@ sub check_table {
|
||||
}
|
||||
my ($dbh, $db, $tbl) = @args{@required_args};
|
||||
my $q = $self->{Quoter} || 'Quoter';
|
||||
$self->{check_table_error} = undef;
|
||||
|
||||
|
||||
my $lctn_sql = 'SELECT @@lower_case_table_names';
|
||||
PTDEBUG && _d($lctn_sql);
|
||||
|
||||
my $lower_case_table_names;
|
||||
eval { ($lower_case_table_names) = $dbh->selectrow_array($lctn_sql); };
|
||||
if ( $EVAL_ERROR ) {
|
||||
PTDEBUG && _d($EVAL_ERROR);
|
||||
$self->{check_table_error} = $EVAL_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
PTDEBUG && _d("lower_case_table_names=$lower_case_table_names");
|
||||
if ($lower_case_table_names > 0) {
|
||||
PTDEBUG && _d("MySQL uses case-insensitive lookup, converting '$tbl' to lowercase");
|
||||
$tbl = lc $tbl;
|
||||
}
|
||||
|
||||
my $db_tbl = $q->quote($db, $tbl);
|
||||
PTDEBUG && _d('Checking', $db_tbl);
|
||||
|
||||
$self->{check_table_error} = undef;
|
||||
|
||||
my $sql = "SHOW TABLES FROM " . $q->quote($db)
|
||||
. ' LIKE ' . $q->literal_like($tbl);
|
||||
PTDEBUG && _d($sql);
|
||||
@@ -8481,7 +8499,7 @@ my $term_readkey = eval {
|
||||
|
||||
use sigtrap 'handler', \&sig_int, 'normal-signals';
|
||||
|
||||
|
||||
my $plugin;
|
||||
my $exit_status = 0;
|
||||
my $oktorun = 1;
|
||||
my $dont_interrupt_now = 0;
|
||||
@@ -8535,6 +8553,9 @@ sub _die {
|
||||
$exit_status ||= 255;
|
||||
chomp ($msg);
|
||||
print "$msg\n";
|
||||
if ( $plugin && $plugin->can('before_die') ) {
|
||||
$plugin->before_die(exit_status => $exit_status);
|
||||
}
|
||||
exit $exit_status;
|
||||
}
|
||||
|
||||
@@ -8853,7 +8874,7 @@ sub main {
|
||||
# ########################################################################
|
||||
# Create --plugin.
|
||||
# ########################################################################
|
||||
my $plugin;
|
||||
|
||||
if ( my $file = $o->get('plugin') ) {
|
||||
_die("--plugin file $file does not exist", INVALID_PLUGIN_FILE) unless -f $file;
|
||||
eval {
|
||||
@@ -8923,13 +8944,17 @@ sub main {
|
||||
for my $slave (@$slaves) {
|
||||
my $is_skip = 0;
|
||||
for my $slave_to_skip (@$slaves_to_skip) {
|
||||
if ($slave->{dsn}->{h} eq $slave_to_skip->{h} && $slave->{dsn}->{P} eq $slave_to_skip->{P}) {
|
||||
if ( $slave->{dsn}->{h} eq $slave_to_skip->{h} ) {
|
||||
my $skip_slave_port = defined($slave_to_skip->{P})
|
||||
? $slave_to_skip->{P} : '3306';
|
||||
if ( ($slave->{dsn}->{P} eq $skip_slave_port) ) {
|
||||
print "Skipping slave " . $slave->description() . "\n";
|
||||
$is_skip = 1;
|
||||
$slave->{dbh}->disconnect();
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!$is_skip) {
|
||||
push @$filtered_slaves, $slave;
|
||||
}
|
||||
@@ -9590,6 +9615,9 @@ sub main {
|
||||
$cxn->dbh()->do($sql);
|
||||
};
|
||||
if ( $EVAL_ERROR ) {
|
||||
if ( $plugin && $plugin->can('before_die') ) {
|
||||
$plugin->before_die(exit_status => $EVAL_ERROR);
|
||||
}
|
||||
# this is trapped by a signal handler. Don't replace it with _die
|
||||
die "Error altering new table $new_tbl->{name}: $EVAL_ERROR\n";
|
||||
}
|
||||
@@ -10172,6 +10200,10 @@ sub main {
|
||||
1 while $nibble_iter->next();
|
||||
};
|
||||
if ( $EVAL_ERROR ) {
|
||||
if ( $plugin && $plugin->can('before_die') ) {
|
||||
$plugin->before_die(exit_status => $EVAL_ERROR);
|
||||
}
|
||||
|
||||
die ts("Error copying rows from $orig_tbl->{name} to "
|
||||
. "$new_tbl->{name}: $EVAL_ERROR");
|
||||
}
|
||||
@@ -11175,7 +11207,7 @@ sub determine_alter_fk_method {
|
||||
return ''; # $alter_fk_method can't be undef
|
||||
}
|
||||
|
||||
# The rebuild_constraints method is the default becuase it's safer
|
||||
# The rebuild_constraints method is the default because it's safer
|
||||
# and doesn't cause the orig table to go missing for a moment.
|
||||
my $method = 'rebuild_constraints';
|
||||
|
||||
@@ -11630,7 +11662,7 @@ sub random_suffix {
|
||||
# duplicate_trigger: If set, it will create the trigger on the new table
|
||||
# with a random string as a trigger name suffix.
|
||||
# It will also not drop the original trigger.
|
||||
# This is usefull when creating a temporary trigger for testing
|
||||
# This is useful when creating a temporary trigger for testing
|
||||
# purposes or if --no-swap-tables AND --no-drop-new-table was
|
||||
# specified along with --preserve-triggers. In this case,
|
||||
# since the original table and triggers are not going to be
|
||||
@@ -13197,6 +13229,7 @@ These hooks, in this order, are called if defined:
|
||||
before_drop_old_table
|
||||
after_drop_old_table
|
||||
before_drop_triggers
|
||||
before_die
|
||||
before_exit
|
||||
get_slave_lag
|
||||
|
||||
@@ -13313,6 +13346,11 @@ Here's a plugin file template for all hooks:
|
||||
print "PLUGIN before_drop_triggers\n";
|
||||
}
|
||||
|
||||
sub before_die {
|
||||
my ($self, %args) = @_;
|
||||
print "PLUGIN before_die\n";
|
||||
}
|
||||
|
||||
sub before_exit {
|
||||
my ($self, %args) = @_;
|
||||
print "PLUGIN before_exit\n";
|
||||
|
@@ -624,6 +624,7 @@ aggregate_stacktrace() {
|
||||
}
|
||||
else {
|
||||
targ = \$2;
|
||||
tfile= \$NF;
|
||||
}
|
||||
# get rid of long symbol names such as 'pthread_cond_wait@@GLIBC_2.3.2'
|
||||
if ( targ ~ /@@/ ) {
|
||||
|
@@ -8067,6 +8067,7 @@ override query_report => sub {
|
||||
: undef;
|
||||
my $fingerprint = substr($item, 0, $self->max_fingerprint_length);
|
||||
my $checksum = make_checksum($item);
|
||||
my $explain = $self->explain_report($sample->{arg}, $sample->{db});
|
||||
my $class = {
|
||||
checksum => $checksum,
|
||||
fingerprint => $fingerprint,
|
||||
@@ -8078,6 +8079,8 @@ override query_report => sub {
|
||||
query => substr($sample->{arg}, 0, $self->max_query_length),
|
||||
ts => $sample->{ts} ? parse_timestamp($sample->{ts}) : undef,
|
||||
Query_time => $sample->{Query_time},
|
||||
$explain ?
|
||||
( explain => $explain ): (),
|
||||
},
|
||||
),
|
||||
};
|
||||
|
@@ -10653,11 +10653,13 @@ sub main {
|
||||
for my $slave_to_skip (@$slaves_to_skip) {
|
||||
my $h_eq_h = $slave->{dsn}->{h} eq $slave_to_skip->{h};
|
||||
my $p_eq_p;
|
||||
if (defined($slave->{dsn}->{P}) || defined($slave_to_skip->{P})) {
|
||||
$p_eq_p = $slave->{dsn}->{P} eq $slave_to_skip->{P};
|
||||
} else {
|
||||
if (!defined($slave->{dsn}->{P}) && !defined($slave_to_skip->{P}) ) {
|
||||
PTDEBUG && _d("Both port DSNs are undefined, setting p_eq_p to true");
|
||||
$p_eq_p = 1;
|
||||
} else {
|
||||
my $skip_slave_port = defined($slave_to_skip->{P})
|
||||
? $slave_to_skip->{P} : '3306';
|
||||
$p_eq_p = $slave->{dsn}->{P} eq $skip_slave_port;
|
||||
}
|
||||
if ($h_eq_h && $p_eq_p) {
|
||||
$found=1;
|
||||
@@ -10955,11 +10957,11 @@ sub main {
|
||||
# the user does --chunk-size-limit=0 to disable the 1st, documented
|
||||
# purpose because, apparently, they're using non-unique indexes and
|
||||
# they don't care about potentially large chunks. But disabling the
|
||||
# 1st purpose adversely affects the 2nd purpose becuase 0 * the chunk size
|
||||
# 1st purpose adversely affects the 2nd purpose because 0 * the chunk size
|
||||
# will always be zero, so tables will only be single-chunked if EXPLAIN
|
||||
# says there are 0 rows, but sometimes EXPLAIN says there is 1 row
|
||||
# even when the table is empty. This wouldn't matter except that nibbling
|
||||
# an empty table doesn't currently work becuase there are no boundaries,
|
||||
# an empty table doesn't currently work because there are no boundaries,
|
||||
# so no checksum is written for the empty table. To fix this and
|
||||
# preserve the two purposes of this option, usages of the 2nd purpose
|
||||
# do || 1 so the limit is never 0 and empty tables are single-chunked.
|
||||
|
@@ -86,8 +86,8 @@ pygments_style = 'sphinx'
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
#modindex_common_prefix = []
|
||||
|
||||
extlinks = {'jirabug': ('https://jira.percona.com/browse/%s', ''),
|
||||
'lpbug': ('https://bugs.launchpad.net/percona-toolkit/+bug/%s', '#')}
|
||||
extlinks = {'jirabug': ('https://jira.percona.com/browse/%s', '%s'),
|
||||
'lpbug': ('https://bugs.launchpad.net/percona-toolkit/+bug/%s', '#%s')}
|
||||
# -- Options for HTML output ---------------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
|
24
go.mod
24
go.mod
@@ -7,12 +7,10 @@ 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 v0.8.0
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/alecthomas/kong v0.8.1
|
||||
github.com/go-ini/ini v1.67.0
|
||||
github.com/golang/mock v1.6.0
|
||||
github.com/google/go-cmp v0.5.9
|
||||
github.com/google/uuid v1.3.1
|
||||
github.com/google/uuid v1.4.0
|
||||
github.com/hashicorp/go-version v1.6.0
|
||||
github.com/howeyc/gopass v0.0.0-20210920133722-c8aef6fb66ef
|
||||
github.com/lib/pq v1.10.9
|
||||
@@ -25,13 +23,11 @@ require (
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/stretchr/testify v1.8.4
|
||||
go.mongodb.org/mongo-driver v1.12.1
|
||||
golang.org/x/crypto v0.13.0
|
||||
go.mongodb.org/mongo-driver v1.13.0
|
||||
golang.org/x/crypto v0.15.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.28.2
|
||||
k8s.io/utils v0.0.0-20230406110748-d93618cff8a2
|
||||
k8s.io/api v0.28.4
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -56,14 +52,14 @@ require (
|
||||
github.com/xdg-go/stringprep v1.0.4 // indirect
|
||||
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||
golang.org/x/net v0.13.0 // indirect
|
||||
golang.org/x/net v0.17.0 // indirect
|
||||
golang.org/x/sync v0.1.0 // indirect
|
||||
golang.org/x/sys v0.12.0 // indirect
|
||||
golang.org/x/term v0.12.0 // indirect
|
||||
golang.org/x/text v0.13.0 // indirect
|
||||
golang.org/x/sys v0.14.0 // indirect
|
||||
golang.org/x/term v0.14.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
k8s.io/apimachinery v0.28.2 // indirect
|
||||
k8s.io/apimachinery v0.28.4 // indirect
|
||||
k8s.io/klog/v2 v2.100.1 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
|
||||
|
40
go.sum
40
go.sum
@@ -8,8 +8,8 @@ github.com/alecthomas/assert/v2 v2.1.0 h1:tbredtNcQnoSd3QBhQWI7QZ3XHOVkw1Moklp2o
|
||||
github.com/alecthomas/assert/v2 v2.1.0/go.mod h1:b/+1DI2Q6NckYi+3mXyH3wFb8qG37K/DuK80n7WefXA=
|
||||
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 v0.8.0 h1:ryDCzutfIqJPnNn0omnrgHLbAggDQM2VWHikE1xqK7s=
|
||||
github.com/alecthomas/kong v0.8.0/go.mod h1:n1iCIO2xS46oE8ZfYCNDqdR0b0wZNrXAIAqro/2132U=
|
||||
github.com/alecthomas/kong v0.8.1 h1:acZdn3m4lLRobeh3Zi2S2EpnXTd1mOL6U7xVml+vfkY=
|
||||
github.com/alecthomas/kong v0.8.1/go.mod h1:n1iCIO2xS46oE8ZfYCNDqdR0b0wZNrXAIAqro/2132U=
|
||||
github.com/alecthomas/repr v0.1.0 h1:ENn2e1+J3k09gyj2shc0dHr/yjaWSHRlrJ4DPMevDqE=
|
||||
github.com/alecthomas/repr v0.1.0/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
|
||||
@@ -41,8 +41,8 @@ github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
|
||||
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
|
||||
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
|
||||
github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
|
||||
@@ -120,16 +120,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.12.1 h1:nLkghSU8fQNaK7oUmDhQFsnrtcoNy7Z6LVFKsEecqgE=
|
||||
go.mongodb.org/mongo-driver v1.12.1/go.mod h1:/rGBTebI3XYboVmgz+Wv3Bcbl3aD0QF9zl6kDDw18rQ=
|
||||
go.mongodb.org/mongo-driver v1.13.0 h1:67DgFFjYOCMWdtTEmKFpV3ffWlFnh+CYZ8ZS/tXWUfY=
|
||||
go.mongodb.org/mongo-driver v1.13.0/go.mod h1:/rGBTebI3XYboVmgz+Wv3Bcbl3aD0QF9zl6kDDw18rQ=
|
||||
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-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
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.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck=
|
||||
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||
golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA=
|
||||
golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g=
|
||||
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=
|
||||
@@ -144,8 +144,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.13.0 h1:Nvo8UFsZ8X3BhAC9699Z1j7XQ3rsZnUUm7jfBEk1ueY=
|
||||
golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
|
||||
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
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=
|
||||
@@ -168,20 +168,20 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
|
||||
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
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.12.0 h1:/ZfYdc3zq+q02Rv9vGqTeSItdzZTSNDmfTi0mBAuidU=
|
||||
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
||||
golang.org/x/term v0.14.0 h1:LGK9IlZ8T9jvdy6cTdfKUCltatMFOehAQo9SRC46UQ8=
|
||||
golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww=
|
||||
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.6/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.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
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=
|
||||
@@ -206,10 +206,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.28.2 h1:9mpl5mOb6vXZvqbQmankOfPIGiudghwCoLl1EYfUZbw=
|
||||
k8s.io/api v0.28.2/go.mod h1:RVnJBsjU8tcMq7C3iaRSGMeaKt2TWEUXcpIt/90fjEg=
|
||||
k8s.io/apimachinery v0.28.2 h1:KCOJLrc6gu+wV1BYgwik4AF4vXOlVJPdiqn0yAWWwXQ=
|
||||
k8s.io/apimachinery v0.28.2/go.mod h1:RdzF87y/ngqk9H4z3EL2Rppv5jj95vGS/HaFXrLDApU=
|
||||
k8s.io/api v0.28.4 h1:8ZBrLjwosLl/NYgv1P7EQLqoO8MGQApnbgH8tu3BMzY=
|
||||
k8s.io/api v0.28.4/go.mod h1:axWTGrY88s/5YE+JSt4uUi6NMM+gur1en2REMR7IRj0=
|
||||
k8s.io/apimachinery v0.28.4 h1:zOSJe1mc+GxuMnFzD4Z/U1wst50X28ZNsn5bhgIIao8=
|
||||
k8s.io/apimachinery v0.28.4/go.mod h1:wI37ncBvfAoswfq626yPTe6Bz1c22L7uaJ8dho83mgg=
|
||||
k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg=
|
||||
k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
|
||||
k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 h1:qY1Ad8PODbnymg2pRbkyMT/ylpTrCM8P2RJ0yroCyIk=
|
||||
|
@@ -241,6 +241,7 @@ override query_report => sub {
|
||||
: undef;
|
||||
my $fingerprint = substr($item, 0, $self->max_fingerprint_length);
|
||||
my $checksum = make_checksum($item);
|
||||
my $explain = $self->explain_report($sample->{arg}, $sample->{db});
|
||||
my $class = {
|
||||
checksum => $checksum,
|
||||
fingerprint => $fingerprint,
|
||||
@@ -252,6 +253,8 @@ override query_report => sub {
|
||||
query => substr($sample->{arg}, 0, $self->max_query_length),
|
||||
ts => $sample->{ts} ? parse_timestamp($sample->{ts}) : undef,
|
||||
Query_time => $sample->{Query_time},
|
||||
$explain ?
|
||||
( explain => $explain ): (),
|
||||
},
|
||||
),
|
||||
};
|
||||
|
@@ -327,11 +327,33 @@ sub check_table {
|
||||
}
|
||||
my ($dbh, $db, $tbl) = @args{@required_args};
|
||||
my $q = $self->{Quoter} || 'Quoter';
|
||||
$self->{check_table_error} = undef;
|
||||
|
||||
# https://dev.mysql.com/doc/refman/8.0/en/identifier-case-sensitivity.html
|
||||
# MySQL may use use case-insensitive table lookup, this is controller by
|
||||
# @@lower_case_table_names. 0 means case sensitive search, 1 or 2 means
|
||||
# case insensitive lookup.
|
||||
|
||||
my $lctn_sql = 'SELECT @@lower_case_table_names';
|
||||
PTDEBUG && _d($lctn_sql);
|
||||
|
||||
my $lower_case_table_names;
|
||||
eval { ($lower_case_table_names) = $dbh->selectrow_array($lctn_sql); };
|
||||
if ( $EVAL_ERROR ) {
|
||||
PTDEBUG && _d($EVAL_ERROR);
|
||||
$self->{check_table_error} = $EVAL_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
PTDEBUG && _d("lower_case_table_names=$lower_case_table_names");
|
||||
if ($lower_case_table_names > 0) {
|
||||
PTDEBUG && _d("MySQL uses case-insensitive lookup, converting '$tbl' to lowercase");
|
||||
$tbl = lc $tbl;
|
||||
}
|
||||
|
||||
my $db_tbl = $q->quote($db, $tbl);
|
||||
PTDEBUG && _d('Checking', $db_tbl);
|
||||
|
||||
$self->{check_table_error} = undef;
|
||||
|
||||
my $sql = "SHOW TABLES FROM " . $q->quote($db)
|
||||
. ' LIKE ' . $q->literal_like($tbl);
|
||||
PTDEBUG && _d($sql);
|
||||
|
@@ -135,9 +135,9 @@ collect_mysql_processlist () {
|
||||
collect_mysql_users () {
|
||||
# The where clause has been added to skip listing MySQL 8+ roles as users.
|
||||
# ROLES are locked accounts, without passwords and expired.
|
||||
$CMD_MYSQL $EXT_ARGV -ss -e 'SELECT COUNT(*), SUM(user=""), SUM(password=""), SUM(password NOT LIKE "*%") FROM mysql.user' 2>/dev/null
|
||||
$CMD_MYSQL $EXT_ARGV -ss -e "SELECT COUNT(*), SUM(user=''), SUM(password=''), SUM(password NOT LIKE '*%') FROM mysql.user" 2>/dev/null
|
||||
if [ "$?" -ne 0 ]; then
|
||||
$CMD_MYSQL $EXT_ARGV -ss -e 'SELECT COUNT(*), SUM(user=""), SUM(authentication_string=""), SUM(authentication_string NOT LIKE "*%") FROM mysql.user WHERE account_locked <> "Y" AND password_expired <> "Y" AND authentication_string <> ""' 2>/dev/null
|
||||
$CMD_MYSQL $EXT_ARGV -ss -e "SELECT COUNT(*), SUM(user=''), SUM(authentication_string=''), SUM(authentication_string NOT LIKE '*%') FROM mysql.user WHERE account_locked <> 'Y' AND password_expired <> 'Y' AND authentication_string <> ''" 2>/dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -168,7 +168,7 @@ collect_internal_vars () {
|
||||
local mysqld_executables="${1:-""}"
|
||||
|
||||
local FNV_64=""
|
||||
if $CMD_MYSQL $EXT_ARGV -e 'SELECT FNV_64("a")' >/dev/null 2>&1; then
|
||||
if $CMD_MYSQL $EXT_ARGV -e "SELECT FNV_64('a')" >/dev/null 2>&1; then
|
||||
FNV_64="Enabled";
|
||||
else
|
||||
FNV_64="Unknown";
|
||||
@@ -215,7 +215,7 @@ collect_internal_vars () {
|
||||
}
|
||||
|
||||
collect_keyring_plugins() {
|
||||
$CMD_MYSQL $EXT_ARGV --table -ss -e 'SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE "keyring%";'
|
||||
$CMD_MYSQL $EXT_ARGV --table -ss -e "SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE 'keyring%';"
|
||||
}
|
||||
|
||||
collect_encrypted_tables() {
|
||||
|
@@ -22,7 +22,7 @@ pkgs = $(shell find . -type d -name "pt-*" -exec basename {} \;)
|
||||
# VERSION ?=$(shell git describe --abbrev=0) doesn't always work here, need to use git log
|
||||
VERSION ?=$(shell git log --no-walk --tags --pretty="%H %d" --decorate=short | head -n1 | awk -F'[, $(CP)]' '{ print $$4; }')
|
||||
BUILD=$(BUILD_DATE)
|
||||
GOVERSION=$(shell go version | cut --delimiter=" " -f3)
|
||||
GOVERSION=$(shell go version | cut -d " " -f3)
|
||||
GOUTILSDIR ?= $(GOPATH)/bin
|
||||
FILES = $(shell find . -type f -name '*.go' -not -path "./vendor/*")
|
||||
PREFIX=$(shell pwd)
|
||||
@@ -127,24 +127,36 @@ env-down: env ## Clean-up MongoDB docker containers cluster
|
||||
docker-compose down -v
|
||||
rm .env
|
||||
|
||||
linux-amd64: ## Build Mongo tools for linux-amd64.
|
||||
linux-amd64: ## Build Go tools for linux-amd64.
|
||||
@echo "Building linux/amd64 binaries in ${BIN_DIR} as version ${VERSION}"
|
||||
@cd ${TOP_DIR} && go get ./...
|
||||
@$(foreach pkg,$(pkgs),rm -f ${BIN_DIR}/$(pkg) 2> /dev/null;)
|
||||
@$(foreach pkg,$(pkgs),GOOS=linux GOARCH=amd64 go build -ldflags ${LDFLAGS} -o ${BIN_DIR}/$(pkg) ./$(pkg);)
|
||||
|
||||
linux-386: ## Build Mongo tools for linux-386
|
||||
linux-386: ## Build Go tools for linux-386
|
||||
@echo "Building linux/386 binaries in ${BIN_DIR} as version ${VERSION}"
|
||||
@cd ${TOP_DIR} && go get ./...
|
||||
@$(foreach pkg,$(pkgs),rm -f ${BIN_DIR}/$(pkg) 2> /dev/null;)
|
||||
@$(foreach pkg,$(pkgs),GOOS=linux GOARCH=386 go build -ldflags ${LDFLAGS} -o ${BIN_DIR}/$(pkg) ./$(pkg);)
|
||||
|
||||
darwin-amd64: ## Build Mongo tools for darwin-amd64 (MacOS)
|
||||
darwin-amd64: ## Build Go tools for darwin-amd64 (MacOS)
|
||||
@echo "Building darwin/amd64 binaries in ${BIN_DIR} as version ${VERSION}"
|
||||
@cd ${TOP_DIR} && go get ./...
|
||||
@$(foreach pkg,$(pkgs),rm -f ${BIN_DIR}/$(pkg) 2> /dev/null;)
|
||||
@$(foreach pkg,$(pkgs),GOOS=darwin GOARCH=amd64 go build -ldflags ${LDFLAGS} -o ${BIN_DIR}/$(pkg) ./$(pkg);)
|
||||
|
||||
darwin-arm64: ## Build Go tools for darwin-arm64 (MacOS)
|
||||
@echo "Building darwin/arm64 binaries in ${BIN_DIR} as version ${VERSION}"
|
||||
@cd ${TOP_DIR} && go get ./...
|
||||
@$(foreach pkg,$(pkgs),rm -f ${BIN_DIR}/$(pkg) 2> /dev/null;)
|
||||
@$(foreach pkg,$(pkgs),GOOS=darwin GOARCH=arm64 go build -ldflags ${LDFLAGS} -o ${BIN_DIR}/$(pkg) ./$(pkg);)
|
||||
|
||||
build:
|
||||
@echo "Building binaries in ${BIN_DIR} as version ${VERSION}"
|
||||
@cd ${TOP_DIR} && go get ./...
|
||||
@$(foreach pkg,$(pkgs),rm -f ${BIN_DIR}/$(pkg) 2> /dev/null;)
|
||||
@$(foreach pkg,$(pkgs),go build -ldflags ${LDFLAGS} -o ${BIN_DIR}/$(pkg) ./$(pkg);)
|
||||
|
||||
style: ## Check code style
|
||||
@echo ">> checking code style"
|
||||
@! gofmt -d $(shell find . -path ./vendor -prune -o -name '*.go' -print) | grep '^'
|
||||
|
@@ -129,14 +129,14 @@ func TestOverrideConfig(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDefaultFiles(t *testing.T) {
|
||||
user, _ := user.Current()
|
||||
current, _ := user.Current()
|
||||
toolname := "pt-testing"
|
||||
|
||||
want := []string{
|
||||
"/etc/percona-toolkit/percona-toolkit.conf",
|
||||
fmt.Sprintf("/etc/percona-toolkit/%s.conf", toolname),
|
||||
fmt.Sprintf("%s/.percona-toolkit.conf", user.HomeDir),
|
||||
fmt.Sprintf("%s/.%s.conf", user.HomeDir, toolname),
|
||||
fmt.Sprintf("%s/.percona-toolkit.conf", current.HomeDir),
|
||||
fmt.Sprintf("%s/.%s.conf", current.HomeDir, toolname),
|
||||
}
|
||||
|
||||
got, err := DefaultConfigFiles(toolname)
|
||||
|
@@ -37,7 +37,7 @@ type Security struct {
|
||||
KeyFile string `bson:"keyFile"`
|
||||
ClusterAuthMode string `bson:"clusterAuthMode"`
|
||||
Authorization string `bson:"authorization"`
|
||||
JavascriptEnabled bool `bson:javascriptEnabled"`
|
||||
JavascriptEnabled bool `bson:"javascriptEnabled"`
|
||||
Sasl struct {
|
||||
HostName string `bson:"hostName"`
|
||||
ServiceName string `bson:"serverName"`
|
||||
|
@@ -31,7 +31,7 @@ type ServerStatus struct {
|
||||
|
||||
type StorageEngine struct {
|
||||
Name string `bson:"name"`
|
||||
SupportCommittedREads bool `bson:supportsCommittedReads"`
|
||||
SupportsCommittedReads bool `bson:"supportsCommittedReads"`
|
||||
ReadOnly bool `bson:"readOnly"`
|
||||
Persistent bool `bson:"persistent"`
|
||||
}
|
||||
|
@@ -24,6 +24,7 @@ type Dumper struct {
|
||||
kubeconfig string
|
||||
resources []string
|
||||
filePaths []string
|
||||
fileContainer string
|
||||
namespace string
|
||||
location string
|
||||
errors string
|
||||
@@ -124,6 +125,7 @@ func New(location, namespace, resource string, kubeconfig string, forwardport st
|
||||
"var/lib/mysql/mysqld.post.processing.log",
|
||||
"var/lib/mysql/auto.cnf",
|
||||
)
|
||||
d.fileContainer = "logs"
|
||||
}
|
||||
d.resources = resources
|
||||
d.crType = resource
|
||||
@@ -272,7 +274,7 @@ func (d *Dumper) DumpCluster() error {
|
||||
// get individual Logs
|
||||
location = filepath.Join(d.location, ns.Name, pod.Name)
|
||||
for _, path := range d.filePaths {
|
||||
err = d.getIndividualFiles(resourceType(d.crType), ns.Name, pod.Name, path, location, tw)
|
||||
err = d.getIndividualFiles(ns.Name, pod.Name, path, location, tw)
|
||||
if err != nil {
|
||||
d.logError(err.Error(), "get file "+path+" for pod "+pod.Name)
|
||||
log.Printf("Error: get %s file: %v", path, err)
|
||||
@@ -370,13 +372,15 @@ type crSecrets struct {
|
||||
} `json:"spec"`
|
||||
}
|
||||
|
||||
// TODO: check if resource parameter is really needed
|
||||
func (d *Dumper) getIndividualFiles(resource, namespace string, podName, path, location string, tw *tar.Writer) error {
|
||||
args := []string{"-n", namespace, "cp", podName + ":" + path, "/dev/stdout"}
|
||||
func (d *Dumper) getIndividualFiles(namespace string, podName, path, location string, tw *tar.Writer) error {
|
||||
if len(d.fileContainer) == 0 {
|
||||
return errors.Errorf("Logs container name is not specified for resource %s in namespace %s", resourceType(d.crType), d.namespace)
|
||||
}
|
||||
args := []string{"-n", namespace, "-c", d.fileContainer, "cp", podName + ":" + path, "/dev/stdout"}
|
||||
output, err := d.runCmd(args...)
|
||||
if err != nil {
|
||||
d.logError(err.Error(), args...)
|
||||
log.Printf("Error: get path %s for resource %s in namespace %s: %v", path, resource, d.namespace, err)
|
||||
log.Printf("Error: get path %s for resource %s in namespace %s: %v", path, resourceType(d.crType), d.namespace, err)
|
||||
return addToArchive(location, d.mode, []byte(err.Error()), tw)
|
||||
}
|
||||
|
||||
|
20
src/go/pt-k8s-debug-collector/dumper/dumper_test.go
Normal file
20
src/go/pt-k8s-debug-collector/dumper/dumper_test.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package dumper
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
/*
|
||||
Unit test for non-existing logs container name error handling
|
||||
*/
|
||||
|
||||
func TestGetIndividualFilesError(t *testing.T) {
|
||||
d := New("", "", "psmdb", "", "")
|
||||
|
||||
err := d.getIndividualFiles("", "", "", "", nil)
|
||||
|
||||
assert.Error(t, err)
|
||||
assert.ErrorContains(t, err, "Logs container name is not specified")
|
||||
}
|
@@ -412,15 +412,15 @@ type multiSorter struct {
|
||||
less []lessFunc
|
||||
}
|
||||
|
||||
// Sort sorts the argument slice according to the less functions passed to OrderedBy.
|
||||
// Sort sorts the argument slice according to the less functions passed to orderedBy.
|
||||
func (ms *multiSorter) Sort(queries []stats.QueryStats) {
|
||||
ms.queries = queries
|
||||
sort.Sort(ms)
|
||||
}
|
||||
|
||||
// OrderedBy returns a Sorter that sorts using the less functions, in order.
|
||||
// orderedBy returns a Sorter that sorts using the less functions, in order.
|
||||
// Call its Sort method to sort the data.
|
||||
func OrderedBy(less ...lessFunc) *multiSorter {
|
||||
func orderedBy(less ...lessFunc) *multiSorter {
|
||||
return &multiSorter{
|
||||
less: less,
|
||||
}
|
||||
@@ -520,7 +520,7 @@ func sortQueries(queries []stats.QueryStats, orderby []string) []stats.QueryStat
|
||||
sortFuncs = append(sortFuncs, f)
|
||||
}
|
||||
|
||||
OrderedBy(sortFuncs...).Sort(queries)
|
||||
orderedBy(sortFuncs...).Sort(queries)
|
||||
return queries
|
||||
}
|
||||
|
||||
|
67
t/pt-archiver/pt-2064.t
Normal file
67
t/pt-archiver/pt-2064.t
Normal file
@@ -0,0 +1,67 @@
|
||||
#!/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 Time::HiRes qw(time);
|
||||
|
||||
use PerconaTest;
|
||||
use Sandbox;
|
||||
use Data::Dumper;
|
||||
require "$trunk/bin/pt-archiver";
|
||||
|
||||
my $dp = new DSNParser(opts=>$dsn_opts);
|
||||
my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
|
||||
my $master_dbh = $sb->get_dbh_for('master');
|
||||
my $slave1_dbh = $sb->get_dbh_for('slave1');
|
||||
|
||||
if ( !$master_dbh ) {
|
||||
plan skip_all => 'Cannot connect to sandbox master';
|
||||
}
|
||||
elsif ( !$slave1_dbh ) {
|
||||
plan skip_all => 'Cannot connect to sandbox slave1';
|
||||
}
|
||||
|
||||
my $cnf = "/tmp/12345/my.sandbox.cnf";
|
||||
my $cmd = "$trunk/bin/pt-archiver";
|
||||
my @args = qw(--where 1=1);
|
||||
|
||||
$sb->create_dbs($master_dbh, ['test']);
|
||||
$sb->load_file('master', 't/pt-archiver/samples/table1.sql');
|
||||
$sb->wait_for_slaves();
|
||||
|
||||
$master_dbh->do('set global innodb_lock_wait_timeout=1');
|
||||
|
||||
$master_dbh->do('begin');
|
||||
$master_dbh->do('select * from test.table_1 for update;');
|
||||
|
||||
my ($output, $exit_val) = full_output(sub {pt_archiver::main(@args, '--source', "D=test,t=table_1,F=$cnf", qw(--purge)) });
|
||||
|
||||
is(
|
||||
$exit_val,
|
||||
0,
|
||||
'No rollback on non-existent destination'
|
||||
);
|
||||
|
||||
unlike(
|
||||
$output,
|
||||
qr/Can't call method "rollback" on an undefined value/,
|
||||
'No rollback on non-existent destination'
|
||||
) or diag($output);
|
||||
|
||||
# #############################################################################
|
||||
# Done.
|
||||
# #############################################################################
|
||||
$master_dbh->do('set global innodb_lock_wait_timeout=DEFAULT');
|
||||
|
||||
$sb->wipe_clean($master_dbh);
|
||||
ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
|
||||
|
||||
done_testing;
|
67
t/pt-archiver/pt-2207.t
Normal file
67
t/pt-archiver/pt-2207.t
Normal file
@@ -0,0 +1,67 @@
|
||||
#!/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-archiver";
|
||||
|
||||
my $dp = new DSNParser(opts=>$dsn_opts);
|
||||
my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
|
||||
my $dbh = $sb->get_dbh_for('master');
|
||||
|
||||
if ( !$dbh ) {
|
||||
plan skip_all => 'Cannot connect to sandbox master';
|
||||
}
|
||||
|
||||
my $output;
|
||||
my $exit_val;
|
||||
my $rows;
|
||||
my $cnf = "/tmp/12345/my.sandbox.cnf";
|
||||
my $cmd = "$trunk/bin/pt-archiver";
|
||||
|
||||
$sb->create_dbs($dbh, ['test']);
|
||||
$sb->load_file('master', 't/pt-archiver/samples/table1.sql');
|
||||
|
||||
# Archive to a file.
|
||||
`rm -f archive.test.table_1`;
|
||||
($output, $exit_val) = full_output(
|
||||
sub { pt_archiver::main(qw(--where 1=1), "--source", "D=test,t=table_1,F=$cnf", "--file", 'archive.%D.%t', "--set-vars", "sql_mode=ANSI_QUOTES") },
|
||||
);
|
||||
|
||||
is($exit_val,
|
||||
0,
|
||||
"SQL Mode ANSI_QUOTES works"
|
||||
) or diag($output);
|
||||
|
||||
is($output, '', 'No output for archiving to a file');
|
||||
$output = `/tmp/12345/use -N -e "select count(*) from test.table_1"`;
|
||||
is($output + 0, 0, 'Purged all rows ok');
|
||||
ok(-f 'archive.test.table_1', 'Archive file written OK');
|
||||
$output = `cat archive.test.table_1`;
|
||||
is($output, <<EOF
|
||||
1\t2\t3\t4
|
||||
2\t\\N\t3\t4
|
||||
3\t2\t3\t\\\t
|
||||
4\t2\t3\t\\
|
||||
EOF
|
||||
, 'File has the right stuff');
|
||||
`rm -f archive.test.table_1`;
|
||||
|
||||
# #############################################################################
|
||||
# Done.
|
||||
# #############################################################################
|
||||
diag(`rm -f /tmp/*.table_1`);
|
||||
$sb->wipe_clean($dbh);
|
||||
ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
|
||||
|
||||
done_testing;
|
80
t/pt-archiver/pt-2279.t
Normal file
80
t/pt-archiver/pt-2279.t
Normal file
@@ -0,0 +1,80 @@
|
||||
#!/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 charnames ':full';
|
||||
|
||||
use PerconaTest;
|
||||
use Sandbox;
|
||||
require "$trunk/bin/pt-archiver";
|
||||
|
||||
my $dp = new DSNParser(opts=>$dsn_opts);
|
||||
my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
|
||||
my $dbh = $sb->get_dbh_for('master');
|
||||
|
||||
if ( !$dbh ) {
|
||||
plan skip_all => 'Cannot connect to sandbox master';
|
||||
}
|
||||
|
||||
my $output;
|
||||
my $cnf = "/tmp/12345/my.sandbox.cnf";
|
||||
my $cmd = "$trunk/bin/pt-archiver";
|
||||
|
||||
$sb->wipe_clean($dbh);
|
||||
$sb->create_dbs($dbh, ['test']);
|
||||
|
||||
# Test --bulk-insert
|
||||
$sb->load_file('master', 't/pt-archiver/samples/pt-2279.sql');
|
||||
|
||||
$output = output(
|
||||
sub { pt_archiver::main(qw(--limit 50 --bulk-insert),
|
||||
qw(--bulk-delete --where 1=1 --statistics --charset utf8mb4),
|
||||
'--source', "L=1,D=test,t=table_1,F=$cnf",
|
||||
'--dest', "t=table_1_dest") },
|
||||
);
|
||||
|
||||
unlike(
|
||||
$output,
|
||||
qr/Cannot find encoding "utf8mb4"/,
|
||||
'Bulk insert does not fail due to missing utf8mb4'
|
||||
) or diag($output);
|
||||
|
||||
# Test --file
|
||||
$sb->load_file('master', 't/pt-archiver/samples/pt-2279.sql');
|
||||
|
||||
$output = output(
|
||||
sub { pt_archiver::main(qw(--limit 50),
|
||||
qw(--where 1=1 --statistics --charset utf8mb4),
|
||||
'--source', "L=1,D=test,t=table_1,F=$cnf",
|
||||
'--file', '/tmp/%Y-%m-%d-%D_%H:%i:%s.%t') },
|
||||
);
|
||||
|
||||
unlike(
|
||||
$output,
|
||||
qr/Cannot find encoding "utf8mb4"/,
|
||||
'Destination file does not fail due to missing utf8mb4'
|
||||
) or diag($output);
|
||||
|
||||
unlike(
|
||||
$output,
|
||||
qr/Cannot open :encoding(utf8mb4)/,
|
||||
'Destination file can be read if encodin utf8mb4 is used'
|
||||
) or diag($output);
|
||||
|
||||
# #############################################################################
|
||||
# Done.
|
||||
# #############################################################################
|
||||
diag(`rm -f /tmp/*.table_1`);
|
||||
$sb->wipe_clean($dbh);
|
||||
ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
|
||||
done_testing;
|
||||
exit;
|
18
t/pt-archiver/samples/pt-2279.sql
Normal file
18
t/pt-archiver/samples/pt-2279.sql
Normal file
@@ -0,0 +1,18 @@
|
||||
DROP TABLE IF EXISTS test.table_1;
|
||||
DROP TABLE IF EXISTS test.table_1_dest;
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
|
||||
CREATE TABLE test.table_1 (
|
||||
id int(11) NOT NULL,
|
||||
c1 varchar(20) DEFAULT NULL,
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
INSERT INTO test.table_1 VALUES(1, 'I love MySQL! 🐬');
|
||||
|
||||
CREATE TABLE test.table_1_dest (
|
||||
id int(11) NOT NULL,
|
||||
c1 varchar(10) DEFAULT NULL,
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
60
t/pt-mysql-summary/pt-2109.t
Normal file
60
t/pt-mysql-summary/pt-2109.t
Normal file
@@ -0,0 +1,60 @@
|
||||
#!/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 PerconaTest;
|
||||
use Sandbox;
|
||||
use DSNParser;
|
||||
require VersionParser;
|
||||
use Test::More;
|
||||
|
||||
local $ENV{PTDEBUG} = "";
|
||||
|
||||
my $dp = new DSNParser(opts=>$dsn_opts);
|
||||
my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
|
||||
my $dbh = $sb->get_dbh_for('master');
|
||||
my $has_keyring_plugin;
|
||||
|
||||
if ( !$dbh ) {
|
||||
plan skip_all => 'Cannot connect to sandbox master';
|
||||
}
|
||||
else {
|
||||
plan tests => 3;
|
||||
}
|
||||
|
||||
my $output;
|
||||
my $cnf = '/tmp/12345/my.sandbox.cnf';
|
||||
|
||||
my ($orig_sql_mode) = $dbh->selectrow_array(q{SELECT @@SQL_MODE});
|
||||
$dbh->do("SET GLOBAL SQL_MODE='ANSI_QUOTES'");
|
||||
|
||||
my $cmd = "$trunk/bin/pt-mysql-summary --sleep 1 -- --defaults-file=$cnf";
|
||||
|
||||
$output = `$cmd 2>&1`;
|
||||
|
||||
unlike(
|
||||
$output,
|
||||
qr/Unknown column 'keyring%' in 'where clause'/s,
|
||||
"pt-mysql-summary works fine with SQL Mode ANSI_QUOTES"
|
||||
);
|
||||
|
||||
unlike(
|
||||
$output,
|
||||
qr/You have an error in your SQL syntax.*wsrep_on/s,
|
||||
"pt-mysql-summary works fine with PXC and SQL Mode ANSI_QUOTES"
|
||||
);
|
||||
|
||||
# #############################################################################
|
||||
# Done.
|
||||
# #############################################################################
|
||||
$dbh->do("SET GLOBAL SQL_MODE='${orig_sql_mode}'");
|
||||
$sb->wipe_clean($dbh);
|
||||
ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
|
||||
exit;
|
@@ -97,6 +97,35 @@ like(
|
||||
"Security works"
|
||||
);
|
||||
|
||||
#
|
||||
# SQL Mode ANSI_QUOTES
|
||||
#
|
||||
|
||||
my ($orig_sql_mode) = $master_dbh->selectrow_array(q{SELECT @@SQL_MODE});
|
||||
$master_dbh->do("SET GLOBAL SQL_MODE='ANSI_QUOTES'");
|
||||
|
||||
$out = `$env $trunk/bin/$tool --sleep 1 --databases mysql 2>/dev/null -- --defaults-file=/tmp/12345/my.sandbox.cnf`;
|
||||
|
||||
like(
|
||||
$out,
|
||||
qr/Database Tables Views SPs Trigs Funcs FKs Partn\s+\Qmysql\E/,
|
||||
"--databases works with SQL Mode ANSI_QUOTES"
|
||||
);
|
||||
|
||||
like(
|
||||
$out,
|
||||
qr/# InnoDB #.*Version.*# MyISAM #/s,
|
||||
"InnoDB section present with SQL Mode ANSI_QUOTES"
|
||||
);
|
||||
|
||||
like(
|
||||
$out,
|
||||
qr/Users \| 2/,
|
||||
"Security works with SQL Mode ANSI_QUOTES"
|
||||
);
|
||||
|
||||
$master_dbh->do("SET GLOBAL SQL_MODE='${orig_sql_mode}'");
|
||||
|
||||
# --read-samples
|
||||
for my $i (2..9) {
|
||||
ok(
|
||||
|
@@ -696,21 +696,30 @@ SKIP: {
|
||||
qr/$skipping_str/s,
|
||||
"--skip-check-slave-lag",
|
||||
);
|
||||
}
|
||||
|
||||
# Use the same data than the previous test
|
||||
$master_dbh->do("DROP DATABASE IF EXISTS test");
|
||||
# Test for skip-check-slave-lag and empty replica port
|
||||
# Use the same data than the previous test
|
||||
$master_dbh->do("DROP DATABASE IF EXISTS test");
|
||||
|
||||
$sb->load_file('master', "$sample/bug-1613915.sql");
|
||||
$output = output(
|
||||
$sb->load_file('master', "$sample/bug-1613915.sql");
|
||||
$output = output(
|
||||
sub { pt_online_schema_change::main(@args, "$master_dsn,D=test,t=o1",
|
||||
'--execute',
|
||||
'--alter', "ADD COLUMN c INT",
|
||||
'--chunk-size', '10',
|
||||
'--skip-check-slave-lag', "h=127.0.0.1,P=".$sb->port_for('slave1'),
|
||||
'--skip-check-slave-lag', "h=127.0.0.1",
|
||||
),
|
||||
},
|
||||
);
|
||||
stderr => 1,
|
||||
);
|
||||
|
||||
unlike(
|
||||
$output,
|
||||
qr/Use of uninitialized value.*/,
|
||||
'No syntax error if port is missed in --skip-check-slave-lag DSN',
|
||||
) or diag($output);
|
||||
|
||||
}
|
||||
|
||||
# #############################################################################
|
||||
# Done.
|
||||
|
79
t/pt-online-schema-change/case-insensitive.t
Normal file
79
t/pt-online-schema-change/case-insensitive.t
Normal file
@@ -0,0 +1,79 @@
|
||||
#!/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 Time::HiRes qw(sleep);
|
||||
|
||||
use PerconaTest;
|
||||
use Sandbox;
|
||||
require "$trunk/bin/pt-online-schema-change";
|
||||
require VersionParser;
|
||||
|
||||
my $dp = new DSNParser(opts=>$dsn_opts);
|
||||
my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
|
||||
my $master_dbh = $sb->get_dbh_for('master');
|
||||
|
||||
if ( !$master_dbh ) {
|
||||
plan skip_all => 'Cannot connect to sandbox master';
|
||||
}
|
||||
|
||||
my @args = qw(--set-vars innodb_lock_wait_timeout=3);
|
||||
my $output = "";
|
||||
my $dsn = "h=127.1,P=12345,u=msandbox,p=msandbox";
|
||||
my $exit = 0;
|
||||
my $sample = "t/pt-online-schema-change/samples";
|
||||
|
||||
my $lower_case_table_names = $master_dbh->selectrow_array('SELECT @@lower_case_table_names');
|
||||
|
||||
if ( $lower_case_table_names == 0) {
|
||||
# Preparing test setup on Linux
|
||||
diag(`$trunk/sandbox/stop-sandbox 12348 >/dev/null`);
|
||||
diag(`EXTRA_DEFAULTS_FILE="$trunk/t/pt-online-schema-change/samples/lower_case_table_names_1.cnf" $trunk/sandbox/start-sandbox master 12348 >/dev/null`);
|
||||
|
||||
$master_dbh = $sb->get_dbh_for('master1');
|
||||
$dsn = "h=127.1,P=12348,u=msandbox,p=msandbox";
|
||||
$sb->load_file('master1', "$sample/basic_no_fks_innodb.sql");
|
||||
} else {
|
||||
$sb->load_file('master', "$sample/basic_no_fks_innodb.sql");
|
||||
}
|
||||
|
||||
($output, $exit) = full_output(
|
||||
sub { pt_online_schema_change::main(@args, "$dsn,D=pt_osc,t=T",
|
||||
'--alter', 'drop column d', '--execute') }
|
||||
);
|
||||
|
||||
like(
|
||||
$output,
|
||||
qr/Successfully altered/,
|
||||
"Table is altered using capital name 'T'"
|
||||
) or diag($output);
|
||||
|
||||
my $ddl = $master_dbh->selectrow_arrayref("show create table pt_osc.T");
|
||||
unlike(
|
||||
$ddl->[1],
|
||||
qr/^\s+["`]d["`]/m,
|
||||
"'D' column is dropped"
|
||||
);
|
||||
|
||||
is(
|
||||
$exit,
|
||||
0,
|
||||
"Exit 0"
|
||||
);
|
||||
|
||||
# #############################################################################
|
||||
# Done.
|
||||
# #############################################################################
|
||||
diag(`$trunk/sandbox/stop-sandbox 12348 >/dev/null`);
|
||||
$master_dbh = $sb->get_dbh_for('master');
|
||||
$sb->wipe_clean($master_dbh);
|
||||
ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
|
||||
done_testing;
|
114
t/pt-online-schema-change/plugin_before_die.t
Normal file
114
t/pt-online-schema-change/plugin_before_die.t
Normal file
@@ -0,0 +1,114 @@
|
||||
#!/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 Data::Dumper;
|
||||
use PerconaTest;
|
||||
use Sandbox;
|
||||
|
||||
require "$trunk/bin/pt-online-schema-change";
|
||||
|
||||
my $dp = new DSNParser(opts=>$dsn_opts);
|
||||
my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
|
||||
my $master_dbh = $sb->get_dbh_for('master');
|
||||
|
||||
if ( !$master_dbh ) {
|
||||
plan skip_all => 'Cannot connect to sandbox master';
|
||||
}
|
||||
|
||||
# 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.
|
||||
my $master_dsn = 'h=127.1,P=12345,u=msandbox,p=msandbox';
|
||||
my @args = (qw(--set-vars innodb_lock_wait_timeout=3));
|
||||
my $sample = "t/pt-online-schema-change/samples/";
|
||||
my $plugin = "$trunk/$sample/plugins";
|
||||
my $output;
|
||||
my $exit_status;
|
||||
|
||||
# ############################################################################
|
||||
# https://bugs.launchpad.net/percona-toolkit/+bug/1171653
|
||||
#
|
||||
# ############################################################################
|
||||
$sb->load_file('master', "$sample/basic_no_fks.sql");
|
||||
|
||||
# Should be greater than chunk-size and big enough, so plugin will trigger few times
|
||||
my $num_rows = 5000;
|
||||
diag("Loading $num_rows into the table. This might take some time.");
|
||||
diag(`util/mysql_random_data_load --host=127.0.0.1 --port=12345 --user=msandbox --password=msandbox pt_osc t $num_rows`);
|
||||
|
||||
($output, $exit_status) = full_output(
|
||||
sub { pt_online_schema_change::main(@args,
|
||||
"$master_dsn,D=pt_osc,t=t",
|
||||
"--alter", "CHARACTER SET utf9",
|
||||
'--plugin', "$plugin/before_die.pm",
|
||||
'--execute') },
|
||||
);
|
||||
|
||||
like(
|
||||
$output,
|
||||
qr/PLUGIN before_die/s,
|
||||
'Plugin before_die called for invalid ALTER command'
|
||||
);
|
||||
|
||||
like(
|
||||
$output,
|
||||
qr/Exit status: .*Unknown character set: 'utf9'/s,
|
||||
'Expected exit status for invalid ALTER command'
|
||||
);
|
||||
|
||||
($output, $exit_status) = full_output(
|
||||
sub { pt_online_schema_change::main(@args,
|
||||
"$master_dsn,D=pt_osc,t=t",
|
||||
"--alter", "ENGINE=InnoDB",
|
||||
'--plugin', "$plugin/before_die_after_nibble.pm",
|
||||
'--execute') },
|
||||
);
|
||||
|
||||
like(
|
||||
$output,
|
||||
qr/PLUGIN before_die/s,
|
||||
'Plugin before_die called for error while copying nibble'
|
||||
);
|
||||
|
||||
like(
|
||||
$output,
|
||||
qr/Exit status: .*You have an error in your SQL syntax/s,
|
||||
'Expected exit status for error while copying nibble'
|
||||
);
|
||||
|
||||
($output, $exit_status) = full_output(
|
||||
sub { pt_online_schema_change::main(@args,
|
||||
"$master_dsn,D=pt_osc,t=t",
|
||||
"--alter", "ENGINE=InnoDB",
|
||||
'--plugin', "$plugin/before_die_after_create.pm",
|
||||
'--execute') },
|
||||
);
|
||||
|
||||
like(
|
||||
$output,
|
||||
qr/PLUGIN before_die/s,
|
||||
'Plugin before_die called for _die call'
|
||||
);
|
||||
|
||||
like(
|
||||
$output,
|
||||
qr/Exit status: 4/s,
|
||||
'Expected exit status for table definition error handled in the _die call'
|
||||
);
|
||||
|
||||
# #############################################################################
|
||||
# Done.
|
||||
# #############################################################################
|
||||
$sb->wipe_clean($master_dbh);
|
||||
ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
|
||||
done_testing;
|
@@ -40,9 +40,13 @@ my $master_dsn = 'h=127.0.0.1,P=12345,u=msandbox,p=msandbox';
|
||||
my $slave_dsn1 = 'h=127.0.0.1,P=12346,u=msandbox,p=msandbox';
|
||||
my $slave_dsn2 = 'h=127.0.0.1,P=12347,u=msandbox,p=msandbox';
|
||||
my $sample = "t/pt-online-schema-change/samples";
|
||||
my ($orig_master_info_repository) = $slave_dbh1->selectrow_array(q{SELECT @@master_info_repository});
|
||||
my ($orig_relay_log_info_repository) = $slave_dbh1->selectrow_array(q{SELECT @@relay_log_info_repository});
|
||||
|
||||
$slave_dbh1->do("stop slave");
|
||||
$slave_dbh1->do("reset slave all");
|
||||
$slave_dbh1->do("SET GLOBAL master_info_repository='TABLE'");
|
||||
$slave_dbh1->do("SET GLOBAL relay_log_info_repository='TABLE'");
|
||||
$slave_dbh1->do("CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=12345, MASTER_USER = 'msandbox', MASTER_PASSWORD='msandbox' FOR CHANNEL 'channel1';");
|
||||
$slave_dbh1->do("start slave");
|
||||
|
||||
@@ -74,6 +78,8 @@ like(
|
||||
$slave_dbh1->do('STOP SLAVE');
|
||||
$master_dbh->do("RESET MASTER");
|
||||
$slave_dbh1->do('RESET SLAVE ALL');
|
||||
$slave_dbh1->do("SET GLOBAL master_info_repository='${orig_master_info_repository}'");
|
||||
$slave_dbh1->do("SET GLOBAL relay_log_info_repository='${orig_relay_log_info_repository}'");
|
||||
$slave_dbh1->do("CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=12345, MASTER_USER = 'msandbox', MASTER_PASSWORD='msandbox';");
|
||||
$slave_dbh1->do('START SLAVE');
|
||||
|
||||
|
@@ -0,0 +1,2 @@
|
||||
[mysqld]
|
||||
lower_case_table_names=1
|
@@ -96,6 +96,11 @@ sub before_drop_triggers {
|
||||
print "PLUGIN before_drop_triggers\n";
|
||||
}
|
||||
|
||||
sub before_die {
|
||||
my ($self, %args) = @_;
|
||||
print "PLUGIN before_die\n";
|
||||
}
|
||||
|
||||
sub before_exit {
|
||||
my ($self, %args) = @_;
|
||||
print "PLUGIN before_exit\n";
|
||||
|
20
t/pt-online-schema-change/samples/plugins/before_die.pm
Normal file
20
t/pt-online-schema-change/samples/plugins/before_die.pm
Normal file
@@ -0,0 +1,20 @@
|
||||
package pt_online_schema_change_plugin;
|
||||
|
||||
use strict;
|
||||
use warnings FATAL => 'all';
|
||||
use English qw(-no_match_vars);
|
||||
use constant PTDEBUG => $ENV{PTDEBUG} || 0;
|
||||
|
||||
sub new {
|
||||
my ($class, %args) = @_;
|
||||
my $self = { %args };
|
||||
return bless $self, $class;
|
||||
}
|
||||
|
||||
sub before_die {
|
||||
my ($self, %args) = @_;
|
||||
print "PLUGIN before_die\n";
|
||||
print "Exit status: $args{exit_status}\n";
|
||||
}
|
||||
|
||||
1;
|
@@ -0,0 +1,33 @@
|
||||
package pt_online_schema_change_plugin;
|
||||
|
||||
use strict;
|
||||
use warnings FATAL => 'all';
|
||||
use English qw(-no_match_vars);
|
||||
use constant PTDEBUG => $ENV{PTDEBUG} || 0;
|
||||
|
||||
sub new {
|
||||
my ($class, %args) = @_;
|
||||
my $self = { %args };
|
||||
return bless $self, $class;
|
||||
}
|
||||
|
||||
sub before_die {
|
||||
my ($self, %args) = @_;
|
||||
print "PLUGIN before_die\n";
|
||||
print "Exit status: $args{exit_status}\n";
|
||||
}
|
||||
|
||||
sub after_create_new_table {
|
||||
my ($self, %args) = @_;
|
||||
|
||||
print "PLUGIN after_create_new_table\n";
|
||||
|
||||
my $dbh = $self->{aux_cxn}->dbh;
|
||||
my $new_tbl = $args{new_tbl}->{name};
|
||||
|
||||
# Remove PRIMARY KEY, so pt-osc fails with an error and handles
|
||||
# it in the _die call
|
||||
$dbh->do("ALTER TABLE ${new_tbl} MODIFY COLUMN id INT NOT NULL, DROP PRIMARY KEY");
|
||||
}
|
||||
|
||||
1;
|
@@ -0,0 +1,32 @@
|
||||
package pt_online_schema_change_plugin;
|
||||
|
||||
use strict;
|
||||
use warnings FATAL => 'all';
|
||||
use English qw(-no_match_vars);
|
||||
use constant PTDEBUG => $ENV{PTDEBUG} || 0;
|
||||
|
||||
sub new {
|
||||
my ($class, %args) = @_;
|
||||
my $self = { %args };
|
||||
return bless $self, $class;
|
||||
}
|
||||
|
||||
sub before_die {
|
||||
my ($self, %args) = @_;
|
||||
print "PLUGIN before_die\n";
|
||||
print "Exit status: $args{exit_status}\n";
|
||||
}
|
||||
|
||||
sub on_copy_rows_after_nibble {
|
||||
my ($self, %args) = @_;
|
||||
my $tbl = $args{tbl};
|
||||
print "PLUGIN on_copy_rows_after_nibble\n";
|
||||
if ($tbl->{row_cnt} > 1000) {
|
||||
my $dbh = $self->{aux_cxn}->dbh;
|
||||
|
||||
# Run invalid query to get error
|
||||
$dbh->do("SELECT * FRO " . $tbl->{name});
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
32
t/pt-pmp/samples/stacktrace-pt-2211.in
Normal file
32
t/pt-pmp/samples/stacktrace-pt-2211.in
Normal file
@@ -0,0 +1,32 @@
|
||||
Thread 69 (Thread 0x7fd4b0049640 (LWP 15380)):
|
||||
#0 0x00007fd4b5c36dc0 in __lll_lock_wait () from /lib64/libpthread.so.0
|
||||
#1 0x00007fd4b5c31703 in __pthread_mutex_cond_lock () from /lib64/libpthread.so.0
|
||||
#2 0x0000000001fa7130 in os_event::wait (this=0x7fd4ac8afbe8) at /home/zongzhi.czz/git/mysql-8.0/storage/innobase/os/os0event.cc:189
|
||||
#3 os_event::wait_low (this=0x7fd4ac8afbe8, reset_sig_count=3187477) at /home/zongzhi.czz/git/mysql-8.0/storage/innobase/os/os0event.cc:372
|
||||
#4 0x0000000001fa743a in os_event_wait_low (event=<optimized out>, reset_sig_count=<optimized out>) at /home/zongzhi.czz/git/mysql-8.0/storage/innobase/os/os0event.cc:608
|
||||
#5 0x000000000206e390 in sync_array_wait_event (arr=arr@entry=0x7fd4ac009ab8, cell=@0x7fd4b0044658: 0x7fd4b23b8028) at /home/zongzhi.czz/git/mysql-8.0/storage/innobase/sync/sync0arr.cc:444
|
||||
#6 0x0000000002071b5a in rw_lock_sx_lock_func (lock=0x7fd4ac85b2d8, pass=pass@entry=0, file_name=file_name@entry=0x2cfe1f0 "/home/zongzhi.czz/git/mysql-8.0/storage/innobase/btr/btr0cur.cc", line=line@entry=836) at /home/zongzhi.czz/git/mysql-8.0/storage/innobase/sync/sync0rw.cc:829
|
||||
#7 0x00000000020f2ae5 in pfs_rw_lock_sx_lock_func (lock=lock@entry=0x7fd4ac85b2d8, file_name=file_name@entry=0x2cfe1f0 "/home/zongzhi.czz/git/mysql-8.0/storage/innobase/btr/btr0cur.cc", line=line@entry=836, pass=0) at /home/zongzhi.czz/git/mysql-8.0/storage/innobase/include/sync0rw.ic:736
|
||||
#8 0x00000000020fe967 in mtr_t::sx_lock (line=836, file=0x2cfe1f0 "/home/zongzhi.czz/git/mysql-8.0/storage/innobase/btr/btr0cur.cc", lock=<optimized out>, this=0x7fd4b0045de0) at /home/zongzhi.czz/git/mysql-8.0/storage/innobase/include/mtr0mtr.ic:242
|
||||
#9 btr_cur_search_to_nth_level (index=index@entry=0x7fd4ac85b188, level=level@entry=0, tuple=tuple@entry=0x7f8e4401ddd8, mode=mode@entry=PAGE_CUR_LE, latch_mode=latch_mode@entry=33, cursor=cursor@entry=0x7fd4b00456a0, has_search_latch=0, file=0x2cf3498 "/home/zongzhi.czz/git/mysql-8.0/storage/innobase/row/row0ins.cc", line=2404, mtr=0x7fd4b0045de0) at /home/zongzhi.czz/git/mysql-8.0/storage/innobase/btr/btr0cur.cc:836
|
||||
#10 0x0000000001fec091 in btr_pcur_t::open (line=2404, file=0x2cf3498 "/home/zongzhi.czz/git/mysql-8.0/storage/innobase/row/row0ins.cc", mtr=0x7fd4b0045de0, latch_mode=33, mode=PAGE_CUR_LE, tuple=0x7f8e4401ddd8, level=0, index=0x7fd4ac85b188, this=0x7fd4b00456a0) at /home/zongzhi.czz/git/mysql-8.0/storage/innobase/include/btr0pcur.h:631#11 row_ins_clust_index_entry_low (flags=<optimized out>, mode=mode@entry=33, index=index@entry=0x7fd4ac85b188, n_uniq=n_uniq@entry=1, entry=entry@entry=0x7f8e4401ddd8, n_ext=n_ext@entry=0, thr=<optimized out>, dup_chk_only=<optimized out>) at /home/zongzhi.czz/git/mysql-8.0/storage/innobase/row/row0ins.cc:2404
|
||||
#12 0x0000000001ff2493 in row_ins_clust_index_entry (index=0x7fd4ac85b188, entry=entry@entry=0x7f8e4401ddd8, thr=thr@entry=0x7f8e4401d358, n_ext=n_ext@entry=0, dup_chk_only=dup_chk_only@entry=false) at /home/zongzhi.czz/git/mysql-8.0/storage/innobase/row/row0ins.cc:3128
|
||||
#13 0x0000000001ff351f in row_ins_index_entry (thr=0x7f8e4401d358, multi_val_pos=@0x7f8e4401d0d0: 0, entry=0x7f8e4401ddd8, index=<optimized out>) at /home/zongzhi.czz/git/mysql-8.0/storage/innobase/row/row0ins.cc:3295
|
||||
#14 row_ins_index_entry_step (thr=0x7f8e4401d358, node=0x7f8e4401d018) at /home/zongzhi.czz/git/mysql-8.0/storage/innobase/row/row0ins.cc:3432
|
||||
#15 row_ins (thr=0x7f8e4401d358, node=0x7f8e4401d018) at /home/zongzhi.czz/git/mysql-8.0/storage/innobase/row/row0ins.cc:3551
|
||||
#16 row_ins_step (thr=thr@entry=0x7f8e4401d358) at /home/zongzhi.czz/git/mysql-8.0/storage/innobase/row/row0ins.cc:3675
|
||||
#17 0x0000000002004cac in row_insert_for_mysql_using_ins_graph (mysql_rec=mysql_rec@entry=0x7f8e4400ae58 "\377\064y\002\a\005\250X272262038040-36454966916-40203159830-44114922317-57338906833-90459983776-67841547117-58042251992-67222347817-09932413691 62585243489-83708933349-63627342446-67953416665-46385069319 ", prebuilt=<optimized out>) at /home/zongzhi.czz/git/mysql-8.0/storage/innobase/row/row0mysql.cc:1580
|
||||
#18 0x0000000002007534 in row_insert_for_mysql (mysql_rec=mysql_rec@entry=0x7f8e4400ae58 "\377\064y\002\a\005\250X272262038040-36454966916-40203159830-44114922317-57338906833-90459983776-67841547117-58042251992-67222347817-09932413691 62585243489-83708933349-63627342446-67953416665-46385069319 ", prebuilt=<optimized out>) at /home/zongzhi.czz/git/mysql-8.0/storage/innobase/row/row0mysql.cc:1706
|
||||
#19 0x0000000001ee9b99 in ha_innobase::write_row (this=0x7f8e4401b138, record=0x7f8e4400ae58 "\377\064y\002\a\005\250X272262038040-36454966916-40203159830-44114922317-57338906833-90459983776-67841547117-58042251992-67222347817-09932413691 62585243489-83708933349-63627342446-67953416665-46385069319 ") at /home/zongzhi.czz/git/mysql-8.0/storage/innobase/handler/ha_innodb.cc:8581
|
||||
#20 0x0000000001018054 in handler::ha_write_row (this=0x7f8e4401b138, buf=0x7f8e4400ae58 "\377\064y\002\a\005\250X272262038040-36454966916-40203159830-44114922317-57338906833-90459983776-67841547117-58042251992-67222347817-09932413691 62585243489-83708933349-63627342446-67953416665-46385069319 ") at /home/zongzhi.czz/git/mysql-8.0/sql/handler.cc:7740
|
||||
#21 0x0000000001208d25 in write_record (thd=thd@entry=0x7f8e44000f10, table=table@entry=0x7f8e4400a4b0, info=info@entry=0x7fd4b0046a10, update=update@entry=0x7fd4b0046a90) at /home/zongzhi.czz/git/mysql-8.0/sql/sql_insert.cc:1946
|
||||
#22 0x0000000001209e81 in Sql_cmd_insert_values::execute_inner (this=0x7f8e4400e2b0, thd=0x7f8e44000f10) at /home/zongzhi.czz/git/mysql-8.0/sql/sql_insert.cc:614
|
||||
#23 0x0000000000e22e78 in Sql_cmd_dml::execute (this=0x7f8e4400e2b0, thd=0x7f8e44000f10) at /home/zongzhi.czz/git/mysql-8.0/sql/sql_select.cc:704
|
||||
#24 0x0000000000dd5da9 in mysql_execute_command (thd=thd@entry=0x7f8e44000f10, first_level=first_level@entry=true) at /home/zongzhi.czz/git/mysql-8.0/sql/sql_parse.cc:3450
|
||||
#25 0x0000000000dd80c1 in mysql_parse (thd=thd@entry=0x7f8e44000f10, parser_state=parser_state@entry=0x7fd4b0048450) at /home/zongzhi.czz/git/mysql-8.0/sql/sql_parse.cc:5257
|
||||
#26 0x0000000000dda8ad in dispatch_command (thd=thd@entry=0x7f8e44000f10, com_data=com_data@entry=0x7fd4b0048b40, command=COM_QUERY) at /home/zongzhi.czz/git/mysql-8.0/sql/sql_parse.cc:1765
|
||||
#27 0x0000000000ddb34c in do_command (thd=thd@entry=0x7f8e44000f10) at /home/zongzhi.czz/git/mysql-8.0/sql/sql_parse.cc:1273
|
||||
#28 0x0000000000eea308 in handle_connection (arg=arg@entry=0x3e8c480) at /home/zongzhi.czz/git/mysql-8.0/sql/conn_handler/connection_handler_per_thread.cc:302
|
||||
#29 0x0000000002303059 in pfs_spawn_thread (arg=0x3f025d0) at /home/zongzhi.czz/git/mysql-8.0/storage/perfschema/pfs.cc:2854
|
||||
#30 0x00007fd4b5c2d3f9 in start_thread () from /lib64/libpthread.so.0
|
||||
#31 0x00007fd4b4ca4303 in clone () from /lib64/libc.so.6
|
1
t/pt-pmp/samples/stacktrace-pt-2211.out
Normal file
1
t/pt-pmp/samples/stacktrace-pt-2211.out
Normal file
@@ -0,0 +1 @@
|
||||
1 __lll_lock_wait(libpthread.so.0),__pthread_mutex_cond_lock(libpthread.so.0),os_event::wait(os0event.cc:189),os_event::wait_low(os0event.cc:372),os_event_wait_low(os0event.cc:608),sync_array_wait_event(sync0arr.cc:444),rw_lock_sx_lock_func(sync0rw.cc:829),pfs_rw_lock_sx_lock_func(sync0rw.ic:736),mtr_t::sx_lock(mtr0mtr.ic:242),btr_cur_search_to_nth_level(btr0cur.cc:836),btr_pcur_t::open(row0ins.cc:2404),row_ins_clust_index_entry(row0ins.cc:3128),row_ins_index_entry(row0ins.cc:3295),row_ins_index_entry_step(row0ins.cc:3432),row_ins(row0ins.cc:3551),row_ins_step(row0ins.cc:3675),row_insert_for_mysql_using_ins_graph(row0mysql.cc:1580),row_insert_for_mysql(row0mysql.cc:1706),ha_innobase::write_row(ha_innodb.cc:8581),handler::ha_write_row(handler.cc:7740),write_record(sql_insert.cc:1946),Sql_cmd_insert_values::execute_inner(sql_insert.cc:614),Sql_cmd_dml::execute(sql_select.cc:704),mysql_execute_command(sql_parse.cc:3450),mysql_parse(sql_parse.cc:5257),dispatch_command(sql_parse.cc:1765),do_command(sql_parse.cc:1273),handle_connection(connection_handler_per_thread.cc:302),pfs_spawn_thread(pfs.cc:2854),start_thread(libpthread.so.0),clone(libc.so.6)
|
@@ -5,5 +5,5 @@
|
||||
3 pthread_cond_wait,MYSQL_LOG::wait_for_update
|
||||
1 select(libc.so.6),handle_connections_sockets
|
||||
1 do_sigwait(libpthread.so.0),sigwait(libpthread.so.0)
|
||||
1 btr_search_guess_on_hash(libc.so.6),btr_cur_search_to_nth_level
|
||||
1 btr_search_guess_on_hash,btr_cur_search_to_nth_level
|
||||
1 btr_cur_search_to_nth_level,btr_estimate_n_rows_in_range
|
||||
|
@@ -1,5 +1,5 @@
|
||||
35 pthread_cond_wait,end_thread,handle_one_connection,start_thread(libpthread.so.0),clone(libc.so.6)
|
||||
20 read(libpthread.so.0),read(unistd.h:35),vio_read(unistd.h:35),my_real_read,my_net_read,handle_one_connection,start_thread(libpthread.so.0),clone(libc.so.6)
|
||||
20 read(libpthread.so.0),read(unistd.h:35),vio_read,my_real_read,my_net_read,handle_one_connection,start_thread(libpthread.so.0),clone(libc.so.6)
|
||||
18 pthread_cond_wait,os_event_wait_low,os_aio_simulated_handle,fil_aio_wait,io_handler_thread,start_thread(libpthread.so.0),clone(libc.so.6)
|
||||
3 pthread_cond_wait,MYSQL_LOG::wait_for_update,mysql_binlog_send,dispatch_command,handle_one_connection,start_thread(libpthread.so.0),clone(libc.so.6)
|
||||
1 select(libc.so.6),os_thread_sleep,srv_master_thread,start_thread(libpthread.so.0),clone(libc.so.6)
|
||||
@@ -7,5 +7,5 @@
|
||||
1 select(libc.so.6),os_thread_sleep,srv_error_monitor_thread,start_thread(libpthread.so.0),clone(libc.so.6)
|
||||
1 select(libc.so.6),handle_connections_sockets,main
|
||||
1 do_sigwait(libpthread.so.0),sigwait(libpthread.so.0),signal_hand,start_thread(libpthread.so.0),clone(libc.so.6)
|
||||
1 btr_search_guess_on_hash(libc.so.6),btr_cur_search_to_nth_level,btr_pcur_open_with_no_init,row_search_for_mysql,ha_innobase::index_read,join_read_always_key,sub_select,evaluate_join_record,sub_select,evaluate_join_record,sub_select,evaluate_join_record,sub_select,evaluate_join_record,sub_select,evaluate_join_record,sub_select,do_select,JOIN::exec,mysql_select,handle_select,mysql_execute_command,mysql_parse,dispatch_command,handle_one_connection,start_thread(libpthread.so.0),clone(libc.so.6)
|
||||
1 btr_search_guess_on_hash,btr_cur_search_to_nth_level,btr_pcur_open_with_no_init,row_search_for_mysql,ha_innobase::index_read,join_read_always_key,sub_select,evaluate_join_record,sub_select,evaluate_join_record,sub_select,evaluate_join_record,sub_select,evaluate_join_record,sub_select,evaluate_join_record,sub_select,do_select,JOIN::exec,mysql_select,handle_select,mysql_execute_command,mysql_parse,dispatch_command,handle_one_connection,start_thread(libpthread.so.0),clone(libc.so.6)
|
||||
1 btr_cur_search_to_nth_level,btr_estimate_n_rows_in_range,ha_innobase::records_in_range,check_quick_keys,check_quick_keys,check_quick_keys,check_quick_keys,check_quick_keys,check_quick_keys,check_quick_keys,check_quick_keys,check_quick_keys,check_quick_keys,check_quick_keys,check_quick_select,get_key_scans_params,SQL_SELECT::test_quick_select,get_quick_record_count,make_join_statistics,JOIN::optimize,mysql_select,handle_select,mysql_execute_command,mysql_parse,dispatch_command,handle_one_connection,start_thread(libpthread.so.0),clone(libc.so.6)
|
||||
|
@@ -45,6 +45,27 @@ ok(
|
||||
),
|
||||
'Analysis for slow007 with --explain, no rows',
|
||||
);
|
||||
|
||||
# output=json
|
||||
|
||||
SKIP: {
|
||||
skip "output=json tests require 5.7" unless $sandbox_version ge '5.7';
|
||||
my $jq = `which jq`;
|
||||
chomp $jq;
|
||||
skip "output=json tests require jq" unless -x "$jq";
|
||||
|
||||
ok(
|
||||
no_diff(
|
||||
sub { pt_query_digest::main(@args, '--output=json',
|
||||
"$trunk/t/lib/samples/slowlogs/slow007.txt") },
|
||||
( $sandbox_version ge '8.0' ? "t/pt-query-digest/samples/slow007_explain_json_1-80.txt"
|
||||
: "t/pt-query-digest/samples/slow007_explain_json_1-57.txt"),
|
||||
post_pipe => 'jq -S .',
|
||||
),
|
||||
'Analysis for slow007 with --explain and --output=json, no rows',
|
||||
);
|
||||
}
|
||||
|
||||
# Normalish output from EXPLAIN.
|
||||
$dbh->do("insert into trees values ('apple'),('orange'),('banana')");
|
||||
|
||||
@@ -60,6 +81,26 @@ ok(
|
||||
'Analysis for slow007 with --explain',
|
||||
);
|
||||
|
||||
# output=json
|
||||
|
||||
SKIP: {
|
||||
skip "output=json tests require 5.7" unless $sandbox_version ge '5.7';
|
||||
my $jq = `which jq`;
|
||||
chomp $jq;
|
||||
skip "output=json tests require jq" unless -x "$jq";
|
||||
|
||||
ok(
|
||||
no_diff(
|
||||
sub { pt_query_digest::main(@args, '--output=json',
|
||||
"$trunk/t/lib/samples/slowlogs/slow007.txt") },
|
||||
( $sandbox_version ge '8.0' ? "t/pt-query-digest/samples/slow007_explain_json_2-80.txt"
|
||||
: "t/pt-query-digest/samples/slow007_explain_json_2-57.txt"),
|
||||
post_pipe => 'jq -S .',
|
||||
),
|
||||
'Analysis for slow007 with --explain and --output=json',
|
||||
);
|
||||
}
|
||||
|
||||
# #############################################################################
|
||||
# Issue 1141: Add "spark charts" to mk-query-digest profile
|
||||
# #############################################################################
|
||||
|
216
t/pt-query-digest/samples/slow007_explain_json_1-57.txt
Normal file
216
t/pt-query-digest/samples/slow007_explain_json_1-57.txt
Normal file
@@ -0,0 +1,216 @@
|
||||
{
|
||||
"classes": [
|
||||
{
|
||||
"attribute": "fingerprint",
|
||||
"checksum": "88F3D65BE48113F18E306CDB7A800841",
|
||||
"distillate": "SELECT trees",
|
||||
"example": {
|
||||
"Query_time": "0.000012",
|
||||
"explain": "# *************************** 1. row ***************************\n# id: 1\n# select_type: SIMPLE\n# table: trees\n# partitions: NULL\n# type: index\n# possible_keys: NULL\n# key: fruit\n# key_len: 27\n# ref: NULL\n# rows: 1\n# filtered: 100.00\n# Extra: Using index\n",
|
||||
"query": "SELECT fruit FROM trees",
|
||||
"ts": "2007-12-18 11:48:27"
|
||||
},
|
||||
"fingerprint": "select fruit from trees",
|
||||
"histograms": {
|
||||
"Query_time": [
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
]
|
||||
},
|
||||
"metrics": {
|
||||
"Filesort": {
|
||||
"yes": "0"
|
||||
},
|
||||
"Filesort_on_disk": {
|
||||
"yes": "0"
|
||||
},
|
||||
"Full_join": {
|
||||
"yes": "0"
|
||||
},
|
||||
"Full_scan": {
|
||||
"yes": "0"
|
||||
},
|
||||
"Lock_time": {
|
||||
"avg": "0.000000",
|
||||
"max": "0.000000",
|
||||
"median": "0.000000",
|
||||
"min": "0.000000",
|
||||
"pct": "1.000000",
|
||||
"pct_95": "0.000000",
|
||||
"stddev": "0.000000",
|
||||
"sum": "0.000000"
|
||||
},
|
||||
"Merge_passes": {
|
||||
"avg": "0",
|
||||
"max": "0",
|
||||
"median": "0",
|
||||
"min": "0",
|
||||
"pct": "1",
|
||||
"pct_95": "0",
|
||||
"stddev": "0",
|
||||
"sum": "0"
|
||||
},
|
||||
"QC_Hit": {
|
||||
"yes": "0"
|
||||
},
|
||||
"Query_length": {
|
||||
"avg": "23",
|
||||
"max": "23",
|
||||
"median": "23",
|
||||
"min": "23",
|
||||
"pct": "1",
|
||||
"pct_95": "23",
|
||||
"stddev": "0",
|
||||
"sum": "23"
|
||||
},
|
||||
"Query_time": {
|
||||
"avg": "0.000012",
|
||||
"max": "0.000012",
|
||||
"median": "0.000012",
|
||||
"min": "0.000012",
|
||||
"pct": "1.000000",
|
||||
"pct_95": "0.000012",
|
||||
"stddev": "0.000000",
|
||||
"sum": "0.000012"
|
||||
},
|
||||
"Rows_examined": {
|
||||
"avg": "0",
|
||||
"max": "0",
|
||||
"median": "0",
|
||||
"min": "0",
|
||||
"pct": "1",
|
||||
"pct_95": "0",
|
||||
"stddev": "0",
|
||||
"sum": "0"
|
||||
},
|
||||
"Rows_sent": {
|
||||
"avg": "0",
|
||||
"max": "0",
|
||||
"median": "0",
|
||||
"min": "0",
|
||||
"pct": "1",
|
||||
"pct_95": "0",
|
||||
"stddev": "0",
|
||||
"sum": "0"
|
||||
},
|
||||
"Tmp_table": {
|
||||
"yes": "0"
|
||||
},
|
||||
"Tmp_table_on_disk": {
|
||||
"yes": "0"
|
||||
},
|
||||
"db": {
|
||||
"value": "food"
|
||||
},
|
||||
"host": {
|
||||
"value": ""
|
||||
},
|
||||
"user": {
|
||||
"value": "[SQL_SLAVE]"
|
||||
}
|
||||
},
|
||||
"query_count": 1,
|
||||
"tables": [
|
||||
{
|
||||
"create": "SHOW CREATE TABLE `food`.`trees`\\G",
|
||||
"status": "SHOW TABLE STATUS FROM `food` LIKE 'trees'\\G"
|
||||
}
|
||||
],
|
||||
"ts_max": "2007-12-18 11:48:27",
|
||||
"ts_min": "2007-12-18 11:48:27"
|
||||
}
|
||||
],
|
||||
"global": {
|
||||
"files": [
|
||||
{
|
||||
"name": "/home/sveta/src/percona/percona-toolkit/t/lib/samples/slowlogs/slow007.txt",
|
||||
"size": 368
|
||||
}
|
||||
],
|
||||
"metrics": {
|
||||
"Filesort": {
|
||||
"cnt": "0"
|
||||
},
|
||||
"Filesort_on_disk": {
|
||||
"cnt": "0"
|
||||
},
|
||||
"Full_join": {
|
||||
"cnt": "0"
|
||||
},
|
||||
"Full_scan": {
|
||||
"cnt": "0"
|
||||
},
|
||||
"Lock_time": {
|
||||
"avg": "0.000000",
|
||||
"max": "0.000000",
|
||||
"median": "0.000000",
|
||||
"min": "0.000000",
|
||||
"pct_95": "0.000000",
|
||||
"stddev": "0.000000",
|
||||
"sum": "0.000000"
|
||||
},
|
||||
"Merge_passes": {
|
||||
"avg": "0",
|
||||
"max": "0",
|
||||
"median": "0",
|
||||
"min": "0",
|
||||
"pct_95": "0",
|
||||
"stddev": "0",
|
||||
"sum": "0"
|
||||
},
|
||||
"QC_Hit": {
|
||||
"cnt": "0"
|
||||
},
|
||||
"Query_length": {
|
||||
"avg": "23",
|
||||
"max": "23",
|
||||
"median": "23",
|
||||
"min": "23",
|
||||
"pct_95": "23",
|
||||
"stddev": "0",
|
||||
"sum": "23"
|
||||
},
|
||||
"Query_time": {
|
||||
"avg": "0.000012",
|
||||
"max": "0.000012",
|
||||
"median": "0.000012",
|
||||
"min": "0.000012",
|
||||
"pct_95": "0.000012",
|
||||
"stddev": "0.000000",
|
||||
"sum": "0.000012"
|
||||
},
|
||||
"Rows_examined": {
|
||||
"avg": "0",
|
||||
"max": "0",
|
||||
"median": "0",
|
||||
"min": "0",
|
||||
"pct_95": "0",
|
||||
"stddev": "0",
|
||||
"sum": "0"
|
||||
},
|
||||
"Rows_sent": {
|
||||
"avg": "0",
|
||||
"max": "0",
|
||||
"median": "0",
|
||||
"min": "0",
|
||||
"pct_95": "0",
|
||||
"stddev": "0",
|
||||
"sum": "0"
|
||||
},
|
||||
"Tmp_table": {
|
||||
"cnt": "0"
|
||||
},
|
||||
"Tmp_table_on_disk": {
|
||||
"cnt": "0"
|
||||
}
|
||||
},
|
||||
"query_count": 1,
|
||||
"unique_query_count": 1
|
||||
}
|
||||
}
|
216
t/pt-query-digest/samples/slow007_explain_json_1-80.txt
Normal file
216
t/pt-query-digest/samples/slow007_explain_json_1-80.txt
Normal file
@@ -0,0 +1,216 @@
|
||||
{
|
||||
"classes": [
|
||||
{
|
||||
"attribute": "fingerprint",
|
||||
"checksum": "88F3D65BE48113F18E306CDB7A800841",
|
||||
"distillate": "SELECT trees",
|
||||
"example": {
|
||||
"Query_time": "0.000012",
|
||||
"explain": "# *************************** 1. row ***************************\n# id: 1\n# select_type: SIMPLE\n# table: trees\n# partitions: NULL\n# type: index\n# possible_keys: NULL\n# key: fruit\n# key_len: 99\n# ref: NULL\n# rows: 1\n# filtered: 100.00\n# Extra: Using index\n",
|
||||
"query": "SELECT fruit FROM trees",
|
||||
"ts": "2007-12-18 11:48:27"
|
||||
},
|
||||
"fingerprint": "select fruit from trees",
|
||||
"histograms": {
|
||||
"Query_time": [
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
]
|
||||
},
|
||||
"metrics": {
|
||||
"Filesort": {
|
||||
"yes": "0"
|
||||
},
|
||||
"Filesort_on_disk": {
|
||||
"yes": "0"
|
||||
},
|
||||
"Full_join": {
|
||||
"yes": "0"
|
||||
},
|
||||
"Full_scan": {
|
||||
"yes": "0"
|
||||
},
|
||||
"Lock_time": {
|
||||
"avg": "0.000000",
|
||||
"max": "0.000000",
|
||||
"median": "0.000000",
|
||||
"min": "0.000000",
|
||||
"pct": "1.000000",
|
||||
"pct_95": "0.000000",
|
||||
"stddev": "0.000000",
|
||||
"sum": "0.000000"
|
||||
},
|
||||
"Merge_passes": {
|
||||
"avg": "0",
|
||||
"max": "0",
|
||||
"median": "0",
|
||||
"min": "0",
|
||||
"pct": "1",
|
||||
"pct_95": "0",
|
||||
"stddev": "0",
|
||||
"sum": "0"
|
||||
},
|
||||
"QC_Hit": {
|
||||
"yes": "0"
|
||||
},
|
||||
"Query_length": {
|
||||
"avg": "23",
|
||||
"max": "23",
|
||||
"median": "23",
|
||||
"min": "23",
|
||||
"pct": "1",
|
||||
"pct_95": "23",
|
||||
"stddev": "0",
|
||||
"sum": "23"
|
||||
},
|
||||
"Query_time": {
|
||||
"avg": "0.000012",
|
||||
"max": "0.000012",
|
||||
"median": "0.000012",
|
||||
"min": "0.000012",
|
||||
"pct": "1.000000",
|
||||
"pct_95": "0.000012",
|
||||
"stddev": "0.000000",
|
||||
"sum": "0.000012"
|
||||
},
|
||||
"Rows_examined": {
|
||||
"avg": "0",
|
||||
"max": "0",
|
||||
"median": "0",
|
||||
"min": "0",
|
||||
"pct": "1",
|
||||
"pct_95": "0",
|
||||
"stddev": "0",
|
||||
"sum": "0"
|
||||
},
|
||||
"Rows_sent": {
|
||||
"avg": "0",
|
||||
"max": "0",
|
||||
"median": "0",
|
||||
"min": "0",
|
||||
"pct": "1",
|
||||
"pct_95": "0",
|
||||
"stddev": "0",
|
||||
"sum": "0"
|
||||
},
|
||||
"Tmp_table": {
|
||||
"yes": "0"
|
||||
},
|
||||
"Tmp_table_on_disk": {
|
||||
"yes": "0"
|
||||
},
|
||||
"db": {
|
||||
"value": "food"
|
||||
},
|
||||
"host": {
|
||||
"value": ""
|
||||
},
|
||||
"user": {
|
||||
"value": "[SQL_SLAVE]"
|
||||
}
|
||||
},
|
||||
"query_count": 1,
|
||||
"tables": [
|
||||
{
|
||||
"create": "SHOW CREATE TABLE `food`.`trees`\\G",
|
||||
"status": "SHOW TABLE STATUS FROM `food` LIKE 'trees'\\G"
|
||||
}
|
||||
],
|
||||
"ts_max": "2007-12-18 11:48:27",
|
||||
"ts_min": "2007-12-18 11:48:27"
|
||||
}
|
||||
],
|
||||
"global": {
|
||||
"files": [
|
||||
{
|
||||
"name": "/home/sveta/src/percona/percona-toolkit/t/lib/samples/slowlogs/slow007.txt",
|
||||
"size": 368
|
||||
}
|
||||
],
|
||||
"metrics": {
|
||||
"Filesort": {
|
||||
"cnt": "0"
|
||||
},
|
||||
"Filesort_on_disk": {
|
||||
"cnt": "0"
|
||||
},
|
||||
"Full_join": {
|
||||
"cnt": "0"
|
||||
},
|
||||
"Full_scan": {
|
||||
"cnt": "0"
|
||||
},
|
||||
"Lock_time": {
|
||||
"avg": "0.000000",
|
||||
"max": "0.000000",
|
||||
"median": "0.000000",
|
||||
"min": "0.000000",
|
||||
"pct_95": "0.000000",
|
||||
"stddev": "0.000000",
|
||||
"sum": "0.000000"
|
||||
},
|
||||
"Merge_passes": {
|
||||
"avg": "0",
|
||||
"max": "0",
|
||||
"median": "0",
|
||||
"min": "0",
|
||||
"pct_95": "0",
|
||||
"stddev": "0",
|
||||
"sum": "0"
|
||||
},
|
||||
"QC_Hit": {
|
||||
"cnt": "0"
|
||||
},
|
||||
"Query_length": {
|
||||
"avg": "23",
|
||||
"max": "23",
|
||||
"median": "23",
|
||||
"min": "23",
|
||||
"pct_95": "23",
|
||||
"stddev": "0",
|
||||
"sum": "23"
|
||||
},
|
||||
"Query_time": {
|
||||
"avg": "0.000012",
|
||||
"max": "0.000012",
|
||||
"median": "0.000012",
|
||||
"min": "0.000012",
|
||||
"pct_95": "0.000012",
|
||||
"stddev": "0.000000",
|
||||
"sum": "0.000012"
|
||||
},
|
||||
"Rows_examined": {
|
||||
"avg": "0",
|
||||
"max": "0",
|
||||
"median": "0",
|
||||
"min": "0",
|
||||
"pct_95": "0",
|
||||
"stddev": "0",
|
||||
"sum": "0"
|
||||
},
|
||||
"Rows_sent": {
|
||||
"avg": "0",
|
||||
"max": "0",
|
||||
"median": "0",
|
||||
"min": "0",
|
||||
"pct_95": "0",
|
||||
"stddev": "0",
|
||||
"sum": "0"
|
||||
},
|
||||
"Tmp_table": {
|
||||
"cnt": "0"
|
||||
},
|
||||
"Tmp_table_on_disk": {
|
||||
"cnt": "0"
|
||||
}
|
||||
},
|
||||
"query_count": 1,
|
||||
"unique_query_count": 1
|
||||
}
|
||||
}
|
216
t/pt-query-digest/samples/slow007_explain_json_2-57.txt
Normal file
216
t/pt-query-digest/samples/slow007_explain_json_2-57.txt
Normal file
@@ -0,0 +1,216 @@
|
||||
{
|
||||
"classes": [
|
||||
{
|
||||
"attribute": "fingerprint",
|
||||
"checksum": "88F3D65BE48113F18E306CDB7A800841",
|
||||
"distillate": "SELECT trees",
|
||||
"example": {
|
||||
"Query_time": "0.000012",
|
||||
"explain": "# *************************** 1. row ***************************\n# id: 1\n# select_type: SIMPLE\n# table: trees\n# partitions: NULL\n# type: index\n# possible_keys: NULL\n# key: fruit\n# key_len: 27\n# ref: NULL\n# rows: 3\n# filtered: 100.00\n# Extra: Using index\n",
|
||||
"query": "SELECT fruit FROM trees",
|
||||
"ts": "2007-12-18 11:48:27"
|
||||
},
|
||||
"fingerprint": "select fruit from trees",
|
||||
"histograms": {
|
||||
"Query_time": [
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
]
|
||||
},
|
||||
"metrics": {
|
||||
"Filesort": {
|
||||
"yes": "0"
|
||||
},
|
||||
"Filesort_on_disk": {
|
||||
"yes": "0"
|
||||
},
|
||||
"Full_join": {
|
||||
"yes": "0"
|
||||
},
|
||||
"Full_scan": {
|
||||
"yes": "0"
|
||||
},
|
||||
"Lock_time": {
|
||||
"avg": "0.000000",
|
||||
"max": "0.000000",
|
||||
"median": "0.000000",
|
||||
"min": "0.000000",
|
||||
"pct": "1.000000",
|
||||
"pct_95": "0.000000",
|
||||
"stddev": "0.000000",
|
||||
"sum": "0.000000"
|
||||
},
|
||||
"Merge_passes": {
|
||||
"avg": "0",
|
||||
"max": "0",
|
||||
"median": "0",
|
||||
"min": "0",
|
||||
"pct": "1",
|
||||
"pct_95": "0",
|
||||
"stddev": "0",
|
||||
"sum": "0"
|
||||
},
|
||||
"QC_Hit": {
|
||||
"yes": "0"
|
||||
},
|
||||
"Query_length": {
|
||||
"avg": "23",
|
||||
"max": "23",
|
||||
"median": "23",
|
||||
"min": "23",
|
||||
"pct": "1",
|
||||
"pct_95": "23",
|
||||
"stddev": "0",
|
||||
"sum": "23"
|
||||
},
|
||||
"Query_time": {
|
||||
"avg": "0.000012",
|
||||
"max": "0.000012",
|
||||
"median": "0.000012",
|
||||
"min": "0.000012",
|
||||
"pct": "1.000000",
|
||||
"pct_95": "0.000012",
|
||||
"stddev": "0.000000",
|
||||
"sum": "0.000012"
|
||||
},
|
||||
"Rows_examined": {
|
||||
"avg": "0",
|
||||
"max": "0",
|
||||
"median": "0",
|
||||
"min": "0",
|
||||
"pct": "1",
|
||||
"pct_95": "0",
|
||||
"stddev": "0",
|
||||
"sum": "0"
|
||||
},
|
||||
"Rows_sent": {
|
||||
"avg": "0",
|
||||
"max": "0",
|
||||
"median": "0",
|
||||
"min": "0",
|
||||
"pct": "1",
|
||||
"pct_95": "0",
|
||||
"stddev": "0",
|
||||
"sum": "0"
|
||||
},
|
||||
"Tmp_table": {
|
||||
"yes": "0"
|
||||
},
|
||||
"Tmp_table_on_disk": {
|
||||
"yes": "0"
|
||||
},
|
||||
"db": {
|
||||
"value": "food"
|
||||
},
|
||||
"host": {
|
||||
"value": ""
|
||||
},
|
||||
"user": {
|
||||
"value": "[SQL_SLAVE]"
|
||||
}
|
||||
},
|
||||
"query_count": 1,
|
||||
"tables": [
|
||||
{
|
||||
"create": "SHOW CREATE TABLE `food`.`trees`\\G",
|
||||
"status": "SHOW TABLE STATUS FROM `food` LIKE 'trees'\\G"
|
||||
}
|
||||
],
|
||||
"ts_max": "2007-12-18 11:48:27",
|
||||
"ts_min": "2007-12-18 11:48:27"
|
||||
}
|
||||
],
|
||||
"global": {
|
||||
"files": [
|
||||
{
|
||||
"name": "/home/sveta/src/percona/percona-toolkit/t/lib/samples/slowlogs/slow007.txt",
|
||||
"size": 368
|
||||
}
|
||||
],
|
||||
"metrics": {
|
||||
"Filesort": {
|
||||
"cnt": "0"
|
||||
},
|
||||
"Filesort_on_disk": {
|
||||
"cnt": "0"
|
||||
},
|
||||
"Full_join": {
|
||||
"cnt": "0"
|
||||
},
|
||||
"Full_scan": {
|
||||
"cnt": "0"
|
||||
},
|
||||
"Lock_time": {
|
||||
"avg": "0.000000",
|
||||
"max": "0.000000",
|
||||
"median": "0.000000",
|
||||
"min": "0.000000",
|
||||
"pct_95": "0.000000",
|
||||
"stddev": "0.000000",
|
||||
"sum": "0.000000"
|
||||
},
|
||||
"Merge_passes": {
|
||||
"avg": "0",
|
||||
"max": "0",
|
||||
"median": "0",
|
||||
"min": "0",
|
||||
"pct_95": "0",
|
||||
"stddev": "0",
|
||||
"sum": "0"
|
||||
},
|
||||
"QC_Hit": {
|
||||
"cnt": "0"
|
||||
},
|
||||
"Query_length": {
|
||||
"avg": "23",
|
||||
"max": "23",
|
||||
"median": "23",
|
||||
"min": "23",
|
||||
"pct_95": "23",
|
||||
"stddev": "0",
|
||||
"sum": "23"
|
||||
},
|
||||
"Query_time": {
|
||||
"avg": "0.000012",
|
||||
"max": "0.000012",
|
||||
"median": "0.000012",
|
||||
"min": "0.000012",
|
||||
"pct_95": "0.000012",
|
||||
"stddev": "0.000000",
|
||||
"sum": "0.000012"
|
||||
},
|
||||
"Rows_examined": {
|
||||
"avg": "0",
|
||||
"max": "0",
|
||||
"median": "0",
|
||||
"min": "0",
|
||||
"pct_95": "0",
|
||||
"stddev": "0",
|
||||
"sum": "0"
|
||||
},
|
||||
"Rows_sent": {
|
||||
"avg": "0",
|
||||
"max": "0",
|
||||
"median": "0",
|
||||
"min": "0",
|
||||
"pct_95": "0",
|
||||
"stddev": "0",
|
||||
"sum": "0"
|
||||
},
|
||||
"Tmp_table": {
|
||||
"cnt": "0"
|
||||
},
|
||||
"Tmp_table_on_disk": {
|
||||
"cnt": "0"
|
||||
}
|
||||
},
|
||||
"query_count": 1,
|
||||
"unique_query_count": 1
|
||||
}
|
||||
}
|
216
t/pt-query-digest/samples/slow007_explain_json_2-80.txt
Normal file
216
t/pt-query-digest/samples/slow007_explain_json_2-80.txt
Normal file
@@ -0,0 +1,216 @@
|
||||
{
|
||||
"classes": [
|
||||
{
|
||||
"attribute": "fingerprint",
|
||||
"checksum": "88F3D65BE48113F18E306CDB7A800841",
|
||||
"distillate": "SELECT trees",
|
||||
"example": {
|
||||
"Query_time": "0.000012",
|
||||
"explain": "# *************************** 1. row ***************************\n# id: 1\n# select_type: SIMPLE\n# table: trees\n# partitions: NULL\n# type: index\n# possible_keys: NULL\n# key: fruit\n# key_len: 99\n# ref: NULL\n# rows: 3\n# filtered: 100.00\n# Extra: Using index\n",
|
||||
"query": "SELECT fruit FROM trees",
|
||||
"ts": "2007-12-18 11:48:27"
|
||||
},
|
||||
"fingerprint": "select fruit from trees",
|
||||
"histograms": {
|
||||
"Query_time": [
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
]
|
||||
},
|
||||
"metrics": {
|
||||
"Filesort": {
|
||||
"yes": "0"
|
||||
},
|
||||
"Filesort_on_disk": {
|
||||
"yes": "0"
|
||||
},
|
||||
"Full_join": {
|
||||
"yes": "0"
|
||||
},
|
||||
"Full_scan": {
|
||||
"yes": "0"
|
||||
},
|
||||
"Lock_time": {
|
||||
"avg": "0.000000",
|
||||
"max": "0.000000",
|
||||
"median": "0.000000",
|
||||
"min": "0.000000",
|
||||
"pct": "1.000000",
|
||||
"pct_95": "0.000000",
|
||||
"stddev": "0.000000",
|
||||
"sum": "0.000000"
|
||||
},
|
||||
"Merge_passes": {
|
||||
"avg": "0",
|
||||
"max": "0",
|
||||
"median": "0",
|
||||
"min": "0",
|
||||
"pct": "1",
|
||||
"pct_95": "0",
|
||||
"stddev": "0",
|
||||
"sum": "0"
|
||||
},
|
||||
"QC_Hit": {
|
||||
"yes": "0"
|
||||
},
|
||||
"Query_length": {
|
||||
"avg": "23",
|
||||
"max": "23",
|
||||
"median": "23",
|
||||
"min": "23",
|
||||
"pct": "1",
|
||||
"pct_95": "23",
|
||||
"stddev": "0",
|
||||
"sum": "23"
|
||||
},
|
||||
"Query_time": {
|
||||
"avg": "0.000012",
|
||||
"max": "0.000012",
|
||||
"median": "0.000012",
|
||||
"min": "0.000012",
|
||||
"pct": "1.000000",
|
||||
"pct_95": "0.000012",
|
||||
"stddev": "0.000000",
|
||||
"sum": "0.000012"
|
||||
},
|
||||
"Rows_examined": {
|
||||
"avg": "0",
|
||||
"max": "0",
|
||||
"median": "0",
|
||||
"min": "0",
|
||||
"pct": "1",
|
||||
"pct_95": "0",
|
||||
"stddev": "0",
|
||||
"sum": "0"
|
||||
},
|
||||
"Rows_sent": {
|
||||
"avg": "0",
|
||||
"max": "0",
|
||||
"median": "0",
|
||||
"min": "0",
|
||||
"pct": "1",
|
||||
"pct_95": "0",
|
||||
"stddev": "0",
|
||||
"sum": "0"
|
||||
},
|
||||
"Tmp_table": {
|
||||
"yes": "0"
|
||||
},
|
||||
"Tmp_table_on_disk": {
|
||||
"yes": "0"
|
||||
},
|
||||
"db": {
|
||||
"value": "food"
|
||||
},
|
||||
"host": {
|
||||
"value": ""
|
||||
},
|
||||
"user": {
|
||||
"value": "[SQL_SLAVE]"
|
||||
}
|
||||
},
|
||||
"query_count": 1,
|
||||
"tables": [
|
||||
{
|
||||
"create": "SHOW CREATE TABLE `food`.`trees`\\G",
|
||||
"status": "SHOW TABLE STATUS FROM `food` LIKE 'trees'\\G"
|
||||
}
|
||||
],
|
||||
"ts_max": "2007-12-18 11:48:27",
|
||||
"ts_min": "2007-12-18 11:48:27"
|
||||
}
|
||||
],
|
||||
"global": {
|
||||
"files": [
|
||||
{
|
||||
"name": "/home/sveta/src/percona/percona-toolkit/t/lib/samples/slowlogs/slow007.txt",
|
||||
"size": 368
|
||||
}
|
||||
],
|
||||
"metrics": {
|
||||
"Filesort": {
|
||||
"cnt": "0"
|
||||
},
|
||||
"Filesort_on_disk": {
|
||||
"cnt": "0"
|
||||
},
|
||||
"Full_join": {
|
||||
"cnt": "0"
|
||||
},
|
||||
"Full_scan": {
|
||||
"cnt": "0"
|
||||
},
|
||||
"Lock_time": {
|
||||
"avg": "0.000000",
|
||||
"max": "0.000000",
|
||||
"median": "0.000000",
|
||||
"min": "0.000000",
|
||||
"pct_95": "0.000000",
|
||||
"stddev": "0.000000",
|
||||
"sum": "0.000000"
|
||||
},
|
||||
"Merge_passes": {
|
||||
"avg": "0",
|
||||
"max": "0",
|
||||
"median": "0",
|
||||
"min": "0",
|
||||
"pct_95": "0",
|
||||
"stddev": "0",
|
||||
"sum": "0"
|
||||
},
|
||||
"QC_Hit": {
|
||||
"cnt": "0"
|
||||
},
|
||||
"Query_length": {
|
||||
"avg": "23",
|
||||
"max": "23",
|
||||
"median": "23",
|
||||
"min": "23",
|
||||
"pct_95": "23",
|
||||
"stddev": "0",
|
||||
"sum": "23"
|
||||
},
|
||||
"Query_time": {
|
||||
"avg": "0.000012",
|
||||
"max": "0.000012",
|
||||
"median": "0.000012",
|
||||
"min": "0.000012",
|
||||
"pct_95": "0.000012",
|
||||
"stddev": "0.000000",
|
||||
"sum": "0.000012"
|
||||
},
|
||||
"Rows_examined": {
|
||||
"avg": "0",
|
||||
"max": "0",
|
||||
"median": "0",
|
||||
"min": "0",
|
||||
"pct_95": "0",
|
||||
"stddev": "0",
|
||||
"sum": "0"
|
||||
},
|
||||
"Rows_sent": {
|
||||
"avg": "0",
|
||||
"max": "0",
|
||||
"median": "0",
|
||||
"min": "0",
|
||||
"pct_95": "0",
|
||||
"stddev": "0",
|
||||
"sum": "0"
|
||||
},
|
||||
"Tmp_table": {
|
||||
"cnt": "0"
|
||||
},
|
||||
"Tmp_table_on_disk": {
|
||||
"cnt": "0"
|
||||
}
|
||||
},
|
||||
"query_count": 1,
|
||||
"unique_query_count": 1
|
||||
}
|
||||
}
|
@@ -221,6 +221,21 @@ like(
|
||||
qr/$skipping_str/s,
|
||||
"--skip-check-slave-lag",
|
||||
);
|
||||
|
||||
# Test for skip-check-slave-lag and empty replica port
|
||||
$output = output(
|
||||
sub { pt_table_checksum::main(@args,
|
||||
'--skip-check-slave-lag', "h=127.0.0.1",
|
||||
),
|
||||
},
|
||||
stderr => 1
|
||||
);
|
||||
|
||||
unlike(
|
||||
$output,
|
||||
qr/Use of uninitialized value.*/,
|
||||
'No syntax error if port is missed in --skip-check-slave-lag DSN',
|
||||
) or diag($output);
|
||||
}
|
||||
# #############################################################################
|
||||
# Illegal division by zero at pt-table-checksum line 7950
|
||||
|
Reference in New Issue
Block a user