WIP MySQL 8 support

This commit is contained in:
Carlos Salguero
2018-01-18 12:47:38 -03:00
parent 1d1c13fbcb
commit 56f5202dbf
16 changed files with 214 additions and 46 deletions

View File

@@ -2305,7 +2305,8 @@ report_mysql_summary () {
section "Plugins"
name_val "InnoDB compression" "$(get_plugin_status "$dir/mysql-plugins" "INNODB_CMP")"
if [ "$(get_var have_query_cache "$dir/mysql-variables")" ]; then
local has_query_cache=$(get_var have_query_cache "$dir/mysql-variables")
if [ "$has_query_cache == 'YES' ]; then
section "Query cache"
local query_cache_size=$(get_var query_cache_size "$dir/mysql-variables")
local used=$(( ${query_cache_size} - $(get_var Qcache_free_memory "$dir/mysql-status") ))

View File

@@ -6732,6 +6732,7 @@ sub BUILDARGS {
num_format => '# %1$-'.$label_width.'s %2$3s %3$7s %4$7s %5$7s %6$7s %7$7s %8$7s %9$7s',
bool_format => '# %1$-'.$label_width.'s %2$3d%% yes, %3$3d%% no',
string_format => '# %1$-'.$label_width.'s %2$s',
no_partitions => 0,
hidden_attrib => { # Don't sort/print these attribs in the reports.
arg => 1, # They're usually handled specially, or not
fingerprint => 1, # printed at all.
@@ -7014,6 +7015,7 @@ sub query_report {
}
}
my $partitions_msg = $self->{no_partitions} ? '' : '/*!50100 PARTITIONS */';
if ( $groupby eq 'fingerprint' ) {
my $samp_query = $qr->shorten($vals->{samp_query}, $self->{options}->{shorten})
if $self->{options}->{shorten};
@@ -7034,7 +7036,7 @@ sub query_report {
$report .= "$samp_query${mark}\n";
}
else {
$report .= "# EXPLAIN /*!50100 PARTITIONS*/\n$samp_query${mark}\n";
$report .= "# EXPLAIN $partitions_msg\n$samp_query${mark}\n";
$report .= $self->explain_report($samp_query, $vals->{default_db});
}
}
@@ -7043,7 +7045,7 @@ sub query_report {
my $converted = $qr->convert_to_select($samp_query);
if ( $converted
&& $converted =~ m/^[\(\s]*select/i ) {
$report .= "# Converted for EXPLAIN\n# EXPLAIN /*!50100 PARTITIONS*/\n$converted${mark}\n";
$report .= "# Converted for EXPLAIN\n# EXPLAIN $partitions_msg\n$converted${mark}\n";
}
}
}
@@ -7746,7 +7748,16 @@ sub explain_report {
PTDEBUG && _d($dbh, "USE", $db);
$dbh->do("USE " . $q->quote($db));
}
my $sth = $dbh->prepare("EXPLAIN /*!50100 PARTITIONS */ $query");
my $sth;
eval {
$sth = $dbh->prepare("EXPLAIN /*!50100 PARTITIONS */ $query");
$sth->execute();
};
if ($EVAL_ERROR) { # MySQL 8.0+ doesn't support PARTITIONS
$self->{no_partitions} = 1;
$sth = $dbh->prepare("EXPLAIN $query");
$sth->execute();
}
$sth->execute();
my $i = 1;
while ( my @row = $sth->fetchrow_array() ) {

View File

@@ -126,6 +126,10 @@ sub BUILDARGS {
num_format => '# %1$-'.$label_width.'s %2$3s %3$7s %4$7s %5$7s %6$7s %7$7s %8$7s %9$7s',
bool_format => '# %1$-'.$label_width.'s %2$3d%% yes, %3$3d%% no',
string_format => '# %1$-'.$label_width.'s %2$s',
# MySQL 8 doesn't support partitions.
# sub explain_report can handle the error but we need to know if /*!50100 PARTITIONS */
# was used or not, to write the correct report headers
no_partitions => 0,
hidden_attrib => { # Don't sort/print these attribs in the reports.
arg => 1, # They're usually handled specially, or not
fingerprint => 1, # printed at all.
@@ -463,6 +467,7 @@ sub query_report {
}
}
my $partitions_msg = $self->{no_partitions} ? '' : '/*!50100 PARTITIONS */';
if ( $groupby eq 'fingerprint' ) {
# Shorten it if necessary (issue 216 and 292).
my $samp_query = $qr->shorten($vals->{samp_query}, $self->{options}->{shorten})
@@ -491,7 +496,7 @@ sub query_report {
$report .= "$samp_query${mark}\n";
}
else {
$report .= "# EXPLAIN /*!50100 PARTITIONS*/\n$samp_query${mark}\n";
$report .= "# EXPLAIN $partitions_msg\n$samp_query${mark}\n";
$report .= $self->explain_report($samp_query, $vals->{default_db});
}
}
@@ -501,7 +506,7 @@ sub query_report {
if ( $converted
&& $converted =~ m/^[\(\s]*select/i ) {
# It converted OK to a SELECT
$report .= "# Converted for EXPLAIN\n# EXPLAIN /*!50100 PARTITIONS*/\n$converted${mark}\n";
$report .= "# Converted for EXPLAIN\n# EXPLAIN $partitions_msg\n$converted${mark}\n";
}
}
}
@@ -1301,7 +1306,16 @@ sub explain_report {
PTDEBUG && _d($dbh, "USE", $db);
$dbh->do("USE " . $q->quote($db));
}
my $sth = $dbh->prepare("EXPLAIN /*!50100 PARTITIONS */ $query");
my $sth;
eval {
$sth = $dbh->prepare("EXPLAIN /*!50100 PARTITIONS */ $query");
$sth->execute();
};
if ($EVAL_ERROR) { # MySQL 8.0+ doesn't support PARTITIONS
$self->{no_partitions} = 1;
$sth = $dbh->prepare("EXPLAIN $query");
$sth->execute();
}
$sth->execute();
my $i = 1;
while ( my @row = $sth->fetchrow_array() ) {

View File

@@ -262,6 +262,10 @@ is(
diag(`/tmp/12345/use -u root -e "GRANT ALL ON *.* TO 'bob'\@'%' IDENTIFIED BY 'msandbox'"`);
diag(`/tmp/12345/use -u root -e "REVOKE SUPER ON *.* FROM 'bob'\@'%'"`);
if ($sandbox_version ge '8.0') {
diag(`/tmp/12345/use -u root -e "REVOKE CONNECTION_ADMIN ON *.* FROM 'bob'\@'%'"`);
}
diag(`/tmp/12345/use -u root -e "FLUSH PRIVILEGES"`);
# Some subtlety here. 'bob' doesn't have enough privileges to change binlog_format
# to STATEMENT if it's set to ROW, so the tool will fail with a different error
@@ -283,10 +287,6 @@ $output = output(
my $b = $ENV{PERCONA_TOOLKIT_BRANCH};
$output = `perl $b/bin/pt-heartbeat -D test --interval 0.8 --update --replace --run-time 1 u=bob,F=/tmp/12346/my.sandbox.cnf 2>&1`;
diag(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
diag($output);
diag("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
like(
$output,
qr/--read-only/,

View File

@@ -37,12 +37,6 @@ if ( !$dbh ) {
plan skip_all => 'Cannot connect to sandbox master';
}
$sb->load_file('master', "t/pt-kill/samples/pt_167.sql");
my $ps = $dbh->prepare('INSERT INTO test.foo VALUES (?)');
for (my $i=0; $i < 20000; $i++) {
$ps->execute($i);
}
sub start_thread {
my ($dp, $o, $dsn, $sleep_time) = @_;
@@ -51,7 +45,7 @@ sub start_thread {
my $cxn = new Cxn(DSNParser => $dp, OptionParser => $o, dsn => $dsn);
$cxn->connect();
my $dbh = $cxn->dbh();
my $sth = $dbh->prepare('SELECT COUNT(*) FROM (SELECT a.id AS a_id, b.id AS b_id FROM foo AS a, foo AS b) AS c');
my $sth = $dbh->prepare('SELECT SLEEP(10)');
# Since this query is going to be killed, wrap the execution in an eval to prevent
# displaying the error message.
eval {
@@ -59,7 +53,7 @@ sub start_thread {
};
}
my $dsn = "h=127.1,P=12345,u=msandbox,p=msandbox,D=test;mysql_server_prepare=1";
my $dsn = "h=127.1,P=12345,u=msandbox,p=msandbox,D=sakila;mysql_server_prepare=1";
my $thr = threads->create('start_thread', $dp, $o, $dp->parse($dsn), 1);
$thr->detach();
threads->yield();
@@ -69,7 +63,7 @@ sleep(1);
my $rows = $dbh->selectall_hashref('show processlist', 'id');
my $pid = 0; # reuse, reset
map { $pid = $_->{id} }
grep { $_->{info} && $_->{info} =~ m/SELECT COUNT\(\*\) FROM \(SELECT a.id/ }
grep { $_->{info} && $_->{info} =~ m/SELECT SLEEP\(10\)/ }
values %$rows;
ok(

View File

@@ -1,4 +0,0 @@
DROP DATABASE IF EXISTS test;
CREATE DATABASE test;
create table test.foo (id integer);

View File

@@ -41,13 +41,12 @@ if ( !$master_dbh ) {
my @args = (qw(--set-vars innodb_lock_wait_timeout=3));
my $output;
my $exit_status;
my $sample = "t/pt-online-schema-change/samples/";
$sb->load_file('master', "$sample/pt-229.sql");
$sb->load_file('master', "t/pt-online-schema-change/samples/pt-229.sql");
my $num_rows = 40000;
diag("Loading $num_rows into the table. This might take some time.");
diag(`util/mysql_random_data_load_linux_amd64 --host=127.1 --port=12345 --user=msandbox --password=msandbox test test_a $num_rows`);
diag(`util/mysql_random_data_loader --host=127.1 --port=12345 --user=msandbox --password=msandbox test test_a $num_rows`);
diag("$num_rows rows loaded. Starting tests.");
$master_dbh->do("FLUSH TABLES");

View File

@@ -24,8 +24,6 @@ if ( !$dbh ) {
plan skip_all => 'Cannot connect to sandbox master';
}
my $sample = "t/pt-query-digest/samples/";
$dbh->do('drop database if exists food');
$dbh->do('create database food');
$dbh->do('use food');
@@ -39,10 +37,11 @@ ok(
no_diff(
sub { pt_query_digest::main(@args,
"$trunk/t/lib/samples/slowlogs/slow007.txt") },
( $sandbox_version ge '5.7' ? "$sample/slow007_explain_1-57.txt"
: $sandbox_version ge '5.5' ? "$sample/slow007_explain_1-55.txt"
: $sandbox_version ge '5.1' ? "$sample/slow007_explain_1-51.txt"
: "$sample/slow007_explain_1.txt"),
( $sandbox_version ge '8.0' ? "t/pt-query-digest/samples/slow007_explain_1-80.txt"
: $sandbox_version ge '5.7' ? "t/pt-query-digest/samples/slow007_explain_1-57.txt"
: $sandbox_version ge '5.5' ? "t/pt-query-digest/samples/slow007_explain_1-55.txt"
: $sandbox_version ge '5.1' ? "t/pt-query-digest/samples/slow007_explain_1-51.txt"
: "t/pt-query-digest/samples/slow007_explain_1.txt"),
),
'Analysis for slow007 with --explain, no rows',
);
@@ -53,9 +52,10 @@ ok(
no_diff(
sub { pt_query_digest::main(@args,
"$trunk/t/lib/samples/slowlogs/slow007.txt") },
( $sandbox_version ge '5.7' ? "$sample/slow007_explain_2-57.txt"
: $sandbox_version ge '5.1' ? "$sample/slow007_explain_2-51.txt"
: "$sample/slow007_explain_2.txt"),
( $sandbox_version ge '8.0' ? "t/pt-query-digest/samples/slow007_explain_2-80.txt"
: $sandbox_version ge '5.7' ? "t/pt-query-digest/samples/slow007_explain_2-57.txt"
: $sandbox_version ge '5.1' ? "t/pt-query-digest/samples/slow007_explain_2-51.txt"
: "t/pt-query-digest/samples/slow007_explain_2.txt"),
),
'Analysis for slow007 with --explain',
);
@@ -67,7 +67,7 @@ ok(
no_diff(
sub { pt_query_digest::main(@args,
"$trunk/t/lib/samples/slowlogs/slow007.txt", qw(--report-format profile)) },
"$sample/slow007_explain_4.txt",
"t/pt-query-digest/samples/slow007_explain_4.txt",
),
'EXPLAIN sparkline in profile'
);
@@ -99,10 +99,11 @@ ok(
'--report-format', 'profile,query_report',
"$trunk/t/pt-query-digest/samples/issue_1196.log",)
},
( $sandbox_version ge '5.7' ? "$sample/issue_1196-output-5.7.txt"
: $sandbox_version ge '5.6' ? "$sample/issue_1196-output-5.6.txt"
: $sandbox_version ge '5.1' ? "$sample/issue_1196-output.txt"
: "$sample/issue_1196-output-5.0.txt"),
( $sandbox_version ge '8.0' ? "t/pt-query-digest/samples/issue_1196-output-8.0.txt"
: $sandbox_version ge '5.7' ? "t/pt-query-digest/samples/issue_1196-output-5.7.txt"
: $sandbox_version ge '5.6' ? "t/pt-query-digest/samples/issue_1196-output-5.6.txt"
: $sandbox_version ge '5.1' ? "t/pt-query-digest/samples/issue_1196-output.txt"
: "t/pt-query-digest/samples/issue_1196-output-5.0.txt"),
),
"--explain sparkline uses event db and doesn't crash ea (issue 1196)"
);

View File

@@ -32,7 +32,7 @@
# Tables
# SHOW TABLE STATUS FROM `issue_1196` LIKE 't'\G
# SHOW CREATE TABLE `issue_1196`.`t`\G
# EXPLAIN /*!50100 PARTITIONS*/
# EXPLAIN /*!50100 PARTITIONS */
select t.a, count(*) from t join t t2 using(a) group by 1 order by 2 desc limit 10\G
# *************************** 1. row ***************************
# id: 1

View File

@@ -0,0 +1,62 @@
# Profile
# Rank Query ID Response time Calls R/Call V/M Item
# ==== ================== ============= ===== ====== ===== ========
# 1 0xD4B6A5CD2F2F485C 0.2148 100.0% 1 0.2148 0.00 SELECT t
# Query 1: 0 QPS, 0x concurrency, ID 0xD4B6A5CD2F2F485C at byte 0 ________
# This item is included in the report because it matches --limit.
# Scores: V/M = 0.00
# Time range: all events occurred at 2010-12-14 16:12:28
# Attribute pct total min max avg 95% stddev median
# ============ === ======= ======= ======= ======= ======= ======= =======
# Count 100 1
# Exec time 100 215ms 215ms 215ms 215ms 215ms 0 215ms
# Lock time 99 162us 162us 162us 162us 162us 0 162us
# Rows sent 100 10 10 10 10 10 0 10
# Rows examine 100 1.96k 1.96k 1.96k 1.96k 1.96k 0 1.96k
# Query size 100 82 82 82 82 82 0 82
# String:
# Databases issue_1196
# Hosts localhost
# Users root
# Query_time distribution
# 1us
# 10us
# 100us
# 1ms
# 10ms
# 100ms ################################################################
# 1s
# 10s+
# Tables
# SHOW TABLE STATUS FROM `issue_1196` LIKE 't'\G
# SHOW CREATE TABLE `issue_1196`.`t`\G
# EXPLAIN /*!50100 PARTITIONS*/
select t.a, count(*) from t join t t2 using(a) group by 1 order by 2 desc limit 10\G
# *************************** 1. row ***************************
# id: 1
# select_type: SIMPLE
# table: t
# partitions: NULL
# type: ALL
# possible_keys: NULL
# key: NULL
# key_len: NULL
# ref: NULL
# rows: 14
# filtered: 100
# Extra: Using temporary; Using filesort
# *************************** 2. row ***************************
# id: 1
# select_type: SIMPLE
# table: t2
# partitions: NULL
# type: ALL
# possible_keys: NULL
# key: NULL
# key_len: NULL
# ref: NULL
# rows: 14
# filtered: 10
# Extra: Using where; Using join buffer (Block Nested Loop)

View File

@@ -28,7 +28,7 @@
# Tables
# SHOW TABLE STATUS FROM `food` LIKE 'trees'\G
# SHOW CREATE TABLE `food`.`trees`\G
# EXPLAIN /*!50100 PARTITIONS*/
# EXPLAIN /*!50100 PARTITIONS */
SELECT fruit FROM trees\G
# *************************** 1. row ***************************
# id: 1

View File

@@ -0,0 +1,45 @@
# Query 1: 0 QPS, 0x concurrency, ID 0x8E306CDB7A800841 at byte 0 ________
# This item is included in the report because it matches --limit.
# Scores: V/M = 0.00
# Time range: all events occurred at 2007-12-18 11:48:27
# Attribute pct total min max avg 95% stddev median
# ============ === ======= ======= ======= ======= ======= ======= =======
# Count 100 1
# Exec time 100 12us 12us 12us 12us 12us 0 12us
# Lock time 0 0 0 0 0 0 0 0
# Rows sent 0 0 0 0 0 0 0 0
# Rows examine 0 0 0 0 0 0 0 0
# Merge passes 0 0 0 0 0 0 0 0
# Query size 100 23 23 23 23 23 0 23
# String:
# Databases food
# Hosts
# Users [SQL_SLAVE]
# Query_time distribution
# 1us
# 10us ################################################################
# 100us
# 1ms
# 10ms
# 100ms
# 1s
# 10s+
# Tables
# SHOW TABLE STATUS FROM `food` LIKE 'trees'\G
# SHOW CREATE TABLE `food`.`trees`\G
# EXPLAIN /*!50100 PARTITIONS*/
SELECT fruit FROM trees\G
# *************************** 1. row ***************************
# id: 1
# select_type: SIMPLE
# table: trees
# partitions: NULL
# type: index
# possible_keys: NULL
# key: fruit
# key_len: 99
# ref: NULL
# rows: 1
# filtered: 100
# Extra: Using index

View File

@@ -28,7 +28,7 @@
# Tables
# SHOW TABLE STATUS FROM `food` LIKE 'trees'\G
# SHOW CREATE TABLE `food`.`trees`\G
# EXPLAIN /*!50100 PARTITIONS*/
# EXPLAIN /*!50100 PARTITIONS */
SELECT fruit FROM trees\G
# *************************** 1. row ***************************
# id: 1

View File

@@ -0,0 +1,45 @@
# Query 1: 0 QPS, 0x concurrency, ID 0x8E306CDB7A800841 at byte 0 ________
# This item is included in the report because it matches --limit.
# Scores: V/M = 0.00
# Time range: all events occurred at 2007-12-18 11:48:27
# Attribute pct total min max avg 95% stddev median
# ============ === ======= ======= ======= ======= ======= ======= =======
# Count 100 1
# Exec time 100 12us 12us 12us 12us 12us 0 12us
# Lock time 0 0 0 0 0 0 0 0
# Rows sent 0 0 0 0 0 0 0 0
# Rows examine 0 0 0 0 0 0 0 0
# Merge passes 0 0 0 0 0 0 0 0
# Query size 100 23 23 23 23 23 0 23
# String:
# Databases food
# Hosts
# Users [SQL_SLAVE]
# Query_time distribution
# 1us
# 10us ################################################################
# 100us
# 1ms
# 10ms
# 100ms
# 1s
# 10s+
# Tables
# SHOW TABLE STATUS FROM `food` LIKE 'trees'\G
# SHOW CREATE TABLE `food`.`trees`\G
# EXPLAIN /*!50100 PARTITIONS*/
SELECT fruit FROM trees\G
# *************************** 1. row ***************************
# id: 1
# select_type: SIMPLE
# table: trees
# partitions: NULL
# type: index
# possible_keys: NULL
# key: fruit
# key_len: 99
# ref: NULL
# rows: 3
# filtered: 100
# Extra: Using index

View File

@@ -28,9 +28,9 @@
# Tables
# SHOW TABLE STATUS FROM `food` LIKE 'trees'\G
# SHOW CREATE TABLE `food`.`trees`\G
# EXPLAIN /*!50100 PARTITIONS*/
# EXPLAIN /*!50100 PARTITIONS */
SELECT fruit FROM trees\G
# EXPLAIN failed: DBD::mysql::st execute failed: Table 'food.trees' doesn't exist [for Statement "EXPLAIN /*!50100 PARTITIONS */ SELECT fruit FROM trees"] at line ?.
# EXPLAIN failed: DBD::mysql::st execute failed: Table 'food.trees' doesn't exist [for Statement "EXPLAIN SELECT fruit FROM trees"] at line ?.
# Profile
# Rank Query ID Response time Calls R/Call V/M Item