polardbxengine/mysql-test/suite/secondary_engine/t/query_preparation_debug.test

174 lines
6.3 KiB
Plaintext

--source include/have_debug.inc
--source include/have_debug_sync.inc
# Supplemental test case for query repreparation. Test what happens if
# EXECUTE fails to open the secondary tables after PREPARE has
# successfully opened them, using a debug flag to inject an error in
# EXECUTE.
--disable_query_log
eval INSTALL PLUGIN MOCK SONAME '$MOCK_PLUGIN';
--enable_query_log
CREATE TABLE t(x INT) SECONDARY_ENGINE MOCK;
INSERT INTO t VALUES (1);
ALTER TABLE t SECONDARY_LOAD;
# First execute the statement without the debug flag. The statement
# should be executed on the secondary engine.
FLUSH STATUS;
PREPARE ps FROM 'SELECT * FROM t';
EXECUTE ps;
SHOW SESSION STATUS LIKE 'Secondary_engine_execution_count';
# Now set the debug flag. Execution fails when preparing the secondary
# engine. The failure triggers a repreparation against the primary
# storage engine.
FLUSH STATUS;
SET DEBUG = '+d,secondary_engine_mock_prepare_error';
EXECUTE ps;
SET DEBUG = '-d,secondary_engine_mock_prepare_error';
SHOW SESSION STATUS LIKE 'Secondary_engine_execution_count';
# The statement remembers that the previous execution failed to open
# the secondary tables, so it will not attempt to use the secondary
# engine on re-execution.
FLUSH STATUS;
EXECUTE ps;
SHOW SESSION STATUS LIKE 'Secondary_engine_execution_count';
DROP TABLE t;
--echo #
--echo # WL#12389: Add interface for optimizing queries in secondary engines
--echo #
CREATE TABLE t1(x INT) SECONDARY_ENGINE MOCK;
INSERT INTO t1 VALUES (1), (2), (3);
CREATE TABLE t2(y INT) SECONDARY_ENGINE MOCK;
INSERT INTO t2 VALUES (3), (4), (5);
ALTER TABLE t1 SECONDARY_LOAD;
ALTER TABLE t2 SECONDARY_LOAD;
ANALYZE TABLE t1, t2;
# Verify that the secondary engine optimization was invoked by
# injecting an error in the secondary engine optimization. The error
# prevents the queries from being offloaded to the MOCK engine.
SET DEBUG = "+d,secondary_engine_mock_optimize_error";
EXPLAIN SELECT * FROM t1;
--error ER_SECONDARY_ENGINE
EXPLAIN SELECT /*+ SET_VAR(use_secondary_engine = FORCED) */ x FROM t1;
EXPLAIN SELECT (SELECT y FROM t2 WHERE y = 1) FROM t1;
EXPLAIN SELECT * FROM t1 UNION ALL SELECT * FROM t2;
EXPLAIN SELECT * FROM t1 UNION DISTINCT SELECT * FROM t2;
SET DEBUG = "-d,secondary_engine_mock_optimize_error";
# The same queries should use the MOCK engine if no error is injected.
EXPLAIN SELECT * FROM t1;
EXPLAIN SELECT (SELECT y FROM t2 WHERE y = 1) FROM t1;
EXPLAIN SELECT * FROM t1 UNION ALL SELECT * FROM t2;
EXPLAIN SELECT * FROM t1 UNION DISTINCT SELECT * FROM t2;
DROP TABLE t1, t2;
# A query that is killed during secondary engine optimization, should
# not be retried in the primary engine.
CREATE TABLE t(x int) SECONDARY_ENGINE MOCK;
INSERT INTO t VALUES (1), (2), (3);
ALTER TABLE t SECONDARY_LOAD;
SET DEBUG_SYNC = 'before_mock_optimize SIGNAL mock WAIT_FOR continue';
--send SELECT * FROM t
--connect(conn1,localhost,root,,)
SET DEBUG_SYNC = 'now WAIT_FOR mock';
SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST
WHERE INFO = 'SELECT * FROM t' INTO @thread_id;
KILL QUERY @thread_id;
SET DEBUG_SYNC = 'now SIGNAL continue';
--connection default
--error ER_QUERY_INTERRUPTED
--reap
--disconnect conn1
DROP TABLE t;
--echo #
--echo # Bug#29023387: GET PLAN COST FROM SECONDARY ENGINE
--echo #
CREATE TABLE t1(x INT, y INT) SECONDARY_ENGINE MOCK;
CREATE TABLE t2(x INT, y INT) SECONDARY_ENGINE MOCK;
CREATE TABLE t3(x INT, y INT) SECONDARY_ENGINE MOCK;
INSERT INTO t1 VALUES (1, 2), (3, 4);
INSERT INTO t1 SELECT * FROM t1;
INSERT INTO t1 SELECT * FROM t1;
INSERT INTO t2 VALUES (1, 2), (3, 4);
INSERT INTO t2 SELECT * FROM t2;
INSERT INTO t3 VALUES (1, 2), (3, 4);
ALTER TABLE t1 SECONDARY_LOAD;
ALTER TABLE t2 SECONDARY_LOAD;
ALTER TABLE t3 SECONDARY_LOAD;
ANALYZE TABLE t1, t2, t3;
SET @@optimizer_trace='enabled=on';
EXPLAIN SELECT * FROM t1 JOIN t2 ON t1.x = t2.y LEFT JOIN t3 ON t2.x = t3.y;
SELECT TRACE->'$**.secondary_engine_cost' FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE;
SET @@optimizer_trace='enabled=off';
# Set a debug flag so that the join order is chosen based on how early
# a table with the alias X is.
SET DEBUG = "+d,secondary_engine_mock_change_join_order";
# The note in the warning from EXPLAIN shows the alias X in different case
# on different platforms, so disable warnings to hide the differences.
--disable_warnings
EXPLAIN SELECT * FROM t1 AS X JOIN t2 ON X.x = t2.y LEFT JOIN t3 ON t2.x = t3.y;
EXPLAIN SELECT * FROM t1 JOIN t2 AS X ON t1.x = X.y LEFT JOIN t3 ON X.x = t3.y;
EXPLAIN SELECT * FROM t1 JOIN t2 ON t1.x = t2.y LEFT JOIN t3 AS X ON t2.x = X.y;
--enable_warnings
SET DEBUG = "-d,secondary_engine_mock_change_join_order";
SET DEBUG = "+d,secondary_engine_mock_compare_cost_error";
# The injected error causes fallback to the primary engine.
EXPLAIN SELECT * FROM t1 JOIN t2 ON t1.x = t2.y LEFT JOIN t3 ON t2.x = t3.y;
SET DEBUG = "-d,secondary_engine_mock_compare_cost_error";
DROP TABLE t1, t2, t3;
--echo #
--echo # Bug#29615190: SELECTS ON TABLES OFFLOADED TO SECONDARY ENGINE ARE
--echo # WRITTEN TWICE TO THE MYSQLD GENERAL LOG
--echo #
# Test what is written to the general log if a statement is attempted
# offloaded, but rejected by the secondary engine. It used to be
# written three times to the general log. Once is enough.
CREATE TABLE t(x INT) SECONDARY_ENGINE MOCK;
ALTER TABLE t SECONDARY_LOAD;
SET @saved_general_log = @@global.general_log;
SET @saved_log_output = @@global.log_output;
SET GLOBAL general_log = 1;
SET GLOBAL log_output = 'table';
SET DEBUG = '+d,secondary_engine_mock_optimize_error';
TRUNCATE TABLE mysql.general_log;
SELECT * FROM t;
# Expect the query to be written once to the general log (or twice
# under ps protocol - once for preparation and once for execution).
--disable_query_log
eval SELECT COUNT(*) - $PS_PROTOCOL AS statement_count
FROM mysql.general_log
WHERE argument = 'SELECT * FROM t';
--enable_query_log
TRUNCATE TABLE mysql.general_log;
PREPARE ps FROM 'SELECT * FROM t';
SELECT COUNT(*) FROM mysql.general_log WHERE argument = 'SELECT * FROM t';
EXECUTE ps;
SELECT COUNT(*) FROM mysql.general_log WHERE argument = 'SELECT * FROM t';
DROP PREPARE ps;
SET GLOBAL general_log = @saved_general_log;
SET GLOBAL log_output = @saved_log_output;
SET DEBUG = '-d,secondary_engine_mock_optimize_error';
TRUNCATE TABLE mysql.general_log;
DROP TABLE t;
--disable_query_log
UNINSTALL PLUGIN mock;
--enable_query_log