Commit 5d20f7b3 authored by Igor Babaev's avatar Igor Babaev

Added missing tests for innodb persistent statistics (from mysql-5.6.10)

Made sure that innodb tables for persistent statistics would not
considered by the server as system tables.
parent 1b6e66fa
TRUNCATE TABLE test_innodb_stats;
-- eval $insert
ANALYZE TABLE test_innodb_stats;
query_vertical SELECT
stat_name,
stat_value,
sample_size,
stat_description
FROM mysql.innodb_index_stats
WHERE
database_name = DATABASE() AND
table_name = 'test_innodb_stats' AND
index_name = 'a_key' AND
stat_name IN ('n_diff_pfx01', 'n_diff_pfx02', 'n_leaf_pages', 'size')
ORDER BY stat_name;
# provoke reading from persistent storage upon next table access (the SELECT
# from information_schema.statistics below)
FLUSH TABLE test_innodb_stats;
# see what we are going to read
query_vertical SELECT * FROM information_schema.statistics
WHERE table_name = 'test_innodb_stats';
This diff is collapsed.
call mtr.add_suppression("InnoDB: Error: Table \"mysql\".\"innodb_index_stats\" not found");
call mtr.add_suppression("InnoDB: Error: Fetch of persistent statistics requested for table");
ALTER TABLE mysql.innodb_index_stats RENAME TO mysql.innodb_index_stats_;
CREATE TABLE test_ps_create_on_corrupted
(a INT, PRIMARY KEY (a))
ENGINE=INNODB STATS_PERSISTENT=1;
SELECT seq_in_index, column_name, cardinality
FROM information_schema.statistics WHERE table_name = 'test_ps_create_on_corrupted'
ORDER BY index_name, seq_in_index;
seq_in_index 1
column_name a
cardinality 0
SELECT table_rows, avg_row_length, max_data_length, index_length
FROM information_schema.tables WHERE table_name = 'test_ps_create_on_corrupted';
table_rows 0
avg_row_length 0
max_data_length 0
index_length 0
ALTER TABLE mysql.innodb_index_stats_ RENAME TO mysql.innodb_index_stats;
DROP TABLE test_ps_create_on_corrupted;
set @save_innodb_stats_persistent= @@innodb_stats_persistent;
set global innodb_stats_persistent=default;
SELECT COUNT(*) FROM mysql.innodb_table_stats WHERE
database_name = 'test' AND
table_name = 'test_ps_create_table';
COUNT(*) 0
CREATE TABLE test_ps_create_table (a INT, PRIMARY KEY (a))
ENGINE=INNODB STATS_PERSISTENT=0;
SELECT COUNT(*) FROM mysql.innodb_table_stats WHERE
database_name = 'test' AND
table_name = 'test_ps_create_table';
COUNT(*) 0
DROP TABLE test_ps_create_table;
CREATE TABLE test_ps_create_table (a INT, PRIMARY KEY (a))
ENGINE=INNODB;
SELECT COUNT(*) FROM mysql.innodb_table_stats WHERE
database_name = 'test' AND
table_name = 'test_ps_create_table';
COUNT(*) 1
DROP TABLE test_ps_create_table;
CREATE TABLE test_ps_create_table (a INT, PRIMARY KEY (a))
ENGINE=INNODB STATS_PERSISTENT=default;
SELECT COUNT(*) FROM mysql.innodb_table_stats WHERE
database_name = 'test' AND
table_name = 'test_ps_create_table';
COUNT(*) 1
DROP TABLE test_ps_create_table;
CREATE TABLE test_ps_create_table (a INT, PRIMARY KEY (a))
ENGINE=INNODB STATS_PERSISTENT=1;
SELECT COUNT(*) FROM mysql.innodb_table_stats WHERE
database_name = 'test' AND
table_name = 'test_ps_create_table';
COUNT(*) 1
DROP TABLE test_ps_create_table;
set global innodb_stats_persistent= @save_innodb_stats_persistent;
Table Op Msg_type Msg_text
test.innodb_stats_drop_locked analyze status OK
SET autocommit=0;
SELECT table_name FROM mysql.innodb_table_stats
WHERE table_name='innodb_stats_drop_locked'
FOR UPDATE;
table_name
innodb_stats_drop_locked
SELECT table_name FROM mysql.innodb_index_stats
WHERE table_name='innodb_stats_drop_locked'
FOR UPDATE;
table_name
innodb_stats_drop_locked
innodb_stats_drop_locked
innodb_stats_drop_locked
innodb_stats_drop_locked
innodb_stats_drop_locked
innodb_stats_drop_locked
innodb_stats_drop_locked
ALTER TABLE innodb_stats_drop_locked DROP INDEX c_key;
Warnings:
Warning 1205 Unable to delete statistics for index c_key from mysql.innodb_index_stats because the rows are locked: Lock wait timeout. They can be deleted later using DELETE FROM mysql.innodb_index_stats WHERE database_name = 'test' AND table_name = 'innodb_stats_drop_locked' AND index_name = 'c_key';
SHOW CREATE TABLE innodb_stats_drop_locked;
Table Create Table
innodb_stats_drop_locked CREATE TABLE `innodb_stats_drop_locked` (
`c` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 STATS_PERSISTENT=1
DROP TABLE innodb_stats_drop_locked;
SHOW TABLES;
Tables_in_test
COMMIT;
SELECT table_name FROM mysql.innodb_table_stats
WHERE table_name='innodb_stats_drop_locked';
table_name
innodb_stats_drop_locked
SELECT table_name FROM mysql.innodb_index_stats
WHERE table_name='innodb_stats_drop_locked';
table_name
innodb_stats_drop_locked
innodb_stats_drop_locked
innodb_stats_drop_locked
innodb_stats_drop_locked
innodb_stats_drop_locked
innodb_stats_drop_locked
innodb_stats_drop_locked
CREATE TABLE test_ps_fetch
(a INT, b INT, c INT, d INT, PRIMARY KEY (a, b), INDEX idx (c, d))
ENGINE=INNODB STATS_PERSISTENT=1;
ANALYZE TABLE test_ps_fetch;
Table test.test_ps_fetch
Op analyze
Msg_type status
Msg_text OK
SELECT n_rows, clustered_index_size, sum_of_other_index_sizes
FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_fetch';
n_rows 0
clustered_index_size 1
sum_of_other_index_sizes 1
SELECT index_name, stat_name, stat_value, sample_size, stat_description
FROM mysql.innodb_index_stats WHERE table_name = 'test_ps_fetch'
ORDER BY index_name, stat_name;
index_name PRIMARY
stat_name n_diff_pfx01
stat_value 0
sample_size 1
stat_description a
index_name PRIMARY
stat_name n_diff_pfx02
stat_value 0
sample_size 1
stat_description a,b
index_name PRIMARY
stat_name n_leaf_pages
stat_value 1
sample_size NULL
stat_description Number of leaf pages in the index
index_name PRIMARY
stat_name size
stat_value 1
sample_size NULL
stat_description Number of pages in the index
index_name idx
stat_name n_diff_pfx01
stat_value 0
sample_size 1
stat_description c
index_name idx
stat_name n_diff_pfx02
stat_value 0
sample_size 1
stat_description c,d
index_name idx
stat_name n_diff_pfx03
stat_value 0
sample_size 1
stat_description c,d,a
index_name idx
stat_name n_diff_pfx04
stat_value 0
sample_size 1
stat_description c,d,a,b
index_name idx
stat_name n_leaf_pages
stat_value 1
sample_size NULL
stat_description Number of leaf pages in the index
index_name idx
stat_name size
stat_value 1
sample_size NULL
stat_description Number of pages in the index
SELECT index_name, seq_in_index, column_name, cardinality
FROM information_schema.statistics WHERE table_name = 'test_ps_fetch'
ORDER BY index_name, seq_in_index;
index_name idx
seq_in_index 1
column_name c
cardinality 0
index_name idx
seq_in_index 2
column_name d
cardinality 0
index_name PRIMARY
seq_in_index 1
column_name a
cardinality 0
index_name PRIMARY
seq_in_index 2
column_name b
cardinality 0
SELECT
table_rows, avg_row_length, max_data_length, index_length
FROM information_schema.tables WHERE table_name = 'test_ps_fetch';
table_rows 0
avg_row_length 0
max_data_length 0
index_length 16384
UPDATE mysql.innodb_table_stats SET
n_rows = 1000,
clustered_index_size = 5
WHERE
table_name = 'test_ps_fetch';
UPDATE mysql.innodb_index_stats SET
stat_value = 20
WHERE
table_name = 'test_ps_fetch' AND
index_name = 'PRIMARY' AND
stat_name = 'n_diff_pfx01';
UPDATE mysql.innodb_index_stats SET
stat_value = 90
WHERE
table_name = 'test_ps_fetch' AND
index_name = 'PRIMARY' AND
stat_name = 'n_diff_pfx02';
UPDATE mysql.innodb_index_stats SET
stat_value = 3
WHERE
table_name = 'test_ps_fetch' AND
index_name = 'idx' AND
stat_name = 'n_diff_pfx01';
UPDATE mysql.innodb_index_stats SET
stat_value = 11
WHERE
table_name = 'test_ps_fetch' AND
index_name = 'idx' AND
stat_name = 'n_diff_pfx02';
FLUSH TABLE test_ps_fetch;
SELECT seq_in_index, column_name, cardinality
FROM information_schema.statistics WHERE table_name = 'test_ps_fetch'
ORDER BY index_name, seq_in_index;
seq_in_index 1
column_name c
cardinality 6
seq_in_index 2
column_name d
cardinality 22
seq_in_index 1
column_name a
cardinality 40
seq_in_index 2
column_name b
cardinality 200
SELECT
table_rows, avg_row_length, max_data_length, index_length
FROM information_schema.tables WHERE table_name = 'test_ps_fetch';
table_rows 1000
avg_row_length 81
max_data_length 0
index_length 16384
DROP TABLE test_ps_fetch;
call mtr.add_suppression("InnoDB: Error: Table \"mysql\".\"innodb_index_stats\" not found");
call mtr.add_suppression("InnoDB: Error: Fetch of persistent statistics requested for table");
CREATE TABLE test_ps_fetch_corrupted
(a INT, PRIMARY KEY (a))
ENGINE=INNODB STATS_PERSISTENT=1;
ANALYZE TABLE test_ps_fetch_corrupted;
Table test.test_ps_fetch_corrupted
Op analyze
Msg_type status
Msg_text OK
SELECT n_rows, clustered_index_size, sum_of_other_index_sizes
FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_fetch_corrupted';
n_rows 0
clustered_index_size 1
sum_of_other_index_sizes 0
ALTER TABLE mysql.innodb_index_stats RENAME TO mysql.innodb_index_stats_;
FLUSH TABLE test_ps_fetch_corrupted;
SELECT seq_in_index, column_name, cardinality
FROM information_schema.statistics WHERE table_name = 'test_ps_fetch_corrupted'
ORDER BY index_name, seq_in_index;
seq_in_index 1
column_name a
cardinality 0
SELECT table_rows, avg_row_length, max_data_length, index_length
FROM information_schema.tables WHERE table_name = 'test_ps_fetch_corrupted';
table_rows 0
avg_row_length 0
max_data_length 0
index_length 0
ALTER TABLE mysql.innodb_index_stats_ RENAME TO mysql.innodb_index_stats;
DROP TABLE test_ps_fetch_corrupted;
CREATE TABLE test_ps_fetch_nonexistent
(a INT, PRIMARY KEY (a))
ENGINE=INNODB STATS_PERSISTENT=1;
ANALYZE TABLE test_ps_fetch_nonexistent;
Table test.test_ps_fetch_nonexistent
Op analyze
Msg_type status
Msg_text OK
SELECT COUNT(*)
FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_fetch_nonexistent';
COUNT(*) 1
DELETE FROM mysql.innodb_index_stats WHERE table_name = 'test_ps_fetch_nonexistent';
DELETE FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_fetch_nonexistent';
FLUSH TABLE test_ps_fetch_nonexistent;
SELECT seq_in_index, column_name, cardinality
FROM information_schema.statistics WHERE table_name = 'test_ps_fetch_nonexistent'
ORDER BY index_name, seq_in_index;
seq_in_index 1
column_name a
cardinality 0
SELECT table_rows, avg_row_length, max_data_length, index_length
FROM information_schema.tables WHERE table_name = 'test_ps_fetch_nonexistent';
table_rows 0
avg_row_length 0
max_data_length 0
index_length 0
DROP TABLE test_ps_fetch_nonexistent;
SELECT table_name, n_rows
FROM mysql.innodb_table_stats
WHERE table_name IN ('stats_rename_old', 'stats_rename_new');
SELECT table_name, index_name, stat_name, stat_value
FROM mysql.innodb_index_stats
WHERE table_name IN ('stats_rename_old', 'stats_rename_new');
CREATE TABLE stats_rename_old (a INT, PRIMARY KEY (a))
ENGINE=INNODB STATS_PERSISTENT=1;
SELECT table_name, n_rows
FROM mysql.innodb_table_stats
WHERE table_name IN ('stats_rename_old', 'stats_rename_new');
table_name stats_rename_old
n_rows 0
SELECT table_name, index_name, stat_name, stat_value
FROM mysql.innodb_index_stats
WHERE table_name IN ('stats_rename_old', 'stats_rename_new');
table_name stats_rename_old
index_name PRIMARY
stat_name n_diff_pfx01
stat_value 0
table_name stats_rename_old
index_name PRIMARY
stat_name n_leaf_pages
stat_value 1
table_name stats_rename_old
index_name PRIMARY
stat_name size
stat_value 1
RENAME TABLE stats_rename_old TO stats_rename_new;
SELECT table_name, n_rows
FROM mysql.innodb_table_stats
WHERE table_name IN ('stats_rename_old', 'stats_rename_new');
table_name stats_rename_new
n_rows 0
SELECT table_name, index_name, stat_name, stat_value
FROM mysql.innodb_index_stats
WHERE table_name IN ('stats_rename_old', 'stats_rename_new');
table_name stats_rename_new
index_name PRIMARY
stat_name n_diff_pfx01
stat_value 0
table_name stats_rename_new
index_name PRIMARY
stat_name n_leaf_pages
stat_value 1
table_name stats_rename_new
index_name PRIMARY
stat_name size
stat_value 1
DROP TABLE stats_rename_new;
CREATE TABLE stats_rename1 (a INT, PRIMARY KEY (a))
ENGINE=INNODB STATS_PERSISTENT=1;
INSERT INTO mysql.innodb_table_stats
SELECT
database_name,
'stats_rename2' AS table_name,
last_update,
123 AS n_rows,
clustered_index_size,
sum_of_other_index_sizes
FROM mysql.innodb_table_stats
WHERE table_name = 'stats_rename1';
INSERT INTO mysql.innodb_index_stats
SELECT
database_name,
'stats_rename2' AS table_name,
index_name,
last_update,
stat_name,
567 AS stat_value,
sample_size,
stat_description
FROM mysql.innodb_index_stats
WHERE table_name = 'stats_rename1';
SELECT table_name, n_rows
FROM mysql.innodb_table_stats
WHERE table_name IN ('stats_rename1', 'stats_rename2');
table_name stats_rename1
n_rows 0
table_name stats_rename2
n_rows 123
SELECT table_name, index_name, stat_name, stat_value
FROM mysql.innodb_index_stats
WHERE table_name IN ('stats_rename1', 'stats_rename2');
table_name stats_rename1
index_name PRIMARY
stat_name n_diff_pfx01
stat_value 0
table_name stats_rename1
index_name PRIMARY
stat_name n_leaf_pages
stat_value 1
table_name stats_rename1
index_name PRIMARY
stat_name size
stat_value 1
table_name stats_rename2
index_name PRIMARY
stat_name n_diff_pfx01
stat_value 567
table_name stats_rename2
index_name PRIMARY
stat_name n_leaf_pages
stat_value 567
table_name stats_rename2
index_name PRIMARY
stat_name size
stat_value 567
RENAME TABLE stats_rename1 TO stats_rename2;
SELECT table_name, n_rows
FROM mysql.innodb_table_stats
WHERE table_name IN ('stats_rename1', 'stats_rename2');
table_name stats_rename2
n_rows 0
SELECT table_name, index_name, stat_name, stat_value
FROM mysql.innodb_index_stats
WHERE table_name IN ('stats_rename1', 'stats_rename2');
table_name stats_rename2
index_name PRIMARY
stat_name n_diff_pfx01
stat_value 0
table_name stats_rename2
index_name PRIMARY
stat_name n_leaf_pages
stat_value 1
table_name stats_rename2
index_name PRIMARY
stat_name size
stat_value 1
DROP TABLE stats_rename2;
#
# Test the persistent stats feature
#
-- source include/have_innodb.inc
-- disable_warnings
-- disable_query_log
DROP TABLE IF EXISTS test_innodb_stats;
CREATE TABLE test_innodb_stats (
a INT,
KEY a_key (a)
) ENGINE=INNODB STATS_PERSISTENT=1;
-- enable_warnings
-- enable_query_log
# test empty table
-- let $insert = SELECT 'dummy INSERT, the table should be empty'
-- source suite/innodb/include/innodb_stats.inc
# test table with 1 row
-- let $insert = INSERT INTO test_innodb_stats (a) VALUES (1)
-- source suite/innodb/include/innodb_stats.inc
# test table with 2 eq rows
-- let $insert = INSERT INTO test_innodb_stats (a) VALUES (1), (1)
-- source suite/innodb/include/innodb_stats.inc
# test table with 3 eq rows
-- let $insert = INSERT INTO test_innodb_stats (a) VALUES (1), (1), (1)
-- source suite/innodb/include/innodb_stats.inc
# test table with 10 eq rows
-- let $insert = INSERT INTO test_innodb_stats (a) VALUES (1), (1), (1), (1), (1), (1), (1), (1), (1), (1)
-- source suite/innodb/include/innodb_stats.inc
# test table with 2 diff rows
-- let $insert = INSERT INTO test_innodb_stats (a) VALUES (1), (2)
-- source suite/innodb/include/innodb_stats.inc
# test table with 2 diff rows, 3 rows in total
-- let $insert = INSERT INTO test_innodb_stats (a) VALUES (1), (1), (2)
-- source suite/innodb/include/innodb_stats.inc
# test table with 3 diff rows
-- let $insert = INSERT INTO test_innodb_stats (a) VALUES (1), (2), (3)
-- source suite/innodb/include/innodb_stats.inc
# test table with 3 diff rows, 5 rows in total
-- let $insert = INSERT INTO test_innodb_stats (a) VALUES (1), (1), (2), (3), (3)
-- source suite/innodb/include/innodb_stats.inc
# test table with 5 diff rows, 10 rows in total
-- let $insert = INSERT INTO test_innodb_stats (a) VALUES (1), (2), (3), (4), (5), (1), (2), (3), (4), (5)
-- source suite/innodb/include/innodb_stats.inc
-- disable_query_log
DROP TABLE test_innodb_stats;
#
# Test creating a persistent stats table on nonexistent or corrupted
# persistent storage
#
-- source include/have_innodb.inc
# Various sizes printed in this test depend on the page size and the
# functionality tested here is not related to the page size, so we only
# test with 16k page size.
-- source include/have_innodb_16k.inc
call mtr.add_suppression("InnoDB: Error: Table \"mysql\".\"innodb_index_stats\" not found");
call mtr.add_suppression("InnoDB: Error: Fetch of persistent statistics requested for table");
-- vertical_results
# corrupt the persistent storage
ALTER TABLE mysql.innodb_index_stats RENAME TO mysql.innodb_index_stats_;
CREATE TABLE test_ps_create_on_corrupted
(a INT, PRIMARY KEY (a))
ENGINE=INNODB STATS_PERSISTENT=1;
# check the stats (should have been generated using the old transient stats
# method)
SELECT seq_in_index, column_name, cardinality
FROM information_schema.statistics WHERE table_name = 'test_ps_create_on_corrupted'
ORDER BY index_name, seq_in_index;
SELECT table_rows, avg_row_length, max_data_length, index_length
FROM information_schema.tables WHERE table_name = 'test_ps_create_on_corrupted';
# restore the persistent storage
ALTER TABLE mysql.innodb_index_stats_ RENAME TO mysql.innodb_index_stats;
DROP TABLE test_ps_create_on_corrupted;
#
# Test CREATE TABLE ... STATS_PERSISTENT=0|1|default
#
-- source include/have_innodb.inc
set @save_innodb_stats_persistent= @@innodb_stats_persistent;
set global innodb_stats_persistent=default;
-- vertical_results
# confirm that nothing is present before the test
SELECT COUNT(*) FROM mysql.innodb_table_stats WHERE
database_name = 'test' AND
table_name = 'test_ps_create_table';
##
CREATE TABLE test_ps_create_table (a INT, PRIMARY KEY (a))
ENGINE=INNODB STATS_PERSISTENT=0;
# nothing should be present
SELECT COUNT(*) FROM mysql.innodb_table_stats WHERE
database_name = 'test' AND
table_name = 'test_ps_create_table';
DROP TABLE test_ps_create_table;
##
CREATE TABLE test_ps_create_table (a INT, PRIMARY KEY (a))
ENGINE=INNODB;
# 1 row should be present if the default of --innodb-stats-persistent is 1
SELECT COUNT(*) FROM mysql.innodb_table_stats WHERE
database_name = 'test' AND
table_name = 'test_ps_create_table';
DROP TABLE test_ps_create_table;
##
CREATE TABLE test_ps_create_table (a INT, PRIMARY KEY (a))
ENGINE=INNODB STATS_PERSISTENT=default;
# 1 row should be present if the default of --innodb-stats-persistent is 1
SELECT COUNT(*) FROM mysql.innodb_table_stats WHERE
database_name = 'test' AND
table_name = 'test_ps_create_table';
DROP TABLE test_ps_create_table;
##
CREATE TABLE test_ps_create_table (a INT, PRIMARY KEY (a))
ENGINE=INNODB STATS_PERSISTENT=1;
# 1 row should be present
SELECT COUNT(*) FROM mysql.innodb_table_stats WHERE
database_name = 'test' AND
table_name = 'test_ps_create_table';
DROP TABLE test_ps_create_table;
set global innodb_stats_persistent= @save_innodb_stats_persistent;
#
# Test the persistent stats feature when DROPping a table or an
# index when the corresponding rows in the stats tables are locked
#
-- source include/have_innodb.inc
-- disable_warnings
-- disable_query_log
DROP TABLE IF EXISTS innodb_stats_drop_locked;
CREATE TABLE innodb_stats_drop_locked (c INT, KEY c_key (c))
ENGINE=INNODB STATS_PERSISTENT=1;
ANALYZE TABLE innodb_stats_drop_locked;
-- enable_warnings
-- enable_query_log
SET autocommit=0;
SELECT table_name FROM mysql.innodb_table_stats
WHERE table_name='innodb_stats_drop_locked'
FOR UPDATE;
SELECT table_name FROM mysql.innodb_index_stats
WHERE table_name='innodb_stats_drop_locked'
FOR UPDATE;
-- connect (con1,localhost,root,,)
-- connection con1
ALTER TABLE innodb_stats_drop_locked DROP INDEX c_key;
# the index should be gone
SHOW CREATE TABLE innodb_stats_drop_locked;
DROP TABLE innodb_stats_drop_locked;
# the table should be gone
SHOW TABLES;
-- connection default
-- disconnect con1
COMMIT;
# the stats should be there
SELECT table_name FROM mysql.innodb_table_stats
WHERE table_name='innodb_stats_drop_locked';
SELECT table_name FROM mysql.innodb_index_stats
WHERE table_name='innodb_stats_drop_locked';
--disable_query_log
call mtr.add_suppression("Unable to delete statistics for table test.innodb_stats_drop_locked: Lock wait timeout. They can be deleted later using DELETE FROM mysql.innodb_index_stats WHERE database_name");
--enable_query_log
#
# Test fetching from stats tables after manual update (ie FLUSH TABLE
# can be used to forcibly (re)fetch the stats from disk)
#
-- source include/have_innodb.inc
# Various sizes printed in this test depend on the page size and the
# functionality tested here is not related to the page size, so we only
# test with 16k page size.
-- source include/have_innodb_16k.inc
-- vertical_results
CREATE TABLE test_ps_fetch
(a INT, b INT, c INT, d INT, PRIMARY KEY (a, b), INDEX idx (c, d))
ENGINE=INNODB STATS_PERSISTENT=1;
ANALYZE TABLE test_ps_fetch;
SELECT n_rows, clustered_index_size, sum_of_other_index_sizes
FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_fetch';
SELECT index_name, stat_name, stat_value, sample_size, stat_description
FROM mysql.innodb_index_stats WHERE table_name = 'test_ps_fetch'
ORDER BY index_name, stat_name;
SELECT index_name, seq_in_index, column_name, cardinality
FROM information_schema.statistics WHERE table_name = 'test_ps_fetch'
ORDER BY index_name, seq_in_index;
SELECT
table_rows, avg_row_length, max_data_length, index_length
FROM information_schema.tables WHERE table_name = 'test_ps_fetch';
UPDATE mysql.innodb_table_stats SET
n_rows = 1000,
clustered_index_size = 5
WHERE
table_name = 'test_ps_fetch';
UPDATE mysql.innodb_index_stats SET
stat_value = 20
WHERE
table_name = 'test_ps_fetch' AND
index_name = 'PRIMARY' AND
stat_name = 'n_diff_pfx01';
UPDATE mysql.innodb_index_stats SET
stat_value = 90
WHERE
table_name = 'test_ps_fetch' AND
index_name = 'PRIMARY' AND
stat_name = 'n_diff_pfx02';
UPDATE mysql.innodb_index_stats SET
stat_value = 3
WHERE
table_name = 'test_ps_fetch' AND
index_name = 'idx' AND
stat_name = 'n_diff_pfx01';
UPDATE mysql.innodb_index_stats SET
stat_value = 11
WHERE
table_name = 'test_ps_fetch' AND
index_name = 'idx' AND
stat_name = 'n_diff_pfx02';
FLUSH TABLE test_ps_fetch;
SELECT seq_in_index, column_name, cardinality
FROM information_schema.statistics WHERE table_name = 'test_ps_fetch'
ORDER BY index_name, seq_in_index;
SELECT
table_rows, avg_row_length, max_data_length, index_length
FROM information_schema.tables WHERE table_name = 'test_ps_fetch';
DROP TABLE test_ps_fetch;
#
# Test fetching from stats tables that are corrupted
#
-- source include/have_innodb.inc
# Various sizes printed in this test depend on the page size and the
# functionality tested here is not related to the page size, so we only
# test with 16k page size.
-- source include/have_innodb_16k.inc
call mtr.add_suppression("InnoDB: Error: Table \"mysql\".\"innodb_index_stats\" not found");
call mtr.add_suppression("InnoDB: Error: Fetch of persistent statistics requested for table");
-- vertical_results
CREATE TABLE test_ps_fetch_corrupted
(a INT, PRIMARY KEY (a))
ENGINE=INNODB STATS_PERSISTENT=1;
# write stats to mysql.innodb_table_stats
ANALYZE TABLE test_ps_fetch_corrupted;
# check that indeed stats were written by ANALYZE above
SELECT n_rows, clustered_index_size, sum_of_other_index_sizes
FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_fetch_corrupted';
# corrupt the persistent storage
ALTER TABLE mysql.innodb_index_stats RENAME TO mysql.innodb_index_stats_;
# reopen the table, this will attept to read from the persistent storage
FLUSH TABLE test_ps_fetch_corrupted;
# check the stats (should have been generated using the old transient stats
# method)
SELECT seq_in_index, column_name, cardinality
FROM information_schema.statistics WHERE table_name = 'test_ps_fetch_corrupted'
ORDER BY index_name, seq_in_index;
SELECT table_rows, avg_row_length, max_data_length, index_length
FROM information_schema.tables WHERE table_name = 'test_ps_fetch_corrupted';
# restore the persistent storage
ALTER TABLE mysql.innodb_index_stats_ RENAME TO mysql.innodb_index_stats;
DROP TABLE test_ps_fetch_corrupted;
#
# Test fetching from stats tables while there are no stats
#
-- source include/have_innodb.inc
-- vertical_results
CREATE TABLE test_ps_fetch_nonexistent
(a INT, PRIMARY KEY (a))
ENGINE=INNODB STATS_PERSISTENT=1;
# write stats to mysql.innodb_table_stats
ANALYZE TABLE test_ps_fetch_nonexistent;
# check that indeed stats were written by ANALYZE above
SELECT COUNT(*)
FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_fetch_nonexistent';
# delete the stats
DELETE FROM mysql.innodb_index_stats WHERE table_name = 'test_ps_fetch_nonexistent';
DELETE FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_fetch_nonexistent';
# reopen the table, this will attept to read the stats
FLUSH TABLE test_ps_fetch_nonexistent;
# check the stats (should have been generated using the old transient stats
# method)
SELECT seq_in_index, column_name, cardinality
FROM information_schema.statistics WHERE table_name = 'test_ps_fetch_nonexistent'
ORDER BY index_name, seq_in_index;
SELECT table_rows, avg_row_length, max_data_length, index_length
FROM information_schema.tables WHERE table_name = 'test_ps_fetch_nonexistent';
DROP TABLE test_ps_fetch_nonexistent;
#
# Test that RENAME TABLE renames the entries in
# mysql.innodb_table_stats and mysql.innodb_index_stats
#
-- source include/have_innodb.inc
-- vertical_results
# confirm that nothing is present before the test
SELECT table_name, n_rows
FROM mysql.innodb_table_stats
WHERE table_name IN ('stats_rename_old', 'stats_rename_new');
SELECT table_name, index_name, stat_name, stat_value
FROM mysql.innodb_index_stats
WHERE table_name IN ('stats_rename_old', 'stats_rename_new');
CREATE TABLE stats_rename_old (a INT, PRIMARY KEY (a))
ENGINE=INNODB STATS_PERSISTENT=1;
# confirm that CREATE inserted a zeroed entries
SELECT table_name, n_rows
FROM mysql.innodb_table_stats
WHERE table_name IN ('stats_rename_old', 'stats_rename_new');
SELECT table_name, index_name, stat_name, stat_value
FROM mysql.innodb_index_stats
WHERE table_name IN ('stats_rename_old', 'stats_rename_new');
RENAME TABLE stats_rename_old TO stats_rename_new;
# confirm that rows were updated correspondingly
SELECT table_name, n_rows
FROM mysql.innodb_table_stats
WHERE table_name IN ('stats_rename_old', 'stats_rename_new');
SELECT table_name, index_name, stat_name, stat_value
FROM mysql.innodb_index_stats
WHERE table_name IN ('stats_rename_old', 'stats_rename_new');
DROP TABLE stats_rename_new;
#
# Test what happens during RENAME TABLE if there are already rows in the stats
# tables for the new table. This cannot happen normally, one have to insert
# manually like what we do here.
#
# The RENAME should succeed and existent rows should be overwritten.
#
-- source include/have_innodb.inc
-- vertical_results
CREATE TABLE stats_rename1 (a INT, PRIMARY KEY (a))
ENGINE=INNODB STATS_PERSISTENT=1;
INSERT INTO mysql.innodb_table_stats
SELECT
database_name,
'stats_rename2' AS table_name,
last_update,
123 AS n_rows,
clustered_index_size,
sum_of_other_index_sizes
FROM mysql.innodb_table_stats
WHERE table_name = 'stats_rename1';
INSERT INTO mysql.innodb_index_stats
SELECT
database_name,
'stats_rename2' AS table_name,
index_name,
last_update,
stat_name,
567 AS stat_value,
sample_size,
stat_description
FROM mysql.innodb_index_stats
WHERE table_name = 'stats_rename1';
SELECT table_name, n_rows
FROM mysql.innodb_table_stats
WHERE table_name IN ('stats_rename1', 'stats_rename2');
SELECT table_name, index_name, stat_name, stat_value
FROM mysql.innodb_index_stats
WHERE table_name IN ('stats_rename1', 'stats_rename2');
RENAME TABLE stats_rename1 TO stats_rename2;
SELECT table_name, n_rows
FROM mysql.innodb_table_stats
WHERE table_name IN ('stats_rename1', 'stats_rename2');
SELECT table_name, index_name, stat_name, stat_value
FROM mysql.innodb_index_stats
WHERE table_name IN ('stats_rename1', 'stats_rename2');
DROP TABLE stats_rename2;
......@@ -562,12 +562,16 @@ inline bool is_system_table_name(const char *name, uint length)
my_tolower(ci, name[2]) == 'm' &&
my_tolower(ci, name[3]) == 'e') ||
/* one of mysql.*_stat tables */
(my_tolower(ci, name[length-5]) == 's' &&
my_tolower(ci, name[length-4]) == 't' &&
my_tolower(ci, name[length-3]) == 'a' &&
my_tolower(ci, name[length-2]) == 't' &&
my_tolower(ci, name[length-1]) == 's') ||
/* one of mysql.*_stat tables, but not mysql.innodb* tables*/
((my_tolower(ci, name[length-5]) == 's' &&
my_tolower(ci, name[length-4]) == 't' &&
my_tolower(ci, name[length-3]) == 'a' &&
my_tolower(ci, name[length-2]) == 't' &&
my_tolower(ci, name[length-1]) == 's') &&
!(my_tolower(ci, name[0]) == 'i' &&
my_tolower(ci, name[1]) == 'n' &&
my_tolower(ci, name[2]) == 'n' &&
my_tolower(ci, name[3]) == 'o')) ||
/* mysql.event table */
(my_tolower(ci, name[0]) == 'e' &&
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment