diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 5008a048148..1979214de17 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -1464,8 +1464,18 @@ void free_used_memory() } +#ifdef EMBEDDED_LIBRARY +void ha_pre_shutdown(); +#endif + + ATTRIBUTE_NORETURN static void cleanup_and_exit(int exit_code) { +#ifdef EMBEDDED_LIBRARY + if (server_initialized) + ha_pre_shutdown(); +#endif + free_used_memory(); /* Only call mysql_server_end if mysql_server_init has been called */ diff --git a/mysql-test/include/default_mysqld.cnf b/mysql-test/include/default_mysqld.cnf index cccf72591cc..4788fbb7ff6 100644 --- a/mysql-test/include/default_mysqld.cnf +++ b/mysql-test/include/default_mysqld.cnf @@ -1,5 +1,5 @@ # Copyright (c) 2007, 2013, Oracle and/or its affiliates -# Copyright (c) 2010, 2019, MariaDB Corporation +# Copyright (c) 2010, 2021, MariaDB Corporation # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -54,7 +54,6 @@ loose-innodb_write_io_threads= 2 loose-innodb_read_io_threads= 2 loose-innodb_log_buffer_size= 1M loose-innodb_log_file_size= 10M -loose-innodb-stats-persistent= OFF slave-net-timeout=120 diff --git a/mysql-test/main/bug39022.result b/mysql-test/main/bug39022.result index 599808ca7d7..5667c36ae94 100644 --- a/mysql-test/main/bug39022.result +++ b/mysql-test/main/bug39022.result @@ -28,7 +28,7 @@ SELECT d FROM t2,t1 WHERE d=(SELECT MAX(a) FROM t1 WHERE t1.a > t2.d) LOCK IN SH connection thread1; # should not crash SELECT d FROM t2,t1 WHERE d=(SELECT MAX(a) FROM t1 WHERE t1.a > t2.d) LOCK IN SHARE MODE; -ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +Got one of the listed errors connection thread2; d disconnect thread2; diff --git a/mysql-test/main/bug39022.test b/mysql-test/main/bug39022.test index d293788e58e..e07d087a320 100644 --- a/mysql-test/main/bug39022.test +++ b/mysql-test/main/bug39022.test @@ -40,7 +40,7 @@ SELECT d FROM t2,t1 WHERE d=(SELECT MAX(a) FROM t1 WHERE t1.a > t2.d) LOCK IN SH connection thread1; --echo # should not crash ---error ER_LOCK_DEADLOCK +--error ER_LOCK_DEADLOCK,ER_LOCK_WAIT_TIMEOUT SELECT d FROM t2,t1 WHERE d=(SELECT MAX(a) FROM t1 WHERE t1.a > t2.d) LOCK IN SHARE MODE; #crashes connection thread2; diff --git a/mysql-test/main/column_compression_rpl.opt b/mysql-test/main/column_compression_rpl.opt new file mode 100644 index 00000000000..1a01b4018c6 --- /dev/null +++ b/mysql-test/main/column_compression_rpl.opt @@ -0,0 +1 @@ +--skip-innodb-stats-persistent diff --git a/mysql-test/main/create_or_replace.result b/mysql-test/main/create_or_replace.result index 1eaf87d190d..19d9f3e65a1 100644 --- a/mysql-test/main/create_or_replace.result +++ b/mysql-test/main/create_or_replace.result @@ -1,4 +1,3 @@ -drop table if exists t1,t2,t3; CREATE TABLE t2 (a int); INSERT INTO t2 VALUES(1),(2),(3); # @@ -259,7 +258,8 @@ Note 1051 Unknown table 'test.t1,mysqltest2.t2' create table test.t1 (i int) engine=myisam; create table mysqltest2.t2 like test.t1; lock table test.t1 write, mysqltest2.t2 write; -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME # MDL_BACKUP_DDL NULL Backup lock # MDL_BACKUP_DML NULL Backup lock @@ -272,7 +272,8 @@ ERROR 42000: A table must have at least 1 column show tables; Tables_in_test t2 -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME # MDL_BACKUP_DDL NULL Backup lock # MDL_BACKUP_DML NULL Backup lock @@ -281,14 +282,16 @@ THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME # MDL_SHARED_NO_READ_WRITE NULL Table metadata lock mysqltest2 t2 create or replace table mysqltest2.t2; ERROR 42000: A table must have at least 1 column -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME create table t1 (i int); drop table t1; create table test.t1 (i int); create table mysqltest2.t2 like test.t1; lock table test.t1 write, mysqltest2.t2 write; -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME # MDL_BACKUP_DDL NULL Backup lock # MDL_BACKUP_DML NULL Backup lock @@ -301,7 +304,8 @@ ERROR 42S21: Duplicate column name 'a' show tables; Tables_in_test t2 -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME # MDL_BACKUP_DDL NULL Backup lock # MDL_BACKUP_DML NULL Backup lock @@ -310,14 +314,16 @@ THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME # MDL_SHARED_NO_READ_WRITE NULL Table metadata lock mysqltest2 t2 create or replace table mysqltest2.t2 (a int) select 1 as 'a', 2 as 'a'; ERROR 42S21: Duplicate column name 'a' -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME create table t1 (i int); drop table t1; create table test.t1 (i int) engine=innodb; create table mysqltest2.t2 like test.t1; lock table test.t1 write, mysqltest2.t2 write; -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME # MDL_BACKUP_DDL NULL Backup lock # MDL_INTENTION_EXCLUSIVE NULL Schema metadata lock mysqltest2 @@ -329,7 +335,8 @@ drop table test.t1,mysqltest2.t2; create table test.t1 (i int) engine=aria transactional=1 checksum=1; create table mysqltest2.t2 like test.t1; lock table test.t1 write, mysqltest2.t2 write; -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME # MDL_BACKUP_DDL NULL Backup lock # MDL_INTENTION_EXCLUSIVE NULL Schema metadata lock mysqltest2 @@ -424,7 +431,8 @@ drop view t1; # create table t1 (a int); lock table t1 write, t2 read; -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME # MDL_BACKUP_DDL NULL Backup lock # MDL_BACKUP_DML NULL Backup lock @@ -432,7 +440,8 @@ THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME # MDL_SHARED_NO_READ_WRITE NULL Table metadata lock test t1 # MDL_SHARED_READ NULL Table metadata lock test t2 create or replace table t1 (i int); -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME # MDL_BACKUP_DDL NULL Backup lock # MDL_BACKUP_DML NULL Backup lock @@ -440,7 +449,8 @@ THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME # MDL_SHARED_NO_READ_WRITE NULL Table metadata lock test t1 # MDL_SHARED_READ NULL Table metadata lock test t2 create or replace table t1 like t2; -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME # MDL_BACKUP_DDL NULL Backup lock # MDL_BACKUP_DML NULL Backup lock @@ -448,7 +458,8 @@ THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME # MDL_SHARED_NO_READ_WRITE NULL Table metadata lock test t1 # MDL_SHARED_READ NULL Table metadata lock test t2 create or replace table t1 select 1 as f1; -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME # MDL_BACKUP_DDL NULL Backup lock # MDL_BACKUP_DML NULL Backup lock diff --git a/mysql-test/main/create_or_replace.test b/mysql-test/main/create_or_replace.test index 1b4994e811f..a39b3bbe1cd 100644 --- a/mysql-test/main/create_or_replace.test +++ b/mysql-test/main/create_or_replace.test @@ -4,9 +4,6 @@ --source include/have_innodb.inc --source include/have_metadata_lock_info.inc ---disable_warnings -drop table if exists t1,t2,t3; ---enable_warnings # # Create help table @@ -215,18 +212,21 @@ create table mysqltest2.t2 like test.t1; lock table test.t1 write, mysqltest2.t2 write; --replace_column 1 # --sorted_result -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; --error ER_TABLE_MUST_HAVE_COLUMNS create or replace table test.t1; show tables; --replace_column 1 # --sorted_result -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; --error ER_TABLE_MUST_HAVE_COLUMNS create or replace table mysqltest2.t2; --replace_column 1 # --sorted_result -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; create table t1 (i int); drop table t1; @@ -235,18 +235,21 @@ create table mysqltest2.t2 like test.t1; lock table test.t1 write, mysqltest2.t2 write; --replace_column 1 # --sorted_result -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; --error ER_DUP_FIELDNAME create or replace table test.t1 (a int) select 1 as 'a', 2 as 'a'; show tables; --replace_column 1 # --sorted_result -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; --error ER_DUP_FIELDNAME create or replace table mysqltest2.t2 (a int) select 1 as 'a', 2 as 'a'; --replace_column 1 # --sorted_result -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; create table t1 (i int); drop table t1; @@ -255,7 +258,8 @@ create table mysqltest2.t2 like test.t1; lock table test.t1 write, mysqltest2.t2 write; --replace_column 1 # --sorted_result -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; unlock tables; drop table test.t1,mysqltest2.t2; @@ -264,7 +268,8 @@ create table mysqltest2.t2 like test.t1; lock table test.t1 write, mysqltest2.t2 write; --replace_column 1 # --sorted_result -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; unlock tables; drop table t1; @@ -344,19 +349,24 @@ create table t1 (a int); lock table t1 write, t2 read; --replace_column 1 # --sorted_result -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; + create or replace table t1 (i int); --replace_column 1 # --sorted_result -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; create or replace table t1 like t2; --replace_column 1 # --sorted_result -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; create or replace table t1 select 1 as f1; --replace_column 1 # --sorted_result -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; drop table t1; unlock tables; diff --git a/mysql-test/main/ctype_utf8mb4_innodb-master.opt b/mysql-test/main/ctype_utf8mb4_innodb-master.opt index 96f0ce3f36c..d1dc9a3e00f 100644 --- a/mysql-test/main/ctype_utf8mb4_innodb-master.opt +++ b/mysql-test/main/ctype_utf8mb4_innodb-master.opt @@ -1 +1,2 @@ --default-storage-engine=MyISAM +--innodb-stats-persistent=OFF diff --git a/mysql-test/main/derived_split_innodb.result b/mysql-test/main/derived_split_innodb.result index 9edf9a1f2ae..21921d86dab 100644 --- a/mysql-test/main/derived_split_innodb.result +++ b/mysql-test/main/derived_split_innodb.result @@ -1,3 +1,5 @@ +SET @save_innodb_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; # # MDEV-16917: do not use splitting for derived with join cache # @@ -241,3 +243,4 @@ set optimizer_switch='split_materialized=default'; set use_stat_tables=default; set optimizer_use_condition_selectivity=default; # End of 10.3 tests +SET GLOBAL innodb_stats_persistent=@save_innodb_stats_persistent; diff --git a/mysql-test/main/derived_split_innodb.test b/mysql-test/main/derived_split_innodb.test index bee9ef497b6..de25fd8e3d3 100644 --- a/mysql-test/main/derived_split_innodb.test +++ b/mysql-test/main/derived_split_innodb.test @@ -2,6 +2,9 @@ --source include/default_optimizer_switch.inc --source include/have_sequence.inc +SET @save_innodb_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; + --echo # --echo # MDEV-16917: do not use splitting for derived with join cache --echo # @@ -193,3 +196,5 @@ set use_stat_tables=default; set optimizer_use_condition_selectivity=default; --echo # End of 10.3 tests + +SET GLOBAL innodb_stats_persistent=@save_innodb_stats_persistent; diff --git a/mysql-test/main/endspace.result b/mysql-test/main/endspace.result index f9619db7e64..e7160f2829b 100644 --- a/mysql-test/main/endspace.result +++ b/mysql-test/main/endspace.result @@ -162,7 +162,8 @@ nothing teststring teststring drop table t1; -create table t1 (text1 varchar(32) not NULL, KEY key1 (text1)) engine=innodb; +create table t1 (text1 varchar(32) not NULL, KEY key1 (text1)) engine=innodb +stats_persistent=0; insert into t1 values ('teststring'), ('nothing'), ('teststring\t'); check table t1; Table Op Msg_type Msg_text diff --git a/mysql-test/main/endspace.test b/mysql-test/main/endspace.test index 69b8133c5f7..be120667b56 100644 --- a/mysql-test/main/endspace.test +++ b/mysql-test/main/endspace.test @@ -74,7 +74,8 @@ drop table t1; # Test InnoDB tables # -create table t1 (text1 varchar(32) not NULL, KEY key1 (text1)) engine=innodb; +create table t1 (text1 varchar(32) not NULL, KEY key1 (text1)) engine=innodb +stats_persistent=0; insert into t1 values ('teststring'), ('nothing'), ('teststring\t'); check table t1; select * from t1 where text1='teststring' or text1 like 'teststring_%'; diff --git a/mysql-test/main/fast_prefix_index_fetch_innodb.result b/mysql-test/main/fast_prefix_index_fetch_innodb.result index ef297e5c6b5..aa888fb0704 100644 --- a/mysql-test/main/fast_prefix_index_fetch_innodb.result +++ b/mysql-test/main/fast_prefix_index_fetch_innodb.result @@ -3,6 +3,8 @@ set global innodb_prefix_index_cluster_optimization = ON; show variables like 'innodb_prefix_index_cluster_optimization'; Variable_name Value innodb_prefix_index_cluster_optimization ON +SET @save_innodb_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = OFF; # Create a table with a large varchar field that we index the prefix # of and ensure we only trigger cluster lookups when we expect it. create table prefixinno ( @@ -455,3 +457,4 @@ blog_id 1 DROP TABLE wp_blogs; SET GLOBAL innodb_prefix_index_cluster_optimization = @save_opt; +SET GLOBAL innodb_stats_persistent = @save_innodb_stats_persistent; diff --git a/mysql-test/main/fast_prefix_index_fetch_innodb.test b/mysql-test/main/fast_prefix_index_fetch_innodb.test index 1987416ff87..cb7ec642fe3 100644 --- a/mysql-test/main/fast_prefix_index_fetch_innodb.test +++ b/mysql-test/main/fast_prefix_index_fetch_innodb.test @@ -4,6 +4,9 @@ SET @save_opt= @@GLOBAL.innodb_prefix_index_cluster_optimization; set global innodb_prefix_index_cluster_optimization = ON; show variables like 'innodb_prefix_index_cluster_optimization'; +SET @save_innodb_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = OFF; + --echo # Create a table with a large varchar field that we index the prefix --echo # of and ensure we only trigger cluster lookups when we expect it. create table prefixinno ( @@ -717,3 +720,4 @@ AND path IN ( '/fondsinvesteringer/', '/' ); DROP TABLE wp_blogs; SET GLOBAL innodb_prefix_index_cluster_optimization = @save_opt; +SET GLOBAL innodb_stats_persistent = @save_innodb_stats_persistent; diff --git a/mysql-test/main/index_merge_innodb.result b/mysql-test/main/index_merge_innodb.result index f1418d6a365..ada2abdc0d6 100644 --- a/mysql-test/main/index_merge_innodb.result +++ b/mysql-test/main/index_merge_innodb.result @@ -6,6 +6,8 @@ SET DEFAULT_STORAGE_ENGINE = InnoDB; set @optimizer_switch_save= @@optimizer_switch; set optimizer_switch='index_merge_sort_intersection=off'; set optimizer_switch='rowid_filter=off'; +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; #---------------- Index merge test 2 ------------------------------------------- create table t1 ( @@ -835,3 +837,4 @@ a b c DROP TABLE t1; SET sort_buffer_size= @save_sort_buffer_size; disconnect disable_purge; +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; diff --git a/mysql-test/main/index_merge_innodb.test b/mysql-test/main/index_merge_innodb.test index 5c4021036e7..e8ebb6b2a64 100644 --- a/mysql-test/main/index_merge_innodb.test +++ b/mysql-test/main/index_merge_innodb.test @@ -27,6 +27,9 @@ set @optimizer_switch_save= @@optimizer_switch; set optimizer_switch='index_merge_sort_intersection=off'; set optimizer_switch='rowid_filter=off'; +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; + # The first two tests are disabled because of non deterministic explain output. # If include/index_merge1.inc can be enabled for InnoDB and all other # storage engines, please remove the subtest for Bug#21277 from @@ -222,3 +225,4 @@ DROP TABLE t1; SET sort_buffer_size= @save_sort_buffer_size; disconnect disable_purge; +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; diff --git a/mysql-test/main/innodb_ext_key.result b/mysql-test/main/innodb_ext_key.result index 0d3e27e5bf0..5b99fa4e30b 100644 --- a/mysql-test/main/innodb_ext_key.result +++ b/mysql-test/main/innodb_ext_key.result @@ -602,6 +602,17 @@ INSERT INTO t3 VALUES (89,'text-8008',''),(90,'text-9008',''),(91,'text-9',''),(92,'text-1009',''), (93,'text-2009',''),(94,'text-3009',''),(95,'text-4009',''),(96,'text-5009',''), (97,'text-6009',''),(98,'text-7009',''),(99,'text-8009',''),(100,'text-9009',''); +ANALYZE TABLE t1,t2,t3; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze Warning Engine-independent statistics are not collected for column 'page_restrictions' +test.t1 analyze status OK +test.t2 analyze status Engine-independent statistics collected +test.t2 analyze status OK +test.t3 analyze status Engine-independent statistics collected +test.t3 analyze Warning Engine-independent statistics are not collected for column 'old_text' +test.t3 analyze Warning Engine-independent statistics are not collected for column 'old_flags' +test.t3 analyze status OK EXPLAIN SELECT * FROM t1, t2 IGNORE INDEX (PRIMARY), t3 WHERE page_id=rev_page AND rev_text_id=old_id AND page_namespace=4 AND page_title='Sandbox' diff --git a/mysql-test/main/innodb_ext_key.test b/mysql-test/main/innodb_ext_key.test index 77eda0df6f6..f1cf6658f0b 100644 --- a/mysql-test/main/innodb_ext_key.test +++ b/mysql-test/main/innodb_ext_key.test @@ -456,6 +456,7 @@ INSERT INTO t3 VALUES (89,'text-8008',''),(90,'text-9008',''),(91,'text-9',''),(92,'text-1009',''), (93,'text-2009',''),(94,'text-3009',''),(95,'text-4009',''),(96,'text-5009',''), (97,'text-6009',''),(98,'text-7009',''),(99,'text-8009',''),(100,'text-9009',''); +ANALYZE TABLE t1,t2,t3; EXPLAIN diff --git a/mysql-test/main/join_outer_innodb.result b/mysql-test/main/join_outer_innodb.result index 09a37a29702..6f87048cdc1 100644 --- a/mysql-test/main/join_outer_innodb.result +++ b/mysql-test/main/join_outer_innodb.result @@ -1,3 +1,5 @@ +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; CREATE TABLE t1 (id int(11) NOT NULL PRIMARY KEY, name varchar(20), INDEX (name)) ENGINE=InnoDB; CREATE TABLE t2 (id int(11) NOT NULL PRIMARY KEY, fkey int(11), @@ -515,3 +517,4 @@ UPDATE t1 LEFT JOIN t2 ON t1.c1 = t2.c2 AND t2.c1 = 3 SET t1.c3 = RAND()*10; COMMIT; SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; DROP TABLE t1,t2; +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; diff --git a/mysql-test/main/join_outer_innodb.test b/mysql-test/main/join_outer_innodb.test index 6b332f3d155..d1a8b0c4ab4 100644 --- a/mysql-test/main/join_outer_innodb.test +++ b/mysql-test/main/join_outer_innodb.test @@ -4,6 +4,8 @@ --source include/have_innodb.inc --source include/default_optimizer_switch.inc +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; # # Test for bug #17164: ORed FALSE blocked conversion of outer join into join @@ -391,3 +393,4 @@ COMMIT; SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; DROP TABLE t1,t2; +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; diff --git a/mysql-test/main/mdl.result b/mysql-test/main/mdl.result index fbf80312ac0..343895803b2 100644 --- a/mysql-test/main/mdl.result +++ b/mysql-test/main/mdl.result @@ -8,20 +8,23 @@ CREATE TABLE t1(a INT) ENGINE=InnoDB; CREATE TABLE t3(a INT) ENGINE=myisam; LOCK TABLES t1 WRITE CONCURRENT, t1 AS t2 READ; -SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info; +SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info +WHERE TABLE_NAME NOT LIKE 'innodb_%_stats'; LOCK_MODE LOCK_TYPE TABLE_SCHEMA TABLE_NAME MDL_BACKUP_TRANS_DML Backup lock MDL_SHARED_NO_READ_WRITE Table metadata lock test t1 UNLOCK TABLES; LOCK TABLES t1 AS t2 READ, t1 WRITE CONCURRENT; -SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info; +SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info +WHERE TABLE_NAME NOT LIKE 'innodb_%_stats'; LOCK_MODE LOCK_TYPE TABLE_SCHEMA TABLE_NAME MDL_BACKUP_TRANS_DML Backup lock MDL_SHARED_WRITE Table metadata lock test t1 MDL_SHARED_READ_ONLY Table metadata lock test t1 UNLOCK TABLES; LOCK TABLES t1 WRITE CONCURRENT, t3 WRITE; -SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info; +SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info +WHERE TABLE_NAME NOT LIKE 'innodb_%_stats'; LOCK_MODE LOCK_TYPE TABLE_SCHEMA TABLE_NAME MDL_BACKUP_DDL Backup lock MDL_BACKUP_DML Backup lock @@ -30,7 +33,8 @@ MDL_SHARED_NO_READ_WRITE Table metadata lock test t3 MDL_INTENTION_EXCLUSIVE Schema metadata lock test UNLOCK TABLES; LOCK TABLES t3 WRITE, t1 WRITE CONCURRENT; -SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info; +SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info +WHERE TABLE_NAME NOT LIKE 'innodb_%_stats'; LOCK_MODE LOCK_TYPE TABLE_SCHEMA TABLE_NAME MDL_BACKUP_DDL Backup lock MDL_BACKUP_DML Backup lock @@ -39,7 +43,8 @@ MDL_SHARED_NO_READ_WRITE Table metadata lock test t3 MDL_INTENTION_EXCLUSIVE Schema metadata lock test UNLOCK TABLES; LOCK TABLES t1 WRITE, mysql.user WRITE; -SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info; +SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info +WHERE TABLE_NAME NOT LIKE 'innodb_%_stats'; LOCK_MODE LOCK_TYPE TABLE_SCHEMA TABLE_NAME MDL_BACKUP_DDL Backup lock MDL_SHARED_NO_READ_WRITE Table metadata lock mysql user @@ -67,7 +72,8 @@ connection locker; insert into t1 values (1); connection default; connection default; -SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info; +SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info +WHERE TABLE_NAME NOT LIKE 'innodb_%_stats'; LOCK_MODE LOCK_TYPE TABLE_SCHEMA TABLE_NAME MDL_BACKUP_FTWRL2 Backup lock MDL_SHARED_WRITE Table metadata lock test t1 @@ -80,7 +86,8 @@ connection locker; insert into t3 values (2); connection default; connection default; -SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info; +SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info +WHERE TABLE_NAME NOT LIKE 'innodb_%_stats'; LOCK_MODE LOCK_TYPE TABLE_SCHEMA TABLE_NAME MDL_BACKUP_FTWRL2 Backup lock MDL_SHARED_WRITE Table metadata lock test t3 diff --git a/mysql-test/main/mdl.test b/mysql-test/main/mdl.test index 0c1b7a13a0c..f7fac0a062d 100644 --- a/mysql-test/main/mdl.test +++ b/mysql-test/main/mdl.test @@ -12,19 +12,24 @@ CREATE TABLE t1(a INT) ENGINE=InnoDB; CREATE TABLE t3(a INT) ENGINE=myisam; LOCK TABLES t1 WRITE CONCURRENT, t1 AS t2 READ; -SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info; +SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info +WHERE TABLE_NAME NOT LIKE 'innodb_%_stats'; UNLOCK TABLES; LOCK TABLES t1 AS t2 READ, t1 WRITE CONCURRENT; -SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info; +SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info +WHERE TABLE_NAME NOT LIKE 'innodb_%_stats'; UNLOCK TABLES; LOCK TABLES t1 WRITE CONCURRENT, t3 WRITE; -SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info; +SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info +WHERE TABLE_NAME NOT LIKE 'innodb_%_stats'; UNLOCK TABLES; LOCK TABLES t3 WRITE, t1 WRITE CONCURRENT; -SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info; +SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info +WHERE TABLE_NAME NOT LIKE 'innodb_%_stats'; UNLOCK TABLES; LOCK TABLES t1 WRITE, mysql.user WRITE; -SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info; +SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info +WHERE TABLE_NAME NOT LIKE 'innodb_%_stats'; UNLOCK TABLES; --error ER_CANT_LOCK_LOG_TABLE LOCK TABLES mysql.general_log WRITE; @@ -55,7 +60,8 @@ let $wait_condition= where state = "Waiting for backup lock"; --source include/wait_condition.inc connection default; -SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info; +SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info +WHERE TABLE_NAME NOT LIKE 'innodb_%_stats'; unlock tables; connection locker; --reap @@ -72,7 +78,8 @@ let $wait_condition= where state = "Waiting for backup lock"; --source include/wait_condition.inc connection default; -SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info; +SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info +WHERE TABLE_NAME NOT LIKE 'innodb_%_stats'; unlock tables; connection locker; --reap diff --git a/mysql-test/main/mysql_upgrade.result b/mysql-test/main/mysql_upgrade.result index 347d942be5e..1c50a499953 100644 --- a/mysql-test/main/mysql_upgrade.result +++ b/mysql-test/main/mysql_upgrade.result @@ -1969,7 +1969,7 @@ rename table mysql.global_priv_bak to mysql.global_priv; # Check that mysql_upgrade can be run on mysqldump # of mysql schema from previous versions # -call mtr.add_suppression("innodb_table_stats has length mismatch in the column name table_name"); +call mtr.add_suppression("innodb_(table|index)_stats has length mismatch in the column name table_name"); call mtr.add_suppression("Column count of mysql.proc is wrong. Expected 21, found 20."); # # Upgrade from version 5.5 diff --git a/mysql-test/main/mysql_upgrade.test b/mysql-test/main/mysql_upgrade.test index ae1b328e699..10dddbe7943 100644 --- a/mysql-test/main/mysql_upgrade.test +++ b/mysql-test/main/mysql_upgrade.test @@ -367,7 +367,7 @@ rename table mysql.global_priv_bak to mysql.global_priv; --echo # # The warning appears during mysql_upgrade, before the schema becomes consistent -call mtr.add_suppression("innodb_table_stats has length mismatch in the column name table_name"); +call mtr.add_suppression("innodb_(table|index)_stats has length mismatch in the column name table_name"); # This comes from opening 10.6 sys.host_summary view that uses sys.format_time function, # on still inconsistent mysql.proc, in older versions call mtr.add_suppression("Column count of mysql.proc is wrong. Expected 21, found 20."); diff --git a/mysql-test/main/order_by_optimizer_innodb.result b/mysql-test/main/order_by_optimizer_innodb.result index 0b62ba997d8..cbb5551b7cf 100644 --- a/mysql-test/main/order_by_optimizer_innodb.result +++ b/mysql-test/main/order_by_optimizer_innodb.result @@ -1,4 +1,5 @@ -drop table if exists t0,t1,t2,t3; +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=OFF; # # MDEV-6402: Optimizer doesn't choose best execution plan when composite key is used # @@ -96,3 +97,4 @@ ORDER BY pk2 DESC LIMIT 21; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ref key1 key1 55 const,const 1 Using where; Using index drop table t1, t2; +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; diff --git a/mysql-test/main/order_by_optimizer_innodb.test b/mysql-test/main/order_by_optimizer_innodb.test index 90430d11549..33f67e522ad 100644 --- a/mysql-test/main/order_by_optimizer_innodb.test +++ b/mysql-test/main/order_by_optimizer_innodb.test @@ -1,8 +1,7 @@ --source include/have_innodb.inc ---disable_warnings -drop table if exists t0,t1,t2,t3; ---enable_warnings +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=OFF; --echo # --echo # MDEV-6402: Optimizer doesn't choose best execution plan when composite key is used @@ -96,3 +95,4 @@ ORDER BY pk2 DESC LIMIT 21; drop table t1, t2; +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; diff --git a/mysql-test/main/range_vs_index_merge.result b/mysql-test/main/range_vs_index_merge.result index 207e012b825..7108fd89a7d 100644 --- a/mysql-test/main/range_vs_index_merge.result +++ b/mysql-test/main/range_vs_index_merge.result @@ -1,5 +1,3 @@ -DROP TABLE IF EXISTS t1,t2,t3,t4; -DROP DATABASE IF EXISTS world; set names utf8; CREATE DATABASE world; use world; diff --git a/mysql-test/main/range_vs_index_merge.test b/mysql-test/main/range_vs_index_merge.test index 94210ce5dd3..670762bcb2f 100644 --- a/mysql-test/main/range_vs_index_merge.test +++ b/mysql-test/main/range_vs_index_merge.test @@ -2,11 +2,6 @@ --source include/default_charset.inc --source include/have_sequence.inc ---disable_warnings -DROP TABLE IF EXISTS t1,t2,t3,t4; -DROP DATABASE IF EXISTS world; ---enable_warnings - set names utf8; CREATE DATABASE world; @@ -1049,6 +1044,8 @@ INSERT INTO t1 VALUES (0,99083,'all','jhjerdvdxboydmpefbiesqbyyvdftsidjtvulamazljx'), (32767,99084,'s','flj'),(-4947,99085,'something','Vermont'), (0,99086,'cjfljhjerd','Washington'); + +ANALYZE TABLE t1; --enable_query_log --enable_result_log diff --git a/mysql-test/main/range_vs_index_merge_innodb.result b/mysql-test/main/range_vs_index_merge_innodb.result index 4ac62e24940..79a670aedb2 100644 --- a/mysql-test/main/range_vs_index_merge_innodb.result +++ b/mysql-test/main/range_vs_index_merge_innodb.result @@ -4,8 +4,6 @@ set @innodb_stats_persistent_sample_pages_save= @@innodb_stats_persistent_sample_pages; set global innodb_stats_persistent= 1; set global innodb_stats_persistent_sample_pages=100; -DROP TABLE IF EXISTS t1,t2,t3,t4; -DROP DATABASE IF EXISTS world; set names utf8; CREATE DATABASE world; use world; diff --git a/mysql-test/main/rowid_filter_innodb.result b/mysql-test/main/rowid_filter_innodb.result index ae52f9416b9..44dd89fa722 100644 --- a/mysql-test/main/rowid_filter_innodb.result +++ b/mysql-test/main/rowid_filter_innodb.result @@ -1,4 +1,6 @@ SET SESSION DEFAULT_STORAGE_ENGINE='InnoDB'; +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; DROP DATABASE IF EXISTS dbt3_s001; CREATE DATABASE dbt3_s001; use dbt3_s001; @@ -2144,13 +2146,14 @@ a b drop table t1; SET @@optimizer_switch=@save_optimizer_switch; set @@use_stat_tables=@save_use_stat_tables; +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; # # MDEV-18755: possible RORI-plan and possible plan with range filter # create table t1 ( pk int not null primary key, f1 varchar(10), f2 varchar(30), a int(10), key (f1), key (f2) -) engine=innodb; +) engine=innodb stats_persistent=0; insert into t1 values (2,'a','a',2),(3,'a','a',null),(4,'a','a',55),(5,'a','a',4),(6,'a','a',0), (7,'a','a',1),(8,'a','a',4),(9,'a','a',null),(10,'a','a',0),(11,'a','a',0), @@ -2513,7 +2516,7 @@ timestamp timestamp NOT NULL DEFAULT current_timestamp(), PRIMARY KEY (id), KEY ixEventWhoisDomainDomain (domain), KEY ixEventWhoisDomainTimestamp (timestamp) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; +) ENGINE=InnoDB STATS_PERSISTENT=0 DEFAULT CHARSET=utf8; INSERT INTO t1 ( id, domain, registrant_name, registrant_organization, registrant_street1, registrant_street2, registrant_street3, registrant_street4, registrant_street5, diff --git a/mysql-test/main/rowid_filter_innodb.test b/mysql-test/main/rowid_filter_innodb.test index ab65a40e89e..bc5518eba8d 100644 --- a/mysql-test/main/rowid_filter_innodb.test +++ b/mysql-test/main/rowid_filter_innodb.test @@ -2,7 +2,13 @@ SET SESSION DEFAULT_STORAGE_ENGINE='InnoDB'; +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; + --source rowid_filter.test + +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; + --source include/have_sequence.inc --echo # @@ -12,7 +18,7 @@ SET SESSION DEFAULT_STORAGE_ENGINE='InnoDB'; create table t1 ( pk int not null primary key, f1 varchar(10), f2 varchar(30), a int(10), key (f1), key (f2) -) engine=innodb; +) engine=innodb stats_persistent=0; insert into t1 values (2,'a','a',2),(3,'a','a',null),(4,'a','a',55),(5,'a','a',4),(6,'a','a',0), @@ -265,7 +271,7 @@ CREATE TABLE t1 ( PRIMARY KEY (id), KEY ixEventWhoisDomainDomain (domain), KEY ixEventWhoisDomainTimestamp (timestamp) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; +) ENGINE=InnoDB STATS_PERSISTENT=0 DEFAULT CHARSET=utf8; INSERT INTO t1 ( id, domain, registrant_name, registrant_organization, registrant_street1, diff --git a/mysql-test/main/rowid_order_innodb.result b/mysql-test/main/rowid_order_innodb.result index 9b32bf6018f..26fb8ebb707 100644 --- a/mysql-test/main/rowid_order_innodb.result +++ b/mysql-test/main/rowid_order_innodb.result @@ -1,3 +1,5 @@ +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; SET SESSION DEFAULT_STORAGE_ENGINE = InnoDB; drop table if exists t1, t2, t3,t4; create table t1 ( @@ -185,3 +187,4 @@ bb b--b 2 2 ccc c--c 2 2 dddd d--d 2 2 drop table t1; +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; diff --git a/mysql-test/main/rowid_order_innodb.test b/mysql-test/main/rowid_order_innodb.test index 152eb28d388..d60c29bebf7 100644 --- a/mysql-test/main/rowid_order_innodb.test +++ b/mysql-test/main/rowid_order_innodb.test @@ -10,5 +10,9 @@ --source include/have_innodb.inc let $engine_type= InnoDB; +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; --source include/rowid_order.inc + +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; diff --git a/mysql-test/main/selectivity_innodb.result b/mysql-test/main/selectivity_innodb.result index a1d227a9baa..5457db21436 100644 --- a/mysql-test/main/selectivity_innodb.result +++ b/mysql-test/main/selectivity_innodb.result @@ -1,6 +1,8 @@ SET SESSION DEFAULT_STORAGE_ENGINE='InnoDB'; set @save_optimizer_switch_for_selectivity_test=@@optimizer_switch; set optimizer_switch='extended_keys=on'; +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; drop table if exists t0,t1,t2,t3; select @@global.use_stat_tables; @@global.use_stat_tables @@ -2153,3 +2155,4 @@ set use_stat_tables= @tmp_ust; set optimizer_use_condition_selectivity= @tmp_oucs; set @@global.histogram_size=@save_histogram_size; SET SESSION DEFAULT_STORAGE_ENGINE=DEFAULT; +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; diff --git a/mysql-test/main/selectivity_innodb.test b/mysql-test/main/selectivity_innodb.test index 4bcdb5d6ec9..c970e7d871d 100644 --- a/mysql-test/main/selectivity_innodb.test +++ b/mysql-test/main/selectivity_innodb.test @@ -7,6 +7,8 @@ SET SESSION DEFAULT_STORAGE_ENGINE='InnoDB'; set @save_optimizer_switch_for_selectivity_test=@@optimizer_switch; set optimizer_switch='extended_keys=on'; +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; --source selectivity.test @@ -233,3 +235,4 @@ set use_stat_tables= @tmp_ust; set optimizer_use_condition_selectivity= @tmp_oucs; set @@global.histogram_size=@save_histogram_size; SET SESSION DEFAULT_STORAGE_ENGINE=DEFAULT; +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; diff --git a/mysql-test/main/subselect-crash_15755.result b/mysql-test/main/subselect-crash_15755.result index 81b4bd16ab5..f7a07fff4ad 100644 --- a/mysql-test/main/subselect-crash_15755.result +++ b/mysql-test/main/subselect-crash_15755.result @@ -1,7 +1,3 @@ -set global innodb_stats_persistent= 1; -drop table if exists t1; -Warnings: -Note 1051 Unknown table 'test.t1' create table t1 ( f1 bigint(20) default 0, f2 varchar(50) default '', @@ -49,7 +45,7 @@ f43 varchar(50) default '', f44 varchar(50) default '', f45 int(10) default 0, f46 tinyint(1) default 0 -) engine=innodb row_format=dynamic; +) engine=innodb stats_persistent=1 row_format=dynamic; insert into t1 () values (),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(); insert into t1 select * from t1; insert into t1 select * from t1; @@ -314,4 +310,3 @@ f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f15 f16 f17 f18 f19 f20 f21 f22 f 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 drop table t1; -set global innodb_stats_persistent= 0; diff --git a/mysql-test/main/subselect-crash_15755.test b/mysql-test/main/subselect-crash_15755.test index 79e259d6337..47879d1bd4d 100644 --- a/mysql-test/main/subselect-crash_15755.test +++ b/mysql-test/main/subselect-crash_15755.test @@ -1,6 +1,4 @@ --source include/have_innodb.inc -set global innodb_stats_persistent= 1; -drop table if exists t1; create table t1 ( f1 bigint(20) default 0, f2 varchar(50) default '', @@ -48,8 +46,7 @@ create table t1 ( f44 varchar(50) default '', f45 int(10) default 0, f46 tinyint(1) default 0 -) engine=innodb row_format=dynamic; - +) engine=innodb stats_persistent=1 row_format=dynamic; insert into t1 () values (),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(); insert into t1 select * from t1; insert into t1 select * from t1; @@ -57,4 +54,3 @@ insert into t1 select * from t1; insert into t1 select * from t1; select * from t1 where f2 in (select f2 from t1 group by f2 having count(distinct f3) = 1); drop table t1; -set global innodb_stats_persistent= 0; diff --git a/mysql-test/main/subselect_innodb.result b/mysql-test/main/subselect_innodb.result index 73ca2640491..abc429fb550 100644 --- a/mysql-test/main/subselect_innodb.result +++ b/mysql-test/main/subselect_innodb.result @@ -1,6 +1,7 @@ set @subselect_innodb_tmp=@@optimizer_switch; set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; -drop table if exists t1,t2,t3; +SET @saved_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = OFF; CREATE TABLE t1 ( FOLDERID VARCHAR(32)BINARY NOT NULL @@ -663,3 +664,4 @@ execute stmt; a b drop table t1,t2; # End of 10.4 tests +SET GLOBAL innodb_stats_persistent = @saved_stats_persistent; diff --git a/mysql-test/main/subselect_innodb.test b/mysql-test/main/subselect_innodb.test index 37f8f40200e..19871e14008 100644 --- a/mysql-test/main/subselect_innodb.test +++ b/mysql-test/main/subselect_innodb.test @@ -4,9 +4,8 @@ # settings are not relevant. set @subselect_innodb_tmp=@@optimizer_switch; set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; ---disable_warnings -drop table if exists t1,t2,t3; ---enable_warnings +SET @saved_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = OFF; # # key field overflow test @@ -662,3 +661,5 @@ execute stmt; drop table t1,t2; --echo # End of 10.4 tests + +SET GLOBAL innodb_stats_persistent = @saved_stats_persistent; diff --git a/mysql-test/main/type_bit_innodb.result b/mysql-test/main/type_bit_innodb.result index 9b186207f3f..a3ac23ebb71 100644 --- a/mysql-test/main/type_bit_innodb.result +++ b/mysql-test/main/type_bit_innodb.result @@ -1,3 +1,5 @@ +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; select 0 + b'1'; 0 + b'1' 1 @@ -34,7 +36,6 @@ select 0 + b'1111111111111111'; select 0 + b'1000000000000001'; 0 + b'1000000000000001' 32769 -drop table if exists t1; create table t1 (a bit(65)) engine=innodb; ERROR 42000: Display width out of range for 'a' (max = 64) create table t1 (a bit(0)) engine=innodb; @@ -422,3 +423,4 @@ hex(f1) hex(f2) 0 0 0 0 drop table t1; +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; diff --git a/mysql-test/main/type_bit_innodb.test b/mysql-test/main/type_bit_innodb.test index 4c6f9bc1b49..6317bbc3a2d 100644 --- a/mysql-test/main/type_bit_innodb.test +++ b/mysql-test/main/type_bit_innodb.test @@ -1,4 +1,7 @@ --source include/have_innodb.inc +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; + # # testing of the BIT column type # @@ -16,10 +19,6 @@ select 0 + b'1000000000000000'; select 0 + b'1111111111111111'; select 0 + b'1000000000000001'; ---disable_warnings -drop table if exists t1; ---enable_warnings - --error 1439 create table t1 (a bit(65)) engine=innodb; @@ -157,3 +156,5 @@ insert into t1 (f1) values (default); insert into t1 values (b'',b''),('',''); select hex(f1), hex(f2) from t1; drop table t1; + +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; diff --git a/mysql-test/main/update_use_source.result b/mysql-test/main/update_use_source.result index 9e43b54d81c..2774e7ee92d 100644 --- a/mysql-test/main/update_use_source.result +++ b/mysql-test/main/update_use_source.result @@ -1,4 +1,4 @@ -create table t1 (old_c1 integer, old_c2 integer,c1 integer, c2 integer, c3 integer) engine=InnoDb; +create table t1 (old_c1 integer, old_c2 integer,c1 integer, c2 integer, c3 integer) engine=InnoDB STATS_PERSISTENT=0; create view v1 as select * from t1 where c2=2; create trigger trg_t1 before update on t1 for each row begin diff --git a/mysql-test/main/update_use_source.test b/mysql-test/main/update_use_source.test index 7ed5f95d68d..d446bd512dd 100644 --- a/mysql-test/main/update_use_source.test +++ b/mysql-test/main/update_use_source.test @@ -1,7 +1,7 @@ --source include/have_sequence.inc --source include/have_innodb.inc -create table t1 (old_c1 integer, old_c2 integer,c1 integer, c2 integer, c3 integer) engine=InnoDb; +create table t1 (old_c1 integer, old_c2 integer,c1 integer, c2 integer, c3 integer) engine=InnoDB STATS_PERSISTENT=0; create view v1 as select * from t1 where c2=2; delimiter /; create trigger trg_t1 before update on t1 for each row diff --git a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_innodb.result b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_innodb.result index f83dc8fbdc0..8cc020311b9 100644 --- a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_innodb.result +++ b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_innodb.result @@ -1,3 +1,5 @@ +SET @save_stats_auto_recalc=@@GLOBAL.innodb_stats_auto_recalc; +SET GLOBAL innodb_stats_auto_recalc=OFF; set sql_mode=""; SET NAMES 'utf8'; # @@ -6372,3 +6374,4 @@ ROLLBACK /* added by mysqlbinlog */; # Cleanup. # DROP TABLE t1; +SET GLOBAL innodb_stats_auto_recalc=@save_stats_auto_recalc; diff --git a/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row_innodb.test b/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row_innodb.test index cef1a712f7d..7bd72657f5a 100644 --- a/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row_innodb.test +++ b/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row_innodb.test @@ -12,6 +12,9 @@ --source include/have_innodb.inc let $engine_type=InnoDB; +SET @save_stats_auto_recalc=@@GLOBAL.innodb_stats_auto_recalc; +SET GLOBAL innodb_stats_auto_recalc=OFF; + # # The test case would also work with statement based or mixed mode logging. # But this would require different result files. To handle this with the @@ -22,3 +25,4 @@ let $engine_type=InnoDB; --source include/mysqlbinlog_row_engine.inc +SET GLOBAL innodb_stats_auto_recalc=@save_stats_auto_recalc; diff --git a/mysql-test/suite/engines/funcs/r/se_join_default.result b/mysql-test/suite/engines/funcs/r/se_join_default.result index a825ad314f3..cc1271020bc 100644 --- a/mysql-test/suite/engines/funcs/r/se_join_default.result +++ b/mysql-test/suite/engines/funcs/r/se_join_default.result @@ -14,47 +14,47 @@ SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 < t2.c1; c1 c1 0 1 0 2 -1 2 0 3 -1 3 -2 3 0 4 -1 4 -2 4 -3 4 0 5 -1 5 -2 5 -3 5 -4 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 0 9 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 5 +4 6 +4 7 +4 8 4 9 +5 6 +5 7 +5 8 5 9 +6 7 +6 8 6 9 +7 8 7 9 8 9 DROP TABLE t1,t2,t3,t4,t5,t6; @@ -73,47 +73,47 @@ SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 < t2.c1; c1 c1 0 1 0 2 -1 2 0 3 -1 3 -2 3 0 4 -1 4 -2 4 -3 4 0 5 -1 5 -2 5 -3 5 -4 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 0 9 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 5 +4 6 +4 7 +4 8 4 9 +5 6 +5 7 +5 8 5 9 +6 7 +6 8 6 9 +7 8 7 9 8 9 DROP TABLE t1,t2,t3,t4,t5,t6; @@ -132,47 +132,47 @@ SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 < t2.c1; c1 c1 0 1 0 2 -1 2 0 3 -1 3 -2 3 0 4 -1 4 -2 4 -3 4 0 5 -1 5 -2 5 -3 5 -4 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 0 9 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 5 +4 6 +4 7 +4 8 4 9 +5 6 +5 7 +5 8 5 9 +6 7 +6 8 6 9 +7 8 7 9 8 9 DROP TABLE t1,t2,t3,t4,t5,t6; @@ -191,47 +191,47 @@ SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 < t2.c1; c1 c1 0 1 0 2 -1 2 0 3 -1 3 -2 3 0 4 -1 4 -2 4 -3 4 0 5 -1 5 -2 5 -3 5 -4 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 0 9 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 5 +4 6 +4 7 +4 8 4 9 +5 6 +5 7 +5 8 5 9 +6 7 +6 8 6 9 +7 8 7 9 8 9 DROP TABLE t1,t2,t3,t4,t5,t6; @@ -250,47 +250,47 @@ SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 < t2.c1; c1 c1 0 1 0 2 -1 2 0 3 -1 3 -2 3 0 4 -1 4 -2 4 -3 4 0 5 -1 5 -2 5 -3 5 -4 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 0 9 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 5 +4 6 +4 7 +4 8 4 9 +5 6 +5 7 +5 8 5 9 +6 7 +6 8 6 9 +7 8 7 9 8 9 DROP TABLE t1,t2,t3,t4,t5,t6; @@ -309,47 +309,47 @@ SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 < t2.c1; c1 c1 0 1 0 2 -1 2 0 3 -1 3 -2 3 0 4 -1 4 -2 4 -3 4 0 5 -1 5 -2 5 -3 5 -4 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 0 9 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 5 +4 6 +4 7 +4 8 4 9 +5 6 +5 7 +5 8 5 9 +6 7 +6 8 6 9 +7 8 7 9 8 9 DROP TABLE t1,t2,t3,t4,t5,t6; @@ -1214,57 +1214,57 @@ SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <= t2.c1; c1 c1 0 0 0 1 -1 1 0 2 -1 2 -2 2 0 3 -1 3 -2 3 -3 3 0 4 -1 4 -2 4 -3 4 -4 4 0 5 -1 5 -2 5 -3 5 -4 5 -5 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 -6 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 -7 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 -8 8 0 9 +1 1 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 2 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 3 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 4 +4 5 +4 6 +4 7 +4 8 4 9 +5 5 +5 6 +5 7 +5 8 5 9 +6 6 +6 7 +6 8 6 9 +7 7 +7 8 7 9 +8 8 8 9 9 9 DROP TABLE t1,t2,t3,t4,t5,t6; @@ -1283,57 +1283,57 @@ SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <= t2.c1; c1 c1 0 0 0 1 -1 1 0 2 -1 2 -2 2 0 3 -1 3 -2 3 -3 3 0 4 -1 4 -2 4 -3 4 -4 4 0 5 -1 5 -2 5 -3 5 -4 5 -5 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 -6 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 -7 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 -8 8 0 9 +1 1 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 2 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 3 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 4 +4 5 +4 6 +4 7 +4 8 4 9 +5 5 +5 6 +5 7 +5 8 5 9 +6 6 +6 7 +6 8 6 9 +7 7 +7 8 7 9 +8 8 8 9 9 9 DROP TABLE t1,t2,t3,t4,t5,t6; @@ -1352,57 +1352,57 @@ SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <= t2.c1; c1 c1 0 0 0 1 -1 1 0 2 -1 2 -2 2 0 3 -1 3 -2 3 -3 3 0 4 -1 4 -2 4 -3 4 -4 4 0 5 -1 5 -2 5 -3 5 -4 5 -5 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 -6 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 -7 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 -8 8 0 9 +1 1 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 2 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 3 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 4 +4 5 +4 6 +4 7 +4 8 4 9 +5 5 +5 6 +5 7 +5 8 5 9 +6 6 +6 7 +6 8 6 9 +7 7 +7 8 7 9 +8 8 8 9 9 9 DROP TABLE t1,t2,t3,t4,t5,t6; @@ -1421,57 +1421,57 @@ SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <= t2.c1; c1 c1 0 0 0 1 -1 1 0 2 -1 2 -2 2 0 3 -1 3 -2 3 -3 3 0 4 -1 4 -2 4 -3 4 -4 4 0 5 -1 5 -2 5 -3 5 -4 5 -5 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 -6 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 -7 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 -8 8 0 9 +1 1 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 2 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 3 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 4 +4 5 +4 6 +4 7 +4 8 4 9 +5 5 +5 6 +5 7 +5 8 5 9 +6 6 +6 7 +6 8 6 9 +7 7 +7 8 7 9 +8 8 8 9 9 9 DROP TABLE t1,t2,t3,t4,t5,t6; @@ -1490,57 +1490,57 @@ SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <= t2.c1; c1 c1 0 0 0 1 -1 1 0 2 -1 2 -2 2 0 3 -1 3 -2 3 -3 3 0 4 -1 4 -2 4 -3 4 -4 4 0 5 -1 5 -2 5 -3 5 -4 5 -5 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 -6 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 -7 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 -8 8 0 9 +1 1 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 2 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 3 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 4 +4 5 +4 6 +4 7 +4 8 4 9 +5 5 +5 6 +5 7 +5 8 5 9 +6 6 +6 7 +6 8 6 9 +7 7 +7 8 7 9 +8 8 8 9 9 9 DROP TABLE t1,t2,t3,t4,t5,t6; @@ -1559,57 +1559,57 @@ SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <= t2.c1; c1 c1 0 0 0 1 -1 1 0 2 -1 2 -2 2 0 3 -1 3 -2 3 -3 3 0 4 -1 4 -2 4 -3 4 -4 4 0 5 -1 5 -2 5 -3 5 -4 5 -5 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 -6 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 -7 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 -8 8 0 9 +1 1 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 2 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 3 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 4 +4 5 +4 6 +4 7 +4 8 4 9 +5 5 +5 6 +5 7 +5 8 5 9 +6 6 +6 7 +6 8 6 9 +7 7 +7 8 7 9 +8 8 8 9 9 9 DROP TABLE t1,t2,t3,t4,t5,t6; @@ -3014,57 +3014,57 @@ SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 >= t2.c1; c1 c1 0 0 1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 1 1 +2 0 2 1 -3 1 -4 1 -5 1 -6 1 -7 1 -8 1 -9 1 2 2 +3 0 +3 1 3 2 -4 2 -5 2 -6 2 -7 2 -8 2 -9 2 3 3 +4 0 +4 1 +4 2 4 3 -5 3 -6 3 -7 3 -8 3 -9 3 4 4 +5 0 +5 1 +5 2 +5 3 5 4 -6 4 -7 4 -8 4 -9 4 5 5 +6 0 +6 1 +6 2 +6 3 +6 4 6 5 -7 5 -8 5 -9 5 6 6 +7 0 +7 1 +7 2 +7 3 +7 4 +7 5 7 6 -8 6 -9 6 7 7 +8 0 +8 1 +8 2 +8 3 +8 4 +8 5 +8 6 8 7 -9 7 8 8 +9 0 +9 1 +9 2 +9 3 +9 4 +9 5 +9 6 +9 7 9 8 9 9 DROP TABLE t1,t2,t3,t4,t5,t6; @@ -3083,57 +3083,57 @@ SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 >= t2.c1; c1 c1 0 0 1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 1 1 +2 0 2 1 -3 1 -4 1 -5 1 -6 1 -7 1 -8 1 -9 1 2 2 +3 0 +3 1 3 2 -4 2 -5 2 -6 2 -7 2 -8 2 -9 2 3 3 +4 0 +4 1 +4 2 4 3 -5 3 -6 3 -7 3 -8 3 -9 3 4 4 +5 0 +5 1 +5 2 +5 3 5 4 -6 4 -7 4 -8 4 -9 4 5 5 +6 0 +6 1 +6 2 +6 3 +6 4 6 5 -7 5 -8 5 -9 5 6 6 +7 0 +7 1 +7 2 +7 3 +7 4 +7 5 7 6 -8 6 -9 6 7 7 +8 0 +8 1 +8 2 +8 3 +8 4 +8 5 +8 6 8 7 -9 7 8 8 +9 0 +9 1 +9 2 +9 3 +9 4 +9 5 +9 6 +9 7 9 8 9 9 DROP TABLE t1,t2,t3,t4,t5,t6; @@ -3152,57 +3152,57 @@ SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 >= t2.c1; c1 c1 0 0 1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 1 1 +2 0 2 1 -3 1 -4 1 -5 1 -6 1 -7 1 -8 1 -9 1 2 2 +3 0 +3 1 3 2 -4 2 -5 2 -6 2 -7 2 -8 2 -9 2 3 3 +4 0 +4 1 +4 2 4 3 -5 3 -6 3 -7 3 -8 3 -9 3 4 4 +5 0 +5 1 +5 2 +5 3 5 4 -6 4 -7 4 -8 4 -9 4 5 5 +6 0 +6 1 +6 2 +6 3 +6 4 6 5 -7 5 -8 5 -9 5 6 6 +7 0 +7 1 +7 2 +7 3 +7 4 +7 5 7 6 -8 6 -9 6 7 7 +8 0 +8 1 +8 2 +8 3 +8 4 +8 5 +8 6 8 7 -9 7 8 8 +9 0 +9 1 +9 2 +9 3 +9 4 +9 5 +9 6 +9 7 9 8 9 9 DROP TABLE t1,t2,t3,t4,t5,t6; @@ -3221,57 +3221,57 @@ SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 >= t2.c1; c1 c1 0 0 1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 1 1 +2 0 2 1 -3 1 -4 1 -5 1 -6 1 -7 1 -8 1 -9 1 2 2 +3 0 +3 1 3 2 -4 2 -5 2 -6 2 -7 2 -8 2 -9 2 3 3 +4 0 +4 1 +4 2 4 3 -5 3 -6 3 -7 3 -8 3 -9 3 4 4 +5 0 +5 1 +5 2 +5 3 5 4 -6 4 -7 4 -8 4 -9 4 5 5 +6 0 +6 1 +6 2 +6 3 +6 4 6 5 -7 5 -8 5 -9 5 6 6 +7 0 +7 1 +7 2 +7 3 +7 4 +7 5 7 6 -8 6 -9 6 7 7 +8 0 +8 1 +8 2 +8 3 +8 4 +8 5 +8 6 8 7 -9 7 8 8 +9 0 +9 1 +9 2 +9 3 +9 4 +9 5 +9 6 +9 7 9 8 9 9 DROP TABLE t1,t2,t3,t4,t5,t6; @@ -3290,57 +3290,57 @@ SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 >= t2.c1; c1 c1 0 0 1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 1 1 +2 0 2 1 -3 1 -4 1 -5 1 -6 1 -7 1 -8 1 -9 1 2 2 +3 0 +3 1 3 2 -4 2 -5 2 -6 2 -7 2 -8 2 -9 2 3 3 +4 0 +4 1 +4 2 4 3 -5 3 -6 3 -7 3 -8 3 -9 3 4 4 +5 0 +5 1 +5 2 +5 3 5 4 -6 4 -7 4 -8 4 -9 4 5 5 +6 0 +6 1 +6 2 +6 3 +6 4 6 5 -7 5 -8 5 -9 5 6 6 +7 0 +7 1 +7 2 +7 3 +7 4 +7 5 7 6 -8 6 -9 6 7 7 +8 0 +8 1 +8 2 +8 3 +8 4 +8 5 +8 6 8 7 -9 7 8 8 +9 0 +9 1 +9 2 +9 3 +9 4 +9 5 +9 6 +9 7 9 8 9 9 DROP TABLE t1,t2,t3,t4,t5,t6; @@ -3359,57 +3359,57 @@ SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 >= t2.c1; c1 c1 0 0 1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 1 1 +2 0 2 1 -3 1 -4 1 -5 1 -6 1 -7 1 -8 1 -9 1 2 2 +3 0 +3 1 3 2 -4 2 -5 2 -6 2 -7 2 -8 2 -9 2 3 3 +4 0 +4 1 +4 2 4 3 -5 3 -6 3 -7 3 -8 3 -9 3 4 4 +5 0 +5 1 +5 2 +5 3 5 4 -6 4 -7 4 -8 4 -9 4 5 5 +6 0 +6 1 +6 2 +6 3 +6 4 6 5 -7 5 -8 5 -9 5 6 6 +7 0 +7 1 +7 2 +7 3 +7 4 +7 5 7 6 -8 6 -9 6 7 7 +8 0 +8 1 +8 2 +8 3 +8 4 +8 5 +8 6 8 7 -9 7 8 8 +9 0 +9 1 +9 2 +9 3 +9 4 +9 5 +9 6 +9 7 9 8 9 9 DROP TABLE t1,t2,t3,t4,t5,t6; @@ -3912,96 +3912,96 @@ INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 != t2.c1; c1 c1 -1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 0 1 -2 1 -3 1 -4 1 -5 1 -6 1 -7 1 -8 1 -9 1 0 2 -1 2 -3 2 -4 2 -5 2 -6 2 -7 2 -8 2 -9 2 0 3 -1 3 -2 3 -4 3 -5 3 -6 3 -7 3 -8 3 -9 3 0 4 -1 4 -2 4 -3 4 -5 4 -6 4 -7 4 -8 4 -9 4 0 5 -1 5 -2 5 -3 5 -4 5 -6 5 -7 5 -8 5 -9 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 -7 6 -8 6 -9 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 -8 7 -9 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 -9 8 0 9 +1 0 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 0 +2 1 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 0 +3 1 +3 2 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 0 +4 1 +4 2 +4 3 +4 5 +4 6 +4 7 +4 8 4 9 +5 0 +5 1 +5 2 +5 3 +5 4 +5 6 +5 7 +5 8 5 9 +6 0 +6 1 +6 2 +6 3 +6 4 +6 5 +6 7 +6 8 6 9 +7 0 +7 1 +7 2 +7 3 +7 4 +7 5 +7 6 +7 8 7 9 +8 0 +8 1 +8 2 +8 3 +8 4 +8 5 +8 6 +8 7 8 9 +9 0 +9 1 +9 2 +9 3 +9 4 +9 5 +9 6 +9 7 +9 8 DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); CREATE TABLE t2 (c1 SMALLINT NOT NULL); @@ -4016,96 +4016,96 @@ INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 != t2.c1; c1 c1 -1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 0 1 -2 1 -3 1 -4 1 -5 1 -6 1 -7 1 -8 1 -9 1 0 2 -1 2 -3 2 -4 2 -5 2 -6 2 -7 2 -8 2 -9 2 0 3 -1 3 -2 3 -4 3 -5 3 -6 3 -7 3 -8 3 -9 3 0 4 -1 4 -2 4 -3 4 -5 4 -6 4 -7 4 -8 4 -9 4 0 5 -1 5 -2 5 -3 5 -4 5 -6 5 -7 5 -8 5 -9 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 -7 6 -8 6 -9 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 -8 7 -9 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 -9 8 0 9 +1 0 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 0 +2 1 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 0 +3 1 +3 2 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 0 +4 1 +4 2 +4 3 +4 5 +4 6 +4 7 +4 8 4 9 +5 0 +5 1 +5 2 +5 3 +5 4 +5 6 +5 7 +5 8 5 9 +6 0 +6 1 +6 2 +6 3 +6 4 +6 5 +6 7 +6 8 6 9 +7 0 +7 1 +7 2 +7 3 +7 4 +7 5 +7 6 +7 8 7 9 +8 0 +8 1 +8 2 +8 3 +8 4 +8 5 +8 6 +8 7 8 9 +9 0 +9 1 +9 2 +9 3 +9 4 +9 5 +9 6 +9 7 +9 8 DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); CREATE TABLE t2 (c1 MEDIUMINT NOT NULL); @@ -4120,96 +4120,96 @@ INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 != t2.c1; c1 c1 -1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 0 1 -2 1 -3 1 -4 1 -5 1 -6 1 -7 1 -8 1 -9 1 0 2 -1 2 -3 2 -4 2 -5 2 -6 2 -7 2 -8 2 -9 2 0 3 -1 3 -2 3 -4 3 -5 3 -6 3 -7 3 -8 3 -9 3 0 4 -1 4 -2 4 -3 4 -5 4 -6 4 -7 4 -8 4 -9 4 0 5 -1 5 -2 5 -3 5 -4 5 -6 5 -7 5 -8 5 -9 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 -7 6 -8 6 -9 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 -8 7 -9 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 -9 8 0 9 +1 0 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 0 +2 1 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 0 +3 1 +3 2 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 0 +4 1 +4 2 +4 3 +4 5 +4 6 +4 7 +4 8 4 9 +5 0 +5 1 +5 2 +5 3 +5 4 +5 6 +5 7 +5 8 5 9 +6 0 +6 1 +6 2 +6 3 +6 4 +6 5 +6 7 +6 8 6 9 +7 0 +7 1 +7 2 +7 3 +7 4 +7 5 +7 6 +7 8 7 9 +8 0 +8 1 +8 2 +8 3 +8 4 +8 5 +8 6 +8 7 8 9 +9 0 +9 1 +9 2 +9 3 +9 4 +9 5 +9 6 +9 7 +9 8 DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); CREATE TABLE t2 (c1 INT NOT NULL); @@ -4224,96 +4224,96 @@ INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 != t2.c1; c1 c1 -1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 0 1 -2 1 -3 1 -4 1 -5 1 -6 1 -7 1 -8 1 -9 1 0 2 -1 2 -3 2 -4 2 -5 2 -6 2 -7 2 -8 2 -9 2 0 3 -1 3 -2 3 -4 3 -5 3 -6 3 -7 3 -8 3 -9 3 0 4 -1 4 -2 4 -3 4 -5 4 -6 4 -7 4 -8 4 -9 4 0 5 -1 5 -2 5 -3 5 -4 5 -6 5 -7 5 -8 5 -9 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 -7 6 -8 6 -9 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 -8 7 -9 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 -9 8 0 9 +1 0 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 0 +2 1 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 0 +3 1 +3 2 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 0 +4 1 +4 2 +4 3 +4 5 +4 6 +4 7 +4 8 4 9 +5 0 +5 1 +5 2 +5 3 +5 4 +5 6 +5 7 +5 8 5 9 +6 0 +6 1 +6 2 +6 3 +6 4 +6 5 +6 7 +6 8 6 9 +7 0 +7 1 +7 2 +7 3 +7 4 +7 5 +7 6 +7 8 7 9 +8 0 +8 1 +8 2 +8 3 +8 4 +8 5 +8 6 +8 7 8 9 +9 0 +9 1 +9 2 +9 3 +9 4 +9 5 +9 6 +9 7 +9 8 DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); CREATE TABLE t2 (c1 INTEGER NOT NULL); @@ -4328,96 +4328,96 @@ INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 != t2.c1; c1 c1 -1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 0 1 -2 1 -3 1 -4 1 -5 1 -6 1 -7 1 -8 1 -9 1 0 2 -1 2 -3 2 -4 2 -5 2 -6 2 -7 2 -8 2 -9 2 0 3 -1 3 -2 3 -4 3 -5 3 -6 3 -7 3 -8 3 -9 3 0 4 -1 4 -2 4 -3 4 -5 4 -6 4 -7 4 -8 4 -9 4 0 5 -1 5 -2 5 -3 5 -4 5 -6 5 -7 5 -8 5 -9 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 -7 6 -8 6 -9 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 -8 7 -9 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 -9 8 0 9 +1 0 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 0 +2 1 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 0 +3 1 +3 2 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 0 +4 1 +4 2 +4 3 +4 5 +4 6 +4 7 +4 8 4 9 +5 0 +5 1 +5 2 +5 3 +5 4 +5 6 +5 7 +5 8 5 9 +6 0 +6 1 +6 2 +6 3 +6 4 +6 5 +6 7 +6 8 6 9 +7 0 +7 1 +7 2 +7 3 +7 4 +7 5 +7 6 +7 8 7 9 +8 0 +8 1 +8 2 +8 3 +8 4 +8 5 +8 6 +8 7 8 9 +9 0 +9 1 +9 2 +9 3 +9 4 +9 5 +9 6 +9 7 +9 8 DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); CREATE TABLE t2 (c1 BIGINT NOT NULL); @@ -4432,96 +4432,96 @@ INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 != t2.c1; c1 c1 -1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 0 1 -2 1 -3 1 -4 1 -5 1 -6 1 -7 1 -8 1 -9 1 0 2 -1 2 -3 2 -4 2 -5 2 -6 2 -7 2 -8 2 -9 2 0 3 -1 3 -2 3 -4 3 -5 3 -6 3 -7 3 -8 3 -9 3 0 4 -1 4 -2 4 -3 4 -5 4 -6 4 -7 4 -8 4 -9 4 0 5 -1 5 -2 5 -3 5 -4 5 -6 5 -7 5 -8 5 -9 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 -7 6 -8 6 -9 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 -8 7 -9 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 -9 8 0 9 +1 0 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 0 +2 1 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 0 +3 1 +3 2 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 0 +4 1 +4 2 +4 3 +4 5 +4 6 +4 7 +4 8 4 9 +5 0 +5 1 +5 2 +5 3 +5 4 +5 6 +5 7 +5 8 5 9 +6 0 +6 1 +6 2 +6 3 +6 4 +6 5 +6 7 +6 8 6 9 +7 0 +7 1 +7 2 +7 3 +7 4 +7 5 +7 6 +7 8 7 9 +8 0 +8 1 +8 2 +8 3 +8 4 +8 5 +8 6 +8 7 8 9 +9 0 +9 1 +9 2 +9 3 +9 4 +9 5 +9 6 +9 7 +9 8 DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); CREATE TABLE t2 (c1 TINYINT NOT NULL); @@ -5502,96 +5502,96 @@ INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <> t2.c1; c1 c1 -1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 0 1 -2 1 -3 1 -4 1 -5 1 -6 1 -7 1 -8 1 -9 1 0 2 -1 2 -3 2 -4 2 -5 2 -6 2 -7 2 -8 2 -9 2 0 3 -1 3 -2 3 -4 3 -5 3 -6 3 -7 3 -8 3 -9 3 0 4 -1 4 -2 4 -3 4 -5 4 -6 4 -7 4 -8 4 -9 4 0 5 -1 5 -2 5 -3 5 -4 5 -6 5 -7 5 -8 5 -9 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 -7 6 -8 6 -9 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 -8 7 -9 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 -9 8 0 9 +1 0 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 0 +2 1 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 0 +3 1 +3 2 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 0 +4 1 +4 2 +4 3 +4 5 +4 6 +4 7 +4 8 4 9 +5 0 +5 1 +5 2 +5 3 +5 4 +5 6 +5 7 +5 8 5 9 +6 0 +6 1 +6 2 +6 3 +6 4 +6 5 +6 7 +6 8 6 9 +7 0 +7 1 +7 2 +7 3 +7 4 +7 5 +7 6 +7 8 7 9 +8 0 +8 1 +8 2 +8 3 +8 4 +8 5 +8 6 +8 7 8 9 +9 0 +9 1 +9 2 +9 3 +9 4 +9 5 +9 6 +9 7 +9 8 DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); CREATE TABLE t2 (c1 SMALLINT NOT NULL); @@ -5606,96 +5606,96 @@ INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <> t2.c1; c1 c1 -1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 0 1 -2 1 -3 1 -4 1 -5 1 -6 1 -7 1 -8 1 -9 1 0 2 -1 2 -3 2 -4 2 -5 2 -6 2 -7 2 -8 2 -9 2 0 3 -1 3 -2 3 -4 3 -5 3 -6 3 -7 3 -8 3 -9 3 0 4 -1 4 -2 4 -3 4 -5 4 -6 4 -7 4 -8 4 -9 4 0 5 -1 5 -2 5 -3 5 -4 5 -6 5 -7 5 -8 5 -9 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 -7 6 -8 6 -9 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 -8 7 -9 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 -9 8 0 9 +1 0 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 0 +2 1 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 0 +3 1 +3 2 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 0 +4 1 +4 2 +4 3 +4 5 +4 6 +4 7 +4 8 4 9 +5 0 +5 1 +5 2 +5 3 +5 4 +5 6 +5 7 +5 8 5 9 +6 0 +6 1 +6 2 +6 3 +6 4 +6 5 +6 7 +6 8 6 9 +7 0 +7 1 +7 2 +7 3 +7 4 +7 5 +7 6 +7 8 7 9 +8 0 +8 1 +8 2 +8 3 +8 4 +8 5 +8 6 +8 7 8 9 +9 0 +9 1 +9 2 +9 3 +9 4 +9 5 +9 6 +9 7 +9 8 DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); CREATE TABLE t2 (c1 MEDIUMINT NOT NULL); @@ -5710,96 +5710,96 @@ INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <> t2.c1; c1 c1 -1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 0 1 -2 1 -3 1 -4 1 -5 1 -6 1 -7 1 -8 1 -9 1 0 2 -1 2 -3 2 -4 2 -5 2 -6 2 -7 2 -8 2 -9 2 0 3 -1 3 -2 3 -4 3 -5 3 -6 3 -7 3 -8 3 -9 3 0 4 -1 4 -2 4 -3 4 -5 4 -6 4 -7 4 -8 4 -9 4 0 5 -1 5 -2 5 -3 5 -4 5 -6 5 -7 5 -8 5 -9 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 -7 6 -8 6 -9 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 -8 7 -9 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 -9 8 0 9 +1 0 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 0 +2 1 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 0 +3 1 +3 2 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 0 +4 1 +4 2 +4 3 +4 5 +4 6 +4 7 +4 8 4 9 +5 0 +5 1 +5 2 +5 3 +5 4 +5 6 +5 7 +5 8 5 9 +6 0 +6 1 +6 2 +6 3 +6 4 +6 5 +6 7 +6 8 6 9 +7 0 +7 1 +7 2 +7 3 +7 4 +7 5 +7 6 +7 8 7 9 +8 0 +8 1 +8 2 +8 3 +8 4 +8 5 +8 6 +8 7 8 9 +9 0 +9 1 +9 2 +9 3 +9 4 +9 5 +9 6 +9 7 +9 8 DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); CREATE TABLE t2 (c1 INT NOT NULL); @@ -5814,96 +5814,96 @@ INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <> t2.c1; c1 c1 -1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 0 1 -2 1 -3 1 -4 1 -5 1 -6 1 -7 1 -8 1 -9 1 0 2 -1 2 -3 2 -4 2 -5 2 -6 2 -7 2 -8 2 -9 2 0 3 -1 3 -2 3 -4 3 -5 3 -6 3 -7 3 -8 3 -9 3 0 4 -1 4 -2 4 -3 4 -5 4 -6 4 -7 4 -8 4 -9 4 0 5 -1 5 -2 5 -3 5 -4 5 -6 5 -7 5 -8 5 -9 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 -7 6 -8 6 -9 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 -8 7 -9 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 -9 8 0 9 +1 0 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 0 +2 1 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 0 +3 1 +3 2 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 0 +4 1 +4 2 +4 3 +4 5 +4 6 +4 7 +4 8 4 9 +5 0 +5 1 +5 2 +5 3 +5 4 +5 6 +5 7 +5 8 5 9 +6 0 +6 1 +6 2 +6 3 +6 4 +6 5 +6 7 +6 8 6 9 +7 0 +7 1 +7 2 +7 3 +7 4 +7 5 +7 6 +7 8 7 9 +8 0 +8 1 +8 2 +8 3 +8 4 +8 5 +8 6 +8 7 8 9 +9 0 +9 1 +9 2 +9 3 +9 4 +9 5 +9 6 +9 7 +9 8 DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); CREATE TABLE t2 (c1 INTEGER NOT NULL); @@ -5918,96 +5918,96 @@ INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <> t2.c1; c1 c1 -1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 0 1 -2 1 -3 1 -4 1 -5 1 -6 1 -7 1 -8 1 -9 1 0 2 -1 2 -3 2 -4 2 -5 2 -6 2 -7 2 -8 2 -9 2 0 3 -1 3 -2 3 -4 3 -5 3 -6 3 -7 3 -8 3 -9 3 0 4 -1 4 -2 4 -3 4 -5 4 -6 4 -7 4 -8 4 -9 4 0 5 -1 5 -2 5 -3 5 -4 5 -6 5 -7 5 -8 5 -9 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 -7 6 -8 6 -9 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 -8 7 -9 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 -9 8 0 9 +1 0 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 0 +2 1 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 0 +3 1 +3 2 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 0 +4 1 +4 2 +4 3 +4 5 +4 6 +4 7 +4 8 4 9 +5 0 +5 1 +5 2 +5 3 +5 4 +5 6 +5 7 +5 8 5 9 +6 0 +6 1 +6 2 +6 3 +6 4 +6 5 +6 7 +6 8 6 9 +7 0 +7 1 +7 2 +7 3 +7 4 +7 5 +7 6 +7 8 7 9 +8 0 +8 1 +8 2 +8 3 +8 4 +8 5 +8 6 +8 7 8 9 +9 0 +9 1 +9 2 +9 3 +9 4 +9 5 +9 6 +9 7 +9 8 DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); CREATE TABLE t2 (c1 BIGINT NOT NULL); @@ -6022,96 +6022,96 @@ INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <> t2.c1; c1 c1 -1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 0 1 -2 1 -3 1 -4 1 -5 1 -6 1 -7 1 -8 1 -9 1 0 2 -1 2 -3 2 -4 2 -5 2 -6 2 -7 2 -8 2 -9 2 0 3 -1 3 -2 3 -4 3 -5 3 -6 3 -7 3 -8 3 -9 3 0 4 -1 4 -2 4 -3 4 -5 4 -6 4 -7 4 -8 4 -9 4 0 5 -1 5 -2 5 -3 5 -4 5 -6 5 -7 5 -8 5 -9 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 -7 6 -8 6 -9 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 -8 7 -9 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 -9 8 0 9 +1 0 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 0 +2 1 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 0 +3 1 +3 2 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 0 +4 1 +4 2 +4 3 +4 5 +4 6 +4 7 +4 8 4 9 +5 0 +5 1 +5 2 +5 3 +5 4 +5 6 +5 7 +5 8 5 9 +6 0 +6 1 +6 2 +6 3 +6 4 +6 5 +6 7 +6 8 6 9 +7 0 +7 1 +7 2 +7 3 +7 4 +7 5 +7 6 +7 8 7 9 +8 0 +8 1 +8 2 +8 3 +8 4 +8 5 +8 6 +8 7 8 9 +9 0 +9 1 +9 2 +9 3 +9 4 +9 5 +9 6 +9 7 +9 8 DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); CREATE TABLE t2 (c1 TINYINT NOT NULL); diff --git a/mysql-test/suite/engines/funcs/t/se_join_default.test b/mysql-test/suite/engines/funcs/t/se_join_default.test index 87e5a4d5b6a..16cdc12a01d 100644 --- a/mysql-test/suite/engines/funcs/t/se_join_default.test +++ b/mysql-test/suite/engines/funcs/t/se_join_default.test @@ -12,6 +12,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 < t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -25,6 +26,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 < t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -38,6 +40,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 < t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -51,6 +54,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 < t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -64,6 +68,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 < t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -77,6 +82,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 < t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -90,6 +96,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 < t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -103,6 +110,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 < t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -116,6 +124,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 < t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -129,6 +138,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 < t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -142,6 +152,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 < t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -155,6 +166,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 < t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -168,6 +180,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 < t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -181,6 +194,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 < t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -194,6 +208,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 < t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -207,6 +222,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 < t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -220,6 +236,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 < t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -233,6 +250,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 < t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -246,6 +264,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 < t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -259,6 +278,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 < t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -272,6 +292,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 < t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -285,6 +306,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 < t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -298,6 +320,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 < t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -311,6 +334,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 < t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -324,6 +348,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 < t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -337,6 +362,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 < t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -350,6 +376,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 < t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -363,6 +390,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 < t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -376,6 +404,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 < t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -389,6 +418,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 < t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -402,6 +432,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <= t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -415,6 +446,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <= t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -428,6 +460,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <= t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -441,6 +474,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <= t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -454,6 +488,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <= t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -467,6 +502,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <= t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -480,6 +516,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 <= t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -493,6 +530,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 <= t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -506,6 +544,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 <= t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -519,6 +558,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 <= t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -532,6 +572,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 <= t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -545,6 +586,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 <= t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -558,6 +600,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 <= t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -571,6 +614,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 <= t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -584,6 +628,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 <= t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -597,6 +642,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 <= t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -610,6 +656,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 <= t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -623,6 +670,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 <= t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -636,6 +684,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 <= t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -649,6 +698,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 <= t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -662,6 +712,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 <= t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -675,6 +726,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 <= t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -688,6 +740,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 <= t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -701,6 +754,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 <= t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -714,6 +768,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 <= t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -727,6 +782,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 <= t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -740,6 +796,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 <= t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -753,6 +810,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 <= t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -766,6 +824,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 <= t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -779,6 +838,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 <= t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -792,6 +852,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 = t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -805,6 +866,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 = t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -818,6 +880,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 = t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -831,6 +894,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 = t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -844,6 +908,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 = t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -857,6 +922,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 = t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -870,6 +936,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 = t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -883,6 +950,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 = t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -896,6 +964,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 = t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -909,6 +978,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 = t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -922,6 +992,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 = t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -935,6 +1006,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 = t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -948,6 +1020,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 = t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -961,6 +1034,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 = t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -974,6 +1048,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 = t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -987,6 +1062,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 = t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -1000,6 +1076,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 = t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -1013,6 +1090,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 = t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -1026,6 +1104,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 = t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -1039,6 +1118,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 = t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -1052,6 +1132,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 = t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -1065,6 +1146,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 = t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -1078,6 +1160,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 = t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -1091,6 +1174,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 = t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -1104,6 +1188,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 = t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -1117,6 +1202,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 = t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -1130,6 +1216,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 = t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -1143,6 +1230,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 = t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -1156,6 +1244,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 = t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -1169,6 +1258,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 = t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -1182,6 +1272,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 >= t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -1195,6 +1286,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 >= t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -1208,6 +1300,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 >= t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -1221,6 +1314,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 >= t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -1234,6 +1328,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 >= t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -1247,6 +1342,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 >= t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -1260,6 +1356,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 >= t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -1273,6 +1370,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 >= t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -1286,6 +1384,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 >= t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -1299,6 +1398,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 >= t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -1312,6 +1412,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 >= t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -1325,6 +1426,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 >= t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -1338,6 +1440,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 >= t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -1351,6 +1454,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 >= t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -1364,6 +1468,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 >= t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -1377,6 +1482,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 >= t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -1390,6 +1496,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 >= t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -1403,6 +1510,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 >= t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -1416,6 +1524,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 >= t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -1429,6 +1538,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 >= t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -1442,6 +1552,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 >= t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -1455,6 +1566,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 >= t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -1468,6 +1580,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 >= t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -1481,6 +1594,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 >= t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -1494,6 +1608,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 >= t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -1507,6 +1622,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 >= t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -1520,6 +1636,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 >= t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -1533,6 +1650,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 >= t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -1546,6 +1664,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 >= t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -1559,6 +1678,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 >= t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -1572,6 +1692,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 != t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -1585,6 +1706,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 != t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -1598,6 +1720,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 != t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -1611,6 +1734,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 != t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -1624,6 +1748,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 != t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -1637,6 +1762,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 != t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -1650,6 +1776,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 != t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -1663,6 +1790,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 != t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -1676,6 +1804,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 != t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -1689,6 +1818,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 != t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -1702,6 +1832,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 != t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -1715,6 +1846,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 != t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -1728,6 +1860,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 != t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -1741,6 +1874,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 != t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -1754,6 +1888,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 != t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -1767,6 +1902,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 != t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -1780,6 +1916,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 != t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -1793,6 +1930,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 != t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -1806,6 +1944,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 != t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -1819,6 +1958,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 != t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -1832,6 +1972,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 != t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -1845,6 +1986,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 != t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -1858,6 +2000,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 != t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -1871,6 +2014,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 != t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -1884,6 +2028,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 != t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -1897,6 +2042,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 != t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -1910,6 +2056,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 != t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -1923,6 +2070,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 != t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -1936,6 +2084,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 != t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -1949,6 +2098,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 != t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -1962,6 +2112,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <> t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -1975,6 +2126,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <> t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -1988,6 +2140,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <> t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -2001,6 +2154,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <> t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -2014,6 +2168,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <> t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -2027,6 +2182,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <> t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -2040,6 +2196,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 <> t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -2053,6 +2210,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 <> t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -2066,6 +2224,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 <> t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -2079,6 +2238,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 <> t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -2092,6 +2252,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 <> t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -2105,6 +2266,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 <> t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -2118,6 +2280,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 <> t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -2131,6 +2294,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 <> t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -2144,6 +2308,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 <> t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -2157,6 +2322,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 <> t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -2170,6 +2336,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 <> t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -2183,6 +2350,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 <> t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -2196,6 +2364,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 <> t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -2209,6 +2378,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 <> t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -2222,6 +2392,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 <> t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -2235,6 +2406,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 <> t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -2248,6 +2420,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 <> t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -2261,6 +2434,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 <> t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -2274,6 +2448,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 <> t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -2287,6 +2462,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 <> t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -2300,6 +2476,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 <> t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -2313,6 +2490,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 <> t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -2326,6 +2504,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 <> t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -2339,6 +2518,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 <> t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -2352,6 +2532,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <=> t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -2365,6 +2546,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <=> t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -2378,6 +2560,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <=> t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -2391,6 +2574,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <=> t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -2404,6 +2588,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <=> t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -2417,6 +2602,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <=> t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -2430,6 +2616,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 <=> t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -2443,6 +2630,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 <=> t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -2456,6 +2644,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 <=> t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -2469,6 +2658,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 <=> t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -2482,6 +2672,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 <=> t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -2495,6 +2686,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 <=> t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -2508,6 +2700,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 <=> t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -2521,6 +2714,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 <=> t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -2534,6 +2728,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 <=> t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -2547,6 +2742,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 <=> t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -2560,6 +2756,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 <=> t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -2573,6 +2770,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 <=> t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -2586,6 +2784,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 <=> t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -2599,6 +2798,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 <=> t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -2612,6 +2812,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 <=> t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -2625,6 +2826,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 <=> t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -2638,6 +2840,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 <=> t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -2651,6 +2854,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 <=> t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -2664,6 +2868,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 <=> t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -2677,6 +2882,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 <=> t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -2690,6 +2896,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 <=> t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -2703,6 +2910,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 <=> t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -2716,6 +2924,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 <=> t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -2729,6 +2938,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 <=> t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; diff --git a/mysql-test/suite/gcol/inc/gcol_keys.inc b/mysql-test/suite/gcol/inc/gcol_keys.inc index cf0612b0d0c..e5ac0afd92a 100644 --- a/mysql-test/suite/gcol/inc/gcol_keys.inc +++ b/mysql-test/suite/gcol/inc/gcol_keys.inc @@ -203,7 +203,7 @@ INSERT INTO c ( col_time_nokey,col_datetime_nokey,col_varchar_nokey) values ('16:21:18.052408','2001-11-08 21:02:12.009395', 'x'), ('18:56:33.027423','2003-04-01 00:00:00', 'i'); ---replace_column 10 x 11 x +--replace_column 9 x 10 x EXPLAIN SELECT outr.col_time_key AS x FROM c as outr diff --git a/mysql-test/suite/gcol/inc/gcol_select.inc b/mysql-test/suite/gcol/inc/gcol_select.inc index 939d2f64e84..2386c55fdbc 100644 --- a/mysql-test/suite/gcol/inc/gcol_select.inc +++ b/mysql-test/suite/gcol/inc/gcol_select.inc @@ -507,7 +507,7 @@ INSERT /*! IGNORE */ INTO cc ( (6, '2008-10-10', NULL, '2000-05-22 00:00:00', 'i'), (8, '2002-01-19', '05:18:40.006865', '2009-02-12 00:00:00', 'v'); ---replace_column 10 # 11 # +--replace_column 9 # 10 # EXPLAIN SELECT subquery2_t2.col_int_key AS subquery2_field1 FROM (c AS subquery2_t1 RIGHT JOIN @@ -544,10 +544,10 @@ CREATE TABLE cc ( KEY (col_int_key) ); INSERT INTO cc (col_int_nokey) VALUES (0),(1),(7),(0),(4),(5); ---replace_column 10 # 11 # +--replace_column 9 # 10 # EXPLAIN SELECT pk FROM cc WHERE col_int_key > 3; SELECT pk FROM cc WHERE col_int_key > 3; ---replace_column 10 # 11 # +--replace_column 9 # 10 # EXPLAIN SELECT pk FROM cc WHERE col_int_key > 3 ORDER BY 1; SELECT pk FROM cc WHERE col_int_key > 3 ORDER BY 1; DROP TABLE cc; @@ -601,7 +601,7 @@ INSERT INTO a ( ANALYZE TABLE a, c; ---replace_column 10 # +--replace_column 9 # --disable_warnings EXPLAIN SELECT @@ -675,7 +675,7 @@ col_varchar_nokey (5, 'b'),(8,'m'),(7, 'j'),(2, 'v'); ANALYZE TABLE c, cc; ---replace_column 10 # +--replace_column 9 # --disable_warnings let query=SELECT @@ -734,7 +734,7 @@ KEY cover_key1 (col_int, col_varchar_255_utf8_key)); INSERT INTO j(col_int, pk, col_varchar_10_utf8) VALUES(9, 1, '951910400'), (-1934295040, 2, '1235025920'),(-584581120, 3, '-1176633344'),(3, 4, '1074462720'); ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT col_varchar_255_utf8_key FROM j ORDER BY 1; SELECT col_varchar_255_utf8_key FROM j ORDER BY col_varchar_255_utf8_key; diff --git a/mysql-test/suite/gcol/inc/gcol_view.inc b/mysql-test/suite/gcol/inc/gcol_view.inc index 6f9ce673199..85caa58c400 100644 --- a/mysql-test/suite/gcol/inc/gcol_view.inc +++ b/mysql-test/suite/gcol/inc/gcol_view.inc @@ -29,20 +29,20 @@ select d,e from v1; select is_updatable from information_schema.views where table_name='v1'; # view with different algorithms (explain output differs) ---replace_column 10 X +--replace_column 9 X explain select d,e from v1; create algorithm=temptable view v2 (d,e) as select abs(b), abs(c) from t1; show create view v2; --sorted_result select d,e from v2; ---replace_column 10 X +--replace_column 9 X explain select d,e from v2; # VIEW on VIEW test create view v3 (d,e) as select d*2, e*2 from v1; --sorted_result select * from v3; ---replace_column 10 X +--replace_column 9 X explain select * from v3; drop view v1,v2,v3; @@ -58,7 +58,7 @@ insert into t1 (a) values (1), (2), (3), (1), (2), (3); create view v1 as select distinct b from t1; --sorted_result select * from v1; ---replace_column 10 X +--replace_column 9 X explain select * from v1; --sorted_result select * from t1; @@ -66,7 +66,7 @@ drop view v1; create view v1 as select distinct c from t1; --sorted_result select * from v1; ---replace_column 10 X +--replace_column 9 X explain select * from v1; --sorted_result select * from t1; @@ -82,13 +82,13 @@ create table t1 (a int not null, insert into t1 (a) values (1), (2), (3), (4); create view v1 as select b+1 from t1 order by 1 desc limit 2; select * from v1; ---replace_column 10 X +--replace_column 9 X explain select * from v1; drop view v1; create view v1 as select c+1 from t1 order by 1 desc limit 2; --sorted_result select * from v1; ---replace_column 10 X +--replace_column 9 X explain select * from v1; drop view v1; drop table t1; diff --git a/mysql-test/suite/gcol/r/gcol_keys_innodb.result b/mysql-test/suite/gcol/r/gcol_keys_innodb.result index 196ceb5459e..edb20af7f1a 100644 --- a/mysql-test/suite/gcol/r/gcol_keys_innodb.result +++ b/mysql-test/suite/gcol/r/gcol_keys_innodb.result @@ -205,7 +205,7 @@ outr.col_varchar_nokey in ('c', 'x', 'i') AND (outr.col_time_key IS NULL OR outr.col_datetime_key = '2009-09-27'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE outr index_merge col_time_key,col_datetime_key col_time_key,col_datetime_key 4,6 NULL 2 x +1 SIMPLE outr index_merge col_time_key,col_datetime_key col_time_key,col_datetime_key 4,6 NULL x x SELECT outr.col_time_key AS x FROM c AS outr diff --git a/mysql-test/suite/gcol/r/gcol_keys_myisam.result b/mysql-test/suite/gcol/r/gcol_keys_myisam.result index c3cb35416ef..364d53afe1d 100644 --- a/mysql-test/suite/gcol/r/gcol_keys_myisam.result +++ b/mysql-test/suite/gcol/r/gcol_keys_myisam.result @@ -205,7 +205,7 @@ outr.col_varchar_nokey in ('c', 'x', 'i') AND (outr.col_time_key IS NULL OR outr.col_datetime_key = '2009-09-27'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE outr index_merge col_time_key,col_datetime_key col_time_key,col_datetime_key 4,6 NULL 2 x +1 SIMPLE outr index_merge col_time_key,col_datetime_key col_time_key,col_datetime_key 4,6 NULL x x SELECT outr.col_time_key AS x FROM c AS outr diff --git a/mysql-test/suite/gcol/r/gcol_select_myisam.result b/mysql-test/suite/gcol/r/gcol_select_myisam.result index 77ab0cdb926..67c495f6a6e 100644 --- a/mysql-test/suite/gcol/r/gcol_select_myisam.result +++ b/mysql-test/suite/gcol/r/gcol_select_myisam.result @@ -591,9 +591,9 @@ FROM (c AS subquery2_t1 RIGHT JOIN (subquery2_t3.col_varchar_key = subquery2_t2.col_varchar_key)) ORDER BY subquery2_field1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE subquery2_t2 index NULL col_int_key_2 10 NULL 20 # -1 SIMPLE subquery2_t3 ALL NULL NULL NULL NULL 20 # -1 SIMPLE subquery2_t1 index NULL PRIMARY 4 NULL 20 # +1 SIMPLE subquery2_t2 index NULL col_int_key_2 10 NULL # # +1 SIMPLE subquery2_t3 ALL NULL NULL NULL NULL # # +1 SIMPLE subquery2_t1 index NULL PRIMARY 4 NULL # # SELECT subquery2_t2.col_int_key AS subquery2_field1 FROM (c AS subquery2_t1 RIGHT JOIN (c AS subquery2_t2 LEFT JOIN cc AS subquery2_t3 ON @@ -794,7 +794,7 @@ KEY (col_int_key) INSERT INTO cc (col_int_nokey) VALUES (0),(1),(7),(0),(4),(5); EXPLAIN SELECT pk FROM cc WHERE col_int_key > 3; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE cc range col_int_key col_int_key 5 NULL 3 # +1 SIMPLE cc range col_int_key col_int_key 5 NULL # # SELECT pk FROM cc WHERE col_int_key > 3; pk 5 @@ -802,7 +802,7 @@ pk 3 EXPLAIN SELECT pk FROM cc WHERE col_int_key > 3 ORDER BY 1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE cc range col_int_key col_int_key 5 NULL 3 # +1 SIMPLE cc range col_int_key col_int_key 5 NULL # # SELECT pk FROM cc WHERE col_int_key > 3 ORDER BY 1; pk 3 @@ -876,12 +876,12 @@ ON (table3.col_int_key = table2.col_int_key ) ) ) ON (table3.col_int_nokey = table2.pk ) ) GROUP BY field1, field2; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY table1 system NULL NULL NULL NULL 1 # -1 PRIMARY table2 ALL PRIMARY,col_int_key,col_int_key_2 NULL NULL NULL 19 # -1 PRIMARY ref key0 key0 9 test.table2.pk,test.table2.col_int_key 10 # -2 DERIVED SUBQUERY1_t2 ALL PRIMARY,col_int_key,col_varchar_key,col_int_key_2 NULL NULL NULL 19 # -2 DERIVED SUBQUERY1_t3 ref PRIMARY,col_varchar_key col_varchar_key 5 test.SUBQUERY1_t2.col_varchar_key 1 # -2 DERIVED SUBQUERY1_t1 ALL col_int_key,col_int_key_2 NULL NULL NULL 19 # +1 PRIMARY table1 system NULL NULL NULL NULL # +1 PRIMARY table2 ALL PRIMARY,col_int_key,col_int_key_2 NULL NULL NULL # Using where +1 PRIMARY ref key0 key0 9 test.table2.pk,test.table2.col_int_key # +2 DERIVED SUBQUERY1_t2 ALL PRIMARY,col_int_key,col_varchar_key,col_int_key_2 NULL NULL NULL # Using where +2 DERIVED SUBQUERY1_t3 ref PRIMARY,col_varchar_key col_varchar_key 5 test.SUBQUERY1_t2.col_varchar_key # +2 DERIVED SUBQUERY1_t1 ALL col_int_key,col_int_key_2 NULL NULL NULL # Using where; Using join buffer (flat, BNL join) SELECT table1.pk AS field1 , table1.col_datetime_key AS field2 @@ -955,10 +955,10 @@ GROUP BY SQ1_field1 , SQ1_field2 ) GROUP BY field1; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY alias1 index NULL col_int_key_3 10 NULL 20 # -1 PRIMARY alias2 index NULL col_int_key_2 10 NULL 20 # -2 MATERIALIZED SQ1_alias1 index col_int_key,col_int_key_2,col_int_key_3 col_int_key 5 NULL 20 # -2 MATERIALIZED SQ1_alias2 ALL NULL NULL NULL NULL 20 # +1 PRIMARY alias1 index NULL col_int_key_3 10 NULL # Using index; Using temporary; Using filesort +1 PRIMARY alias2 index NULL col_int_key_2 10 NULL # Using where; Using index; Using join buffer (flat, BNL join) +2 MATERIALIZED SQ1_alias1 index col_int_key,col_int_key_2,col_int_key_3 col_int_key 5 NULL # Using index +2 MATERIALIZED SQ1_alias2 ALL NULL NULL NULL NULL # Using join buffer (flat, BNL join) SELECT alias2 . col_varchar_key AS field1 FROM ( cc AS alias1 , cc AS alias2 ) @@ -1018,7 +1018,7 @@ INSERT INTO j(col_int, pk, col_varchar_10_utf8) VALUES(9, 1, '951910400'), (-1934295040, 2, '1235025920'),(-584581120, 3, '-1176633344'),(3, 4, '1074462720'); EXPLAIN SELECT col_varchar_255_utf8_key FROM j ORDER BY 1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE j index NULL cover_key1 773 NULL 4 # +1 SIMPLE j index NULL cover_key1 773 NULL # Using index; Using filesort SELECT col_varchar_255_utf8_key FROM j ORDER BY col_varchar_255_utf8_key; col_varchar_255_utf8_key -117663334 diff --git a/mysql-test/suite/gcol/r/gcol_view_innodb.result b/mysql-test/suite/gcol/r/gcol_view_innodb.result index ac23d64bcee..15e1cfeb983 100644 --- a/mysql-test/suite/gcol/r/gcol_view_innodb.result +++ b/mysql-test/suite/gcol/r/gcol_view_innodb.result @@ -20,7 +20,7 @@ is_updatable NO explain select d,e from v1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 5 X +1 SIMPLE t1 ALL NULL NULL NULL NULL X create algorithm=temptable view v2 (d,e) as select abs(b), abs(c) from t1; show create view v2; View Create View character_set_client collation_connection @@ -34,8 +34,8 @@ d e 3 3 explain select d,e from v2; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL NULL NULL NULL NULL 5 X -2 DERIVED t1 ALL NULL NULL NULL NULL 5 X +1 PRIMARY ALL NULL NULL NULL NULL X +2 DERIVED t1 ALL NULL NULL NULL NULL X create view v3 (d,e) as select d*2, e*2 from v1; select * from v3; d e @@ -46,7 +46,7 @@ d e 6 6 explain select * from v3; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 5 X +1 SIMPLE t1 ALL NULL NULL NULL NULL X drop view v1,v2,v3; drop table t1; create table t1 (a int not null, @@ -61,8 +61,8 @@ b -3 explain select * from v1; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL NULL NULL NULL NULL 6 X -2 DERIVED t1 ALL NULL NULL NULL NULL 6 X +1 PRIMARY ALL NULL NULL NULL NULL X +2 DERIVED t1 ALL NULL NULL NULL NULL X Using temporary select * from t1; a b c 1 -1 -1 @@ -80,8 +80,8 @@ c -3 explain select * from v1; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL NULL NULL NULL NULL 6 X -2 DERIVED t1 ALL NULL NULL NULL NULL 6 X +1 PRIMARY ALL NULL NULL NULL NULL X +2 DERIVED t1 ALL NULL NULL NULL NULL X Using temporary select * from t1; a b c 1 -1 -1 @@ -103,8 +103,8 @@ b+1 -1 explain select * from v1; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL NULL NULL NULL NULL 2 X -2 DERIVED t1 ALL NULL NULL NULL NULL 4 X +1 PRIMARY ALL NULL NULL NULL NULL X +2 DERIVED t1 ALL NULL NULL NULL NULL X Using filesort drop view v1; create view v1 as select c+1 from t1 order by 1 desc limit 2; select * from v1; @@ -113,8 +113,8 @@ c+1 0 explain select * from v1; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL NULL NULL NULL NULL 2 X -2 DERIVED t1 ALL NULL NULL NULL NULL 4 X +1 PRIMARY ALL NULL NULL NULL NULL X +2 DERIVED t1 ALL NULL NULL NULL NULL X Using filesort drop view v1; drop table t1; create table t1 (a int, diff --git a/mysql-test/suite/gcol/r/gcol_view_myisam.result b/mysql-test/suite/gcol/r/gcol_view_myisam.result index ddbbf44222c..d266405dc66 100644 --- a/mysql-test/suite/gcol/r/gcol_view_myisam.result +++ b/mysql-test/suite/gcol/r/gcol_view_myisam.result @@ -20,7 +20,7 @@ is_updatable NO explain select d,e from v1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 5 X +1 SIMPLE t1 ALL NULL NULL NULL NULL X create algorithm=temptable view v2 (d,e) as select abs(b), abs(c) from t1; show create view v2; View Create View character_set_client collation_connection @@ -34,8 +34,8 @@ d e 3 3 explain select d,e from v2; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL NULL NULL NULL NULL 5 X -2 DERIVED t1 ALL NULL NULL NULL NULL 5 X +1 PRIMARY ALL NULL NULL NULL NULL X +2 DERIVED t1 ALL NULL NULL NULL NULL X create view v3 (d,e) as select d*2, e*2 from v1; select * from v3; d e @@ -46,7 +46,7 @@ d e 6 6 explain select * from v3; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 5 X +1 SIMPLE t1 ALL NULL NULL NULL NULL X drop view v1,v2,v3; drop table t1; create table t1 (a int not null, @@ -61,8 +61,8 @@ b -3 explain select * from v1; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL NULL NULL NULL NULL 6 X -2 DERIVED t1 ALL NULL NULL NULL NULL 6 X +1 PRIMARY ALL NULL NULL NULL NULL X +2 DERIVED t1 ALL NULL NULL NULL NULL X Using temporary select * from t1; a b c 1 -1 -1 @@ -80,8 +80,8 @@ c -3 explain select * from v1; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL NULL NULL NULL NULL 6 X -2 DERIVED t1 ALL NULL NULL NULL NULL 6 X +1 PRIMARY ALL NULL NULL NULL NULL X +2 DERIVED t1 ALL NULL NULL NULL NULL X Using temporary select * from t1; a b c 1 -1 -1 @@ -103,8 +103,8 @@ b+1 -1 explain select * from v1; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL NULL NULL NULL NULL 2 X -2 DERIVED t1 ALL NULL NULL NULL NULL 4 X +1 PRIMARY ALL NULL NULL NULL NULL X +2 DERIVED t1 ALL NULL NULL NULL NULL X Using filesort drop view v1; create view v1 as select c+1 from t1 order by 1 desc limit 2; select * from v1; @@ -113,8 +113,8 @@ c+1 0 explain select * from v1; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL NULL NULL NULL NULL 2 X -2 DERIVED t1 ALL NULL NULL NULL NULL 4 X +1 PRIMARY ALL NULL NULL NULL NULL X +2 DERIVED t1 ALL NULL NULL NULL NULL X Using filesort drop view v1; drop table t1; create table t1 (a int, diff --git a/mysql-test/suite/gcol/r/innodb_virtual_debug_purge.result b/mysql-test/suite/gcol/r/innodb_virtual_debug_purge.result index 3658e38125f..93bba0039f9 100644 --- a/mysql-test/suite/gcol/r/innodb_virtual_debug_purge.result +++ b/mysql-test/suite/gcol/r/innodb_virtual_debug_purge.result @@ -2,6 +2,8 @@ set default_storage_engine=innodb; set @old_dbug=@@global.debug_dbug; SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; +SET @saved_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = OFF; CREATE TABLE `t` ( `a` BLOB, `b` BLOB, @@ -206,3 +208,4 @@ connection default; DROP TABLE t1, t2; set debug_sync=reset; SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; +SET GLOBAL innodb_stats_persistent = @saved_stats_persistent; diff --git a/mysql-test/suite/gcol/t/innodb_virtual_debug_purge.test b/mysql-test/suite/gcol/t/innodb_virtual_debug_purge.test index cdec8107095..2f1f8b29aba 100644 --- a/mysql-test/suite/gcol/t/innodb_virtual_debug_purge.test +++ b/mysql-test/suite/gcol/t/innodb_virtual_debug_purge.test @@ -8,6 +8,8 @@ set @old_dbug=@@global.debug_dbug; # Ensure that the history list length will actually be decremented by purge. SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; +SET @saved_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = OFF; CREATE TABLE `t` ( `a` BLOB, @@ -263,3 +265,4 @@ DROP TABLE t1, t2; set debug_sync=reset; SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; +SET GLOBAL innodb_stats_persistent = @saved_stats_persistent; diff --git a/mysql-test/suite/innodb/r/alter_partitioned.result b/mysql-test/suite/innodb/r/alter_partitioned.result index 6c32142db9a..e46fa66e43b 100644 --- a/mysql-test/suite/innodb/r/alter_partitioned.result +++ b/mysql-test/suite/innodb/r/alter_partitioned.result @@ -11,6 +11,8 @@ SAVEPOINT sp; INSERT INTO t1 (pk) VALUES (1); ROLLBACK TO SAVEPOINT sp; connection default; +SET @save_timeout=@@lock_wait_timeout; +SET @save_innodb_timeout=@@innodb_lock_wait_timeout; SET lock_wait_timeout=0; SET innodb_lock_wait_timeout=0; ALTER TABLE t1 PARTITION BY HASH(pk); @@ -24,6 +26,8 @@ t1 CREATE TABLE `t1` ( connection con1; COMMIT; connection default; +SET lock_wait_timeout=@save_timeout; +SET innodb_lock_wait_timeout=@save_innodb_timeout; ALTER TABLE t2 PARTITION BY HASH(pk); disconnect con1; connection default; diff --git a/mysql-test/suite/innodb/r/doublewrite.result b/mysql-test/suite/innodb/r/doublewrite.result index 322385088b2..234d58012d3 100644 --- a/mysql-test/suite/innodb/r/doublewrite.result +++ b/mysql-test/suite/innodb/r/doublewrite.result @@ -17,7 +17,7 @@ innodb_saved_page_number_debug 0 connect stop_purge,localhost,root,,; START TRANSACTION WITH CONSISTENT SNAPSHOT; connection default; -create table t1 (f1 int primary key, f2 blob) engine=innodb; +create table t1 (f1 int primary key, f2 blob) engine=innodb stats_persistent=0; start transaction; insert into t1 values(1, repeat('#',12)); insert into t1 values(2, repeat('+',12)); diff --git a/mysql-test/suite/innodb/r/innodb-16k.result b/mysql-test/suite/innodb/r/innodb-16k.result index 3cf72975cdc..84b1eb6d3d3 100644 --- a/mysql-test/suite/innodb/r/innodb-16k.result +++ b/mysql-test/suite/innodb/r/innodb-16k.result @@ -1,4 +1,6 @@ call mtr.add_suppression("InnoDB: Cannot add field .* in table"); +SET @save_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; +SET GLOBAL innodb_purge_rseg_truncate_frequency=1; # Test 1) Show the page size from Information Schema SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_page_size'; @@ -164,13 +166,15 @@ INSERT INTO t2 VALUES ('jejdkrun87'),('adfd72nh9k'), CREATE TABLE t1(a int, b blob, c text, d text NOT NULL) ENGINE=innodb DEFAULT CHARSET=utf8; INSERT INTO t1 -SELECT a,LEFT(REPEAT(d,100*a),65535),REPEAT(d,20*a),d FROM t2,t3; +SELECT a,LEFT(REPEAT(d,100*a),65535),REPEAT(d,20*a),d FROM t2,t3 +ORDER BY a,d; DROP TABLE t2, t3; SELECT COUNT(*) FROM t1 WHERE a=44; COUNT(*) 5 SELECT a, -LENGTH(b),b=LEFT(REPEAT(d,100*a),65535),LENGTH(c),c=REPEAT(d,20*a),d FROM t1; +LENGTH(b),b=LEFT(REPEAT(d,100*a),65535),LENGTH(c),c=REPEAT(d,20*a),d FROM t1 +ORDER BY a,d; a LENGTH(b) b=LEFT(REPEAT(d,100*a),65535) LENGTH(c) c=REPEAT(d,20*a) d 22 22000 1 4400 1 adfd72nh9k 22 35200 1 7040 1 adfdijn0loKNHJik @@ -211,7 +215,8 @@ SELECT COUNT(*) FROM t1 WHERE a=44; COUNT(*) 5 SELECT a, -LENGTH(b), b=LEFT(REPEAT(d,100*a), 65535),LENGTH(c), c=REPEAT(d,20*a), d FROM t1; +LENGTH(b), b=LEFT(REPEAT(d,100*a), 65535),LENGTH(c), c=REPEAT(d,20*a), d FROM t1 +ORDER BY a,d; a LENGTH(b) b=LEFT(REPEAT(d,100*a), 65535) LENGTH(c) c=REPEAT(d,20*a) d 22 22000 1 4400 1 adfd72nh9k 22 35200 1 7040 1 adfdijn0loKNHJik @@ -498,7 +503,9 @@ ERROR 42000: Row size too large (> 8126). Changing some columns to TEXT or BLOB CREATE TABLE t1(c text, PRIMARY KEY (c(438))) ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII; INSERT INTO t1 VALUES(REPEAT('A',512)),(REPEAT('B',512)); +InnoDB 0 transactions not purged DROP TABLE t1; DROP TABLE t1_purge, t2_purge, t3_purge, t4_purge; DROP TABLE tlong; DROP TABLE tlong2; +SET GLOBAL innodb_purge_rseg_truncate_frequency=@save_frequency; diff --git a/mysql-test/suite/innodb/r/innodb-32k.result b/mysql-test/suite/innodb/r/innodb-32k.result index 184d7fde052..3660fac3a2f 100644 --- a/mysql-test/suite/innodb/r/innodb-32k.result +++ b/mysql-test/suite/innodb/r/innodb-32k.result @@ -1,3 +1,4 @@ +SET GLOBAL innodb_purge_rseg_truncate_frequency=1; call mtr.add_suppression("Innodb: Cannot add field.*row size is"); # Test 1) Show the page size from Information Schema SELECT variable_value FROM information_schema.global_status @@ -283,6 +284,7 @@ Level Code Message UPDATE t3 SET c = REPEAT('b',32800); SHOW WARNINGS; Level Code Message +InnoDB 0 transactions not purged DROP TABLE t3; DROP TABLE t1_purge, t2_purge, t3_purge, t4_purge; DROP TABLE tlong; diff --git a/mysql-test/suite/innodb/r/innodb-alter-tempfile.result b/mysql-test/suite/innodb/r/innodb-alter-tempfile.result index bc40e5f4b71..a64b2339a39 100644 --- a/mysql-test/suite/innodb/r/innodb-alter-tempfile.result +++ b/mysql-test/suite/innodb/r/innodb-alter-tempfile.result @@ -45,7 +45,7 @@ set DEBUG_SYNC="now WAIT_FOR default_signal"; disconnect con1; SHOW KEYS FROM t1; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment Ignored -t1 1 f1 1 f1 A 2 NULL NULL BTREE NO +t1 1 f1 1 f1 A # NULL NULL BTREE NO DROP TABLE t1; # # MDEV-25503 InnoDB hangs on startup during recovery diff --git a/mysql-test/suite/innodb/r/innodb-dict.result b/mysql-test/suite/innodb/r/innodb-dict.result index e3b2f0d5288..d56fec0f9af 100644 --- a/mysql-test/suite/innodb/r/innodb-dict.result +++ b/mysql-test/suite/innodb/r/innodb-dict.result @@ -24,6 +24,10 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref my_d my_d 5 const 128 Using index ALTER TABLE t1 DROP INDEX my_d; ALTER TABLE t1 MODIFY COLUMN D INT; +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK ALTER TABLE t1 ADD INDEX my_d (D); EXPLAIN SELECT d FROM t1 WHERE d = 5; id select_type table type possible_keys key key_len ref rows Extra diff --git a/mysql-test/suite/innodb/r/innodb-index-online.result b/mysql-test/suite/innodb/r/innodb-index-online.result index 92a2f57397c..6ad5c20ffed 100644 --- a/mysql-test/suite/innodb/r/innodb-index-online.result +++ b/mysql-test/suite/innodb/r/innodb-index-online.result @@ -148,6 +148,9 @@ database_name table_name index_name last_update stat_name stat_value sample_size test t1 PRIMARY LAST_UPDATE n_diff_pfx01 5 1 c1 test t1 PRIMARY LAST_UPDATE n_leaf_pages 1 NULL Number of leaf pages in the index test t1 PRIMARY LAST_UPDATE size 1 NULL Number of pages in the index +test t1_c2_stats GEN_CLUST_INDEX LAST_UPDATE n_diff_pfx01 3 1 DB_ROW_ID +test t1_c2_stats GEN_CLUST_INDEX LAST_UPDATE n_leaf_pages 1 NULL Number of leaf pages in the index +test t1_c2_stats GEN_CLUST_INDEX LAST_UPDATE size 1 NULL Number of pages in the index connection con1; KILL QUERY @id; ERROR 70100: Query execution was interrupted diff --git a/mysql-test/suite/innodb/r/innodb-isolation.result b/mysql-test/suite/innodb/r/innodb-isolation.result index ce9c530ff44..b6e512cc6de 100644 --- a/mysql-test/suite/innodb/r/innodb-isolation.result +++ b/mysql-test/suite/innodb/r/innodb-isolation.result @@ -939,40 +939,40 @@ COUNT(*) # EXPLAIN SELECT * FROM t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 12 # +1 SIMPLE t1 ALL NULL NULL NULL NULL # EXPLAIN SELECT COUNT(*) FROM t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL k2 5 NULL 12 Using index +1 SIMPLE t1 index NULL k2 5 NULL # Using index EXPLAIN SELECT COUNT(c1) FROM t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL k2 5 NULL 12 Using index +1 SIMPLE t1 index NULL k2 5 NULL # Using index EXPLAIN SELECT COUNT(c2) FROM t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL k2 5 NULL 12 # +1 SIMPLE t1 index NULL k2 5 NULL # Using index EXPLAIN SELECT COUNT(c3) FROM t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 12 # +1 SIMPLE t1 ALL NULL NULL NULL NULL # EXPLAIN SELECT SUM(c1) FROM t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL k2 5 NULL 12 # +1 SIMPLE t1 index NULL k2 5 NULL # Using index EXPLAIN SELECT SUM(c2) FROM t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL k2 5 NULL 12 # +1 SIMPLE t1 index NULL k2 5 NULL # Using index EXPLAIN SELECT AVG(c1), MAX(c1), MIN(c2), AVG(c3), SUM(c4) FROM t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 12 # +1 SIMPLE t1 ALL NULL NULL NULL NULL # EXPLAIN SELECT c1, c2 FROM t1 WHERE c1 > ((SELECT COUNT(*) FROM t1) / 2); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 range PRIMARY PRIMARY 4 NULL 8 # -2 SUBQUERY t1 index NULL k2 5 NULL 12 # +1 PRIMARY t1 range PRIMARY PRIMARY 4 NULL # Using where +2 SUBQUERY t1 index NULL k2 5 NULL # Using index EXPLAIN SELECT COUNT(c2) FROM t1 WHERE c1 > ((SELECT COUNT(*) FROM t1) / 2); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 range PRIMARY PRIMARY 4 NULL 8 # -2 SUBQUERY t1 index NULL k2 5 NULL 12 # +1 PRIMARY t1 range PRIMARY PRIMARY 4 NULL # Using where +2 SUBQUERY t1 index NULL k2 5 NULL # Using index EXPLAIN SELECT COUNT(*) FROM t1 WHERE c1 > (SELECT AVG(c1) FROM t1); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 range PRIMARY PRIMARY 4 NULL 7 # -2 SUBQUERY t1 index NULL k2 5 NULL 12 # +1 PRIMARY t1 range PRIMARY PRIMARY 4 NULL # Using where; Using index +2 SUBQUERY t1 index NULL k2 5 NULL # Using index # # Make all indexes in t2 obsolete to the active repeatable read transaction # in the default connection. @@ -1395,11 +1395,11 @@ disconnect con3; CREATE TABLE t1(c1 INT NOT NULL PRIMARY KEY, c2 INT NOT NULL DEFAULT 1, c3 char(20) DEFAULT '', -KEY c2_idx (c2)) ENGINE=InnoDB; +KEY c2_idx (c2)) ENGINE=InnoDB STATS_PERSISTENT=0; INSERT INTO t1(c1) VALUES (1), (2), (3); INSERT INTO t1(c1) SELECT c1 + 10 FROM t1; INSERT INTO t1(c1) SELECT c1 + 100 FROM t1; -CREATE TABLE t2 SELECT * FROM t1; +CREATE TABLE t2 STATS_PERSISTENT=0 SELECT * FROM t1; EXPLAIN SELECT COUNT(*) FROM t1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index NULL c2_idx 4 NULL 12 Using index diff --git a/mysql-test/suite/innodb/r/innodb-wl5522-debug.result b/mysql-test/suite/innodb/r/innodb-wl5522-debug.result index 2109d47bf4b..5236ae750c8 100644 --- a/mysql-test/suite/innodb/r/innodb-wl5522-debug.result +++ b/mysql-test/suite/innodb/r/innodb-wl5522-debug.result @@ -8,6 +8,7 @@ call mtr.add_suppression("InnoDB: Page 0 at offset 0 looks corrupted in file"); call mtr.add_suppression("InnoDB: Page for tablespace "); call mtr.add_suppression("InnoDB: Invalid FSP_SPACE_FLAGS="); call mtr.add_suppression("InnoDB: Unknown index id .* on page"); +call mtr.add_suppression("InnoDB: Cannot save statistics for table `test`\\.`t1` because the \\.ibd file is missing"); FLUSH TABLES; SET GLOBAL innodb_file_per_table = 1; CREATE TABLE t1 (c1 INT) ENGINE = InnoDB; diff --git a/mysql-test/suite/innodb/r/innodb-wl5522.result b/mysql-test/suite/innodb/r/innodb-wl5522.result index 16cbc113267..dc03bd91424 100644 --- a/mysql-test/suite/innodb/r/innodb-wl5522.result +++ b/mysql-test/suite/innodb/r/innodb-wl5522.result @@ -1,5 +1,6 @@ call mtr.add_suppression("InnoDB: Unable to import tablespace .* because it already exists. Please DISCARD the tablespace before IMPORT\\."); call mtr.add_suppression("Index for table 't2' is corrupt; try to repair it"); +call mtr.add_suppression("InnoDB: Cannot save statistics for table `test`\\.`t1` because the \\.ibd file is missing"); FLUSH TABLES; CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, diff --git a/mysql-test/suite/innodb/r/innodb.result b/mysql-test/suite/innodb/r/innodb.result index 7cb8602412a..d799cbb8fd9 100644 --- a/mysql-test/suite/innodb/r/innodb.result +++ b/mysql-test/suite/innodb/r/innodb.result @@ -45,7 +45,7 @@ level tinyint(4) DEFAULT '0' NOT NULL, PRIMARY KEY (id), KEY parent_id (parent_id), KEY level (level) -) engine=innodb; +) engine=innodb stats_persistent=0; INSERT INTO t1 VALUES (1,0,0),(3,1,1),(4,1,1),(8,2,2),(9,2,2),(17,3,2),(22,4,2),(24,4,2),(28,5,2),(29,5,2),(30,5,2),(31,6,2),(32,6,2),(33,6,2),(203,7,2),(202,7,2),(20,3,2),(157,0,0),(193,5,2),(40,7,2),(2,1,1),(15,2,2),(6,1,1),(34,6,2),(35,6,2),(16,3,2),(7,1,1),(36,7,2),(18,3,2),(26,5,2),(27,5,2),(183,4,2),(38,7,2),(25,5,2),(37,7,2),(21,4,2),(19,3,2),(5,1,1),(179,5,2); update t1 set parent_id=parent_id+100; select * from t1 where parent_id=102; diff --git a/mysql-test/suite/innodb/r/innodb_bug84958.result b/mysql-test/suite/innodb/r/innodb_bug84958.result index b721c73a0fc..a216dde1648 100644 --- a/mysql-test/suite/innodb/r/innodb_bug84958.result +++ b/mysql-test/suite/innodb/r/innodb_bug84958.result @@ -29,7 +29,7 @@ END~~ # Create a table with one record in it and start an RR transaction # CREATE TABLE t1 (a INT, b INT, c INT, PRIMARY KEY(a,b), KEY (b,c)) -ENGINE=InnoDB; +ENGINE=InnoDB STATS_PERSISTENT=0; BEGIN; SELECT * FROM t1; a b c diff --git a/mysql-test/suite/innodb/r/innodb_defrag_stats.result b/mysql-test/suite/innodb/r/innodb_defrag_stats.result index c2fd378cb4b..4fdcf42faa1 100644 --- a/mysql-test/suite/innodb/r/innodb_defrag_stats.result +++ b/mysql-test/suite/innodb/r/innodb_defrag_stats.result @@ -1,6 +1,6 @@ select @@global.innodb_stats_persistent; @@global.innodb_stats_persistent -0 +1 set global innodb_defragment_stats_accuracy = 20; CREATE TABLE t1(a INT PRIMARY KEY, b VARCHAR(256), KEY SECOND(a, b)) ENGINE=INNODB; diff --git a/mysql-test/suite/innodb/r/innodb_stats_drop_locked.result b/mysql-test/suite/innodb/r/innodb_stats_drop_locked.result index 7a6d5c46aab..13f21463390 100644 --- a/mysql-test/suite/innodb/r/innodb_stats_drop_locked.result +++ b/mysql-test/suite/innodb/r/innodb_stats_drop_locked.result @@ -26,6 +26,7 @@ innodb_stats_drop_locked innodb_stats_drop_locked innodb_stats_drop_locked connect con1,localhost,root,,; +SET innodb_lock_wait_timeout=1; ALTER TABLE innodb_stats_drop_locked DROP INDEX c_key; ERROR HY000: Lock wait timeout exceeded; try restarting transaction SHOW CREATE TABLE innodb_stats_drop_locked; diff --git a/mysql-test/suite/innodb/r/monitor.result b/mysql-test/suite/innodb/r/monitor.result index 0b2b0049f68..2e5e5e2241a 100644 --- a/mysql-test/suite/innodb/r/monitor.result +++ b/mysql-test/suite/innodb/r/monitor.result @@ -578,7 +578,7 @@ set global innodb_monitor_reset_all = default; # Bug#22576241 SETTING INNODB_MONITOR_ENABLE TO ALL DOES NOT ENABLE ALL # MONITORS # -CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB STATS_PERSISTENT=0; SELECT NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME LIKE 'buffer_page_written_index_leaf'; NAME COUNT > 0 diff --git a/mysql-test/suite/innodb/r/update_time.result b/mysql-test/suite/innodb/r/update_time.result index c2a842b7bfc..a1da8cc422a 100644 --- a/mysql-test/suite/innodb/r/update_time.result +++ b/mysql-test/suite/innodb/r/update_time.result @@ -2,7 +2,7 @@ # Test that INFORMATION_SCHEMA.TABLES.UPDATE_TIME is filled # correctly for InnoDB tables. # -CREATE TABLE t (a INT) ENGINE=INNODB; +CREATE TABLE t (a INT) ENGINE=INNODB STATS_PERSISTENT=0; SELECT update_time FROM information_schema.tables WHERE table_name = 't'; update_time NULL diff --git a/mysql-test/suite/innodb/t/alter_partitioned.test b/mysql-test/suite/innodb/t/alter_partitioned.test index 4990c265b5e..aaada25dcbe 100644 --- a/mysql-test/suite/innodb/t/alter_partitioned.test +++ b/mysql-test/suite/innodb/t/alter_partitioned.test @@ -18,6 +18,8 @@ INSERT INTO t1 (pk) VALUES (1); ROLLBACK TO SAVEPOINT sp; --connection default +SET @save_timeout=@@lock_wait_timeout; +SET @save_innodb_timeout=@@innodb_lock_wait_timeout; SET lock_wait_timeout=0; SET innodb_lock_wait_timeout=0; --error ER_LOCK_WAIT_TIMEOUT @@ -27,6 +29,8 @@ SHOW CREATE TABLE t1; --connection con1 COMMIT; --connection default +SET lock_wait_timeout=@save_timeout; +SET innodb_lock_wait_timeout=@save_innodb_timeout; ALTER TABLE t2 PARTITION BY HASH(pk); # Cleanup --disconnect con1 diff --git a/mysql-test/suite/innodb/t/doublewrite.test b/mysql-test/suite/innodb/t/doublewrite.test index fac1812e565..cedd2c9942b 100644 --- a/mysql-test/suite/innodb/t/doublewrite.test +++ b/mysql-test/suite/innodb/t/doublewrite.test @@ -38,7 +38,7 @@ connect (stop_purge,localhost,root,,); START TRANSACTION WITH CONSISTENT SNAPSHOT; connection default; -create table t1 (f1 int primary key, f2 blob) engine=innodb; +create table t1 (f1 int primary key, f2 blob) engine=innodb stats_persistent=0; start transaction; insert into t1 values(1, repeat('#',12)); diff --git a/mysql-test/suite/innodb/t/innodb-16k.test b/mysql-test/suite/innodb/t/innodb-16k.test index 89819ba7b6d..c059f62385b 100644 --- a/mysql-test/suite/innodb/t/innodb-16k.test +++ b/mysql-test/suite/innodb/t/innodb-16k.test @@ -4,6 +4,8 @@ --source include/have_innodb_16k.inc call mtr.add_suppression("InnoDB: Cannot add field .* in table"); +SET @save_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; +SET GLOBAL innodb_purge_rseg_truncate_frequency=1; let $MYSQLD_DATADIR= `select @@datadir`; @@ -183,11 +185,13 @@ INSERT INTO t2 VALUES ('jejdkrun87'),('adfd72nh9k'), CREATE TABLE t1(a int, b blob, c text, d text NOT NULL) ENGINE=innodb DEFAULT CHARSET=utf8; INSERT INTO t1 -SELECT a,LEFT(REPEAT(d,100*a),65535),REPEAT(d,20*a),d FROM t2,t3; +SELECT a,LEFT(REPEAT(d,100*a),65535),REPEAT(d,20*a),d FROM t2,t3 +ORDER BY a,d; DROP TABLE t2, t3; SELECT COUNT(*) FROM t1 WHERE a=44; SELECT a, -LENGTH(b),b=LEFT(REPEAT(d,100*a),65535),LENGTH(c),c=REPEAT(d,20*a),d FROM t1; +LENGTH(b),b=LEFT(REPEAT(d,100*a),65535),LENGTH(c),c=REPEAT(d,20*a),d FROM t1 +ORDER BY a,d; # in-place alter table should trigger ER_PRIMARY_CANT_HAVE_NULL --error ER_DUP_ENTRY @@ -200,7 +204,8 @@ CHECK TABLE t1; ALTER TABLE t1 ADD PRIMARY KEY (a,b(255),c(255)), ADD KEY (b(767)); SELECT COUNT(*) FROM t1 WHERE a=44; SELECT a, -LENGTH(b), b=LEFT(REPEAT(d,100*a), 65535),LENGTH(c), c=REPEAT(d,20*a), d FROM t1; +LENGTH(b), b=LEFT(REPEAT(d,100*a), 65535),LENGTH(c), c=REPEAT(d,20*a), d FROM t1 +ORDER BY a,d; SHOW CREATE TABLE t1; CHECK TABLE t1; DROP TABLE t1; @@ -450,13 +455,11 @@ ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII; INSERT INTO t1 VALUES(REPEAT('A',512)),(REPEAT('B',512)); +--source include/wait_all_purged.inc + DROP TABLE t1; - -# The tests that uses these tables required the purge thread to run. -# Just in case it has not by now, provide a 10 second wait. - ---sleep 10 - DROP TABLE t1_purge, t2_purge, t3_purge, t4_purge; DROP TABLE tlong; DROP TABLE tlong2; + +SET GLOBAL innodb_purge_rseg_truncate_frequency=@save_frequency; \ No newline at end of file diff --git a/mysql-test/suite/innodb/t/innodb-32k.test b/mysql-test/suite/innodb/t/innodb-32k.test index 983ba88370a..07c6c10d013 100644 --- a/mysql-test/suite/innodb/t/innodb-32k.test +++ b/mysql-test/suite/innodb/t/innodb-32k.test @@ -3,6 +3,8 @@ --source include/have_innodb.inc --source include/have_innodb_32k.inc +SET GLOBAL innodb_purge_rseg_truncate_frequency=1; + call mtr.add_suppression("Innodb: Cannot add field.*row size is"); let $MYSQLD_DATADIR= `select @@datadir`; @@ -334,13 +336,10 @@ UPDATE t3 SET c = REPEAT('b',16928); SHOW WARNINGS; UPDATE t3 SET c = REPEAT('b',32800); SHOW WARNINGS; + +--source include/wait_all_purged.inc + DROP TABLE t3; - -# The tests that uses these tables required the purge thread to run. -# Just in case it has not by now, provide a 10 second wait. - ---sleep 10 - DROP TABLE t1_purge, t2_purge, t3_purge, t4_purge; DROP TABLE tlong; DROP TABLE tlong2; diff --git a/mysql-test/suite/innodb/t/innodb-alter-tempfile.test b/mysql-test/suite/innodb/t/innodb-alter-tempfile.test index 979005f6410..769ac8fa4bc 100644 --- a/mysql-test/suite/innodb/t/innodb-alter-tempfile.test +++ b/mysql-test/suite/innodb/t/innodb-alter-tempfile.test @@ -65,6 +65,7 @@ set DEBUG_SYNC="now WAIT_FOR default_signal"; --let $shutdown_timeout=0 --source include/restart_mysqld.inc disconnect con1; +--replace_column 7 # SHOW KEYS FROM t1; DROP TABLE t1; remove_files_wildcard $datadir/test #sql-*.frm; diff --git a/mysql-test/suite/innodb/t/innodb-dict.test b/mysql-test/suite/innodb/t/innodb-dict.test index 25a284569db..13472f016ea 100644 --- a/mysql-test/suite/innodb/t/innodb-dict.test +++ b/mysql-test/suite/innodb/t/innodb-dict.test @@ -24,6 +24,7 @@ EXPLAIN SELECT d FROM t1 WHERE d = 5; EXPLAIN SELECT D FROM t1 WHERE D = 5; ALTER TABLE t1 DROP INDEX my_d; ALTER TABLE t1 MODIFY COLUMN D INT; +ANALYZE TABLE t1; ALTER TABLE t1 ADD INDEX my_d (D); EXPLAIN SELECT d FROM t1 WHERE d = 5; EXPLAIN SELECT D FROM t1 WHERE D = 5; diff --git a/mysql-test/suite/innodb/t/innodb-index.opt b/mysql-test/suite/innodb/t/innodb-index.opt new file mode 100644 index 00000000000..1a01b4018c6 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-index.opt @@ -0,0 +1 @@ +--skip-innodb-stats-persistent diff --git a/mysql-test/suite/innodb/t/innodb-index_ucs2.opt b/mysql-test/suite/innodb/t/innodb-index_ucs2.opt new file mode 100644 index 00000000000..1a01b4018c6 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-index_ucs2.opt @@ -0,0 +1 @@ +--skip-innodb-stats-persistent diff --git a/mysql-test/suite/innodb/t/innodb-isolation.test b/mysql-test/suite/innodb/t/innodb-isolation.test index d00fefb9fc6..6d347dc71af 100644 --- a/mysql-test/suite/innodb/t/innodb-isolation.test +++ b/mysql-test/suite/innodb/t/innodb-isolation.test @@ -162,28 +162,30 @@ COMMIT; --echo # --echo # Show The EXPLAIN output for these queries; --echo # -# column 10 is the row count provided by handler::info(). In InnoDB, this is +# column 9 is the row count provided by handler::info(). In InnoDB, this is # a statistical estimate. After the multi-transactional changes above, # Solaris reports 10 rows which is correct, but other OSes report 9. ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT * FROM t1; +--replace_column 9 # EXPLAIN SELECT COUNT(*) FROM t1; +--replace_column 9 # EXPLAIN SELECT COUNT(c1) FROM t1; ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT COUNT(c2) FROM t1; ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT COUNT(c3) FROM t1; ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT SUM(c1) FROM t1; ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT SUM(c2) FROM t1; ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT AVG(c1), MAX(c1), MIN(c2), AVG(c3), SUM(c4) FROM t1; ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT c1, c2 FROM t1 WHERE c1 > ((SELECT COUNT(*) FROM t1) / 2); ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT COUNT(c2) FROM t1 WHERE c1 > ((SELECT COUNT(*) FROM t1) / 2); ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT COUNT(*) FROM t1 WHERE c1 > (SELECT AVG(c1) FROM t1); --echo # @@ -334,13 +336,13 @@ eval set global innodb_lock_wait_timeout=$initial_timeout; CREATE TABLE t1(c1 INT NOT NULL PRIMARY KEY, c2 INT NOT NULL DEFAULT 1, c3 char(20) DEFAULT '', - KEY c2_idx (c2)) ENGINE=InnoDB; + KEY c2_idx (c2)) ENGINE=InnoDB STATS_PERSISTENT=0; INSERT INTO t1(c1) VALUES (1), (2), (3); INSERT INTO t1(c1) SELECT c1 + 10 FROM t1; INSERT INTO t1(c1) SELECT c1 + 100 FROM t1; -CREATE TABLE t2 SELECT * FROM t1; +CREATE TABLE t2 STATS_PERSISTENT=0 SELECT * FROM t1; let query1= SELECT COUNT(*) FROM t1; let query2= SELECT COUNT(*) FROM t1 FORCE INDEX(c2_idx); diff --git a/mysql-test/suite/innodb/t/innodb-stats-modified-counter.opt b/mysql-test/suite/innodb/t/innodb-stats-modified-counter.opt index 3e5b41c6db9..1cfd8e7112e 100644 --- a/mysql-test/suite/innodb/t/innodb-stats-modified-counter.opt +++ b/mysql-test/suite/innodb/t/innodb-stats-modified-counter.opt @@ -1 +1 @@ ---loose-innodb-sys-tablestats +--loose-innodb-sys-tablestats --skip-innodb-stats-persistent diff --git a/mysql-test/suite/innodb/t/innodb-wl5522-debug.test b/mysql-test/suite/innodb/t/innodb-wl5522-debug.test index 7256e2f23e0..0adf0eaf43b 100644 --- a/mysql-test/suite/innodb/t/innodb-wl5522-debug.test +++ b/mysql-test/suite/innodb/t/innodb-wl5522-debug.test @@ -28,6 +28,7 @@ call mtr.add_suppression("InnoDB: Page 0 at offset 0 looks corrupted in file"); call mtr.add_suppression("InnoDB: Page for tablespace "); call mtr.add_suppression("InnoDB: Invalid FSP_SPACE_FLAGS="); call mtr.add_suppression("InnoDB: Unknown index id .* on page"); +call mtr.add_suppression("InnoDB: Cannot save statistics for table `test`\\.`t1` because the \\.ibd file is missing"); FLUSH TABLES; let MYSQLD_DATADIR =`SELECT @@datadir`; diff --git a/mysql-test/suite/innodb/t/innodb-wl5522.test b/mysql-test/suite/innodb/t/innodb-wl5522.test index 9b18b29fc20..a70ae86f1cd 100644 --- a/mysql-test/suite/innodb/t/innodb-wl5522.test +++ b/mysql-test/suite/innodb/t/innodb-wl5522.test @@ -7,6 +7,8 @@ call mtr.add_suppression("InnoDB: Unable to import tablespace .* because it already exists. Please DISCARD the tablespace before IMPORT\\."); call mtr.add_suppression("Index for table 't2' is corrupt; try to repair it"); +call mtr.add_suppression("InnoDB: Cannot save statistics for table `test`\\.`t1` because the \\.ibd file is missing"); + FLUSH TABLES; let $MYSQLD_TMPDIR = `SELECT @@tmpdir`; diff --git a/mysql-test/suite/innodb/t/innodb.test b/mysql-test/suite/innodb/t/innodb.test index a50d3b7d9af..3a8c12dfbbd 100644 --- a/mysql-test/suite/innodb/t/innodb.test +++ b/mysql-test/suite/innodb/t/innodb.test @@ -79,7 +79,7 @@ CREATE TABLE t1 ( PRIMARY KEY (id), KEY parent_id (parent_id), KEY level (level) -) engine=innodb; +) engine=innodb stats_persistent=0; INSERT INTO t1 VALUES (1,0,0),(3,1,1),(4,1,1),(8,2,2),(9,2,2),(17,3,2),(22,4,2),(24,4,2),(28,5,2),(29,5,2),(30,5,2),(31,6,2),(32,6,2),(33,6,2),(203,7,2),(202,7,2),(20,3,2),(157,0,0),(193,5,2),(40,7,2),(2,1,1),(15,2,2),(6,1,1),(34,6,2),(35,6,2),(16,3,2),(7,1,1),(36,7,2),(18,3,2),(26,5,2),(27,5,2),(183,4,2),(38,7,2),(25,5,2),(37,7,2),(21,4,2),(19,3,2),(5,1,1),(179,5,2); update t1 set parent_id=parent_id+100; select * from t1 where parent_id=102; diff --git a/mysql-test/suite/innodb/t/innodb_bug57252.test b/mysql-test/suite/innodb/t/innodb_bug57252.test index 5a4ca1ab6d8..eafcaee19bd 100644 --- a/mysql-test/suite/innodb/t/innodb_bug57252.test +++ b/mysql-test/suite/innodb/t/innodb_bug57252.test @@ -9,7 +9,7 @@ SET @innodb_stats_on_metadata_orig = @@innodb_stats_on_metadata; -CREATE TABLE bug57252 (a INT, KEY akey (a)) ENGINE=INNODB; +CREATE TABLE bug57252 (a INT, KEY akey (a)) ENGINE=INNODB STATS_PERSISTENT=0; BEGIN; let $i = 10; diff --git a/mysql-test/suite/innodb/t/innodb_bug84958.test b/mysql-test/suite/innodb/t/innodb_bug84958.test index cbcc5d1abc6..f895c8d1245 100644 --- a/mysql-test/suite/innodb/t/innodb_bug84958.test +++ b/mysql-test/suite/innodb/t/innodb_bug84958.test @@ -36,7 +36,7 @@ DELIMITER ;~~ --echo # Create a table with one record in it and start an RR transaction --echo # CREATE TABLE t1 (a INT, b INT, c INT, PRIMARY KEY(a,b), KEY (b,c)) -ENGINE=InnoDB; +ENGINE=InnoDB STATS_PERSISTENT=0; BEGIN; SELECT * FROM t1; diff --git a/mysql-test/suite/innodb/t/innodb_stats_drop_locked.test b/mysql-test/suite/innodb/t/innodb_stats_drop_locked.test index ab4cc78b337..6532816bb37 100644 --- a/mysql-test/suite/innodb/t/innodb_stats_drop_locked.test +++ b/mysql-test/suite/innodb/t/innodb_stats_drop_locked.test @@ -23,6 +23,8 @@ WHERE table_name='innodb_stats_drop_locked' FOR UPDATE; -- connect (con1,localhost,root,,) +SET innodb_lock_wait_timeout=1; + --error ER_LOCK_WAIT_TIMEOUT ALTER TABLE innodb_stats_drop_locked DROP INDEX c_key; diff --git a/mysql-test/suite/innodb/t/instant_alter.opt b/mysql-test/suite/innodb/t/instant_alter.opt index 99bf0e5a28b..1f0d2d43ddf 100644 --- a/mysql-test/suite/innodb/t/instant_alter.opt +++ b/mysql-test/suite/innodb/t/instant_alter.opt @@ -1 +1 @@ ---innodb-sys-tablestats +--innodb-sys-tablestats --skip-innodb-stats-persistent diff --git a/mysql-test/suite/innodb/t/instant_alter_debug.combinations b/mysql-test/suite/innodb/t/instant_alter_debug.combinations index f3bc2cc0c25..5f98b128ab6 100644 --- a/mysql-test/suite/innodb/t/instant_alter_debug.combinations +++ b/mysql-test/suite/innodb/t/instant_alter_debug.combinations @@ -1,4 +1,6 @@ [redundant] innodb_default_row_format=redundant +innodb_stats_persistent=off [dynamic] innodb_default_row_format=dynamic +innodb_stats_persistent=off diff --git a/mysql-test/suite/innodb/t/monitor.test b/mysql-test/suite/innodb/t/monitor.test index b80d9deabc1..3a004b22751 100644 --- a/mysql-test/suite/innodb/t/monitor.test +++ b/mysql-test/suite/innodb/t/monitor.test @@ -394,7 +394,7 @@ set global innodb_monitor_reset_all = default; --echo # Bug#22576241 SETTING INNODB_MONITOR_ENABLE TO ALL DOES NOT ENABLE ALL --echo # MONITORS --echo # -CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB STATS_PERSISTENT=0; let $innodb_monitor_enable = `SELECT @@innodb_monitor_enable`; diff --git a/mysql-test/suite/innodb/t/purge_secondary.opt b/mysql-test/suite/innodb/t/purge_secondary.opt index e98e639d5f4..2821c98397c 100644 --- a/mysql-test/suite/innodb/t/purge_secondary.opt +++ b/mysql-test/suite/innodb/t/purge_secondary.opt @@ -1,3 +1,4 @@ --innodb-sys-tablestats --innodb_buffer_pool_size=5M --innodb_monitor_enable=module_buffer +--skip-innodb-stats-persistent diff --git a/mysql-test/suite/innodb/t/update_time.test b/mysql-test/suite/innodb/t/update_time.test index a95c5171e9b..8ccf7c0d532 100644 --- a/mysql-test/suite/innodb/t/update_time.test +++ b/mysql-test/suite/innodb/t/update_time.test @@ -11,7 +11,7 @@ # This test is slow on buildbot. --source include/big_test.inc -CREATE TABLE t (a INT) ENGINE=INNODB; +CREATE TABLE t (a INT) ENGINE=INNODB STATS_PERSISTENT=0; SELECT update_time FROM information_schema.tables WHERE table_name = 't'; diff --git a/mysql-test/suite/innodb_fts/r/misc_debug.result b/mysql-test/suite/innodb_fts/r/misc_debug.result index e8a462f2751..d012fa5a9c8 100644 --- a/mysql-test/suite/innodb_fts/r/misc_debug.result +++ b/mysql-test/suite/innodb_fts/r/misc_debug.result @@ -55,6 +55,7 @@ DROP TABLE t1; # MDEV-25663 Double free of transaction during TRUNCATE # call mtr.add_suppression("InnoDB: \\(Too many concurrent transactions\\)"); +call mtr.add_suppression("InnoDB: Cannot save table statistics for table `test`\\.`t1`: Too many concurrent transactions"); CREATE TABLE t1 (b CHAR(12), FULLTEXT KEY(b)) engine=InnoDB; SET debug_dbug='+d,ib_create_table_fail_too_many_trx'; TRUNCATE t1; diff --git a/mysql-test/suite/innodb_fts/t/misc_debug.test b/mysql-test/suite/innodb_fts/t/misc_debug.test index b1193d0ec3c..bbf3afe69e5 100644 --- a/mysql-test/suite/innodb_fts/t/misc_debug.test +++ b/mysql-test/suite/innodb_fts/t/misc_debug.test @@ -85,6 +85,7 @@ DROP TABLE t1; --echo # MDEV-25663 Double free of transaction during TRUNCATE --echo # call mtr.add_suppression("InnoDB: \\(Too many concurrent transactions\\)"); +call mtr.add_suppression("InnoDB: Cannot save table statistics for table `test`\\.`t1`: Too many concurrent transactions"); CREATE TABLE t1 (b CHAR(12), FULLTEXT KEY(b)) engine=InnoDB; SET debug_dbug='+d,ib_create_table_fail_too_many_trx'; diff --git a/mysql-test/suite/innodb_gis/r/1.result b/mysql-test/suite/innodb_gis/r/1.result index 26fdf39baf3..f8db53a4ca9 100644 --- a/mysql-test/suite/innodb_gis/r/1.result +++ b/mysql-test/suite/innodb_gis/r/1.result @@ -227,7 +227,7 @@ fid ST_AsText(ST_Envelope(g)) 121 POLYGON((3 6,44 6,44 9,3 9,3 6)) explain extended select ST_Dimension(g), ST_GeometryType(g), ST_IsEmpty(g), ST_AsText(ST_Envelope(g)) from gis_geometry; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE gis_geometry ALL NULL NULL NULL NULL 21 # +1 SIMPLE gis_geometry ALL NULL NULL NULL NULL # # Warnings: Note 1003 select st_dimension(`test`.`gis_geometry`.`g`) AS `ST_Dimension(g)`,st_geometrytype(`test`.`gis_geometry`.`g`) AS `ST_GeometryType(g)`,st_isempty(`test`.`gis_geometry`.`g`) AS `ST_IsEmpty(g)`,st_astext(st_envelope(`test`.`gis_geometry`.`g`)) AS `ST_AsText(ST_Envelope(g))` from `test`.`gis_geometry` SELECT fid, ST_X(g) FROM gis_point; @@ -244,7 +244,7 @@ fid ST_Y(g) 104 20 explain extended select ST_X(g),ST_Y(g) FROM gis_point; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE gis_point ALL NULL NULL NULL NULL 4 # +1 SIMPLE gis_point ALL NULL NULL NULL NULL # # Warnings: Note 1003 select st_x(`test`.`gis_point`.`g`) AS `ST_X(g)`,st_y(`test`.`gis_point`.`g`) AS `ST_Y(g)` from `test`.`gis_point` SELECT fid, ST_AsText(ST_StartPoint(g)) FROM gis_line; @@ -279,7 +279,7 @@ fid ST_IsClosed(g) 107 0 explain extended select ST_AsText(ST_StartPoint(g)),ST_AsText(ST_EndPoint(g)),ST_Length(g),ST_NumPoints(g),ST_AsText(ST_PointN(g, 2)),ST_IsClosed(g) FROM gis_line; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE gis_line ALL NULL NULL NULL NULL 3 # +1 SIMPLE gis_line ALL NULL NULL NULL NULL # # Warnings: Note 1003 select st_astext(st_startpoint(`test`.`gis_line`.`g`)) AS `ST_AsText(ST_StartPoint(g))`,st_astext(st_endpoint(`test`.`gis_line`.`g`)) AS `ST_AsText(ST_EndPoint(g))`,st_length(`test`.`gis_line`.`g`) AS `ST_Length(g)`,st_numpoints(`test`.`gis_line`.`g`) AS `ST_NumPoints(g)`,st_astext(st_pointn(`test`.`gis_line`.`g`,2)) AS `ST_AsText(ST_PointN(g, 2))`,st_isclosed(`test`.`gis_line`.`g`) AS `ST_IsClosed(g)` from `test`.`gis_line` SELECT fid, ST_AsText(ST_Centroid(g)) FROM gis_polygon; @@ -309,7 +309,7 @@ fid ST_AsText(ST_InteriorRingN(g, 1)) 110 NULL explain extended select ST_AsText(ST_Centroid(g)),ST_Area(g),ST_AsText(ST_ExteriorRing(g)),ST_NumInteriorRings(g),ST_AsText(ST_InteriorRingN(g, 1)) FROM gis_polygon; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE gis_polygon ALL NULL NULL NULL NULL 3 # +1 SIMPLE gis_polygon ALL NULL NULL NULL NULL # # Warnings: Note 1003 select st_astext(st_centroid(`test`.`gis_polygon`.`g`)) AS `ST_AsText(ST_Centroid(g))`,st_area(`test`.`gis_polygon`.`g`) AS `ST_Area(g)`,st_astext(st_exteriorring(`test`.`gis_polygon`.`g`)) AS `ST_AsText(ST_ExteriorRing(g))`,st_numinteriorrings(`test`.`gis_polygon`.`g`) AS `ST_NumInteriorRings(g)`,st_astext(st_interiorringn(`test`.`gis_polygon`.`g`,1)) AS `ST_AsText(ST_InteriorRingN(g, 1))` from `test`.`gis_polygon` SELECT fid, ST_IsClosed(g) FROM gis_multi_line; @@ -348,7 +348,7 @@ fid ST_NumGeometries(g) 121 2 explain extended SELECT fid, ST_NumGeometries(g) from gis_multi_point; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE gis_multi_point ALL NULL NULL NULL NULL 3 # +1 SIMPLE gis_multi_point ALL NULL NULL NULL NULL # # Warnings: Note 1003 select `test`.`gis_multi_point`.`fid` AS `fid`,st_numgeometries(`test`.`gis_multi_point`.`g`) AS `ST_NumGeometries(g)` from `test`.`gis_multi_point` SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_multi_point; @@ -376,7 +376,7 @@ fid ST_AsText(ST_GeometryN(g, 1)) 121 POINT(44 6) explain extended SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_multi_point; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE gis_multi_point ALL NULL NULL NULL NULL 3 # +1 SIMPLE gis_multi_point ALL NULL NULL NULL NULL # # Warnings: Note 1003 select `test`.`gis_multi_point`.`fid` AS `fid`,st_astext(st_geometryn(`test`.`gis_multi_point`.`g`,2)) AS `ST_AsText(ST_GeometryN(g, 2))` from `test`.`gis_multi_point` SELECT g1.fid as first, g2.fid as second, @@ -395,8 +395,8 @@ MBREquals(g1.g, g2.g) as e, MBRDisjoint(g1.g, g2.g) as d, ST_Touches(g1.g, g2.g) MBRIntersects(g1.g, g2.g) as i, ST_Crosses(g1.g, g2.g) as r FROM gis_geometrycollection g1, gis_geometrycollection g2 ORDER BY first, second; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE g1 ALL NULL NULL NULL NULL 2 # Using temporary; Using filesort -1 SIMPLE g2 ALL NULL NULL NULL NULL 2 # Using join buffer (flat, BNL join) +1 SIMPLE g1 ALL NULL NULL NULL NULL # # Using temporary; Using filesort +1 SIMPLE g2 ALL NULL NULL NULL NULL # # Using join buffer (flat, BNL join) Warnings: Note 1003 select `test`.`g1`.`fid` AS `first`,`test`.`g2`.`fid` AS `second`,mbrwithin(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `w`,mbrcontains(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `c`,mbroverlaps(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `o`,mbrequals(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `e`,mbrdisjoint(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `d`,st_touches(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `t`,mbrintersects(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `i`,st_crosses(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `r` from `test`.`gis_geometrycollection` `g1` join `test`.`gis_geometrycollection` `g2` order by `test`.`g1`.`fid`,`test`.`g2`.`fid` DROP TABLE gis_point, gis_line, gis_polygon, gis_multi_point, gis_multi_line, gis_multi_polygon, gis_geometrycollection, gis_geometry; diff --git a/mysql-test/suite/innodb_gis/r/geometry.result b/mysql-test/suite/innodb_gis/r/geometry.result index 70e0f04cdf1..437ff23e334 100644 --- a/mysql-test/suite/innodb_gis/r/geometry.result +++ b/mysql-test/suite/innodb_gis/r/geometry.result @@ -1,5 +1,7 @@ SET default_storage_engine=InnoDB; SET innodb_strict_mode=OFF; +SET @save_innodb_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; CREATE TABLE gis_point (fid INTEGER NOT NULL PRIMARY KEY, g POINT) ENGINE=InnoDB; CREATE TABLE gis_line (fid INTEGER NOT NULL PRIMARY KEY, g LINESTRING) ENGINE=InnoDB; CREATE TABLE gis_polygon (fid INTEGER NOT NULL PRIMARY KEY, g POLYGON) ENGINE=InnoDB; @@ -179,39 +181,39 @@ CREATE UNIQUE INDEX idx2 on tab(c8(5) ASC) ; EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab WHERE c2=ST_LineFromText('LINESTRING(10 10,20 20,30 30)'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab ref idx1 idx1 8 const 1 # +1 SIMPLE tab ref idx1 idx1 8 const # Using where #check index with WKB function EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab WHERE c2=ST_LineStringFromWKB(ST_AsWKB(ST_LineFromText('LINESTRING(10 10,20 20,30 30)'))); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab ref idx1 idx1 8 const 1 # +1 SIMPLE tab ref idx1 idx1 8 const # Using where #check index with WKT function EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab WHERE c3=ST_PolyFromText('POLYGON((0 0,5 5,10 10,15 15,0 0),(10 10,20 20,30 30,40 40,10 10))'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab ref idx3 idx3 8 const 1 # +1 SIMPLE tab ref idx3 idx3 8 const # Using where #check index with WKB function EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab WHERE c3=ST_PolyFromWKB(ST_AsWkB(ST_PolyFromText('POLYGON((0 0,5 5,10 10,15 15,0 0),(10 10,20 20,30 30,40 40,10 10))'))); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab ref idx3 idx3 8 const 1 # +1 SIMPLE tab ref idx3 idx3 8 const # Using where #check index with WKT function EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab WHERE c8=ST_GeomCollFromText('GeometryCollection(Point(1 1),LineString(2 2, 3 3))'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab const idx2 idx2 8 const 1 # +1 SIMPLE tab const idx2 idx2 8 const # #check index with WKB function EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab WHERE c8=ST_GeometryFromWKB(ST_AsWKB(ST_GeomCollFromText('GeometryCollection(Point(1 1),LineString(2 2, 3 3))'))); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab const idx2 idx2 8 const 1 # +1 SIMPLE tab const idx2 idx2 8 const # #check index with DELETE operation EXPLAIN DELETE FROM tab WHERE c8=ST_GeometryFromWKB(ST_AsWKB(ST_GeomCollFromText('GeometryCollection(Point(1 1),LineString(2 2, 3 3))'))); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab range idx2 idx2 8 NULL 1 # +1 SIMPLE tab range idx2 idx2 8 NULL # Using where #check the spatial values SELECT ST_AsText(c1) FROM tab; ST_AsText(c1) @@ -703,39 +705,39 @@ CREATE UNIQUE INDEX idx2 on tab3(c8(5) ASC) ; EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab3 WHERE c2=ST_LineFromText('LINESTRING(10 10,20 20,30 30)'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab3 ref idx1 idx1 8 const 1 # +1 SIMPLE tab3 ref idx1 idx1 8 const # Using where #check index with WKB function EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab3 WHERE c2=ST_LineStringFromWKB(ST_AsWKB(ST_LineFromText('LINESTRING(10 10,20 20,30 30)'))); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab3 ref idx1 idx1 8 const 1 # +1 SIMPLE tab3 ref idx1 idx1 8 const # Using where #check index with WKT function EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab3 WHERE c3=ST_PolyFromText('POLYGON((0 0,5 5,10 10,15 15,0 0),(10 10,20 20,30 30,40 40,10 10))'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab3 ref idx3 idx3 8 const 1 # +1 SIMPLE tab3 ref idx3 idx3 8 const # Using where #check index with WKB function EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab3 WHERE c3=ST_PolyFromWKB(ST_AsWkB(ST_PolyFromText('POLYGON((0 0,5 5,10 10,15 15,0 0),(10 10,20 20,30 30,40 40,10 10))'))); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab3 ref idx3 idx3 8 const 1 # +1 SIMPLE tab3 ref idx3 idx3 8 const # Using where #check index with WKT function EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab3 WHERE c8=ST_GeomCollFromText('GeometryCollection(Point(1 1),LineString(2 2, 3 3))'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab3 const idx2 idx2 8 const 1 # +1 SIMPLE tab3 const idx2 idx2 8 const # #check index with WKB function EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab3 WHERE c8=ST_GeometryFromWKB(ST_AsWKB(ST_GeomCollFromText('GeometryCollection(Point(1 1),LineString(2 2, 3 3))'))); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab3 const idx2 idx2 8 const 1 # +1 SIMPLE tab3 const idx2 idx2 8 const # #check index with DELETE operation EXPLAIN DELETE FROM tab3 WHERE c8=ST_GeometryFromWKB(ST_AsWKB(ST_GeomCollFromText('GeometryCollection(Point(1 1),LineString(2 2, 3 3))'))); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab3 range idx2 idx2 8 NULL 1 # +1 SIMPLE tab3 range idx2 idx2 8 NULL # Using where #check the spatial values SELECT ST_AsText(c1) FROM tab3; ST_AsText(c1) @@ -783,12 +785,12 @@ tab3 CREATE TABLE `tab3` ( EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab3 WHERE c2=ST_LineStringFromWKB(ST_AsWKB(ST_LineFromText('LINESTRING(10 10,20 20,30 30)'))); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab3 ref idx1 idx1 8 const 1 # +1 SIMPLE tab3 ref idx1 idx1 8 const # Using where #check index with WKT function EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab3 WHERE c3=ST_PolyFromText('POLYGON((0 0,5 5,10 10,15 15,0 0),(10 10,20 20,30 30,40 40,10 10))'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab3 ref idx3 idx3 8 const 1 # +1 SIMPLE tab3 ref idx3 idx3 8 const # Using where #check the Geometry property functions SELECT fid, ST_Dimension(g) FROM gis_geometry; fid ST_Dimension(g) @@ -888,7 +890,7 @@ fid ST_AsText(ST_Envelope(g)) 122 POLYGON((3 6,44 6,44 9,3 9,3 6)) explain extended select ST_Dimension(g), ST_GeometryType(g), ST_IsEmpty(g), ST_AsText(ST_Envelope(g)) from gis_geometry; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE gis_geometry ALL NULL NULL NULL NULL 22 # +1 SIMPLE gis_geometry ALL NULL NULL NULL NULL # 100.00 Warnings: Note 1003 select st_dimension(`test`.`gis_geometry`.`g`) AS `ST_Dimension(g)`,st_geometrytype(`test`.`gis_geometry`.`g`) AS `ST_GeometryType(g)`,st_isempty(`test`.`gis_geometry`.`g`) AS `ST_IsEmpty(g)`,st_astext(st_envelope(`test`.`gis_geometry`.`g`)) AS `ST_AsText(ST_Envelope(g))` from `test`.`gis_geometry` #check Geometry point functions @@ -906,7 +908,7 @@ fid ST_Y(g) 104 20 explain extended select ST_X(g),ST_Y(g) FROM gis_point; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE gis_point ALL NULL NULL NULL NULL 4 # +1 SIMPLE gis_point ALL NULL NULL NULL NULL # 100.00 Warnings: Note 1003 select st_x(`test`.`gis_point`.`g`) AS `ST_X(g)`,st_y(`test`.`gis_point`.`g`) AS `ST_Y(g)` from `test`.`gis_point` SELECT fid, ST_AsText(ST_StartPoint(g)) FROM gis_line; @@ -942,7 +944,7 @@ fid ST_IsClosed(g) explain extended select ST_AsText(ST_StartPoint(g)),ST_AsText(ST_EndPoint(g)), ST_Length(g),ST_NumPoints(g),ST_AsText(ST_PointN(g, 2)),ST_IsClosed(g) FROM gis_line; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE gis_line ALL NULL NULL NULL NULL 3 # +1 SIMPLE gis_line ALL NULL NULL NULL NULL # 100.00 Warnings: Note 1003 select st_astext(st_startpoint(`test`.`gis_line`.`g`)) AS `ST_AsText(ST_StartPoint(g))`,st_astext(st_endpoint(`test`.`gis_line`.`g`)) AS `ST_AsText(ST_EndPoint(g))`,st_length(`test`.`gis_line`.`g`) AS `ST_Length(g)`,st_numpoints(`test`.`gis_line`.`g`) AS `ST_NumPoints(g)`,st_astext(st_pointn(`test`.`gis_line`.`g`,2)) AS `ST_AsText(ST_PointN(g, 2))`,st_isclosed(`test`.`gis_line`.`g`) AS `ST_IsClosed(g)` from `test`.`gis_line` SELECT fid, ST_AsText(ST_Centroid(g)) FROM gis_polygon; @@ -973,7 +975,7 @@ fid ST_AsText(ST_InteriorRingN(g, 1)) explain extended select ST_AsText(ST_Centroid(g)),ST_Area(g),ST_AsText(ST_ExteriorRing(g)), ST_NumInteriorRings(g),ST_AsText(ST_InteriorRingN(g, 1)) FROM gis_polygon; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE gis_polygon ALL NULL NULL NULL NULL 3 # +1 SIMPLE gis_polygon ALL NULL NULL NULL NULL # 100.00 Warnings: Note 1003 select st_astext(st_centroid(`test`.`gis_polygon`.`g`)) AS `ST_AsText(ST_Centroid(g))`,st_area(`test`.`gis_polygon`.`g`) AS `ST_Area(g)`,st_astext(st_exteriorring(`test`.`gis_polygon`.`g`)) AS `ST_AsText(ST_ExteriorRing(g))`,st_numinteriorrings(`test`.`gis_polygon`.`g`) AS `ST_NumInteriorRings(g)`,st_astext(st_interiorringn(`test`.`gis_polygon`.`g`,1)) AS `ST_AsText(ST_InteriorRingN(g, 1))` from `test`.`gis_polygon` SELECT fid, ST_IsClosed(g) FROM gis_multi_line; @@ -1013,7 +1015,7 @@ fid ST_NumGeometries(g) 122 2 explain extended SELECT fid, ST_NumGeometries(g) from gis_multi_point; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE gis_multi_point ALL NULL NULL NULL NULL 3 # +1 SIMPLE gis_multi_point ALL NULL NULL NULL NULL # 100.00 Warnings: Note 1003 select `test`.`gis_multi_point`.`fid` AS `fid`,st_numgeometries(`test`.`gis_multi_point`.`g`) AS `ST_NumGeometries(g)` from `test`.`gis_multi_point` SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_multi_point; @@ -1043,7 +1045,7 @@ fid ST_AsText(ST_GeometryN(g, 1)) 122 POINT(44 6) explain extended SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_multi_point; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE gis_multi_point ALL NULL NULL NULL NULL 3 # +1 SIMPLE gis_multi_point ALL NULL NULL NULL NULL # 100.00 Warnings: Note 1003 select `test`.`gis_multi_point`.`fid` AS `fid`,st_astext(st_geometryn(`test`.`gis_multi_point`.`g`,2)) AS `ST_AsText(ST_GeometryN(g, 2))` from `test`.`gis_multi_point` SELECT g1.fid as first, g2.fid as second, @@ -1067,8 +1069,8 @@ MBREquals(g1.g, g2.g) as e, MBRDisjoint(g1.g, g2.g) as d, ST_Touches(g1.g, g2.g) MBRIntersects(g1.g, g2.g) as i, ST_Crosses(g1.g, g2.g) as r FROM gis_geometrycollection g1, gis_geometrycollection g2 ORDER BY first, second; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE g1 ALL NULL NULL NULL NULL 3 # Using temporary; Using filesort -1 SIMPLE g2 ALL NULL NULL NULL NULL 3 # Using join buffer (flat, BNL join) +1 SIMPLE g1 ALL NULL NULL NULL NULL # 100.00 Using temporary; Using filesort +1 SIMPLE g2 ALL NULL NULL NULL NULL # 100.00 Using join buffer (flat, BNL join) Warnings: Note 1003 select `test`.`g1`.`fid` AS `first`,`test`.`g2`.`fid` AS `second`,mbrwithin(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `w`,mbrcontains(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `c`,mbroverlaps(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `o`,mbrequals(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `e`,mbrdisjoint(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `d`,st_touches(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `t`,mbrintersects(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `i`,st_crosses(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `r` from `test`.`gis_geometrycollection` `g1` join `test`.`gis_geometrycollection` `g2` order by `test`.`g1`.`fid`,`test`.`g2`.`fid` # check support of Foreign Key constraint @@ -1113,3 +1115,4 @@ DROP TABLE tab,tab2,tab3,parent; DROP PROCEDURE geominout; DROP PROCEDURE geom_insert; DROP PROCEDURE geom_cursor; +SET GLOBAL innodb_stats_persistent=@save_innodb_stats_persistent; diff --git a/mysql-test/suite/innodb_gis/r/gis.result b/mysql-test/suite/innodb_gis/r/gis.result index e673d92f5c6..f41fcab5bbb 100644 --- a/mysql-test/suite/innodb_gis/r/gis.result +++ b/mysql-test/suite/innodb_gis/r/gis.result @@ -1,5 +1,6 @@ SET default_storage_engine=InnoDB; -DROP TABLE IF EXISTS t1, gis_point, gis_line, gis_polygon, gis_multi_point, gis_multi_line, gis_multi_polygon, gis_geometrycollection, gis_geometry; +SET @save_innodb_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; CREATE TABLE gis_point (fid INTEGER NOT NULL PRIMARY KEY, g POINT); CREATE TABLE gis_line (fid INTEGER NOT NULL PRIMARY KEY, g LINESTRING); CREATE TABLE gis_polygon (fid INTEGER NOT NULL PRIMARY KEY, g POLYGON); @@ -227,7 +228,7 @@ fid ST_AsText(ST_Envelope(g)) 121 POLYGON((3 6,44 6,44 9,3 9,3 6)) explain extended select ST_Dimension(g), ST_GeometryType(g), ST_IsEmpty(g), ST_AsText(ST_Envelope(g)) from gis_geometry; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE gis_geometry ALL NULL NULL NULL NULL 21 # +1 SIMPLE gis_geometry ALL NULL NULL NULL NULL # 100.00 Warnings: Note 1003 select st_dimension(`test`.`gis_geometry`.`g`) AS `ST_Dimension(g)`,st_geometrytype(`test`.`gis_geometry`.`g`) AS `ST_GeometryType(g)`,st_isempty(`test`.`gis_geometry`.`g`) AS `ST_IsEmpty(g)`,st_astext(st_envelope(`test`.`gis_geometry`.`g`)) AS `ST_AsText(ST_Envelope(g))` from `test`.`gis_geometry` SELECT fid, ST_X(g) FROM gis_point; @@ -244,7 +245,7 @@ fid ST_Y(g) 104 20 explain extended select ST_X(g),ST_Y(g) FROM gis_point; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE gis_point ALL NULL NULL NULL NULL 4 # +1 SIMPLE gis_point ALL NULL NULL NULL NULL # 100.00 Warnings: Note 1003 select st_x(`test`.`gis_point`.`g`) AS `ST_X(g)`,st_y(`test`.`gis_point`.`g`) AS `ST_Y(g)` from `test`.`gis_point` SELECT fid, ST_AsText(ST_StartPoint(g)) FROM gis_line; @@ -279,7 +280,7 @@ fid ST_IsClosed(g) 107 0 explain extended select ST_AsText(ST_StartPoint(g)),ST_AsText(ST_EndPoint(g)),ST_Length(g),ST_NumPoints(g),ST_AsText(ST_PointN(g, 2)),ST_IsClosed(g) FROM gis_line; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE gis_line ALL NULL NULL NULL NULL 3 # +1 SIMPLE gis_line ALL NULL NULL NULL NULL # 100.00 Warnings: Note 1003 select st_astext(st_startpoint(`test`.`gis_line`.`g`)) AS `ST_AsText(ST_StartPoint(g))`,st_astext(st_endpoint(`test`.`gis_line`.`g`)) AS `ST_AsText(ST_EndPoint(g))`,st_length(`test`.`gis_line`.`g`) AS `ST_Length(g)`,st_numpoints(`test`.`gis_line`.`g`) AS `ST_NumPoints(g)`,st_astext(st_pointn(`test`.`gis_line`.`g`,2)) AS `ST_AsText(ST_PointN(g, 2))`,st_isclosed(`test`.`gis_line`.`g`) AS `ST_IsClosed(g)` from `test`.`gis_line` SELECT fid, ST_AsText(ST_Centroid(g)) FROM gis_polygon; @@ -309,7 +310,7 @@ fid ST_AsText(ST_InteriorRingN(g, 1)) 110 NULL explain extended select ST_AsText(ST_Centroid(g)),ST_Area(g),ST_AsText(ST_ExteriorRing(g)),ST_NumInteriorRings(g),ST_AsText(ST_InteriorRingN(g, 1)) FROM gis_polygon; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE gis_polygon ALL NULL NULL NULL NULL 3 # +1 SIMPLE gis_polygon ALL NULL NULL NULL NULL # 100.00 Warnings: Note 1003 select st_astext(st_centroid(`test`.`gis_polygon`.`g`)) AS `ST_AsText(ST_Centroid(g))`,st_area(`test`.`gis_polygon`.`g`) AS `ST_Area(g)`,st_astext(st_exteriorring(`test`.`gis_polygon`.`g`)) AS `ST_AsText(ST_ExteriorRing(g))`,st_numinteriorrings(`test`.`gis_polygon`.`g`) AS `ST_NumInteriorRings(g)`,st_astext(st_interiorringn(`test`.`gis_polygon`.`g`,1)) AS `ST_AsText(ST_InteriorRingN(g, 1))` from `test`.`gis_polygon` SELECT fid, ST_IsClosed(g) FROM gis_multi_line; @@ -348,7 +349,7 @@ fid ST_NumGeometries(g) 121 2 explain extended SELECT fid, ST_NumGeometries(g) from gis_multi_point; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE gis_multi_point ALL NULL NULL NULL NULL 3 # +1 SIMPLE gis_multi_point ALL NULL NULL NULL NULL # 100.00 Warnings: Note 1003 select `test`.`gis_multi_point`.`fid` AS `fid`,st_numgeometries(`test`.`gis_multi_point`.`g`) AS `ST_NumGeometries(g)` from `test`.`gis_multi_point` SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_multi_point; @@ -376,7 +377,7 @@ fid ST_AsText(ST_GeometryN(g, 1)) 121 POINT(44 6) explain extended SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_multi_point; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE gis_multi_point ALL NULL NULL NULL NULL 3 # +1 SIMPLE gis_multi_point ALL NULL NULL NULL NULL # 100.00 Warnings: Note 1003 select `test`.`gis_multi_point`.`fid` AS `fid`,st_astext(st_geometryn(`test`.`gis_multi_point`.`g`,2)) AS `ST_AsText(ST_GeometryN(g, 2))` from `test`.`gis_multi_point` SELECT g1.fid as first, g2.fid as second, @@ -395,8 +396,8 @@ MBREquals(g1.g, g2.g) as e, MBRDisjoint(g1.g, g2.g) as d, ST_Touches(g1.g, g2.g) MBRIntersects(g1.g, g2.g) as i, ST_Crosses(g1.g, g2.g) as r FROM gis_geometrycollection g1, gis_geometrycollection g2 ORDER BY first, second; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE g1 ALL NULL NULL NULL NULL 2 # Using temporary; Using filesort -1 SIMPLE g2 ALL NULL NULL NULL NULL 2 # Using join buffer (flat, BNL join) +1 SIMPLE g1 ALL NULL NULL NULL NULL # 100.00 Using temporary; Using filesort +1 SIMPLE g2 ALL NULL NULL NULL NULL # 100.00 Using join buffer (flat, BNL join) Warnings: Note 1003 select `test`.`g1`.`fid` AS `first`,`test`.`g2`.`fid` AS `second`,mbrwithin(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `w`,mbrcontains(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `c`,mbroverlaps(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `o`,mbrequals(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `e`,mbrdisjoint(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `d`,st_touches(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `t`,mbrintersects(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `i`,st_crosses(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `r` from `test`.`gis_geometrycollection` `g1` join `test`.`gis_geometrycollection` `g2` order by `test`.`g1`.`fid`,`test`.`g2`.`fid` DROP TABLE gis_point, gis_line, gis_polygon, gis_multi_point, gis_multi_line, gis_multi_polygon, gis_geometrycollection, gis_geometry; @@ -1497,3 +1498,4 @@ COUNT(*) 1 DROP TABLE t1; DROP DATABASE gis_ogs; +SET GLOBAL innodb_stats_persistent=@save_innodb_stats_persistent; diff --git a/mysql-test/suite/innodb_gis/r/point_basic.result b/mysql-test/suite/innodb_gis/r/point_basic.result index 4842c72d99c..14f07d4facf 100644 --- a/mysql-test/suite/innodb_gis/r/point_basic.result +++ b/mysql-test/suite/innodb_gis/r/point_basic.result @@ -25,7 +25,7 @@ INSERT INTO gis_point VALUES (ST_PointFromText('POINT(100.32374832 101.23741821)'), ST_PointFromText('POINT(100.32374832 101.98527111)')); EXPLAIN SELECT ST_AsText(p1), ST_AsText(p2) FROM gis_point GROUP BY p1, p2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE gis_point ALL NULL NULL NULL NULL 4 # +1 SIMPLE gis_point ALL NULL NULL NULL NULL # Using temporary; Using filesort SELECT ST_AsText(p1), ST_AsText(p2) FROM gis_point GROUP BY p1, p2; ST_AsText(p1) ST_AsText(p2) POINT(100.32374832 101.23741821) POINT(100.32374832 101.98527111) @@ -277,7 +277,7 @@ DROP TABLE t1; # # Test when the POINT is on B-TREE # -CREATE TABLE gis_point(fid INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, p POINT, KEY(p)) ENGINE=InnoDB; +CREATE TABLE gis_point(fid INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, p POINT, KEY(p)) ENGINE=InnoDB STATS_PERSISTENT=0; INSERT INTO gis_point VALUES (101, ST_PointFromText('POINT(10 10)')), (102, ST_PointFromText('POINT(20 10)')), @@ -302,7 +302,7 @@ INSERT INTO gis_point VALUES 'The ORDER BY will use filesort' EXPLAIN SELECT ST_AsText(p) FROM gis_point ORDER BY p; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE gis_point ALL NULL NULL NULL NULL 10 # +1 SIMPLE gis_point ALL NULL NULL NULL NULL # Using filesort SELECT ST_AsText(p) FROM gis_point ORDER BY p; ST_AsText(p) POINT(10 10) @@ -1326,7 +1326,7 @@ test.gis_point check status OK The ORDER BY for spatial index will use filesort EXPLAIN SELECT ST_AsText(p1), ST_AsText(p2) FROM gis_point ORDER BY p1, p2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE gis_point ALL NULL NULL NULL NULL 13 # +1 SIMPLE gis_point ALL NULL NULL NULL NULL # Using filesort SELECT ST_AsText(p1), ST_AsText(p2) FROM gis_point ORDER BY p1, p2; ST_AsText(p1) ST_AsText(p2) POINT(2 4) POINT(-2 -6) @@ -1488,7 +1488,7 @@ a ST_AsText(p) ST_AsText(l) ST_AsText(g) 2 POINT(20 20) LINESTRING(2 3,7 8,9 10,15 16) POLYGON((10 30,30 40,40 50,40 30,30 20,10 30)) EXPLAIN UPDATE t1 SET p = ST_GeomFromText('POINT(30 30)') WHERE p = ST_GeomFromText('POINT(20 20)'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 27 NULL 1 # +1 SIMPLE t1 range PRIMARY PRIMARY 27 NULL # Using where UPDATE t1 SET p = ST_GeomFromText('POINT(30 30)') WHERE p = ST_GeomFromText('POINT(20 20)'); SELECT a, ST_AsText(p), ST_AsText(l), ST_AsText(g) FROM t1; a ST_AsText(p) ST_AsText(l) ST_AsText(g) @@ -1526,7 +1526,7 @@ ALTER TABLE t1 DROP PRIMARY KEY; ALTER TABLE t1 ADD PRIMARY KEY(p); EXPLAIN SELECT a, ST_AsText(p) FROM t1 WHERE a = 2 AND p = ST_GeomFromText('POINT(30 30)'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 const PRIMARY,idx2 PRIMARY 27 const 1 # +1 SIMPLE t1 const PRIMARY,idx2 PRIMARY 27 const # SELECT a, ST_AsText(p) FROM t1 WHERE a = 2 AND p = ST_GeomFromText('POINT(30 30)'); a ST_AsText(p) 2 POINT(30 30) diff --git a/mysql-test/suite/innodb_gis/r/point_big.result b/mysql-test/suite/innodb_gis/r/point_big.result index c471ab6adb2..7248c55bafe 100644 --- a/mysql-test/suite/innodb_gis/r/point_big.result +++ b/mysql-test/suite/innodb_gis/r/point_big.result @@ -260,7 +260,7 @@ INSERT INTO gis_point VALUES 'The ORDER BY for spatial index will use filesort' EXPLAIN SELECT ST_AsText(p1), ST_AsText(p2) FROM gis_point ORDER BY p1, p2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE gis_point ALL NULL NULL NULL NULL 13 # +1 SIMPLE gis_point ALL NULL NULL NULL NULL # Using filesort SELECT ST_AsText(p1), ST_AsText(p2) FROM gis_point ORDER BY p1, p2; ST_AsText(p1) ST_AsText(p2) POINT(2 4) POINT(-2 -6) diff --git a/mysql-test/suite/innodb_gis/r/rt_precise.result b/mysql-test/suite/innodb_gis/r/rt_precise.result index c83b88b568c..4929dfc99a8 100644 --- a/mysql-test/suite/innodb_gis/r/rt_precise.result +++ b/mysql-test/suite/innodb_gis/r/rt_precise.result @@ -22,7 +22,7 @@ test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK EXPLAIN SELECT fid, ST_AsText(g) FROM t1 WHERE ST_Within(g, ST_GeomFromText('Polygon((140 140,160 140,160 160,140 140))')); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL gis_key NULL NULL NULL 150 # +1 SIMPLE t1 ALL gis_key NULL NULL NULL # Using where SELECT fid, ST_AsText(g) FROM t1 WHERE ST_Within(g, ST_GeomFromText('Polygon((140 140,160 140,160 160,140 160,140 140))')) ORDER BY fid; fid ST_AsText(g) 1 LINESTRING(150 150,150 150) diff --git a/mysql-test/suite/innodb_gis/r/types.result b/mysql-test/suite/innodb_gis/r/types.result index 9eb40dc4231..a337ee10e3d 100644 --- a/mysql-test/suite/innodb_gis/r/types.result +++ b/mysql-test/suite/innodb_gis/r/types.result @@ -33,7 +33,7 @@ GEOMETRYCOLLECTION(POINT(1 1),LINESTRING(2 2,3 3)) CREATE INDEX i_p ON t_wl6455 (g(10)); EXPLAIN SELECT ST_AsText(g) FROM t_wl6455 WHERE g = POINT(2,2); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t_wl6455 ref i_p i_p 12 const 2 # +1 SIMPLE t_wl6455 ref i_p i_p 12 const # Using where SELECT ST_AsText(g) FROM t_wl6455 WHERE g = POINT(2,2); ST_AsText(g) POINT(2 2) diff --git a/mysql-test/suite/innodb_gis/t/1.test b/mysql-test/suite/innodb_gis/t/1.test index f08fdaddbda..950db360794 100644 --- a/mysql-test/suite/innodb_gis/t/1.test +++ b/mysql-test/suite/innodb_gis/t/1.test @@ -91,12 +91,12 @@ SELECT fid, ST_Dimension(g) FROM gis_geometry; SELECT fid, ST_GeometryType(g) FROM gis_geometry; SELECT fid, ST_IsEmpty(g) FROM gis_geometry; SELECT fid, ST_AsText(ST_Envelope(g)) FROM gis_geometry; ---replace_column 10 # +--replace_column 9 # 10 # explain extended select ST_Dimension(g), ST_GeometryType(g), ST_IsEmpty(g), ST_AsText(ST_Envelope(g)) from gis_geometry; SELECT fid, ST_X(g) FROM gis_point; SELECT fid, ST_Y(g) FROM gis_point; ---replace_column 10 # +--replace_column 9 # 10 # explain extended select ST_X(g),ST_Y(g) FROM gis_point; SELECT fid, ST_AsText(ST_StartPoint(g)) FROM gis_line; @@ -105,7 +105,7 @@ SELECT fid, ST_Length(g) FROM gis_line; SELECT fid, ST_NumPoints(g) FROM gis_line; SELECT fid, ST_AsText(ST_PointN(g, 2)) FROM gis_line; SELECT fid, ST_IsClosed(g) FROM gis_line; ---replace_column 10 # +--replace_column 9 # 10 # explain extended select ST_AsText(ST_StartPoint(g)),ST_AsText(ST_EndPoint(g)),ST_Length(g),ST_NumPoints(g),ST_AsText(ST_PointN(g, 2)),ST_IsClosed(g) FROM gis_line; SELECT fid, ST_AsText(ST_Centroid(g)) FROM gis_polygon; @@ -113,7 +113,7 @@ SELECT fid, ST_Area(g) FROM gis_polygon; SELECT fid, ST_AsText(ST_ExteriorRing(g)) FROM gis_polygon; SELECT fid, ST_NumInteriorRings(g) FROM gis_polygon; SELECT fid, ST_AsText(ST_InteriorRingN(g, 1)) FROM gis_polygon; ---replace_column 10 # +--replace_column 9 # 10 # explain extended select ST_AsText(ST_Centroid(g)),ST_Area(g),ST_AsText(ST_ExteriorRing(g)),ST_NumInteriorRings(g),ST_AsText(ST_InteriorRingN(g, 1)) FROM gis_polygon; SELECT fid, ST_IsClosed(g) FROM gis_multi_line; @@ -125,7 +125,7 @@ SELECT fid, ST_NumGeometries(g) from gis_multi_point; SELECT fid, ST_NumGeometries(g) from gis_multi_line; SELECT fid, ST_NumGeometries(g) from gis_multi_polygon; SELECT fid, ST_NumGeometries(g) from gis_geometrycollection; ---replace_column 10 # +--replace_column 9 # 10 # explain extended SELECT fid, ST_NumGeometries(g) from gis_multi_point; SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_multi_point; @@ -133,7 +133,7 @@ SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_multi_line; SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_multi_polygon; SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_geometrycollection; SELECT fid, ST_AsText(ST_GeometryN(g, 1)) from gis_geometrycollection; ---replace_column 10 # +--replace_column 9 # 10 # explain extended SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_multi_point; SELECT g1.fid as first, g2.fid as second, @@ -141,7 +141,7 @@ MBRWithin(g1.g, g2.g) as w, MBRContains(g1.g, g2.g) as c, MBROverlaps(g1.g, g2.g MBREquals(g1.g, g2.g) as e, MBRDisjoint(g1.g, g2.g) as d, ST_Touches(g1.g, g2.g) as t, MBRIntersects(g1.g, g2.g) as i, ST_Crosses(g1.g, g2.g) as r FROM gis_geometrycollection g1, gis_geometrycollection g2 ORDER BY first, second; ---replace_column 10 # +--replace_column 9 # 10 # explain extended SELECT g1.fid as first, g2.fid as second, MBRWithin(g1.g, g2.g) as w, MBRContains(g1.g, g2.g) as c, MBROverlaps(g1.g, g2.g) as o, MBREquals(g1.g, g2.g) as e, MBRDisjoint(g1.g, g2.g) as d, ST_Touches(g1.g, g2.g) as t, diff --git a/mysql-test/suite/innodb_gis/t/geometry.test b/mysql-test/suite/innodb_gis/t/geometry.test index 3efc664fbd2..4e8f0f729b5 100644 --- a/mysql-test/suite/innodb_gis/t/geometry.test +++ b/mysql-test/suite/innodb_gis/t/geometry.test @@ -14,6 +14,8 @@ SET default_storage_engine=InnoDB; SET innodb_strict_mode=OFF; +SET @save_innodb_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; # # Spatial objects @@ -132,55 +134,55 @@ CREATE INDEX idx3 on tab(c3(5) ASC) USING BTREE; CREATE UNIQUE INDEX idx2 on tab(c8(5) ASC) ; --echo #check equality predicate on the index columns ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab WHERE c2=ST_LineFromText('LINESTRING(10 10,20 20,30 30)'); --echo #check index with WKB function ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab WHERE c2=ST_LineStringFromWKB(ST_AsWKB(ST_LineFromText('LINESTRING(10 10,20 20,30 30)'))); --echo #check index with WKT function ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab WHERE c3=ST_PolyFromText('POLYGON((0 0,5 5,10 10,15 15,0 0),(10 10,20 20,30 30,40 40,10 10))'); --echo #check index with WKB function ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab WHERE c3=ST_PolyFromWKB(ST_AsWkB(ST_PolyFromText('POLYGON((0 0,5 5,10 10,15 15,0 0),(10 10,20 20,30 30,40 40,10 10))'))); --echo #check index with WKT function ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab WHERE c8=ST_GeomCollFromText('GeometryCollection(Point(1 1),LineString(2 2, 3 3))'); --echo #check index with WKB function ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab WHERE c8=ST_GeometryFromWKB(ST_AsWKB(ST_GeomCollFromText('GeometryCollection(Point(1 1),LineString(2 2, 3 3))'))); #--echo #check range predicate on the index columns -#--replace_column 10 # +#--replace_column 9 # #--error ER_WRONG_ARGUMENTS #EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab #WHERE c2>=ST_LineFromText('LINESTRING(10 10,20 20,30 30)'); # -#--replace_column 10 # +#--replace_column 9 # #--error ER_WRONG_ARGUMENTS #EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab #WHERE c3>=ST_PolyFromText('POLYGON((0 0,5 5,10 10,15 15,0 0),(10 10,20 20,30 30,40 40,10 10))'); # -#--replace_column 10 # +#--replace_column 9 # #--error ER_WRONG_ARGUMENTS #EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab #WHERE c8>=ST_GeomCollFromText('GeometryCollection(Point(1 1),LineString(2 2, 3 3))'); --echo #check index with DELETE operation ---replace_column 10 # +--replace_column 9 # EXPLAIN DELETE FROM tab WHERE c8=ST_GeometryFromWKB(ST_AsWKB(ST_GeomCollFromText('GeometryCollection(Point(1 1),LineString(2 2, 3 3))'))); @@ -487,55 +489,55 @@ CREATE UNIQUE INDEX idx2 on tab3(c8(5) ASC) ; --enable_warnings --echo #check equality predicate on the index columns ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab3 WHERE c2=ST_LineFromText('LINESTRING(10 10,20 20,30 30)'); --echo #check index with WKB function ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab3 WHERE c2=ST_LineStringFromWKB(ST_AsWKB(ST_LineFromText('LINESTRING(10 10,20 20,30 30)'))); --echo #check index with WKT function ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab3 WHERE c3=ST_PolyFromText('POLYGON((0 0,5 5,10 10,15 15,0 0),(10 10,20 20,30 30,40 40,10 10))'); --echo #check index with WKB function ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab3 WHERE c3=ST_PolyFromWKB(ST_AsWkB(ST_PolyFromText('POLYGON((0 0,5 5,10 10,15 15,0 0),(10 10,20 20,30 30,40 40,10 10))'))); --echo #check index with WKT function ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab3 WHERE c8=ST_GeomCollFromText('GeometryCollection(Point(1 1),LineString(2 2, 3 3))'); --echo #check index with WKB function ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab3 WHERE c8=ST_GeometryFromWKB(ST_AsWKB(ST_GeomCollFromText('GeometryCollection(Point(1 1),LineString(2 2, 3 3))'))); # --echo #check range predicate on the index columns -# --replace_column 10 # +# --replace_column 9 # # --error ER_WRONG_ARGUMENTS # EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab3 # WHERE c2>=ST_LineFromText('LINESTRING(10 10,20 20,30 30)'); # -# --replace_column 10 # +# --replace_column 9 # # --error ER_WRONG_ARGUMENTS # EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab3 # WHERE c3>=ST_PolyFromText('POLYGON((0 0,5 5,10 10,15 15,0 0),(10 10,20 20,30 30,40 40,10 10))'); -# --replace_column 10 # +# --replace_column 9 # # --error ER_WRONG_ARGUMENTS # EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab3 # WHERE c8>=ST_GeomCollFromText('GeometryCollection(Point(1 1),LineString(2 2, 3 3))'); --echo #check index with DELETE operation ---replace_column 10 # +--replace_column 9 # EXPLAIN DELETE FROM tab3 WHERE c8=ST_GeometryFromWKB(ST_AsWKB(ST_GeomCollFromText('GeometryCollection(Point(1 1),LineString(2 2, 3 3))'))); @@ -559,12 +561,12 @@ ALTER TABLE tab3 ROW_FORMAT=Dynamic; SHOW CREATE TABLE tab3; --echo #check index with WKB function ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab3 WHERE c2=ST_LineStringFromWKB(ST_AsWKB(ST_LineFromText('LINESTRING(10 10,20 20,30 30)'))); --echo #check index with WKT function ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab3 WHERE c3=ST_PolyFromText('POLYGON((0 0,5 5,10 10,15 15,0 0),(10 10,20 20,30 30,40 40,10 10))'); @@ -575,13 +577,13 @@ SELECT fid, ST_Dimension(g) FROM gis_geometry; SELECT fid, ST_GeometryType(g) FROM gis_geometry; SELECT fid, ST_IsEmpty(g) FROM gis_geometry; SELECT fid, ST_AsText(ST_Envelope(g)) FROM gis_geometry; ---replace_column 10 # +--replace_column 9 # explain extended select ST_Dimension(g), ST_GeometryType(g), ST_IsEmpty(g), ST_AsText(ST_Envelope(g)) from gis_geometry; --echo #check Geometry point functions SELECT fid, ST_X(g) FROM gis_point; SELECT fid, ST_Y(g) FROM gis_point; ---replace_column 10 # +--replace_column 9 # explain extended select ST_X(g),ST_Y(g) FROM gis_point; SELECT fid, ST_AsText(ST_StartPoint(g)) FROM gis_line; @@ -590,7 +592,7 @@ SELECT fid, ST_Length(g) FROM gis_line; SELECT fid, ST_NumPoints(g) FROM gis_line; SELECT fid, ST_AsText(ST_PointN(g, 2)) FROM gis_line; SELECT fid, ST_IsClosed(g) FROM gis_line; ---replace_column 10 # +--replace_column 9 # explain extended select ST_AsText(ST_StartPoint(g)),ST_AsText(ST_EndPoint(g)), ST_Length(g),ST_NumPoints(g),ST_AsText(ST_PointN(g, 2)),ST_IsClosed(g) FROM gis_line; @@ -599,7 +601,7 @@ SELECT fid, ST_Area(g) FROM gis_polygon; SELECT fid, ST_AsText(ST_ExteriorRing(g)) FROM gis_polygon; SELECT fid, ST_NumInteriorRings(g) FROM gis_polygon; SELECT fid, ST_AsText(ST_InteriorRingN(g, 1)) FROM gis_polygon; ---replace_column 10 # +--replace_column 9 # explain extended select ST_AsText(ST_Centroid(g)),ST_Area(g),ST_AsText(ST_ExteriorRing(g)), ST_NumInteriorRings(g),ST_AsText(ST_InteriorRingN(g, 1)) FROM gis_polygon; @@ -612,7 +614,7 @@ SELECT fid, ST_NumGeometries(g) from gis_multi_point; SELECT fid, ST_NumGeometries(g) from gis_multi_line; SELECT fid, ST_NumGeometries(g) from gis_multi_polygon; SELECT fid, ST_NumGeometries(g) from gis_geometrycollection; ---replace_column 10 # +--replace_column 9 # explain extended SELECT fid, ST_NumGeometries(g) from gis_multi_point; SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_multi_point; @@ -620,7 +622,7 @@ SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_multi_line; SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_multi_polygon; SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_geometrycollection; SELECT fid, ST_AsText(ST_GeometryN(g, 1)) from gis_geometrycollection; ---replace_column 10 # +--replace_column 9 # explain extended SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_multi_point; SELECT g1.fid as first, g2.fid as second, @@ -628,7 +630,7 @@ MBRWithin(g1.g, g2.g) as w, MBRContains(g1.g, g2.g) as c, MBROverlaps(g1.g, g2.g MBREquals(g1.g, g2.g) as e, MBRDisjoint(g1.g, g2.g) as d, ST_Touches(g1.g, g2.g) as t, MBRIntersects(g1.g, g2.g) as i, ST_Crosses(g1.g, g2.g) as r FROM gis_geometrycollection g1, gis_geometrycollection g2 ORDER BY first, second; ---replace_column 10 # +--replace_column 9 # explain extended SELECT g1.fid as first, g2.fid as second, MBRWithin(g1.g, g2.g) as w, MBRContains(g1.g, g2.g) as c, MBROverlaps(g1.g, g2.g) as o, MBREquals(g1.g, g2.g) as e, MBRDisjoint(g1.g, g2.g) as d, ST_Touches(g1.g, g2.g) as t, @@ -680,3 +682,5 @@ DROP TABLE tab,tab2,tab3,parent; DROP PROCEDURE geominout; DROP PROCEDURE geom_insert; DROP PROCEDURE geom_cursor; + +SET GLOBAL innodb_stats_persistent=@save_innodb_stats_persistent; diff --git a/mysql-test/suite/innodb_gis/t/gis.test b/mysql-test/suite/innodb_gis/t/gis.test index 2963c033d80..966aea7bc77 100644 --- a/mysql-test/suite/innodb_gis/t/gis.test +++ b/mysql-test/suite/innodb_gis/t/gis.test @@ -5,15 +5,13 @@ --source include/have_sequence.inc SET default_storage_engine=InnoDB; +SET @save_innodb_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; # # Spatial objects # ---disable_warnings -DROP TABLE IF EXISTS t1, gis_point, gis_line, gis_polygon, gis_multi_point, gis_multi_line, gis_multi_polygon, gis_geometrycollection, gis_geometry; ---enable_warnings - CREATE TABLE gis_point (fid INTEGER NOT NULL PRIMARY KEY, g POINT); CREATE TABLE gis_line (fid INTEGER NOT NULL PRIMARY KEY, g LINESTRING); CREATE TABLE gis_polygon (fid INTEGER NOT NULL PRIMARY KEY, g POLYGON); @@ -90,12 +88,12 @@ SELECT fid, ST_Dimension(g) FROM gis_geometry; SELECT fid, ST_GeometryType(g) FROM gis_geometry; SELECT fid, ST_IsEmpty(g) FROM gis_geometry; SELECT fid, ST_AsText(ST_Envelope(g)) FROM gis_geometry; ---replace_column 10 # +--replace_column 9 # explain extended select ST_Dimension(g), ST_GeometryType(g), ST_IsEmpty(g), ST_AsText(ST_Envelope(g)) from gis_geometry; SELECT fid, ST_X(g) FROM gis_point; SELECT fid, ST_Y(g) FROM gis_point; ---replace_column 10 # +--replace_column 9 # explain extended select ST_X(g),ST_Y(g) FROM gis_point; SELECT fid, ST_AsText(ST_StartPoint(g)) FROM gis_line; @@ -104,7 +102,7 @@ SELECT fid, ST_Length(g) FROM gis_line; SELECT fid, ST_NumPoints(g) FROM gis_line; SELECT fid, ST_AsText(ST_PointN(g, 2)) FROM gis_line; SELECT fid, ST_IsClosed(g) FROM gis_line; ---replace_column 10 # +--replace_column 9 # explain extended select ST_AsText(ST_StartPoint(g)),ST_AsText(ST_EndPoint(g)),ST_Length(g),ST_NumPoints(g),ST_AsText(ST_PointN(g, 2)),ST_IsClosed(g) FROM gis_line; SELECT fid, ST_AsText(ST_Centroid(g)) FROM gis_polygon; @@ -112,7 +110,7 @@ SELECT fid, ST_Area(g) FROM gis_polygon; SELECT fid, ST_AsText(ST_ExteriorRing(g)) FROM gis_polygon; SELECT fid, ST_NumInteriorRings(g) FROM gis_polygon; SELECT fid, ST_AsText(ST_InteriorRingN(g, 1)) FROM gis_polygon; ---replace_column 10 # +--replace_column 9 # explain extended select ST_AsText(ST_Centroid(g)),ST_Area(g),ST_AsText(ST_ExteriorRing(g)),ST_NumInteriorRings(g),ST_AsText(ST_InteriorRingN(g, 1)) FROM gis_polygon; SELECT fid, ST_IsClosed(g) FROM gis_multi_line; @@ -124,7 +122,7 @@ SELECT fid, ST_NumGeometries(g) from gis_multi_point; SELECT fid, ST_NumGeometries(g) from gis_multi_line; SELECT fid, ST_NumGeometries(g) from gis_multi_polygon; SELECT fid, ST_NumGeometries(g) from gis_geometrycollection; ---replace_column 10 # +--replace_column 9 # explain extended SELECT fid, ST_NumGeometries(g) from gis_multi_point; SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_multi_point; @@ -132,7 +130,7 @@ SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_multi_line; SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_multi_polygon; SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_geometrycollection; SELECT fid, ST_AsText(ST_GeometryN(g, 1)) from gis_geometrycollection; ---replace_column 10 # +--replace_column 9 # explain extended SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_multi_point; SELECT g1.fid as first, g2.fid as second, @@ -140,7 +138,7 @@ MBRWithin(g1.g, g2.g) as w, MBRContains(g1.g, g2.g) as c, MBROverlaps(g1.g, g2.g MBREquals(g1.g, g2.g) as e, MBRDisjoint(g1.g, g2.g) as d, ST_Touches(g1.g, g2.g) as t, MBRIntersects(g1.g, g2.g) as i, ST_Crosses(g1.g, g2.g) as r FROM gis_geometrycollection g1, gis_geometrycollection g2 ORDER BY first, second; ---replace_column 10 # +--replace_column 9 # explain extended SELECT g1.fid as first, g2.fid as second, MBRWithin(g1.g, g2.g) as w, MBRContains(g1.g, g2.g) as c, MBROverlaps(g1.g, g2.g) as o, MBREquals(g1.g, g2.g) as e, MBRDisjoint(g1.g, g2.g) as d, ST_Touches(g1.g, g2.g) as t, @@ -1443,3 +1441,5 @@ SELECT COUNT(*) FROM t1 WHERE MBRIntersects(GeomFromText('Polygon((0 0,0 10,10 1 DROP TABLE t1; DROP DATABASE gis_ogs; + +SET GLOBAL innodb_stats_persistent=@save_innodb_stats_persistent; diff --git a/mysql-test/suite/innodb_gis/t/point_basic.test b/mysql-test/suite/innodb_gis/t/point_basic.test index 3ab1ab5c902..f6bc6d234a7 100644 --- a/mysql-test/suite/innodb_gis/t/point_basic.test +++ b/mysql-test/suite/innodb_gis/t/point_basic.test @@ -31,7 +31,7 @@ INSERT INTO gis_point VALUES (ST_PointFromText('POINT(100.32374832 101.23741821)'), ST_PointFromText('POINT(200.32247328 101.86728201)')), (ST_PointFromText('POINT(100.32374832 101.23741821)'), ST_PointFromText('POINT(100.32374832 101.98527111)')); ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT ST_AsText(p1), ST_AsText(p2) FROM gis_point GROUP BY p1, p2; SELECT ST_AsText(p1), ST_AsText(p2) FROM gis_point GROUP BY p1, p2; @@ -196,7 +196,7 @@ DROP TABLE t1; --echo # --echo # Test when the POINT is on B-TREE --echo # -CREATE TABLE gis_point(fid INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, p POINT, KEY(p)) ENGINE=InnoDB; +CREATE TABLE gis_point(fid INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, p POINT, KEY(p)) ENGINE=InnoDB STATS_PERSISTENT=0; INSERT INTO gis_point VALUES (101, ST_PointFromText('POINT(10 10)')), @@ -216,7 +216,7 @@ INSERT INTO gis_point VALUES (206, ST_PointFromWKB(ST_AsWKB(ST_PointFromText('POINT(103.43718640 105.248206478)')))); -- echo 'The ORDER BY will use filesort' ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT ST_AsText(p) FROM gis_point ORDER BY p; SELECT ST_AsText(p) FROM gis_point ORDER BY p; @@ -640,7 +640,7 @@ ALTER TABLE gis_point ENGINE InnoDB; CHECK TABLE gis_point; -- echo The ORDER BY for spatial index will use filesort ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT ST_AsText(p1), ST_AsText(p2) FROM gis_point ORDER BY p1, p2; SELECT ST_AsText(p1), ST_AsText(p2) FROM gis_point ORDER BY p1, p2; @@ -766,7 +766,7 @@ ST_GeomFromText('POLYGON((10 30, 30 40, 40 50, 40 30, 30 20, 10 30))')); SELECT a, ST_AsText(p), ST_AsText(l), ST_AsText(g) FROM t1; ---replace_column 10 # +--replace_column 9 # EXPLAIN UPDATE t1 SET p = ST_GeomFromText('POINT(30 30)') WHERE p = ST_GeomFromText('POINT(20 20)'); UPDATE t1 SET p = ST_GeomFromText('POINT(30 30)') WHERE p = ST_GeomFromText('POINT(20 20)'); @@ -807,7 +807,7 @@ SELECT a, ST_AsText(p), ST_AsText(l), ST_AsText(g) FROM t1; ALTER TABLE t1 DROP PRIMARY KEY; ALTER TABLE t1 ADD PRIMARY KEY(p); ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT a, ST_AsText(p) FROM t1 WHERE a = 2 AND p = ST_GeomFromText('POINT(30 30)'); SELECT a, ST_AsText(p) FROM t1 WHERE a = 2 AND p = ST_GeomFromText('POINT(30 30)'); diff --git a/mysql-test/suite/innodb_gis/t/point_big.test b/mysql-test/suite/innodb_gis/t/point_big.test index d9a00474d89..d46fc5d9139 100644 --- a/mysql-test/suite/innodb_gis/t/point_big.test +++ b/mysql-test/suite/innodb_gis/t/point_big.test @@ -145,7 +145,7 @@ INSERT INTO gis_point VALUES (ST_PointFromText('POINT(32.1234 64.2468)'), ST_PointFromText('POINT(-1 -1)')); -- echo 'The ORDER BY for spatial index will use filesort' ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT ST_AsText(p1), ST_AsText(p2) FROM gis_point ORDER BY p1, p2; SELECT ST_AsText(p1), ST_AsText(p2) FROM gis_point ORDER BY p1, p2; diff --git a/mysql-test/suite/innodb_gis/t/rt_precise.test b/mysql-test/suite/innodb_gis/t/rt_precise.test index 8049ff02ff1..2f155814eb6 100644 --- a/mysql-test/suite/innodb_gis/t/rt_precise.test +++ b/mysql-test/suite/innodb_gis/t/rt_precise.test @@ -37,7 +37,7 @@ SELECT count(*) FROM t1; ANALYZE TABLE t1; ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT fid, ST_AsText(g) FROM t1 WHERE ST_Within(g, ST_GeomFromText('Polygon((140 140,160 140,160 160,140 140))')); SELECT fid, ST_AsText(g) FROM t1 WHERE ST_Within(g, ST_GeomFromText('Polygon((140 140,160 140,160 160,140 160,140 140))')) ORDER BY fid; diff --git a/mysql-test/suite/innodb_gis/t/types.test b/mysql-test/suite/innodb_gis/t/types.test index 0db836b94ba..1303e4c487b 100644 --- a/mysql-test/suite/innodb_gis/t/types.test +++ b/mysql-test/suite/innodb_gis/t/types.test @@ -48,7 +48,7 @@ SELECT ST_AsText(g) FROM t_wl6455; CREATE INDEX i_p ON t_wl6455 (g(10)); # Select on prefix index. ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT ST_AsText(g) FROM t_wl6455 WHERE g = POINT(2,2); SELECT ST_AsText(g) FROM t_wl6455 WHERE g = POINT(2,2); diff --git a/mysql-test/suite/innodb_zip/r/wl5522_debug_zip.result b/mysql-test/suite/innodb_zip/r/wl5522_debug_zip.result index 7221358efee..4c36f9d3872 100644 --- a/mysql-test/suite/innodb_zip/r/wl5522_debug_zip.result +++ b/mysql-test/suite/innodb_zip/r/wl5522_debug_zip.result @@ -8,6 +8,7 @@ call mtr.add_suppression("InnoDB: Operating system error number"); call mtr.add_suppression("InnoDB: The error means"); call mtr.add_suppression("InnoDB: Cannot open datafile .*t1\\.ibd"); call mtr.add_suppression("InnoDB: Ignoring tablespace for test/t1 "); +call mtr.add_suppression("InnoDB: Cannot save statistics for table `test`\\.`t1` because the \\.ibd file is missing"); FLUSH TABLES; SET SESSION innodb_strict_mode=1; CREATE TABLE t1 (c1 INT) ENGINE = Innodb diff --git a/mysql-test/suite/innodb_zip/r/wl5522_zip.result b/mysql-test/suite/innodb_zip/r/wl5522_zip.result index c0fddf7e8ed..4d6d23a3bff 100644 --- a/mysql-test/suite/innodb_zip/r/wl5522_zip.result +++ b/mysql-test/suite/innodb_zip/r/wl5522_zip.result @@ -1,4 +1,5 @@ call mtr.add_suppression("InnoDB: Unable to import tablespace .* because it already exists. Please DISCARD the tablespace before IMPORT\\."); +call mtr.add_suppression("InnoDB: Cannot save statistics for table `test`\\.`t1` because the \\.ibd file is missing"); SET SESSION innodb_strict_mode=1; CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, diff --git a/mysql-test/suite/innodb_zip/r/wl6344_compress_level.result b/mysql-test/suite/innodb_zip/r/wl6344_compress_level.result index b33d9c0c8de..3798d0679db 100644 --- a/mysql-test/suite/innodb_zip/r/wl6344_compress_level.result +++ b/mysql-test/suite/innodb_zip/r/wl6344_compress_level.result @@ -1,4 +1,5 @@ -SET GLOBAL Innodb_file_per_table=on; +SET @save_innodb_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = OFF; SET @save_innodb_compression_level = @@global.innodb_compression_level; SET global innodb_compression_level=0; #create table with 1K block size @@ -107,3 +108,4 @@ SELECT @size >= 0; 1 DROP TABLE tab5, tab6; SET GLOBAL innodb_compression_level = @save_innodb_compression_level; +SET GLOBAL innodb_stats_persistent = @save_innodb_stats_persistent; diff --git a/mysql-test/suite/innodb_zip/t/wl5522_debug_zip.test b/mysql-test/suite/innodb_zip/t/wl5522_debug_zip.test index 42f76a78ed9..1f2b00610ce 100644 --- a/mysql-test/suite/innodb_zip/t/wl5522_debug_zip.test +++ b/mysql-test/suite/innodb_zip/t/wl5522_debug_zip.test @@ -24,6 +24,7 @@ call mtr.add_suppression("InnoDB: Operating system error number"); call mtr.add_suppression("InnoDB: The error means"); call mtr.add_suppression("InnoDB: Cannot open datafile .*t1\\.ibd"); call mtr.add_suppression("InnoDB: Ignoring tablespace for test/t1 "); +call mtr.add_suppression("InnoDB: Cannot save statistics for table `test`\\.`t1` because the \\.ibd file is missing"); FLUSH TABLES; let MYSQLD_DATADIR =`SELECT @@datadir`; diff --git a/mysql-test/suite/innodb_zip/t/wl5522_zip.test b/mysql-test/suite/innodb_zip/t/wl5522_zip.test index d5e6bc6e725..dbb698cc545 100644 --- a/mysql-test/suite/innodb_zip/t/wl5522_zip.test +++ b/mysql-test/suite/innodb_zip/t/wl5522_zip.test @@ -5,6 +5,7 @@ -- source include/have_sequence.inc call mtr.add_suppression("InnoDB: Unable to import tablespace .* because it already exists. Please DISCARD the tablespace before IMPORT\\."); +call mtr.add_suppression("InnoDB: Cannot save statistics for table `test`\\.`t1` because the \\.ibd file is missing"); SET SESSION innodb_strict_mode=1; diff --git a/mysql-test/suite/innodb_zip/t/wl6344_compress_level.test b/mysql-test/suite/innodb_zip/t/wl6344_compress_level.test index 690efffed56..f0ddb35aa4a 100644 --- a/mysql-test/suite/innodb_zip/t/wl6344_compress_level.test +++ b/mysql-test/suite/innodb_zip/t/wl6344_compress_level.test @@ -11,9 +11,9 @@ #******************************************************************* --source include/innodb_page_size_small.inc -SET GLOBAL Innodb_file_per_table=on; +SET @save_innodb_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = OFF; SET @save_innodb_compression_level = @@global.innodb_compression_level; - SET global innodb_compression_level=0; -- echo #create table with 1K block size @@ -106,3 +106,4 @@ SELECT @size >= 0; DROP TABLE tab5, tab6; SET GLOBAL innodb_compression_level = @save_innodb_compression_level; +SET GLOBAL innodb_stats_persistent = @save_innodb_stats_persistent; diff --git a/mysql-test/suite/parts/r/longname.result b/mysql-test/suite/parts/r/longname.result index 1b8f823c98f..a54de1e295d 100644 --- a/mysql-test/suite/parts/r/longname.result +++ b/mysql-test/suite/parts/r/longname.result @@ -14,6 +14,10 @@ PARTITION test_jfg_partition_name_with_60_chars_1234567890123456789012 VALUES LE PARTITION pmax VALUES LESS THAN MAXVALUE ENGINE = InnoDB); select database_name, table_name, length(table_name) from mysql.innodb_table_stats where database_name = 'mysqltest1'; database_name table_name length(table_name) +mysqltest1 test_jfg_table_name_with_64_chars_123456789012345678901234567890#P#pmax#SP#pmaxsp0 82 +mysqltest1 test_jfg_table_name_with_64_chars_123456789012345678901234567890#P#pmax#SP#pmaxsp1 82 +mysqltest1 test_jfg_table_name_with_64_chars_123456789012345678901234567890#P#test_jfg_partition_name_with_60_chars_1234567890123456789012#SP#test_jfg_partition_name_with_60_chars_1234567890123456789012sp0 194 +mysqltest1 test_jfg_table_name_with_64_chars_123456789012345678901234567890#P#test_jfg_partition_name_with_60_chars_1234567890123456789012#SP#test_jfg_partition_name_with_60_chars_1234567890123456789012sp1 194 CREATE TABLE mysqltest1.éééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééé ( id int(10) unsigned NOT NULL, id2 int(10) unsigned NOT NULL, diff --git a/mysql-test/suite/parts/r/partition_alter1_2_innodb.result b/mysql-test/suite/parts/r/partition_alter1_2_innodb.result index 3f720024f72..a71cae0ca17 100644 --- a/mysql-test/suite/parts/r/partition_alter1_2_innodb.result +++ b/mysql-test/suite/parts/r/partition_alter1_2_innodb.result @@ -1,4 +1,6 @@ SET @max_row = 20; +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; SET @@session.default_storage_engine = 'InnoDB'; #------------------------------------------------------------------------ @@ -36634,3 +36636,4 @@ DROP TABLE IF EXISTS t1; DROP TABLE IF EXISTS t0_aux; DROP TABLE IF EXISTS t0_definition; DROP TABLE IF EXISTS t0_template; +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; diff --git a/mysql-test/suite/parts/r/partition_alter3_innodb.result b/mysql-test/suite/parts/r/partition_alter3_innodb.result index a859f8200c0..66531c2b699 100644 --- a/mysql-test/suite/parts/r/partition_alter3_innodb.result +++ b/mysql-test/suite/parts/r/partition_alter3_innodb.result @@ -1,4 +1,6 @@ SET @max_row = 20; +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; SET @@session.default_storage_engine = 'InnoDB'; #------------------------------------------------------------------------ @@ -808,3 +810,4 @@ DROP TABLE IF EXISTS t1; DROP TABLE IF EXISTS t0_aux; DROP TABLE IF EXISTS t0_definition; DROP TABLE IF EXISTS t0_template; +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; diff --git a/mysql-test/suite/parts/r/partition_debug_sync_innodb.result b/mysql-test/suite/parts/r/partition_debug_sync_innodb.result index 4841c93e29f..7388eb73ea8 100644 --- a/mysql-test/suite/parts/r/partition_debug_sync_innodb.result +++ b/mysql-test/suite/parts/r/partition_debug_sync_innodb.result @@ -36,7 +36,7 @@ DROP TABLE t1; # Bug#50561: ALTER PARTITIONS does not have adequate lock, breaks with # concurrent I_S query create table t1 (a int) -engine = innodb +engine = innodb stats_persistent=0 partition by range (a) (partition p0 values less than MAXVALUE); insert into t1 values (1), (11), (21), (33); @@ -50,7 +50,7 @@ SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 +) ENGINE=InnoDB DEFAULT CHARSET=latin1 STATS_PERSISTENT=0 PARTITION BY RANGE (`a`) (PARTITION `p0` VALUES LESS THAN MAXVALUE ENGINE = InnoDB) db.opt @@ -89,7 +89,7 @@ SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 +) ENGINE=InnoDB DEFAULT CHARSET=latin1 STATS_PERSISTENT=0 PARTITION BY RANGE (`a`) (PARTITION `p0` VALUES LESS THAN (10) ENGINE = InnoDB, PARTITION `p10` VALUES LESS THAN MAXVALUE ENGINE = InnoDB) diff --git a/mysql-test/suite/parts/r/partition_special_innodb.result b/mysql-test/suite/parts/r/partition_special_innodb.result index 37191eae502..c36eda2345a 100644 --- a/mysql-test/suite/parts/r/partition_special_innodb.result +++ b/mysql-test/suite/parts/r/partition_special_innodb.result @@ -216,14 +216,12 @@ ENGINE = InnoDB PARTITION BY HASH (a) PARTITIONS 2; connect con1, localhost, root,,; -connect con2, localhost, root,,; -connection con1; SET autocommit=OFF; START TRANSACTION; INSERT INTO t1 VALUES (NULL, 'first row t2'); -connection con2; +connect con2, localhost, root,,; SET autocommit=OFF; -SET SESSION lock_wait_timeout= 1; +SET SESSION lock_wait_timeout= 0; ALTER TABLE t1 AUTO_INCREMENT = 10; ERROR HY000: Lock wait timeout exceeded; try restarting transaction disconnect con2; @@ -233,17 +231,12 @@ DROP TABLE t1; # # Bug#53676: Unexpected errors and possible table corruption on # ADD PARTITION and LOCK TABLE -connect con1,localhost,root,,; CREATE TABLE t1 ( i INT NOT NULL AUTO_INCREMENT PRIMARY KEY, f INT ) ENGINE = InnoDB PARTITION BY HASH(i) PARTITIONS 2; INSERT INTO t1 VALUES (2, 2), (3, 3), (4, 4), (5, 5); -connect con2,localhost,root,,; -SET lock_wait_timeout = 2; -connection con1; -#Connection 1 locks the table LOCK TABLE t1 READ; -connection con2; -# Connection 2 tries to add partitions: +connect con2,localhost,root,,; +SET lock_wait_timeout = 0; # First attempt: lock wait timeout (as expected) ALTER TABLE t1 ADD PARTITION PARTITIONS 2; ERROR HY000: Lock wait timeout exceeded; try restarting transaction @@ -263,12 +256,10 @@ i f 3 3 4 4 5 5 -connection con1; -# Connection 1 unlocks the table and locks it again: +connection default; UNLOCK TABLES; LOCK TABLE t1 READ; connection con2; -# Connection 2 tries again to add partitions: # Third attempt: says that the table does not exist ALTER TABLE t1 ADD PARTITION PARTITIONS 2; ERROR HY000: Lock wait timeout exceeded; try restarting transaction @@ -276,22 +267,21 @@ ERROR HY000: Lock wait timeout exceeded; try restarting transaction CHECK TABLE t1; Table Op Msg_type Msg_text test.t1 check status OK -connection con1; +connection default; UNLOCK TABLES; connection con2; DROP TABLE t1; -connection con1; +connection default; CREATE TABLE t2 ( i INT NOT NULL AUTO_INCREMENT PRIMARY KEY, f INT ) ENGINE = InnoDB PARTITION BY HASH(i) PARTITIONS 2; -connection con2; -SET lock_wait_timeout = 2; -connection con1; LOCK TABLE t2 READ; connection con2; +SET lock_wait_timeout = 0; ALTER TABLE t2 ADD PARTITION PARTITIONS 2; ERROR HY000: Lock wait timeout exceeded; try restarting transaction +SET lock_wait_timeout = 2; ALTER TABLE t2 ADD PARTITION PARTITIONS 2; -connection con1; +connection default; UNLOCK TABLES; connection con2; connect con3,localhost,root,,; @@ -301,31 +291,23 @@ test.t2 check status OK SELECT * FROM t2; i f DROP TABLE t2; -connection con1; +connection default; CREATE TABLE t3 ( i INT NOT NULL AUTO_INCREMENT PRIMARY KEY, f INT ) ENGINE = InnoDB PARTITION BY HASH(i) PARTITIONS 2; -connection con2; -SET lock_wait_timeout = 2; -connection con1; -# Connection 1 locks the table LOCK TABLE t3 READ; connection con2; -# Connection 2 tries to add partitions (timeout): +SET lock_wait_timeout = 0; ALTER TABLE t3 ADD PARTITION PARTITIONS 2; ERROR HY000: Lock wait timeout exceeded; try restarting transaction connection con3; -SET lock_wait_timeout = 2; -# Connection 3 tries to add partitions (partition already exists): +SET lock_wait_timeout = 0; ALTER TABLE t3 ADD PARTITION PARTITIONS 2; ERROR HY000: Lock wait timeout exceeded; try restarting transaction connect con4,localhost,root,,; -# Connection 4 tries to rename the table: RENAME TABLE t3 TO t4; -connection con1; -# Connection 1 unlocks the table: +connection default; UNLOCK TABLES; connection con4; -# Connection 4 gets error on rename: connect con5,localhost,root,,; # SHOW TABLES returns the table (not renamed): SHOW TABLES; @@ -339,7 +321,6 @@ disconnect con5; disconnect con4; disconnect con3; disconnect con2; -disconnect con1; connection default; CREATE TABLE t1( f1 INT, f2 VARCHAR(10) CHARSET ascii, @@ -350,17 +331,12 @@ PARTITION p2 VALUES LESS THAN (100)); ALTER TABLE t1 convert to charset ascii collate ascii_bin, ALGORITHM=INSTANT; DROP TABLE t1; # Test WRITE LOCK. -connect con1,localhost,root,,; CREATE TABLE t1 ( i INT NOT NULL AUTO_INCREMENT PRIMARY KEY, f INT ) ENGINE = InnoDB PARTITION BY HASH(i) PARTITIONS 2; INSERT INTO t1 VALUES (3, 3), (4, 4); -connect con2,localhost,root,,; -SET lock_wait_timeout = 2; -connection con1; -#Connection 1 locks the table LOCK TABLE t1 WRITE; -connection con2; -# Check that we still can SELECT, but not insert/update/delete. +connect con2,localhost,root,,; +SET lock_wait_timeout = 0; # Check that we only can select, not insert/update/delete. INSERT INTO t1 VALUES (NULL, 1), (NULL, 2), (10, 10), (11, 11); ERROR HY000: Lock wait timeout exceeded; try restarting transaction @@ -370,9 +346,9 @@ DELETE FROM t1 WHERE i = 10; ERROR HY000: Lock wait timeout exceeded; try restarting transaction SELECT * FROM t1; ERROR HY000: Lock wait timeout exceeded; try restarting transaction -connection con1; +connection default; UNLOCK TABLES; connection con2; DROP TABLE t1; -disconnect con1; +disconnect con2; connection default; diff --git a/mysql-test/suite/parts/t/partition_alter1_2_innodb.test b/mysql-test/suite/parts/t/partition_alter1_2_innodb.test index 71f9d33c72b..5293e547dbf 100644 --- a/mysql-test/suite/parts/t/partition_alter1_2_innodb.test +++ b/mysql-test/suite/parts/t/partition_alter1_2_innodb.test @@ -71,6 +71,9 @@ let $do_pk_tests= 1; # and smaller than the maximum value of SIGNED INTEGER let $MAX_VALUE= (2147483646); +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; + # Generate the prerequisites ($variables, @variables, tables) needed --source suite/parts/inc/partition.pre @@ -87,3 +90,5 @@ let $MAX_VALUE= (2147483646); #------------------------------------------------------------------------------# # Cleanup --source suite/parts/inc/partition_cleanup.inc + +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; diff --git a/mysql-test/suite/parts/t/partition_alter3_innodb.test b/mysql-test/suite/parts/t/partition_alter3_innodb.test index c63cf00bc53..d86c0e1122d 100644 --- a/mysql-test/suite/parts/t/partition_alter3_innodb.test +++ b/mysql-test/suite/parts/t/partition_alter3_innodb.test @@ -63,6 +63,9 @@ let $do_pk_tests= 1; # and smaller than the maximum value of SIGNED INTEGER let $MAX_VALUE= (2147483646); +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; + # Generate the prerequisites ($variables, @variables, tables) needed --source suite/parts/inc/partition.pre @@ -79,3 +82,5 @@ let $MAX_VALUE= (2147483646); #------------------------------------------------------------------------------# # Cleanup --source suite/parts/inc/partition_cleanup.inc + +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; diff --git a/mysql-test/suite/parts/t/partition_debug_sync_innodb.test b/mysql-test/suite/parts/t/partition_debug_sync_innodb.test index d73333c3b8d..9d2557a64e6 100644 --- a/mysql-test/suite/parts/t/partition_debug_sync_innodb.test +++ b/mysql-test/suite/parts/t/partition_debug_sync_innodb.test @@ -45,7 +45,7 @@ DROP TABLE t1; --echo # Bug#50561: ALTER PARTITIONS does not have adequate lock, breaks with --echo # concurrent I_S query create table t1 (a int) -engine = innodb +engine = innodb stats_persistent=0 partition by range (a) (partition p0 values less than MAXVALUE); insert into t1 values (1), (11), (21), (33); diff --git a/mysql-test/suite/parts/t/partition_special_innodb-master.opt b/mysql-test/suite/parts/t/partition_special_innodb-master.opt deleted file mode 100644 index 79851bac7b2..00000000000 --- a/mysql-test/suite/parts/t/partition_special_innodb-master.opt +++ /dev/null @@ -1 +0,0 @@ ---loose-innodb-lock-wait-timeout=2 --loose-innodb-file-per-table diff --git a/mysql-test/suite/parts/t/partition_special_innodb.test b/mysql-test/suite/parts/t/partition_special_innodb.test index a25feed08ef..6273cc5cb2a 100644 --- a/mysql-test/suite/parts/t/partition_special_innodb.test +++ b/mysql-test/suite/parts/t/partition_special_innodb.test @@ -59,16 +59,13 @@ PARTITION BY HASH (a) PARTITIONS 2; connect (con1, localhost, root,,); -connect (con2, localhost, root,,); - ---connection con1 SET autocommit=OFF; START TRANSACTION; INSERT INTO t1 VALUES (NULL, 'first row t2'); ---connection con2 +connect (con2, localhost, root,,); SET autocommit=OFF; -SET SESSION lock_wait_timeout= 1; +SET SESSION lock_wait_timeout= 0; --error ER_LOCK_WAIT_TIMEOUT ALTER TABLE t1 AUTO_INCREMENT = 10; @@ -80,20 +77,14 @@ DROP TABLE t1; --echo # --echo # Bug#53676: Unexpected errors and possible table corruption on --echo # ADD PARTITION and LOCK TABLE ---connect (con1,localhost,root,,) CREATE TABLE t1 ( i INT NOT NULL AUTO_INCREMENT PRIMARY KEY, f INT ) ENGINE = InnoDB PARTITION BY HASH(i) PARTITIONS 2; INSERT INTO t1 VALUES (2, 2), (3, 3), (4, 4), (5, 5); ---connect (con2,localhost,root,,) -SET lock_wait_timeout = 2; - ---connection con1 ---echo #Connection 1 locks the table LOCK TABLE t1 READ; ---connection con2 ---echo # Connection 2 tries to add partitions: +--connect (con2,localhost,root,,) +SET lock_wait_timeout = 0; --echo # First attempt: lock wait timeout (as expected) --error ER_LOCK_WAIT_TIMEOUT ALTER TABLE t1 ADD PARTITION PARTITIONS 2; @@ -110,21 +101,18 @@ DELETE FROM t1 WHERE i = 10; --sorted_result SELECT * FROM t1; ---connection con1 ---echo # Connection 1 unlocks the table and locks it again: +--connection default UNLOCK TABLES; ---real_sleep 1 LOCK TABLE t1 READ; --connection con2 ---echo # Connection 2 tries again to add partitions: --echo # Third attempt: says that the table does not exist --error ER_LOCK_WAIT_TIMEOUT ALTER TABLE t1 ADD PARTITION PARTITIONS 2; --echo # Check table returns the same (not after fixing bug#56172!) CHECK TABLE t1; ---connection con1 +--connection default UNLOCK TABLES; --connection con2 @@ -134,23 +122,21 @@ DROP TABLE t1; # Test2 ---connection con1 +--connection default CREATE TABLE t2 ( i INT NOT NULL AUTO_INCREMENT PRIMARY KEY, f INT ) ENGINE = InnoDB PARTITION BY HASH(i) PARTITIONS 2; ---connection con2 -SET lock_wait_timeout = 2; - ---connection con1 LOCK TABLE t2 READ; --connection con2 +SET lock_wait_timeout = 0; --error ER_LOCK_WAIT_TIMEOUT ALTER TABLE t2 ADD PARTITION PARTITIONS 2; +SET lock_wait_timeout = 2; send ALTER TABLE t2 ADD PARTITION PARTITIONS 2; ---connection con1 +--connection default UNLOCK TABLES; --connection con2 @@ -164,40 +150,30 @@ DROP TABLE t2; # End of Test2 # Test #3 ---connection con1 +--connection default CREATE TABLE t3 ( i INT NOT NULL AUTO_INCREMENT PRIMARY KEY, f INT ) ENGINE = InnoDB PARTITION BY HASH(i) PARTITIONS 2; ---connection con2 -SET lock_wait_timeout = 2; - ---connection con1 ---echo # Connection 1 locks the table LOCK TABLE t3 READ; --connection con2 ---echo # Connection 2 tries to add partitions (timeout): +SET lock_wait_timeout = 0; --error ER_LOCK_WAIT_TIMEOUT ALTER TABLE t3 ADD PARTITION PARTITIONS 2; --connection con3 -SET lock_wait_timeout = 2; ---echo # Connection 3 tries to add partitions (partition already exists): +SET lock_wait_timeout = 0; --error ER_LOCK_WAIT_TIMEOUT ALTER TABLE t3 ADD PARTITION PARTITIONS 2; --connect (con4,localhost,root,,) ---echo # Connection 4 tries to rename the table: send RENAME TABLE t3 TO t4; ---connection con1 ---real_sleep 1 ---echo # Connection 1 unlocks the table: +--connection default UNLOCK TABLES; --connection con4 ---echo # Connection 4 gets error on rename: --reap --connect (con5,localhost,root,,) @@ -212,7 +188,6 @@ DROP TABLE t4; --disconnect con4 --disconnect con3 --disconnect con2 ---disconnect con1 --connection default # End of Test #3 @@ -227,20 +202,14 @@ ALTER TABLE t1 convert to charset ascii collate ascii_bin, ALGORITHM=INSTANT; DROP TABLE t1; --echo # Test WRITE LOCK. ---connect (con1,localhost,root,,) CREATE TABLE t1 ( i INT NOT NULL AUTO_INCREMENT PRIMARY KEY, f INT ) ENGINE = InnoDB PARTITION BY HASH(i) PARTITIONS 2; INSERT INTO t1 VALUES (3, 3), (4, 4); ---connect (con2,localhost,root,,) -SET lock_wait_timeout = 2; - ---connection con1 ---echo #Connection 1 locks the table LOCK TABLE t1 WRITE; ---connection con2 ---echo # Check that we still can SELECT, but not insert/update/delete. +--connect (con2,localhost,root,,) +SET lock_wait_timeout = 0; --echo # Check that we only can select, not insert/update/delete. --error ER_LOCK_WAIT_TIMEOUT INSERT INTO t1 VALUES (NULL, 1), (NULL, 2), (10, 10), (11, 11); @@ -251,11 +220,11 @@ DELETE FROM t1 WHERE i = 10; --error ER_LOCK_WAIT_TIMEOUT SELECT * FROM t1; ---connection con1 +--connection default UNLOCK TABLES; --connection con2 DROP TABLE t1; ---disconnect con1 +--disconnect con2 --connection default diff --git a/mysql-test/suite/perfschema/r/sxlock_func.result b/mysql-test/suite/perfschema/r/sxlock_func.result index 943f2c9301b..8f4c2fdcece 100644 --- a/mysql-test/suite/perfschema/r/sxlock_func.result +++ b/mysql-test/suite/perfschema/r/sxlock_func.result @@ -35,10 +35,10 @@ SELECT DISTINCT event_name FROM performance_schema.events_waits_history_long WHERE event_name LIKE 'wait/synch/rwlock/innodb/%' AND event_name NOT IN ('wait/synch/rwlock/innodb/btr_search_latch', +'wait/synch/rwlock/innodb/dict_operation_lock', 'wait/synch/rwlock/innodb/trx_purge_latch') ORDER BY event_name; event_name -wait/synch/rwlock/innodb/dict_operation_lock wait/synch/rwlock/innodb/fil_space_latch wait/synch/rwlock/innodb/lock_latch SELECT event_name FROM performance_schema.events_waits_history_long diff --git a/mysql-test/suite/perfschema/t/sxlock_func.test b/mysql-test/suite/perfschema/t/sxlock_func.test index b8852c51ccb..c628158c9ea 100644 --- a/mysql-test/suite/perfschema/t/sxlock_func.test +++ b/mysql-test/suite/perfschema/t/sxlock_func.test @@ -42,11 +42,13 @@ commit; drop table t1; # Make sure some rw-lock operations have been executed +# (there will only occasionally be waits on some rw-locks) SELECT DISTINCT event_name FROM performance_schema.events_waits_history_long WHERE event_name LIKE 'wait/synch/rwlock/innodb/%' AND event_name NOT IN ('wait/synch/rwlock/innodb/btr_search_latch', + 'wait/synch/rwlock/innodb/dict_operation_lock', 'wait/synch/rwlock/innodb/trx_purge_latch') ORDER BY event_name; diff --git a/mysql-test/suite/sys_vars/r/innodb_stats_persistent_basic.result b/mysql-test/suite/sys_vars/r/innodb_stats_persistent_basic.result index 94de032a0fd..c7dccdd2398 100644 --- a/mysql-test/suite/sys_vars/r/innodb_stats_persistent_basic.result +++ b/mysql-test/suite/sys_vars/r/innodb_stats_persistent_basic.result @@ -1,6 +1,7 @@ +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; SELECT @@innodb_stats_persistent; @@innodb_stats_persistent -0 +1 SET GLOBAL innodb_stats_persistent=ON; SELECT @@innodb_stats_persistent; @@innodb_stats_persistent @@ -21,4 +22,4 @@ SET GLOBAL innodb_stats_persistent=123; ERROR 42000: Variable 'innodb_stats_persistent' can't be set to the value of '123' SET GLOBAL innodb_stats_persistent='foo'; ERROR 42000: Variable 'innodb_stats_persistent' can't be set to the value of 'foo' -SET GLOBAL innodb_stats_persistent=OFF; +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; diff --git a/mysql-test/suite/sys_vars/t/innodb_stats_persistent_basic.test b/mysql-test/suite/sys_vars/t/innodb_stats_persistent_basic.test index c5f977321b7..e1b650184ac 100644 --- a/mysql-test/suite/sys_vars/t/innodb_stats_persistent_basic.test +++ b/mysql-test/suite/sys_vars/t/innodb_stats_persistent_basic.test @@ -4,6 +4,7 @@ -- source include/have_innodb.inc +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; # show the default value SELECT @@innodb_stats_persistent; @@ -28,4 +29,4 @@ SET GLOBAL innodb_stats_persistent=123; SET GLOBAL innodb_stats_persistent='foo'; # restore the environment -SET GLOBAL innodb_stats_persistent=OFF; \ No newline at end of file +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; diff --git a/mysql-test/suite/vcol/r/vcol_select_innodb.result b/mysql-test/suite/vcol/r/vcol_select_innodb.result index e275a66091c..40308b6e072 100644 --- a/mysql-test/suite/vcol/r/vcol_select_innodb.result +++ b/mysql-test/suite/vcol/r/vcol_select_innodb.result @@ -1,4 +1,6 @@ SET @@session.default_storage_engine = 'InnoDB'; +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; create table t1 (a int, b int as (-a), c int as (-a) persistent, @@ -265,3 +267,4 @@ NULL explain select sum(c) from t1 group by b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using temporary; Using filesort +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; diff --git a/mysql-test/suite/vcol/r/vcol_view_innodb.result b/mysql-test/suite/vcol/r/vcol_view_innodb.result index e6895243371..53ef6e0709c 100644 --- a/mysql-test/suite/vcol/r/vcol_view_innodb.result +++ b/mysql-test/suite/vcol/r/vcol_view_innodb.result @@ -1,4 +1,6 @@ SET @@session.default_storage_engine = 'InnoDB'; +SET @save_innodb_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; create table t1 (a int not null, b int as (-a), c int as (-a) persistent); @@ -281,3 +283,4 @@ a b c 0 0 0 drop view v1; drop table t1; +SET GLOBAL innodb_stats_persistent=@save_innodb_stats_persistent; diff --git a/mysql-test/suite/vcol/t/vcol_select_innodb.test b/mysql-test/suite/vcol/t/vcol_select_innodb.test index 606801a213a..5b04096a5a5 100644 --- a/mysql-test/suite/vcol/t/vcol_select_innodb.test +++ b/mysql-test/suite/vcol/t/vcol_select_innodb.test @@ -36,6 +36,8 @@ # Set the session storage engine --source include/have_innodb.inc eval SET @@session.default_storage_engine = 'InnoDB'; +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; ##### Workarounds for known open engine specific bugs # none @@ -47,6 +49,8 @@ eval SET @@session.default_storage_engine = 'InnoDB'; #------------------------------------------------------------------------------# # Execute storage engine specific tests +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; + #------------------------------------------------------------------------------# # Cleanup --source suite/vcol/inc/vcol_cleanup.inc diff --git a/mysql-test/suite/vcol/t/vcol_view_innodb.test b/mysql-test/suite/vcol/t/vcol_view_innodb.test index fd77489f5dc..3b869425ecb 100644 --- a/mysql-test/suite/vcol/t/vcol_view_innodb.test +++ b/mysql-test/suite/vcol/t/vcol_view_innodb.test @@ -35,6 +35,8 @@ # Set the session storage engine --source include/have_innodb.inc eval SET @@session.default_storage_engine = 'InnoDB'; +SET @save_innodb_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; ##### Workarounds for known open engine specific bugs # none @@ -46,6 +48,8 @@ eval SET @@session.default_storage_engine = 'InnoDB'; #------------------------------------------------------------------------------# # Execute storage engine specific tests +SET GLOBAL innodb_stats_persistent=@save_innodb_stats_persistent; + #------------------------------------------------------------------------------# # Cleanup --source suite/vcol/inc/vcol_cleanup.inc diff --git a/mysql-test/suite/versioning/r/cte.result b/mysql-test/suite/versioning/r/cte.result index 4c0867d579b..6ca9c238d45 100644 --- a/mysql-test/suite/versioning/r/cte.result +++ b/mysql-test/suite/versioning/r/cte.result @@ -1,3 +1,5 @@ +SET @saved_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = OFF; set time_zone="+00:00"; set default_storage_engine=innodb; create or replace table dept ( @@ -311,3 +313,4 @@ emp_id name mgr address drop table emp; drop table dept; drop table addr; +SET GLOBAL innodb_stats_persistent = @saved_stats_persistent; diff --git a/mysql-test/suite/versioning/r/partition.result b/mysql-test/suite/versioning/r/partition.result index d6e6d827ddc..f651d25ce7c 100644 --- a/mysql-test/suite/versioning/r/partition.result +++ b/mysql-test/suite/versioning/r/partition.result @@ -1,3 +1,5 @@ +SET @save_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; call mtr.add_suppression("need more HISTORY partitions"); set system_versioning_alter_history=keep; # Check conventional partitioning on temporal tables @@ -1281,3 +1283,5 @@ drop tables t1; # # End of 10.5 tests # +SET GLOBAL innodb_stats_persistent=@save_persistent; +# End of 10.6 tests diff --git a/mysql-test/suite/versioning/r/select.result b/mysql-test/suite/versioning/r/select.result index 6df18403ee3..90c99d1bf0e 100644 --- a/mysql-test/suite/versioning/r/select.result +++ b/mysql-test/suite/versioning/r/select.result @@ -1,3 +1,5 @@ +SET @saved_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = OFF; create or replace table t1 ( x int unsigned, y int unsigned, @@ -705,3 +707,4 @@ No A B C D 32 1 1 1 1 33 1 1 1 1 34 1 1 1 1 +SET GLOBAL innodb_stats_persistent = @saved_stats_persistent; diff --git a/mysql-test/suite/versioning/t/cte.test b/mysql-test/suite/versioning/t/cte.test index 5f2a709eebe..025e1b2319d 100644 --- a/mysql-test/suite/versioning/t/cte.test +++ b/mysql-test/suite/versioning/t/cte.test @@ -5,6 +5,9 @@ if (`SELECT $PS_PROTOCOL != 0`) --source include/have_innodb.inc --source include/default_optimizer_switch.inc +SET @saved_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = OFF; + set time_zone="+00:00"; set default_storage_engine=innodb; create or replace table dept ( @@ -230,3 +233,5 @@ select * from (select * from emp natural join addr) for system_time all as t; drop table emp; drop table dept; drop table addr; + +SET GLOBAL innodb_stats_persistent = @saved_stats_persistent; diff --git a/mysql-test/suite/versioning/t/partition.test b/mysql-test/suite/versioning/t/partition.test index 61cfe702f8a..044c0d64d37 100644 --- a/mysql-test/suite/versioning/t/partition.test +++ b/mysql-test/suite/versioning/t/partition.test @@ -2,6 +2,9 @@ -- source suite/versioning/common.inc -- source suite/versioning/engines.inc +SET @save_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; + call mtr.add_suppression("need more HISTORY partitions"); --enable_prepare_warnings @@ -1102,4 +1105,8 @@ drop tables t1; --echo # End of 10.5 tests --echo # +SET GLOBAL innodb_stats_persistent=@save_persistent; + +--echo # End of 10.6 tests + --source suite/versioning/common_finish.inc diff --git a/mysql-test/suite/versioning/t/select.test b/mysql-test/suite/versioning/t/select.test index bf27723adee..9142a8fae8a 100644 --- a/mysql-test/suite/versioning/t/select.test +++ b/mysql-test/suite/versioning/t/select.test @@ -6,6 +6,9 @@ if (`SELECT $PS_PROTOCOL != 0`) --source suite/versioning/common.inc --source include/default_optimizer_switch.inc +SET @saved_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = OFF; + --enable_prepare_warnings # test_01 @@ -482,4 +485,6 @@ drop tables x, x_p; call verify_trt_dummy(34); --disable_prepare_warnings +SET GLOBAL innodb_stats_persistent = @saved_stats_persistent; + -- source suite/versioning/common_finish.inc diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 75015200ca7..fc751f2e4c1 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -5017,13 +5017,9 @@ void reset_thd(MYSQL_THD thd) guarantees, in other words, server can't send OK packet before modified data is durable in redo log. */ -extern "C" MYSQL_THD thd_increment_pending_ops(void) +extern "C" void thd_increment_pending_ops(MYSQL_THD thd) { - THD *thd = current_thd; - if (!thd) - return NULL; thd->async_state.inc_pending_ops(); - return thd; } /** diff --git a/sql/sql_class.h b/sql/sql_class.h index 252f83e7592..e569fcd32d6 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2531,7 +2531,7 @@ struct thd_async_state } }; -extern "C" MYSQL_THD thd_increment_pending_ops(void); +extern "C" void thd_increment_pending_ops(MYSQL_THD); extern "C" void thd_decrement_pending_ops(MYSQL_THD); diff --git a/storage/innobase/btr/btr0defragment.cc b/storage/innobase/btr/btr0defragment.cc index fa0ad06d7ab..0e21acb4fda 100644 --- a/storage/innobase/btr/btr0defragment.cc +++ b/storage/innobase/btr/btr0defragment.cc @@ -36,6 +36,7 @@ Modified 30/07/2014 Jan Lindström jan.lindstrom@mariadb.com #include "ibuf0ibuf.h" #include "lock0lock.h" #include "srv0start.h" +#include "mysqld.h" #include @@ -614,6 +615,9 @@ The state (current item) is stored in function parameter. */ static void btr_defragment_chunk(void*) { + THD *thd = innobase_create_background_thd("InnoDB defragment"); + set_current_thd(thd); + btr_defragment_item_t* item = nullptr; mtr_t mtr; @@ -622,7 +626,11 @@ static void btr_defragment_chunk(void*) while (srv_shutdown_state == SRV_SHUTDOWN_NONE) { if (!item) { if (btr_defragment_wq.empty()) { +release_and_exit: mysql_mutex_unlock(&btr_defragment_mutex); +func_exit: + set_current_thd(nullptr); + innobase_destroy_background_thd(thd); return; } item = *btr_defragment_wq.begin(); @@ -651,7 +659,7 @@ processed: int sleep_ms = (int)((srv_defragment_interval - elapsed) / 1000 / 1000); if (sleep_ms) { btr_defragment_timer->set_time(sleep_ms, 0); - return; + goto func_exit; } } log_free_check(); @@ -693,7 +701,8 @@ processed: << " index " << index->name() << " failed with error " << err; } else { - err = dict_stats_save_defrag_summary(index); + err = dict_stats_save_defrag_summary(index, + thd); if (err != DB_SUCCESS) { ib::error() << "Saving defragmentation summary for table " @@ -711,5 +720,5 @@ processed: } } - mysql_mutex_unlock(&btr_defragment_mutex); + goto release_and_exit; } diff --git a/storage/innobase/btr/btr0sea.cc b/storage/innobase/btr/btr0sea.cc index a5e22fa0c2a..6fb4a01951a 100644 --- a/storage/innobase/btr/btr0sea.cc +++ b/storage/innobase/btr/btr0sea.cc @@ -230,12 +230,12 @@ void btr_search_disable() { dict_table_t* table; - dict_sys.mutex_lock(); + dict_sys.freeze(SRW_LOCK_CALL); btr_search_x_lock_all(); if (!btr_search_enabled) { - dict_sys.mutex_unlock(); + dict_sys.unfreeze(); btr_search_x_unlock_all(); return; } @@ -256,7 +256,7 @@ void btr_search_disable() btr_search_disable_ref_count(table); } - dict_sys.mutex_unlock(); + dict_sys.unfreeze(); /* Set all block->index = NULL. */ buf_pool.clear_hash_index(); @@ -1263,7 +1263,7 @@ retry: ut_ad(page_is_leaf(block->frame)); /* We must not dereference block->index here, because it could be freed - if (index->table->n_ref_count == 0). + if (!index->table->get_ref_count() && !dict_sys.frozen()). Determine the ahi_slot based on the block contents. */ const index_id_t index_id @@ -1436,10 +1436,8 @@ void btr_search_drop_page_hash_when_freed(const page_id_t page_id) /* In all our callers, the table handle should be open, or we should be in the process of dropping the table (preventing eviction). */ -#ifdef SAFE_MUTEX DBUG_ASSERT(block->index->table->get_ref_count() - || dict_sys.mutex_is_locked()); -#endif /* SAFE_MUTEX */ + || dict_sys.locked()); btr_search_drop_page_hash_index(block); } } diff --git a/storage/innobase/dict/dict0boot.cc b/storage/innobase/dict/dict0boot.cc index a4cb92ea473..ab968f5047a 100644 --- a/storage/innobase/dict/dict0boot.cc +++ b/storage/innobase/dict/dict0boot.cc @@ -225,7 +225,7 @@ dict_boot(void) heap = mem_heap_create(450); - dict_sys.mutex_lock(); + dict_sys.lock(SRW_LOCK_CALL); /* Get the dictionary header */ const byte* dict_hdr = &dict_hdr_get(&mtr)->frame[DICT_HDR]; @@ -413,10 +413,10 @@ dict_boot(void) dict_load_sys_table(dict_sys.sys_columns); dict_load_sys_table(dict_sys.sys_indexes); dict_load_sys_table(dict_sys.sys_fields); - dict_sys.mutex_unlock(); + dict_sys.unlock(); dict_sys.load_sys_tables(); } else { - dict_sys.mutex_unlock(); + dict_sys.unlock(); } return(err); diff --git a/storage/innobase/dict/dict0crea.cc b/storage/innobase/dict/dict0crea.cc index 44d56d40151..ec4db448b0a 100644 --- a/storage/innobase/dict/dict0crea.cc +++ b/storage/innobase/dict/dict0crea.cc @@ -33,6 +33,7 @@ Created 1/8/1996 Heikki Tuuri #include "mach0data.h" #include "dict0boot.h" #include "dict0dict.h" +#include "lock0lock.h" #include "que0que.h" #include "row0ins.h" #include "row0mysql.h" @@ -343,7 +344,7 @@ dict_build_table_def_step( que_thr_t* thr, /*!< in: query thread */ tab_node_t* node) /*!< in: table create node */ { - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); dict_table_t* table = node->table; ut_ad(!table->is_temporary()); ut_ad(!table->space); @@ -403,7 +404,7 @@ dict_build_v_col_def_step( Based on an index object, this function builds the entry to be inserted in the SYS_INDEXES system table. @return the tuple which should be inserted */ -static +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dtuple_t* dict_create_sys_indexes_tuple( /*==========================*/ @@ -416,7 +417,7 @@ dict_create_sys_indexes_tuple( dfield_t* dfield; byte* ptr; - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); ut_ad(index); ut_ad(index->table->space || !UT_LIST_GET_LEN(index->table->indexes) || index->table->file_unreadable); @@ -646,14 +647,14 @@ dict_build_index_def_step( dtuple_t* row; trx_t* trx; - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); trx = thr_get_trx(thr); index = node->index; table = dict_table_open_on_name( - node->table_name, TRUE, FALSE, DICT_ERR_IGNORE_DROP); + node->table_name, true, DICT_ERR_IGNORE_DROP); if (!table) { return DB_TABLE_NOT_FOUND; @@ -691,7 +692,7 @@ dict_build_index_def( dict_index_t* index, /*!< in/out: index */ trx_t* trx) /*!< in/out: InnoDB transaction handle */ { - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); ut_ad((UT_LIST_GET_LEN(table->indexes) > 0) || dict_index_is_clust(index)); @@ -734,7 +735,7 @@ dict_create_index_tree_step( dict_index_t* index; dtuple_t* search_tuple; - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); index = node->index; @@ -803,7 +804,7 @@ dict_create_index_tree_in_mem( { mtr_t mtr; - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); ut_ad(!(index->type & DICT_FTS)); mtr_start(&mtr); @@ -833,7 +834,7 @@ uint32_t dict_drop_index_tree(btr_pcur_t *pcur, trx_t *trx, mtr_t *mtr) { rec_t *rec= btr_pcur_get_rec(pcur); - ut_d(if (trx) dict_sys.assert_locked()); + ut_ad(!trx || dict_sys.locked()); ut_ad(!dict_table_is_comp(dict_sys.sys_indexes)); btr_pcur_store_position(pcur, mtr); @@ -995,7 +996,7 @@ dict_create_table_step( trx_t* trx; ut_ad(thr); - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); trx = thr_get_trx(thr); @@ -1171,7 +1172,7 @@ dict_create_index_step( trx_t* trx; ut_ad(thr); - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); trx = thr_get_trx(thr); @@ -1319,7 +1320,7 @@ bool dict_sys_t::load_sys_tables() { ut_ad(!srv_any_background_activity()); bool mismatch= false; - mutex_lock(); + lock(SRW_LOCK_CALL); if (!(sys_foreign= load_table(SYS_TABLE[SYS_FOREIGN], DICT_ERR_IGNORE_FK_NOKEY))); else if (UT_LIST_GET_LEN(sys_foreign->indexes) == 3 && @@ -1354,7 +1355,7 @@ bool dict_sys_t::load_sys_tables() mismatch= true; ib::error() << "Invalid definition of SYS_VIRTUAL"; } - mutex_unlock(); + unlock(); return mismatch; } @@ -1377,7 +1378,18 @@ dberr_t dict_sys_t::create_or_check_sys_tables() return DB_SUCCESS; trx_t *trx= trx_create(); - trx->dict_operation= true; + trx_start_for_ddl(trx); + + { + LockMutexGuard g{SRW_LOCK_CALL}; + trx->mutex_lock(); + lock_table_create(dict_sys.sys_tables, LOCK_X, trx); + lock_table_create(dict_sys.sys_columns, LOCK_X, trx); + lock_table_create(dict_sys.sys_indexes, LOCK_X, trx); + lock_table_create(dict_sys.sys_fields, LOCK_X, trx); + trx->mutex_unlock(); + } + row_mysql_lock_data_dictionary(trx); /* NOTE: when designing InnoDB's foreign key support in 2001, Heikki Tuuri @@ -1403,7 +1415,7 @@ dberr_t dict_sys_t::create_or_check_sys_tables() " ON SYS_FOREIGN (FOR_NAME);\n" "CREATE INDEX REF_IND" " ON SYS_FOREIGN (REF_NAME);\n" - "END;\n", false, trx); + "END;\n", trx); if (UNIV_UNLIKELY(error != DB_SUCCESS)) { tablename= SYS_TABLE[SYS_FOREIGN].data(); @@ -1425,7 +1437,7 @@ err_exit: " FOR_COL_NAME CHAR, REF_COL_NAME CHAR);\n" "CREATE UNIQUE CLUSTERED INDEX ID_IND" " ON SYS_FOREIGN_COLS (ID, POS);\n" - "END;\n", false, trx); + "END;\n", trx); if (UNIV_UNLIKELY(error != DB_SUCCESS)) { tablename= SYS_TABLE[SYS_FOREIGN_COLS].data(); @@ -1440,7 +1452,7 @@ err_exit: "SYS_VIRTUAL(TABLE_ID BIGINT,POS INT,BASE_POS INT);\n" "CREATE UNIQUE CLUSTERED INDEX BASE_IDX" " ON SYS_VIRTUAL(TABLE_ID, POS, BASE_POS);\n" - "END;\n", false, trx); + "END;\n", trx); if (UNIV_UNLIKELY(error != DB_SUCCESS)) { tablename= SYS_TABLE[SYS_VIRTUAL].data(); @@ -1453,13 +1465,13 @@ err_exit: trx->free(); srv_file_per_table= srv_file_per_table_backup; - mutex_lock(); + lock(SRW_LOCK_CALL); if (sys_foreign); else if (!(sys_foreign= load_table(SYS_TABLE[SYS_FOREIGN]))) { tablename= SYS_TABLE[SYS_FOREIGN].data(); load_fail: - mutex_unlock(); + unlock(); ib::error() << "Failed to CREATE TABLE " << tablename; return DB_TABLE_NOT_FOUND; } @@ -1484,7 +1496,7 @@ load_fail: else prevent_eviction(sys_virtual); - mutex_unlock(); + unlock(); return DB_SUCCESS; } @@ -1504,7 +1516,7 @@ dict_foreign_eval_sql( dberr_t error; FILE* ef = dict_foreign_err_file; - error = que_eval_sql(info, sql, FALSE, trx); + error = que_eval_sql(info, sql, trx); if (error == DB_DUPLICATE_KEY) { mysql_mutex_lock(&dict_foreign_err_mutex); @@ -1877,7 +1889,7 @@ dict_create_add_foreigns_to_dictionary( const dict_table_t* table, trx_t* trx) { - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); if (!dict_sys.sys_foreign) { diff --git a/storage/innobase/dict/dict0defrag_bg.cc b/storage/innobase/dict/dict0defrag_bg.cc index 4be6a28882e..8dd1a8601aa 100644 --- a/storage/innobase/dict/dict0defrag_bg.cc +++ b/storage/innobase/dict/dict0defrag_bg.cc @@ -29,6 +29,9 @@ Created 25/08/2016 Jan Lindström #include "dict0defrag_bg.h" #include "btr0btr.h" #include "srv0start.h" +#include "trx0trx.h" +#include "lock0lock.h" +#include "row0mysql.h" static mysql_mutex_t defrag_pool_mutex; @@ -145,7 +148,7 @@ dict_stats_defrag_pool_del( { ut_a((table && !index) || (!table && index)); ut_ad(!srv_read_only_mode); - dict_sys.assert_locked(); + ut_ad(dict_sys.frozen()); mysql_mutex_lock(&defrag_pool_mutex); @@ -170,85 +173,114 @@ dict_stats_defrag_pool_del( /*****************************************************************//** Get the first index that has been added for updating persistent defrag stats and eventually save its stats. */ -static -void -dict_stats_process_entry_from_defrag_pool() +static void dict_stats_process_entry_from_defrag_pool() { - table_id_t table_id; - index_id_t index_id; + table_id_t table_id; + index_id_t index_id; - ut_ad(!srv_read_only_mode); + ut_ad(!srv_read_only_mode); - /* pop the first index from the auto defrag pool */ - if (!dict_stats_defrag_pool_get(&table_id, &index_id)) { - /* no index in defrag pool */ - return; - } + /* pop the first index from the auto defrag pool */ + if (!dict_stats_defrag_pool_get(&table_id, &index_id)) + /* no index in defrag pool */ + return; - dict_table_t* table; + dict_sys.freeze(SRW_LOCK_CALL); - dict_sys.mutex_lock(); - - /* If the table is no longer cached, we've already lost the in - memory stats so there's nothing really to write to disk. */ - table = dict_table_open_on_id(table_id, TRUE, - DICT_TABLE_OP_OPEN_ONLY_IF_CACHED); - - dict_index_t* index = table && !table->corrupted - ? dict_table_find_index_on_id(table, index_id) - : NULL; - - if (!index || index->is_corrupted()) { - if (table) { - dict_table_close(table, TRUE, FALSE); - } - dict_sys.mutex_unlock(); - return; - } - - dict_sys.mutex_unlock(); - dict_stats_save_defrag_stats(index); - dict_table_close(table, FALSE, FALSE); + /* If the table is no longer cached, we've already lost the in + memory stats so there's nothing really to write to disk. */ + dict_table_t *table= dict_sys.find_table(table_id); + dict_index_t *index= table && table->corrupted + ? nullptr : dict_table_find_index_on_id(table, index_id); + const bool save= index && !index->is_corrupted(); + if (save) + table->acquire(); + dict_sys.unfreeze(); + if (save) + { + dict_stats_save_defrag_stats(index); + table->release(); + } } -/*****************************************************************//** +/** Get the first index that has been added for updating persistent defrag stats and eventually save its stats. */ -void -dict_defrag_process_entries_from_defrag_pool() -/*==========================================*/ +void dict_defrag_process_entries_from_defrag_pool() { - while (defrag_pool.size()) { - dict_stats_process_entry_from_defrag_pool(); - } + while (!defrag_pool.empty()) + dict_stats_process_entry_from_defrag_pool(); } /*********************************************************************//** Save defragmentation result. @return DB_SUCCESS or error code */ -dberr_t -dict_stats_save_defrag_summary( -/*============================*/ - dict_index_t* index) /*!< in: index */ +dberr_t dict_stats_save_defrag_summary(dict_index_t *index, THD *thd) { - dberr_t ret=DB_SUCCESS; + if (index->is_ibuf()) + return DB_SUCCESS; - if (dict_index_is_ibuf(index)) { - return DB_SUCCESS; - } + MDL_ticket *mdl_table= nullptr, *mdl_index= nullptr; + dict_table_t *table_stats= dict_table_open_on_name(TABLE_STATS_NAME, false, + DICT_ERR_IGNORE_NONE); + if (table_stats) + { + dict_sys.freeze(SRW_LOCK_CALL); + table_stats= dict_acquire_mdl_shared(table_stats, thd, &mdl_table); + dict_sys.unfreeze(); + } + if (!table_stats || strcmp(table_stats->name.m_name, TABLE_STATS_NAME)) + { +release_and_exit: + if (table_stats) + dict_table_close(table_stats, false, thd, mdl_table); + return DB_STATS_DO_NOT_EXIST; + } - dict_sys_lock(); + dict_table_t *index_stats= dict_table_open_on_name(INDEX_STATS_NAME, false, + DICT_ERR_IGNORE_NONE); + if (index_stats) + { + dict_sys.freeze(SRW_LOCK_CALL); + index_stats= dict_acquire_mdl_shared(index_stats, thd, &mdl_index); + dict_sys.unfreeze(); + } + if (!index_stats) + goto release_and_exit; + if (strcmp(index_stats->name.m_name, INDEX_STATS_NAME)) + { + dict_table_close(index_stats, false, thd, mdl_index); + goto release_and_exit; + } - ret = dict_stats_save_index_stat(index, time(NULL), "n_pages_freed", - index->stat_defrag_n_pages_freed, - NULL, - "Number of pages freed during" - " last defragmentation run.", - NULL); + trx_t *trx= trx_create(); + trx->mysql_thd= thd; + trx_start_internal(trx); + dberr_t ret= lock_table_for_trx(table_stats, trx, LOCK_X); + if (ret == DB_SUCCESS) + ret= lock_table_for_trx(index_stats, trx, LOCK_X); + row_mysql_lock_data_dictionary(trx); + if (ret == DB_SUCCESS) + ret= dict_stats_save_index_stat(index, time(nullptr), "n_pages_freed", + index->stat_defrag_n_pages_freed, + nullptr, + "Number of pages freed during" + " last defragmentation run.", + trx); + if (ret == DB_SUCCESS) + trx->commit(); + else + trx->rollback(); - dict_sys_unlock(); + if (table_stats) + dict_table_close(table_stats, true, thd, mdl_table); + if (index_stats) + dict_table_close(index_stats, true, thd, mdl_index); - return (ret); + row_mysql_unlock_data_dictionary(trx); + trx->free(); + + return ret; } /**************************************************************//** @@ -304,63 +336,97 @@ dict_stats_save_defrag_stats( /*============================*/ dict_index_t* index) /*!< in: index */ { - dberr_t ret; + if (index->is_ibuf()) + return DB_SUCCESS; + if (!index->is_readable()) + return dict_stats_report_error(index->table, true); - if (dict_index_is_ibuf(index)) { - return DB_SUCCESS; - } + const time_t now= time(nullptr); + mtr_t mtr; + ulint n_leaf_pages; + mtr.start(); + mtr_s_lock_index(index, &mtr); + ulint n_leaf_reserved= btr_get_size_and_reserved(index, BTR_N_LEAF_PAGES, + &n_leaf_pages, &mtr); + mtr.commit(); - if (!index->is_readable()) { - return dict_stats_report_error(index->table, true); - } + if (n_leaf_reserved == ULINT_UNDEFINED) + return DB_SUCCESS; - const time_t now = time(NULL); - mtr_t mtr; - ulint n_leaf_pages; - ulint n_leaf_reserved; - mtr.start(); - mtr_s_lock_index(index, &mtr); - n_leaf_reserved = btr_get_size_and_reserved(index, BTR_N_LEAF_PAGES, - &n_leaf_pages, &mtr); - mtr.commit(); + THD *thd= current_thd; + MDL_ticket *mdl_table= nullptr, *mdl_index= nullptr; + dict_table_t* table_stats= dict_table_open_on_name(TABLE_STATS_NAME, false, + DICT_ERR_IGNORE_NONE); + if (table_stats) + { + dict_sys.freeze(SRW_LOCK_CALL); + table_stats= dict_acquire_mdl_shared(table_stats, thd, &mdl_table); + dict_sys.unfreeze(); + } + if (!table_stats || strcmp(table_stats->name.m_name, TABLE_STATS_NAME)) + { +release_and_exit: + if (table_stats) + dict_table_close(table_stats, false, thd, mdl_table); + return DB_STATS_DO_NOT_EXIST; + } - if (n_leaf_reserved == ULINT_UNDEFINED) { - // The index name is different during fast index creation, - // so the stats won't be associated with the right index - // for later use. We just return without saving. - return DB_SUCCESS; - } + dict_table_t *index_stats= dict_table_open_on_name(INDEX_STATS_NAME, false, + DICT_ERR_IGNORE_NONE); + if (index_stats) + { + dict_sys.freeze(SRW_LOCK_CALL); + index_stats= dict_acquire_mdl_shared(index_stats, thd, &mdl_index); + dict_sys.unfreeze(); + } + if (!index_stats) + goto release_and_exit; - dict_sys_lock(); - ret = dict_stats_save_index_stat(index, now, "n_page_split", - index->stat_defrag_n_page_split, - NULL, - "Number of new page splits on leaves" - " since last defragmentation.", - NULL); - if (ret != DB_SUCCESS) { - goto end; - } + if (strcmp(index_stats->name.m_name, INDEX_STATS_NAME)) + { + dict_table_close(index_stats, false, thd, mdl_index); + goto release_and_exit; + } - ret = dict_stats_save_index_stat( - index, now, "n_leaf_pages_defrag", - n_leaf_pages, - NULL, - "Number of leaf pages when this stat is saved to disk", - NULL); - if (ret != DB_SUCCESS) { - goto end; - } + trx_t *trx= trx_create(); + trx->mysql_thd= thd; + trx_start_internal(trx); + dberr_t ret= lock_table_for_trx(table_stats, trx, LOCK_X); + if (ret == DB_SUCCESS) + ret= lock_table_for_trx(index_stats, trx, LOCK_X); - ret = dict_stats_save_index_stat( - index, now, "n_leaf_pages_reserved", - n_leaf_reserved, - NULL, - "Number of pages reserved for this index leaves when this stat " - "is saved to disk", - NULL); + row_mysql_lock_data_dictionary(trx); -end: - dict_sys_unlock(); - return ret; + if (ret == DB_SUCCESS) + ret= dict_stats_save_index_stat(index, now, "n_page_split", + index->stat_defrag_n_page_split, nullptr, + "Number of new page splits on leaves" + " since last defragmentation.", trx); + + if (ret == DB_SUCCESS) + ret= dict_stats_save_index_stat(index, now, "n_leaf_pages_defrag", + n_leaf_pages, nullptr, + "Number of leaf pages when" + " this stat is saved to disk", trx); + + if (ret == DB_SUCCESS) + ret= dict_stats_save_index_stat(index, now, "n_leaf_pages_reserved", + n_leaf_reserved, nullptr, + "Number of pages reserved for" + " this index leaves" + " when this stat is saved to disk", trx); + + if (ret == DB_SUCCESS) + trx->commit(); + else + trx->rollback(); + + if (table_stats) + dict_table_close(table_stats, true, thd, mdl_table); + if (index_stats) + dict_table_close(index_stats, true, thd, mdl_index); + row_mysql_unlock_data_dictionary(trx); + trx->free(); + + return ret; } diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index 2ab5f9a07c9..447ff7929f0 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -86,7 +86,7 @@ const span dict_sys_t::SYS_TABLE[]= /** Diagnostic message for exceeding the mutex_lock_wait() timeout */ const char dict_sys_t::fatal_msg[]= - "innodb_fatal_semaphore_wait_threshold was exceeded for dict_sys.mutex. " + "innodb_fatal_semaphore_wait_threshold was exceeded for dict_sys.latch. " "Please refer to " "https://mariadb.com/kb/en/how-to-produce-a-full-stack-trace-for-mysqld/"; @@ -209,102 +209,34 @@ dict_remove_db_name( return(s + 1); } -/** Open a persistent table. -@param[in] table_id persistent table identifier -@param[in] ignore_err errors to ignore -@param[in] cached_only whether to skip loading -@return persistent table -@retval NULL if not found */ -static dict_table_t* dict_table_open_on_id_low( - table_id_t table_id, - dict_err_ignore_t ignore_err, - bool cached_only) +/** Decrement the count of open handles */ +void dict_table_close(dict_table_t *table) { - dict_table_t* table = dict_sys.find_table(table_id); - - if (!table && !cached_only) { - table = dict_load_table_on_id(table_id, ignore_err); - } - - return table; -} - -/**********************************************************************//** -Try to drop any indexes after an aborted index creation. -This can also be after a server kill during DROP INDEX. */ -static -void -dict_table_try_drop_aborted( -/*========================*/ - dict_table_t* table, /*!< in: table, or NULL if it - needs to be looked up again */ - table_id_t table_id, /*!< in: table identifier */ - uint32_t ref_count) /*!< in: expected table->n_ref_count */ -{ - trx_t* trx; - - trx = trx_create(); - trx->op_info = "try to drop any indexes after an aborted index creation"; - row_mysql_lock_data_dictionary(trx); - trx->dict_operation = true; - - if (table == NULL) { - table = dict_table_open_on_id_low( - table_id, DICT_ERR_IGNORE_FK_NOKEY, FALSE); - } else { - ut_ad(table->id == table_id); - } - - if (table && table->get_ref_count() == ref_count && table->drop_aborted - && !UT_LIST_GET_FIRST(table->locks)) { - /* Silence a debug assertion in row_merge_drop_indexes(). */ - ut_d(table->acquire()); - row_merge_drop_indexes(trx, table, true); - ut_d(table->release()); - ut_ad(table->get_ref_count() == ref_count); - trx_commit_for_mysql(trx); - } - - row_mysql_unlock_data_dictionary(trx); - trx->free(); -} - -/**********************************************************************//** -When opening a table, -try to drop any indexes after an aborted index creation. -Release the dict_sys.mutex. */ -static -void -dict_table_try_drop_aborted_and_mutex_exit( -/*=======================================*/ - dict_table_t* table, /*!< in: table (may be NULL) */ - ibool try_drop) /*!< in: FALSE if should try to - drop indexes whose online creation - was aborted */ -{ - if (try_drop - && table != NULL - && table->drop_aborted - && table->get_ref_count() == 1 - && dict_table_get_first_index(table)) { - - /* Attempt to drop the indexes whose online creation - was aborted. */ - table_id_t table_id = table->id; - - dict_sys.mutex_unlock(); - - dict_table_try_drop_aborted(table, table_id, 1); - } else { - dict_sys.mutex_unlock(); - } + if (table->get_ref_count() == 1 && + dict_stats_is_persistent_enabled(table) && + strchr(table->name.m_name, '/')) + { + /* It looks like we are closing the last handle. The user could + have executed FLUSH TABLES in order to have the statistics reloaded + from the InnoDB persistent statistics tables. We must acquire + exclusive dict_sys.latch to prevent a race condition with another + thread concurrently acquiring a handle on the table. */ + dict_sys.lock(SRW_LOCK_CALL); + if (table->release()) + { + table->stats_mutex_lock(); + dict_stats_deinit(table); + table->stats_mutex_unlock(); + } + dict_sys.unlock(); + } + else + table->release(); } /** Decrements the count of open handles of a table. @param[in,out] table table -@param[in] dict_locked data dictionary locked -@param[in] try_drop try to drop any orphan indexes after - an aborted online index creation +@param[in] dict_locked whether dict_sys.latch is being held @param[in] thd thread to release MDL @param[in] mdl metadata lock or NULL if the thread is a foreground one. */ @@ -312,56 +244,32 @@ void dict_table_close( dict_table_t* table, bool dict_locked, - bool try_drop, THD* thd, MDL_ticket* mdl) { - if (!dict_locked) { - dict_sys.mutex_lock(); - } + if (!dict_locked) + dict_table_close(table); + else + { + if (table->release() && dict_stats_is_persistent_enabled(table) && + strchr(table->name.m_name, '/')) + { + /* Force persistent stats re-read upon next open of the table so + that FLUSH TABLE can be used to forcibly fetch stats from disk if + they have been manually modified. */ + table->stats_mutex_lock(); + dict_stats_deinit(table); + table->stats_mutex_unlock(); + } - dict_sys.assert_locked(); - ut_a(table->get_ref_count() > 0); + ut_ad(dict_lru_validate()); + ut_ad(dict_sys.find(table)); + } - const bool last_handle = table->release(); - - /* Force persistent stats re-read upon next open of the table - so that FLUSH TABLE can be used to forcibly fetch stats from disk - if they have been manually modified. We reset table->stat_initialized - only if table reference count is 0 because we do not want too frequent - stats re-reads (e.g. in other cases than FLUSH TABLE). */ - if (last_handle && strchr(table->name.m_name, '/') != NULL - && dict_stats_is_persistent_enabled(table)) { - - table->stats_mutex_lock(); - dict_stats_deinit(table); - table->stats_mutex_unlock(); - } - - ut_ad(dict_lru_validate()); - ut_ad(dict_sys.find(table)); - - if (!dict_locked) { - table_id_t table_id = table->id; - const bool drop_aborted = last_handle && try_drop - && table->drop_aborted - && dict_table_get_first_index(table); - - dict_sys.mutex_unlock(); - - /* dict_table_try_drop_aborted() can generate undo logs. - So it should be avoided after shutdown of background - threads */ - if (drop_aborted && !srv_undo_sources) { - dict_table_try_drop_aborted(NULL, table_id, 0); - } - } - - if (!thd || !mdl) { - } else if (MDL_context *mdl_context= static_cast( - thd_mdl_context(thd))) { - mdl_context->release_lock(mdl); - } + if (!thd || !mdl); + else if (MDL_context *mdl_context= static_cast + (thd_mdl_context(thd))) + mdl_context->release_lock(mdl); } /** Check if the table has a given (non_virtual) column. @@ -691,7 +599,7 @@ dict_index_get_nth_field_pos( } /** Parse the table file name into table name and database name. -@tparam dict_locked whether dict_sys.mutex is being held +@tparam dict_locked whether dict_sys.lock() was called @param[in,out] db_name database name buffer @param[in,out] tbl_name table name buffer @param[out] db_name_len database name length @@ -706,8 +614,8 @@ bool dict_table_t::parse_name(char (&db_name)[NAME_LEN + 1], char tbl_buf[MAX_TABLE_NAME_LEN + 1]; if (!dict_locked) - dict_sys.mutex_lock(); /* protect against renaming */ - dict_sys.assert_locked(); + dict_sys.freeze(SRW_LOCK_CALL); /* protect against renaming */ + ut_ad(dict_sys.frozen()); const size_t db_len= name.dblen(); ut_ad(db_len <= MAX_DATABASE_NAME_LEN); @@ -726,7 +634,7 @@ bool dict_table_t::parse_name(char (&db_name)[NAME_LEN + 1], tbl_buf[tbl_len]= 0; if (!dict_locked) - dict_sys.mutex_unlock(); + dict_sys.unfreeze(); *db_name_len= filename_to_tablename(db_buf, db_name, MAX_DATABASE_NAME_LEN + 1, true); @@ -766,13 +674,14 @@ dict_acquire_mdl_shared(dict_table_t *table, if (trylock) { - dict_sys.mutex_lock(); + dict_sys.freeze(SRW_LOCK_CALL); db_len= dict_get_db_name_len(table->name.m_name); - dict_sys.mutex_unlock(); + dict_sys.unfreeze(); } else { - dict_sys.assert_locked(); + ut_ad(dict_sys.frozen()); + ut_ad(!dict_sys.locked()); db_len= dict_get_db_name_len(table->name.m_name); } @@ -795,7 +704,6 @@ dict_acquire_mdl_shared(dict_table_t *table, retry: if (!unaccessible && (!table->is_readable() || table->corrupted)) { -is_unaccessible: if (*mdl) { mdl_context->release_lock(*mdl); @@ -811,10 +719,12 @@ is_unaccessible: return nullptr; if (!trylock) - dict_sys.mutex_unlock(); + dict_sys.unfreeze(); + { MDL_request request; - MDL_REQUEST_INIT(&request,MDL_key::TABLE, db_buf, tbl_buf, MDL_SHARED, MDL_EXPLICIT); + MDL_REQUEST_INIT(&request,MDL_key::TABLE, db_buf, tbl_buf, MDL_SHARED, + MDL_EXPLICIT); if (trylock ? mdl_context->try_acquire_lock(&request) : mdl_context->acquire_lock(&request, @@ -828,19 +738,37 @@ is_unaccessible: return nullptr; } else + { *mdl= request.ticket; + if (trylock && !*mdl) + return nullptr; + } } - if (!trylock) - dict_sys.mutex_lock(); - else if (!*mdl) - return nullptr; - - table= dict_table_open_on_id(table_id, !trylock, table_op); - - if (!table) + dict_sys.freeze(SRW_LOCK_CALL); + table= dict_sys.find_table(table_id); + if (table) + table->acquire(); + if (!table && table_op != DICT_TABLE_OP_OPEN_ONLY_IF_CACHED) { - /* The table was dropped. */ + dict_sys.unfreeze(); + dict_sys.lock(SRW_LOCK_CALL); + table= dict_load_table_on_id(table_id, + table_op == DICT_TABLE_OP_LOAD_TABLESPACE + ? DICT_ERR_IGNORE_RECOVER_LOCK + : DICT_ERR_IGNORE_FK_NOKEY); + if (table) + table->acquire(); + dict_sys.unlock(); + dict_sys.freeze(SRW_LOCK_CALL); + } + + if (!table || !table->is_accessible()) + { + table= nullptr; +return_without_mdl: + if (trylock) + dict_sys.unfreeze(); if (*mdl) { mdl_context->release_lock(*mdl); @@ -849,21 +777,13 @@ is_unaccessible: return nullptr; } - if (!table->is_accessible()) - goto is_unaccessible; - size_t db1_len, tbl1_len; if (!table->parse_name(db_buf1, tbl_buf1, &db1_len, &tbl1_len)) { /* The table was renamed to #sql prefix. Release MDL (if any) for the old name and return. */ - if (*mdl) - { - mdl_context->release_lock(*mdl); - *mdl= nullptr; - } - return table; + goto return_without_mdl; } if (*mdl) @@ -871,7 +791,11 @@ is_unaccessible: if (db_len == db1_len && tbl_len == tbl1_len && !memcmp(db_buf, db_buf1, db_len) && !memcmp(tbl_buf, tbl_buf1, tbl_len)) + { + if (trylock) + dict_sys.unfreeze(); return table; + } /* The table was renamed. Release MDL for the old name and try to acquire MDL for the new name. */ @@ -887,8 +811,10 @@ is_unaccessible: goto retry; } -template dict_table_t* -dict_acquire_mdl_shared(dict_table_t*,THD*,MDL_ticket**,dict_table_op_t); +template dict_table_t* dict_acquire_mdl_shared +(dict_table_t*,THD*,MDL_ticket**,dict_table_op_t); +template dict_table_t* dict_acquire_mdl_shared +(dict_table_t*,THD*,MDL_ticket**,dict_table_op_t); /** Look up a table by numeric identifier. @param[in] table_id table identifier @@ -902,34 +828,47 @@ dict_table_open_on_id(table_id_t table_id, bool dict_locked, dict_table_op_t table_op, THD *thd, MDL_ticket **mdl) { - if (!dict_locked) { - dict_sys.mutex_lock(); - } + if (!dict_locked) + dict_sys.freeze(SRW_LOCK_CALL); - dict_sys.assert_locked(); + dict_table_t *table= dict_sys.find_table(table_id); - dict_table_t* table = dict_table_open_on_id_low( - table_id, - table_op == DICT_TABLE_OP_LOAD_TABLESPACE - ? DICT_ERR_IGNORE_RECOVER_LOCK - : DICT_ERR_IGNORE_FK_NOKEY, - table_op == DICT_TABLE_OP_OPEN_ONLY_IF_CACHED); + if (table) + { + table->acquire(); + if (thd && !dict_locked) + table= dict_acquire_mdl_shared(table, thd, mdl, table_op); + } + else if (table_op != DICT_TABLE_OP_OPEN_ONLY_IF_CACHED) + { + if (!dict_locked) + { + dict_sys.unfreeze(); + dict_sys.lock(SRW_LOCK_CALL); + } + table= dict_load_table_on_id(table_id, + table_op == DICT_TABLE_OP_LOAD_TABLESPACE + ? DICT_ERR_IGNORE_RECOVER_LOCK + : DICT_ERR_IGNORE_FK_NOKEY); + if (table) + table->acquire(); + if (!dict_locked) + { + dict_sys.unlock(); + if (table && thd) + { + dict_sys.freeze(SRW_LOCK_CALL); + table= dict_acquire_mdl_shared(table, thd, mdl, table_op); + dict_sys.unfreeze(); + } + return table; + } + } - if (table) { - dict_sys.acquire(table); - } + if (!dict_locked) + dict_sys.unfreeze(); - if (!dict_locked) { - if (thd) { - table = dict_acquire_mdl_shared( - table, thd, mdl, table_op); - } - - dict_table_try_drop_aborted_and_mutex_exit( - table, table_op == DICT_TABLE_OP_DROP_ORPHAN); - } - - return table; + return table; } /********************************************************************//** @@ -991,8 +930,6 @@ void dict_sys_t::create() UT_LIST_INIT(table_LRU, &dict_table_t::table_LRU); UT_LIST_INIT(table_non_LRU, &dict_table_t::table_LRU); - mysql_mutex_init(dict_sys_mutex_key, &mutex, nullptr); - const ulint hash_size = buf_pool_get_curr_size() / (DICT_POOL_PER_TABLE_HASH * UNIV_WORD_SIZE); @@ -1013,27 +950,17 @@ void dict_sys_t::create() } -/** Acquire a reference to a cached table. */ -inline void dict_sys_t::acquire(dict_table_t *table) -{ - ut_ad(dict_sys.find(table)); - if (table->can_be_evicted) - { - UT_LIST_REMOVE(table_LRU, table); - UT_LIST_ADD_FIRST(table_LRU, table); - } - - table->acquire(); -} - -void dict_sys_t::mutex_lock_wait() +void dict_sys_t::lock_wait(SRW_LOCK_ARGS(const char *file, unsigned line)) { ulonglong now= my_hrtime_coarse().val, old= 0; - if (mutex_wait_start.compare_exchange_strong + if (latch_ex_wait_start.compare_exchange_strong (old, now, std::memory_order_relaxed, std::memory_order_relaxed)) { - mysql_mutex_lock(&mutex); - mutex_wait_start.store(0, std::memory_order_relaxed); + latch.wr_lock(SRW_LOCK_ARGS(file, line)); + latch_ex_wait_start.store(0, std::memory_order_relaxed); + ut_ad(!latch_readers); + ut_ad(!latch_ex); + ut_d(latch_ex= true); return; } @@ -1047,103 +974,105 @@ void dict_sys_t::mutex_lock_wait() if (waited > threshold / 4) ib::warn() << "A long wait (" << waited - << " seconds) was observed for dict_sys.mutex"; - mysql_mutex_lock(&mutex); -} - -#ifdef HAVE_PSI_MUTEX_INTERFACE -/** Acquire the mutex */ -void dict_sys_t::mutex_lock() -{ - if (mysql_mutex_trylock(&mutex)) - mutex_lock_wait(); -} - -/** Release the mutex */ -void dict_sys_t::mutex_unlock() { mysql_mutex_unlock(&mutex); } -#endif - -/** Lock the data dictionary cache. */ -void dict_sys_t::lock(SRW_LOCK_ARGS(const char *file, unsigned line)) -{ - ut_ad(this == &dict_sys); - ut_ad(is_initialised()); + << " seconds) was observed for dict_sys.latch"; latch.wr_lock(SRW_LOCK_ARGS(file, line)); + ut_ad(!latch_readers); ut_ad(!latch_ex); ut_d(latch_ex= true); - mutex_lock(); } +#ifdef UNIV_PFS_RWLOCK +ATTRIBUTE_NOINLINE void dict_sys_t::unlock() +{ + ut_ad(latch_ex); + ut_ad(!latch_readers); + ut_d(latch_ex= false); + latch.wr_unlock(); +} + +ATTRIBUTE_NOINLINE void dict_sys_t::freeze(const char *file, unsigned line) +{ + latch.rd_lock(file, line); + ut_ad(!latch_ex); + ut_d(latch_readers++); +} + +ATTRIBUTE_NOINLINE void dict_sys_t::unfreeze() +{ + ut_ad(!latch_ex); + ut_ad(latch_readers--); + latch.rd_unlock(); +} +#endif /* UNIV_PFS_RWLOCK */ + /**********************************************************************//** -Returns a table object and increment its open handle count. +Returns a table object and increments its open handle count. NOTE! This is a high-level function to be used mainly from outside the -'dict' module. Inside this directory dict_table_get_low +'dict' directory. Inside this directory dict_table_get_low is usually the appropriate function. -@return table, NULL if does not exist */ +@param[in] table_name Table name +@param[in] dict_locked whether dict_sys.latch is being held exclusively +@param[in] ignore_err error to be ignored when loading the table +@return table +@retval nullptr if does not exist */ dict_table_t* dict_table_open_on_name( -/*====================*/ - const char* table_name, /*!< in: table name */ - ibool dict_locked, /*!< in: TRUE=data dictionary locked */ - ibool try_drop, /*!< in: TRUE=try to drop any orphan - indexes after an aborted online - index creation */ - dict_err_ignore_t - ignore_err) /*!< in: error to be ignored when - loading a table definition */ + const char* table_name, + bool dict_locked, + dict_err_ignore_t ignore_err) { - dict_table_t* table; - DBUG_ENTER("dict_table_open_on_name"); - DBUG_PRINT("dict_table_open_on_name", ("table: '%s'", table_name)); + dict_table_t *table; + DBUG_ENTER("dict_table_open_on_name"); + DBUG_PRINT("dict_table_open_on_name", ("table: '%s'", table_name)); - if (!dict_locked) { - dict_sys.mutex_lock(); - } + const span name{table_name, strlen(table_name)}; - ut_ad(table_name); - table = dict_sys.load_table({table_name, strlen(table_name)}, - ignore_err); + if (!dict_locked) + { + dict_sys.freeze(SRW_LOCK_CALL); + table= dict_sys.find_table(name); + if (table) + { + ut_ad(table->cached); + if (!(ignore_err & ~DICT_ERR_IGNORE_FK_NOKEY) && + !table->is_readable() && table->corrupted) + { + ib::error() << "Table " << table->name + << " is corrupted. Please drop the table and recreate."; + dict_sys.unfreeze(); + DBUG_RETURN(nullptr); + } + table->acquire(); + dict_sys.unfreeze(); + DBUG_RETURN(table); + } + dict_sys.unfreeze(); + dict_sys.lock(SRW_LOCK_CALL); + } - if (table) { - ut_ad(table->cached); + table= dict_sys.load_table(name, ignore_err); - /* If table is encrypted or corrupted */ - if (!(ignore_err & ~DICT_ERR_IGNORE_FK_NOKEY) - && !table->is_readable()) { - /* Make life easy for drop table. */ - dict_sys.prevent_eviction(table); + if (table) + { + ut_ad(table->cached); + if (!(ignore_err & ~DICT_ERR_IGNORE_FK_NOKEY) && + !table->is_readable() && table->corrupted) + { + ib::error() << "Table " << table->name + << " is corrupted. Please drop the table and recreate."; + if (!dict_locked) + dict_sys.unlock(); + DBUG_RETURN(nullptr); + } - if (table->corrupted) { + table->acquire(); + } - ib::error() << "Table " << table->name - << " is corrupted. Please " - "drop the table and recreate."; - if (!dict_locked) { - dict_sys.mutex_unlock(); - } + ut_ad(dict_lru_validate()); + if (!dict_locked) + dict_sys.unlock(); - DBUG_RETURN(NULL); - } - - dict_sys.acquire(table); - - if (!dict_locked) { - dict_sys.mutex_unlock(); - } - - DBUG_RETURN(table); - } - - dict_sys.acquire(table); - } - - ut_ad(dict_lru_validate()); - - if (!dict_locked) { - dict_table_try_drop_aborted_and_mutex_exit(table, try_drop); - } - - DBUG_RETURN(table); + DBUG_RETURN(table); } /**********************************************************************//** @@ -1252,7 +1181,7 @@ inline void dict_sys_t::add(dict_table_t* table) @return whether the table can be evicted */ static bool dict_table_can_be_evicted(dict_table_t *table) { - ut_d(dict_sys.assert_locked()); + ut_ad(dict_sys.locked()); ut_a(table->can_be_evicted); ut_a(table->foreign_set.empty()); ut_a(table->referenced_set.empty()); @@ -1423,8 +1352,8 @@ dict_table_find_index_on_id( } /**********************************************************************//** -Looks for an index with the given id. NOTE that we do not reserve -the dictionary mutex: this function is for emergency purposes like +Looks for an index with the given id. NOTE that we do not acquire +dict_sys.latch: this function is for emergency purposes like printing info of a corrupt database page! @return index or NULL if not found in cache */ dict_index_t* @@ -1540,7 +1469,7 @@ dict_table_rename_in_cache( ulint fold; char old_name[MAX_FULL_NAME_LEN + 1]; - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); /* store the old/current name to an automatic variable */ const size_t old_name_len = strlen(table->name.m_name); @@ -1864,7 +1793,7 @@ dict_table_change_id_in_cache( dict_table_t* table, /*!< in/out: table object already in cache */ table_id_t new_id) /*!< in: new id to set */ { - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); ut_ad(!table->is_temporary()); @@ -1937,23 +1866,6 @@ void dict_sys_t::remove(dict_table_t* table, bool lru, bool keep) UT_LIST_REMOVE(table_non_LRU, table); } - if (lru && table->drop_aborted) { - /* When evicting the table definition, - drop the orphan indexes from the data dictionary - and free the index pages. */ - trx_t* trx = trx_create(); - - ut_d(dict_sys.assert_locked()); - /* Mimic row_mysql_lock_data_dictionary(). */ - trx->dict_operation_lock_mode = RW_X_LATCH; - - trx->dict_operation = true; - row_merge_drop_indexes_dict(trx, table->id); - trx_commit_for_mysql(trx); - trx->dict_operation_lock_mode = 0; - trx->free(); - } - /* Free virtual column template if any */ if (table->vc_templ != NULL) { dict_free_vc_templ(table->vc_templ); @@ -2033,7 +1945,7 @@ dict_index_add_to_cache( ulint n_ord; ulint i; - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); ut_ad(index->n_def == index->n_fields); ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); ut_ad(!dict_index_is_online_ddl(index)); @@ -2161,7 +2073,7 @@ dict_index_remove_from_cache_low( ut_ad(table && index); ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); ut_ad(table->id); #ifdef BTR_CUR_HASH_ADAPT ut_ad(!index->freed()); @@ -2243,7 +2155,7 @@ dict_index_find_cols( const dict_table_t* table = index->table; ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); for (ulint i = 0; i < index->n_fields; i++) { ulint j; @@ -2512,7 +2424,7 @@ dict_index_build_internal_clust( ut_ad(index->is_primary()); ut_ad(!index->has_virtual()); - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); /* Create a new index object with certainly enough fields */ new_index = dict_mem_index_create(index->table, index->name, @@ -2667,7 +2579,7 @@ dict_index_build_internal_non_clust( ut_ad(table && index); ut_ad(!dict_index_is_clust(index)); ut_ad(!dict_index_is_ibuf(index)); - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); /* The clustered index should be the first in the list of indexes */ clust_index = UT_LIST_GET_FIRST(table->indexes); @@ -2761,7 +2673,7 @@ dict_index_build_internal_fts( dict_index_t* new_index; ut_ad(index->type == DICT_FTS); - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); /* Create a new index */ new_index = dict_mem_index_create(index->table, index->name, @@ -2813,7 +2725,7 @@ dict_foreign_remove_from_cache( /*===========================*/ dict_foreign_t* foreign) /*!< in, own: foreign constraint */ { - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); ut_a(foreign); if (foreign->referenced_table != NULL) { @@ -2838,7 +2750,7 @@ dict_foreign_find( dict_table_t* table, /*!< in: table object */ dict_foreign_t* foreign) /*!< in: foreign constraint */ { - dict_sys.assert_locked(); + ut_ad(dict_sys.frozen()); ut_ad(dict_foreign_set_validate(table->foreign_set)); ut_ad(dict_foreign_set_validate(table->referenced_set)); @@ -2892,7 +2804,7 @@ dict_foreign_find_index( /*!< out: index where error happened */ { - dict_sys.assert_locked(); + ut_ad(dict_sys.frozen()); if (error) { *error = FK_INDEX_NOT_FOUND; @@ -2990,7 +2902,7 @@ dict_foreign_add_to_cache( DBUG_ENTER("dict_foreign_add_to_cache"); DBUG_PRINT("dict_foreign_add_to_cache", ("id: %s", foreign->id)); - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); for_table = dict_sys.find_table( {foreign->foreign_table_name_lookup, @@ -3637,7 +3549,7 @@ dict_foreign_parse_drop_constraints( ptr = str; - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); loop: ptr = dict_scan_to(ptr, "DROP"); @@ -3739,14 +3651,14 @@ syntax_error: /**********************************************************************//** Returns an index object if it is found in the dictionary cache. -Assumes that dict_sys.mutex is already being held. +Assumes that dict_sys.latch is already being held. @return index, NULL if not found */ dict_index_t* dict_index_get_if_in_cache_low( /*===========================*/ index_id_t index_id) /*!< in: index id */ { - dict_sys.assert_locked(); + ut_ad(dict_sys.frozen()); return(dict_index_find_on_id_low(index_id)); } @@ -3766,11 +3678,11 @@ dict_index_get_if_in_cache( return(NULL); } - dict_sys.mutex_lock(); + dict_sys.freeze(SRW_LOCK_CALL); index = dict_index_get_if_in_cache_low(index_id); - dict_sys.mutex_unlock(); + dict_sys.unfreeze(); return(index); } @@ -4056,7 +3968,7 @@ dict_print_info_on_foreign_keys( dict_foreign_t* foreign; std::string str; - dict_sys.mutex_lock(); + dict_sys.freeze(SRW_LOCK_CALL); for (dict_foreign_set::iterator it = table->foreign_set.begin(); it != table->foreign_set.end(); @@ -4123,7 +4035,7 @@ dict_print_info_on_foreign_keys( } } - dict_sys.mutex_unlock(); + dict_sys.unfreeze(); return str; } @@ -4200,12 +4112,7 @@ void dict_set_encrypted_by_space(const fil_space_t* space) /**********************************************************************//** Flags an index corrupted both in the data dictionary cache and in the SYS_INDEXES */ -void -dict_set_corrupted( -/*===============*/ - dict_index_t* index, /*!< in/out: index */ - trx_t* trx, /*!< in/out: transaction */ - const char* ctx) /*!< in: context */ +void dict_set_corrupted(dict_index_t *index, const char *ctx, bool dict_locked) { mem_heap_t* heap; mtr_t mtr; @@ -4215,13 +4122,12 @@ dict_set_corrupted( byte* buf; const char* status; btr_cur_t cursor; - bool locked = RW_X_LATCH == trx->dict_operation_lock_mode; - if (!locked) { - row_mysql_lock_data_dictionary(trx); + if (!dict_locked) { + dict_sys.lock(SRW_LOCK_CALL); } - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); ut_ad(!dict_table_is_comp(dict_sys.sys_tables)); ut_ad(!dict_table_is_comp(dict_sys.sys_indexes)); @@ -4288,14 +4194,13 @@ fail: } mtr_commit(&mtr); - mem_heap_empty(heap); + mem_heap_free(heap); ib::error() << status << " corruption of " << index->name << " in table " << index->table->name << " in " << ctx; - mem_heap_free(heap); func_exit: - if (!locked) { - row_mysql_unlock_data_dictionary(trx); + if (!dict_locked) { + dict_sys.unlock(); } } @@ -4309,7 +4214,7 @@ dict_set_corrupted_index_cache_only( { ut_ad(index != NULL); ut_ad(index->table != NULL); - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); ut_ad(!dict_table_is_comp(dict_sys.sys_tables)); ut_ad(!dict_table_is_comp(dict_sys.sys_indexes)); @@ -4343,13 +4248,13 @@ dict_index_set_merge_threshold( ut_ad(!dict_table_is_comp(dict_sys.sys_tables)); ut_ad(!dict_table_is_comp(dict_sys.sys_indexes)); - dict_sys_lock(); - heap = mem_heap_create(sizeof(dtuple_t) + 2 * (sizeof(dfield_t) + sizeof(que_fork_t) + sizeof(upd_node_t) + sizeof(upd_t) + 12)); - mtr_start(&mtr); + mtr.start(); + + dict_sys.lock(SRW_LOCK_CALL); sys_index = UT_LIST_GET_FIRST(dict_sys.sys_indexes->indexes); @@ -4387,7 +4292,7 @@ dict_index_set_merge_threshold( mtr_commit(&mtr); mem_heap_free(heap); - dict_sys_unlock(); + dict_sys.unlock(); } #ifdef UNIV_DEBUG @@ -4419,14 +4324,14 @@ void dict_set_merge_threshold_all_debug( uint merge_threshold_all) { - dict_sys.mutex_lock(); + dict_sys.freeze(SRW_LOCK_CALL); dict_set_merge_threshold_list_debug( &dict_sys.table_LRU, merge_threshold_all); dict_set_merge_threshold_list_debug( &dict_sys.table_non_LRU, merge_threshold_all); - dict_sys.mutex_unlock(); + dict_sys.unfreeze(); } #endif /* UNIV_DEBUG */ @@ -4544,7 +4449,7 @@ dict_table_check_for_dup_indexes( const dict_index_t* index1; const dict_index_t* index2; - dict_sys.assert_locked(); + ut_ad(dict_sys.frozen()); /* The primary index _must_ exist */ ut_a(UT_LIST_GET_LEN(table->indexes) > 0); @@ -4656,7 +4561,7 @@ void dict_sys_t::resize() { ut_ad(this == &dict_sys); ut_ad(is_initialised()); - mutex_lock(); + lock(SRW_LOCK_CALL); /* all table entries are in table_LRU and table_non_LRU lists */ table_hash.free(); @@ -4694,7 +4599,7 @@ void dict_sys_t::resize() HASH_INSERT(dict_table_t, id_hash, id_hash, id_fold, table); } - mutex_unlock(); + unlock(); } /** Close the data dictionary cache on shutdown. */ @@ -4703,10 +4608,10 @@ void dict_sys_t::close() ut_ad(this == &dict_sys); if (!is_initialised()) return; - mutex_lock(); + lock(SRW_LOCK_CALL); - /* Free the hash elements. We don't remove them from the table - because we are going to destroy the table anyway. */ + /* Free the hash elements. We don't remove them from table_hash + because we are invoking table_hash.free() below. */ for (ulint i= table_hash.n_cells; i--; ) while (dict_table_t *table= static_cast (HASH_GET_FIRST(&table_hash, i))) @@ -4721,8 +4626,7 @@ void dict_sys_t::close() /* No temporary tables should exist at this point. */ temp_id_hash.free(); - mutex_unlock(); - mysql_mutex_destroy(&mutex); + unlock(); latch.destroy(); mysql_mutex_destroy(&dict_foreign_err_mutex); @@ -4747,7 +4651,7 @@ dict_lru_validate(void) { dict_table_t* table; - dict_sys.assert_locked(); + ut_ad(dict_sys.frozen()); for (table = UT_LIST_GET_FIRST(dict_sys.table_LRU); table != NULL; diff --git a/storage/innobase/dict/dict0load.cc b/storage/innobase/dict/dict0load.cc index a4a5633adff..f8a2f98067c 100644 --- a/storage/innobase/dict/dict0load.cc +++ b/storage/innobase/dict/dict0load.cc @@ -509,7 +509,7 @@ dict_sys_tables_rec_check( const byte* field; ulint len; - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); if (rec_get_deleted_flag(rec, 0)) { return("delete-marked record in SYS_TABLES"); @@ -826,7 +826,7 @@ static uint32_t dict_check_sys_tables() DBUG_ENTER("dict_check_sys_tables"); - ut_d(dict_sys.assert_locked()); + ut_ad(dict_sys.locked()); mtr_start(&mtr); @@ -932,7 +932,7 @@ void dict_check_tablespaces_and_store_max_id() DBUG_ENTER("dict_check_tablespaces_and_store_max_id"); - dict_sys_lock(); + dict_sys.lock(SRW_LOCK_CALL); /* Initialize the max space_id from sys header */ mtr.start(); @@ -947,7 +947,7 @@ void dict_check_tablespaces_and_store_max_id() max_space_id = dict_check_sys_tables(); fil_set_max_space_id_if_bigger(max_space_id); - dict_sys_unlock(); + dict_sys.unlock(); DBUG_VOID_RETURN; } @@ -1235,7 +1235,7 @@ dict_load_columns( mtr_t mtr; ulint n_skipped = 0; - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); mtr_start(&mtr); @@ -1349,7 +1349,7 @@ dict_load_virtual_one_col( mtr_t mtr; ulint skipped = 0; - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); if (v_col->num_base == 0) { return; @@ -1579,7 +1579,7 @@ dict_load_fields( mtr_t mtr; dberr_t error; - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); mtr_start(&mtr); @@ -1809,7 +1809,7 @@ dict_load_indexes( mtr_t mtr; dberr_t error = DB_SUCCESS; - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); mtr_start(&mtr); @@ -2116,7 +2116,7 @@ dict_save_data_dir_path( dict_table_t* table, /*!< in/out: table */ const char* filepath) /*!< in: filepath of tablespace */ { - dict_sys.assert_locked(); + ut_ad(dict_sys.frozen()); ut_a(DICT_TF_HAS_DATA_DIR(table->flags)); ut_a(!table->data_dir_path); @@ -2139,20 +2139,17 @@ dict_save_data_dir_path( } } -/** Make sure the data_dir_path is saved in dict_table_t if needed. -@param[in] table Table object -@param[in] dict_mutex_own true if dict_sys.mutex is owned already */ -void -dict_get_and_save_data_dir_path( - dict_table_t* table, - bool dict_mutex_own) +/** Make sure the data_file_name is saved in dict_table_t if needed. +@param[in,out] table Table object +@param[in] dict_locked dict_sys.frozen() */ +void dict_get_and_save_data_dir_path(dict_table_t* table, bool dict_locked) { ut_ad(!table->is_temporary()); ut_ad(!table->space || table->space->id == table->space_id); if (!table->data_dir_path && table->space_id && table->space) { - if (!dict_mutex_own) { - dict_sys.mutex_lock(); + if (!dict_locked) { + dict_sys.freeze(SRW_LOCK_CALL); } table->flags |= 1 << DICT_TF_POS_DATA_DIR @@ -2170,8 +2167,8 @@ dict_get_and_save_data_dir_path( & ((1U << DICT_TF_BITS) - 1); } - if (!dict_mutex_own) { - dict_sys.mutex_unlock(); + if (!dict_locked) { + dict_sys.unfreeze(); } } } @@ -2282,7 +2279,7 @@ static dict_table_t *dict_load_table_one(const span &name, DBUG_PRINT("dict_load_table_one", ("table: %.*s", name.size(), name.data())); - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); heap = mem_heap_create(32000); @@ -2538,10 +2535,10 @@ dict_load_table_on_id( ulint len; mtr_t mtr; - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); /* NOTE that the operation of this function is protected by - the dictionary mutex, and therefore no deadlocks can occur + dict_sys.latch, and therefore no deadlocks can occur with other dictionary operations. */ mtr.start(); @@ -2621,7 +2618,7 @@ dict_load_sys_table( { mem_heap_t* heap; - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); heap = mem_heap_create(1000); @@ -2656,7 +2653,7 @@ dict_load_foreign_cols( mtr_t mtr; size_t id_len; - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); id_len = strlen(foreign->id); @@ -2798,7 +2795,7 @@ dict_load_foreign( DBUG_PRINT("dict_load_foreign", ("id: '%s', check_recursive: %d", id, check_recursive)); - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); id_len = strlen(id); @@ -2971,7 +2968,7 @@ dict_load_foreigns( DBUG_ENTER("dict_load_foreigns"); - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); if (!dict_sys.sys_foreign || !dict_sys.sys_foreign_cols) { if (ignore_err & DICT_ERR_IGNORE_FK_NOKEY) { diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc index eb2f06ab31e..d7466ae5f8a 100644 --- a/storage/innobase/dict/dict0stats.cc +++ b/storage/innobase/dict/dict0stats.cc @@ -25,11 +25,10 @@ Created Jan 06, 2010 Vasil Dimov *******************************************************/ #include "dict0stats.h" -#include "ut0ut.h" -#include "ut0rnd.h" #include "dyn0buf.h" #include "row0sel.h" #include "trx0trx.h" +#include "lock0lock.h" #include "pars0pars.h" #include #include "log.h" @@ -142,7 +141,7 @@ typedef ut_allocator > typedef std::map index_map_t; -inline bool dict_table_t::is_stats_table() const +bool dict_table_t::is_stats_table() const { return !strcmp(name.m_name, TABLE_STATS_NAME) || !strcmp(name.m_name, INDEX_STATS_NAME); @@ -326,7 +325,6 @@ static bool innodb_index_stats_not_found_reported; Checks whether a table exists and whether it has the given structure. The table must have the same number of columns with the same names and types. The order of the columns does not matter. -The caller must own the dictionary mutex. dict_table_schema_check() @{ @return DB_SUCCESS if the table exists and contains the necessary columns */ static @@ -478,21 +476,16 @@ dict_table_schema_check( Checks whether the persistent statistics storage exists and that all tables have the proper structure. @return true if exists and all tables are ok */ -static -bool -dict_stats_persistent_storage_check( -/*================================*/ - bool caller_has_dict_sys_mutex) /*!< in: true if the caller - owns dict_sys.mutex */ +static bool dict_stats_persistent_storage_check(bool dict_already_locked) { char errstr[512]; dberr_t ret; - if (!caller_has_dict_sys_mutex) { - dict_sys.mutex_lock(); + if (!dict_already_locked) { + dict_sys.lock(SRW_LOCK_CALL); } - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); /* first check table_stats */ ret = dict_table_schema_check(&table_stats_schema, errstr, @@ -503,8 +496,8 @@ dict_stats_persistent_storage_check( sizeof(errstr)); } - if (!caller_has_dict_sys_mutex) { - dict_sys.mutex_unlock(); + if (!dict_already_locked) { + dict_sys.unlock(); } if (ret != DB_SUCCESS && ret != DB_STATS_DO_NOT_EXIST) { @@ -523,14 +516,12 @@ This function will free the pinfo object. @param[in,out] pinfo pinfo to pass to que_eval_sql() must already have any literals bound to it @param[in] sql SQL string to execute -@param[in,out] trx in case of NULL the function will allocate and -free the trx object. If it is not NULL then it will be rolled back -only in the case of error, but not freed. +@param[in,out] trx transaction @return DB_SUCCESS or error code */ static dberr_t dict_stats_exec_sql(pars_info_t *pinfo, const char* sql, trx_t *trx) { - ut_d(dict_sys.assert_locked()); + ut_ad(dict_sys.locked()); if (!dict_stats_persistent_storage_check(true)) { @@ -538,22 +529,7 @@ dberr_t dict_stats_exec_sql(pars_info_t *pinfo, const char* sql, trx_t *trx) return DB_STATS_DO_NOT_EXIST; } - if (trx) - return que_eval_sql(pinfo, sql, FALSE, trx); - - trx= trx_create(); - trx_start_internal(trx); - - trx->dict_operation_lock_mode= RW_X_LATCH; - dberr_t err= que_eval_sql(pinfo, sql, FALSE, trx); - - if (err == DB_SUCCESS) - trx->commit(); - else - trx->rollback(); - trx->dict_operation_lock_mode= 0; - trx->free(); - return err; + return que_eval_sql(pinfo, sql, trx); } /*********************************************************************//** @@ -863,9 +839,6 @@ dict_stats_assert_initialized( MEM_CHECK_DEFINED(&table->stat_modified_counter, sizeof table->stat_modified_counter); - MEM_CHECK_DEFINED(&table->stats_bg_flag, - sizeof table->stats_bg_flag); - for (dict_index_t* index = dict_table_get_first_index(table); index != NULL; index = dict_table_get_next_index(index)) { @@ -1014,7 +987,7 @@ dict_table_t* dict_stats_snapshot_create( dict_table_t* table) { - dict_sys.mutex_lock(); + dict_sys.lock(SRW_LOCK_CALL); dict_stats_assert_initialized(table); @@ -1033,9 +1006,8 @@ dict_stats_snapshot_create( t->stat_persistent = table->stat_persistent; t->stats_auto_recalc = table->stats_auto_recalc; t->stats_sample_pages = table->stats_sample_pages; - t->stats_bg_flag = table->stats_bg_flag; - dict_sys.mutex_unlock(); + dict_sys.unlock(); return(t); } @@ -1074,14 +1046,13 @@ dict_stats_update_transient_for_index( Initialize some bogus index cardinality statistics, so that the data can be queried in various means, also via secondary indexes. */ +dummy_empty: index->table->stats_mutex_lock(); dict_stats_empty_index(index, false); index->table->stats_mutex_unlock(); #if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG } else if (ibuf_debug && !dict_index_is_clust(index)) { - index->table->stats_mutex_lock(); - dict_stats_empty_index(index, false); - index->table->stats_mutex_unlock(); + goto dummy_empty; #endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ } else { mtr_t mtr; @@ -1102,10 +1073,7 @@ dict_stats_update_transient_for_index( switch (size) { case ULINT_UNDEFINED: - index->table->stats_mutex_lock(); - dict_stats_empty_index(index, false); - index->table->stats_mutex_unlock(); - return; + goto dummy_empty; case 0: /* The root node of the tree is a leaf */ size = 1; @@ -2524,21 +2492,20 @@ dict_stats_update_persistent( continue; } - if (!(table->stats_bg_flag & BG_STAT_SHOULD_QUIT)) { - table->stats_mutex_unlock(); - stats = dict_stats_analyze_index(index); - table->stats_mutex_lock(); + table->stats_mutex_unlock(); + stats = dict_stats_analyze_index(index); + table->stats_mutex_lock(); - index->stat_index_size = stats.index_size; - index->stat_n_leaf_pages = stats.n_leaf_pages; - for (size_t i = 0; i < stats.stats.size(); ++i) { - index->stat_n_diff_key_vals[i] - = stats.stats[i].n_diff_key_vals; - index->stat_n_sample_sizes[i] - = stats.stats[i].n_sample_sizes; - index->stat_n_non_null_key_vals[i] - = stats.stats[i].n_non_null_key_vals; - } + index->stat_index_size = stats.index_size; + index->stat_n_leaf_pages = stats.n_leaf_pages; + + for (size_t i = 0; i < stats.stats.size(); ++i) { + index->stat_n_diff_key_vals[i] + = stats.stats[i].n_diff_key_vals; + index->stat_n_sample_sizes[i] + = stats.stats[i].n_sample_sizes; + index->stat_n_non_null_key_vals[i] + = stats.stats[i].n_non_null_key_vals; } table->stat_sum_of_other_index_sizes @@ -2567,9 +2534,7 @@ storage. @param[in] stat_value value of the stat @param[in] sample_size n pages sampled or NULL @param[in] stat_description description of the stat -@param[in,out] trx in case of NULL the function will -allocate and free the trx object. If it is not NULL then it will be -rolled back only in the case of error, but not freed. +@param[in,out] trx transaction @return DB_SUCCESS or error code */ dberr_t dict_stats_save_index_stat( @@ -2586,7 +2551,7 @@ dict_stats_save_index_stat( char db_utf8[MAX_DB_UTF8_LEN]; char table_utf8[MAX_TABLE_UTF8_LEN]; - ut_d(dict_sys.assert_locked()); + ut_ad(dict_sys.locked()); dict_fs2utf8(index->table->name.m_name, db_utf8, sizeof(db_utf8), table_utf8, sizeof(table_utf8)); @@ -2700,8 +2665,6 @@ dict_stats_save( const index_id_t* only_for_index) { pars_info_t* pinfo; - dberr_t ret; - dict_table_t* table; char db_utf8[MAX_DB_UTF8_LEN]; char table_utf8[MAX_TABLE_UTF8_LEN]; @@ -2713,16 +2676,59 @@ dict_stats_save( return (dict_stats_report_error(table_orig)); } - table = dict_stats_snapshot_create(table_orig); + THD* thd = current_thd; + MDL_ticket *mdl_table = nullptr, *mdl_index = nullptr; + dict_table_t* table_stats = dict_table_open_on_name( + TABLE_STATS_NAME, false, DICT_ERR_IGNORE_NONE); + if (table_stats) { + dict_sys.freeze(SRW_LOCK_CALL); + table_stats = dict_acquire_mdl_shared(table_stats, thd, + &mdl_table); + dict_sys.unfreeze(); + } + if (!table_stats + || strcmp(table_stats->name.m_name, TABLE_STATS_NAME)) { +release_and_exit: + if (table_stats) { + dict_table_close(table_stats, false, thd, mdl_table); + } + return DB_STATS_DO_NOT_EXIST; + } + + dict_table_t* index_stats = dict_table_open_on_name( + INDEX_STATS_NAME, false, DICT_ERR_IGNORE_NONE); + if (index_stats) { + dict_sys.freeze(SRW_LOCK_CALL); + index_stats = dict_acquire_mdl_shared(index_stats, thd, + &mdl_index); + dict_sys.unfreeze(); + } + if (!index_stats) { + goto release_and_exit; + } + if (strcmp(index_stats->name.m_name, INDEX_STATS_NAME)) { + dict_table_close(index_stats, false, thd, mdl_index); + goto release_and_exit; + } + + dict_table_t* table = dict_stats_snapshot_create(table_orig); dict_fs2utf8(table->name.m_name, db_utf8, sizeof(db_utf8), table_utf8, sizeof(table_utf8)); - const time_t now = time(NULL); trx_t* trx = trx_create(); + trx->mysql_thd = thd; trx_start_internal(trx); - trx->dict_operation_lock_mode = RW_X_LATCH; - dict_sys_lock(); + dberr_t ret = trx->read_only + ? DB_READ_ONLY + : lock_table_for_trx(table_stats, trx, LOCK_X); + if (ret == DB_SUCCESS) { + ret = lock_table_for_trx(index_stats, trx, LOCK_X); + } + if (ret != DB_SUCCESS) { + trx->commit(); + goto unlocked_free_and_exit; + } pinfo = pars_info_create(); @@ -2735,6 +2741,9 @@ dict_stats_save( pars_info_add_ull_literal(pinfo, "sum_of_other_index_sizes", table->stat_sum_of_other_index_sizes); + dict_sys.lock(SRW_LOCK_CALL); + trx->dict_operation_lock_mode = true; + ret = dict_stats_exec_sql( pinfo, "PROCEDURE TABLE_STATS_SAVE () IS\n" @@ -2763,10 +2772,13 @@ dict_stats_save( rollback_and_exit: trx->rollback(); free_and_exit: - trx->dict_operation_lock_mode = 0; - dict_sys_unlock(); + trx->dict_operation_lock_mode = false; + dict_sys.unlock(); +unlocked_free_and_exit: trx->free(); dict_stats_snapshot_free(table); + dict_table_close(table_stats, false, thd, mdl_table); + dict_table_close(index_stats, false, thd, mdl_index); return ret; } @@ -3237,13 +3249,7 @@ dict_stats_fetch_from_ps( trx = trx_create(); - /* Use 'read-uncommitted' so that the SELECTs we execute - do not get blocked in case some user has locked the rows we - are SELECTing */ - - trx->isolation_level = TRX_ISO_READ_UNCOMMITTED; - - trx_start_internal(trx); + trx_start_internal_read_only(trx); dict_fs2utf8(table->name.m_name, db_utf8, sizeof(db_utf8), table_utf8, sizeof(table_utf8)); @@ -3265,7 +3271,7 @@ dict_stats_fetch_from_ps( "fetch_index_stats_step", dict_stats_fetch_index_stats_step, &index_fetch_arg); - + dict_sys.lock(SRW_LOCK_CALL); /* FIXME: remove this */ ret = que_eval_sql(pinfo, "PROCEDURE FETCH_STATS () IS\n" "found INT;\n" @@ -3319,9 +3325,9 @@ dict_stats_fetch_from_ps( "END LOOP;\n" "CLOSE index_stats_cur;\n" - "END;", - TRUE, trx); + "END;", trx); /* pinfo is freed by que_eval_sql() */ + dict_sys.unlock(); trx_commit_for_mysql(trx); @@ -3634,7 +3640,7 @@ dberr_t dict_stats_delete_from_table_stats(const char *database_name, { pars_info_t* pinfo; - ut_d(dict_sys.assert_locked()); + ut_ad(dict_sys.locked()); pinfo = pars_info_create(); @@ -3654,14 +3660,14 @@ dberr_t dict_stats_delete_from_table_stats(const char *database_name, /** Execute DELETE FROM mysql.innodb_index_stats @param database_name database name @param table_name table name -@param trx transaction (nullptr=start and commit a new one) +@param trx transaction @return DB_SUCCESS or error code */ dberr_t dict_stats_delete_from_index_stats(const char *database_name, const char *table_name, trx_t *trx) { pars_info_t* pinfo; - ut_d(dict_sys.assert_locked()); + ut_ad(dict_sys.locked()); pinfo = pars_info_create(); @@ -3682,7 +3688,7 @@ dberr_t dict_stats_delete_from_index_stats(const char *database_name, @param database_name database name @param table_name table name @param index_name name of the index -@param trx transaction (nullptr=start and commit a new one) +@param trx transaction @return DB_SUCCESS or error code */ dberr_t dict_stats_delete_from_index_stats(const char *database_name, const char *table_name, @@ -3690,7 +3696,7 @@ dberr_t dict_stats_delete_from_index_stats(const char *database_name, { pars_info_t* pinfo; - ut_d(dict_sys.assert_locked()); + ut_ad(dict_sys.locked()); pinfo = pars_info_create(); diff --git a/storage/innobase/dict/dict0stats_bg.cc b/storage/innobase/dict/dict0stats_bg.cc index dbaff373ac4..1a5f8b0bda5 100644 --- a/storage/innobase/dict/dict0stats_bg.cc +++ b/storage/innobase/dict/dict0stats_bg.cc @@ -50,22 +50,23 @@ static void dict_stats_schedule(int ms); my_bool innodb_dict_stats_disabled_debug; #endif /* UNIV_DEBUG */ -/** This mutex protects the "recalc_pool" variable. */ +/** Protects recalc_pool */ static mysql_mutex_t recalc_pool_mutex; -/** Allocator type, used by std::vector */ -typedef ut_allocator - recalc_pool_allocator_t; +/** for signaling recalc::state */ +static pthread_cond_t recalc_pool_cond; -/** The multitude of tables whose stats are to be automatically -recalculated - an STL vector */ -typedef std::vector - recalc_pool_t; +/** Work item of the recalc_pool; protected by recalc_pool_mutex */ +struct recalc +{ + /** identifies a table with persistent statistics */ + table_id_t id; + /** state of the entry */ + enum { IDLE, IN_PROGRESS, IN_PROGRESS_DELETING, DELETING} state; +}; -/** Iterator type for iterating over the elements of objects of type -recalc_pool_t. */ -typedef recalc_pool_t::iterator - recalc_pool_iterator_t; +/** The multitude of tables whose stats are to be automatically recalculated */ +typedef std::vector> recalc_pool_t; /** Pool where we store information on which tables are to be processed by background statistics gathering. */ @@ -102,35 +103,22 @@ background stats gathering thread. Only the table id is added to the list, so the table can be closed after being enqueued and it will be opened when needed. If the table does not exist later (has been DROPped), then it will be removed from the pool and skipped. */ -static -void -dict_stats_recalc_pool_add( -/*=======================*/ - const dict_table_t* table, /*!< in: table to add */ - bool schedule_dict_stats_task = true /*!< in: schedule dict stats task */ -) +static void dict_stats_recalc_pool_add(table_id_t id) { - ut_ad(!srv_read_only_mode); + ut_ad(!srv_read_only_mode); + ut_ad(id); + mysql_mutex_lock(&recalc_pool_mutex); - mysql_mutex_lock(&recalc_pool_mutex); + const auto begin= recalc_pool.begin(), end= recalc_pool.end(); + if (end == std::find_if(begin, end, [&](const recalc &r){return r.id == id;})) + { + recalc_pool.emplace_back(recalc{id, recalc::IDLE}); + } - /* quit if already in the list */ - for (recalc_pool_iterator_t iter = recalc_pool.begin(); - iter != recalc_pool.end(); - ++iter) { - - if (*iter == table->id) { - mysql_mutex_unlock(&recalc_pool_mutex); - return; - } - } - - recalc_pool.push_back(table->id); - if (recalc_pool.size() == 1 && schedule_dict_stats_task) { - dict_stats_schedule_now(); - } - mysql_mutex_unlock(&recalc_pool_mutex); + mysql_mutex_unlock(&recalc_pool_mutex); + if (begin == end) + dict_stats_schedule_now(); } #ifdef WITH_WSREP @@ -146,8 +134,6 @@ schedule new estimates for table and index statistics to be calculated. void dict_stats_update_if_needed_func(dict_table_t *table) #endif { - dict_sys.assert_not_locked(); - if (UNIV_UNLIKELY(!table->stat_initialized)) { /* The table may have been evicted from dict_sys and reloaded internally by InnoDB for FOREIGN KEY @@ -198,7 +184,7 @@ void dict_stats_update_if_needed_func(dict_table_t *table) } #endif /* WITH_WSREP */ - dict_stats_recalc_pool_add(table); + dict_stats_recalc_pool_add(table->id); table->stat_modified_counter = 0; } return; @@ -220,83 +206,41 @@ void dict_stats_update_if_needed_func(dict_table_t *table) } } -/*****************************************************************//** -Get a table from the auto recalc pool. The returned table id is removed -from the pool. -@return true if the pool was non-empty and "id" was set, false otherwise */ -static -bool -dict_stats_recalc_pool_get( -/*=======================*/ - table_id_t* id) /*!< out: table id, or unmodified if list is - empty */ +/** Delete a table from the auto recalc pool, and ensure that +no statistics are being updated on it. */ +void dict_stats_recalc_pool_del(table_id_t id, bool have_mdl_exclusive) { - ut_ad(!srv_read_only_mode); + ut_ad(!srv_read_only_mode); + ut_ad(id); - mysql_mutex_lock(&recalc_pool_mutex); + mysql_mutex_lock(&recalc_pool_mutex); - if (recalc_pool.empty()) { - mysql_mutex_unlock(&recalc_pool_mutex); - return(false); - } + const auto end= recalc_pool.end(); + auto i= std::find_if(recalc_pool.begin(), end, + [&](const recalc &r){return r.id == id;}); + if (i != end) + { + switch (i->state) { + case recalc::IN_PROGRESS: + if (!have_mdl_exclusive) + { + i->state= recalc::IN_PROGRESS_DELETING; + do + my_cond_wait(&recalc_pool_cond, &recalc_pool_mutex.m_mutex); + while (i->state == recalc::IN_PROGRESS_DELETING); + } + /* fall through */ + case recalc::IDLE: + recalc_pool.erase(i); + break; + case recalc::IN_PROGRESS_DELETING: + case recalc::DELETING: + /* another thread will delete the entry in dict_stats_recalc_pool_del() */ + break; + } + } - *id = recalc_pool.at(0); - - recalc_pool.erase(recalc_pool.begin()); - - mysql_mutex_unlock(&recalc_pool_mutex); - - return(true); -} - -/*****************************************************************//** -Delete a given table from the auto recalc pool. -dict_stats_recalc_pool_del() */ -void -dict_stats_recalc_pool_del( -/*=======================*/ - const dict_table_t* table) /*!< in: table to remove */ -{ - ut_ad(!srv_read_only_mode); - dict_sys.assert_locked(); - - mysql_mutex_lock(&recalc_pool_mutex); - - ut_ad(table->id > 0); - - for (recalc_pool_iterator_t iter = recalc_pool.begin(); - iter != recalc_pool.end(); - ++iter) { - - if (*iter == table->id) { - /* erase() invalidates the iterator */ - recalc_pool.erase(iter); - break; - } - } - - mysql_mutex_unlock(&recalc_pool_mutex); -} - -/*****************************************************************//** -Wait until background stats thread has stopped using the specified table. -The caller must have locked the data dictionary using -row_mysql_lock_data_dictionary() and this function may unlock it temporarily -and restore the lock before it exits. -The background stats thread is guaranteed not to start using the specified -table after this function returns and before the caller unlocks the data -dictionary because it sets the BG_STAT_IN_PROGRESS bit in table->stats_bg_flag -under dict_sys.mutex. */ -void -dict_stats_wait_bg_to_stop_using_table( -/*===================================*/ - dict_table_t* table, /*!< in/out: table */ - trx_t* trx) /*!< in/out: transaction to use for - unlocking/locking the data dict */ -{ - while (!dict_stats_stop_bg(table)) { - DICT_BG_YIELD(trx); - } + mysql_mutex_unlock(&recalc_pool_mutex); } /*****************************************************************//** @@ -306,6 +250,7 @@ void dict_stats_init() { ut_ad(!srv_read_only_mode); mysql_mutex_init(recalc_pool_mutex_key, &recalc_pool_mutex, nullptr); + pthread_cond_init(&recalc_pool_cond, nullptr); dict_defrag_pool_init(); stats_initialised= true; } @@ -326,81 +271,100 @@ void dict_stats_deinit() dict_defrag_pool_deinit(); mysql_mutex_destroy(&recalc_pool_mutex); + pthread_cond_destroy(&recalc_pool_cond); } /** Get the first table that has been added for auto recalc and eventually update its stats. @return whether the first entry can be processed immediately */ -static bool dict_stats_process_entry_from_recalc_pool() +static bool dict_stats_process_entry_from_recalc_pool(THD *thd) { - table_id_t table_id; + ut_ad(!srv_read_only_mode); + table_id_t table_id; + mysql_mutex_lock(&recalc_pool_mutex); +next_table_id_with_mutex: + for (auto &r : recalc_pool) + { + if ((table_id= r.id) && r.state == recalc::IDLE) + { + r.state= recalc::IN_PROGRESS; + mysql_mutex_unlock(&recalc_pool_mutex); + goto process; + } + } + mysql_mutex_unlock(&recalc_pool_mutex); + return false; - ut_ad(!srv_read_only_mode); +process: + MDL_ticket *mdl= nullptr; + dict_table_t *table= dict_table_open_on_id(table_id, false, + DICT_TABLE_OP_NORMAL, thd, &mdl); + if (!table) + { +invalid_table_id: + mysql_mutex_lock(&recalc_pool_mutex); + auto i= std::find_if(recalc_pool.begin(), recalc_pool.end(), + [&](const recalc &r){return r.id == table_id;}); + if (i == recalc_pool.end()); + else if (UNIV_LIKELY(i->state == recalc::IN_PROGRESS)) + recalc_pool.erase(i); + else + { + ut_ad(i->state == recalc::IN_PROGRESS_DELETING); + i->state= recalc::DELETING; + pthread_cond_broadcast(&recalc_pool_cond); + } + goto next_table_id_with_mutex; + } -next_table_id: - /* pop the first table from the auto recalc pool */ - if (!dict_stats_recalc_pool_get(&table_id)) { - /* no tables for auto recalc */ - return false; - } + ut_ad(!table->is_temporary()); - dict_table_t* table; + if (!mdl || !table->is_accessible()) + { + dict_table_close(table, false, thd, mdl); + goto invalid_table_id; + } - dict_sys.mutex_lock(); + /* time() could be expensive, the current function + is called once every time a table has been changed more than 10% and + on a system with lots of small tables, this could become hot. If we + find out that this is a problem, then the check below could eventually + be replaced with something else, though a time interval is the natural + approach. */ + const bool update_now= + difftime(time(nullptr), table->stats_last_recalc) >= MIN_RECALC_INTERVAL; - table = dict_table_open_on_id(table_id, TRUE, DICT_TABLE_OP_NORMAL); + if (update_now) + dict_stats_update(table, DICT_STATS_RECALC_PERSISTENT); - if (table == NULL) { - /* table does not exist, must have been DROPped - after its id was enqueued */ - goto no_table; - } + dict_table_close(table, false, thd, mdl); - ut_ad(!table->is_temporary()); + mysql_mutex_lock(&recalc_pool_mutex); + auto i= std::find_if(recalc_pool.begin(), recalc_pool.end(), + [&](const recalc &r){return r.id == table_id;}); + if (i == recalc_pool.end()) + goto done; + else if (i->state == recalc::IN_PROGRESS_DELETING) + { + i->state= recalc::DELETING; + pthread_cond_broadcast(&recalc_pool_cond); +done: + mysql_mutex_unlock(&recalc_pool_mutex); + } + else + { + ut_ad(i->state == recalc::IN_PROGRESS); + recalc_pool.erase(i); + const bool reschedule= !update_now && recalc_pool.empty(); + if (!update_now) + recalc_pool.emplace_back(recalc{table_id, recalc::IDLE}); + mysql_mutex_unlock(&recalc_pool_mutex); + if (reschedule) + dict_stats_schedule(MIN_RECALC_INTERVAL * 1000); + } - if (!table->is_accessible()) { - dict_table_close(table, TRUE, FALSE); -no_table: - dict_sys.mutex_unlock(); - goto next_table_id; - } - - table->stats_bg_flag |= BG_STAT_IN_PROGRESS; - - dict_sys.mutex_unlock(); - - /* time() could be expensive, the current function - is called once every time a table has been changed more than 10% and - on a system with lots of small tables, this could become hot. If we - find out that this is a problem, then the check below could eventually - be replaced with something else, though a time interval is the natural - approach. */ - int ret; - if (difftime(time(NULL), table->stats_last_recalc) - < MIN_RECALC_INTERVAL) { - - /* Stats were (re)calculated not long ago. To avoid - too frequent stats updates we put back the table on - the auto recalc list and do nothing. */ - - dict_stats_recalc_pool_add(table, false); - dict_stats_schedule(MIN_RECALC_INTERVAL*1000); - ret = false; - } else { - - dict_stats_update(table, DICT_STATS_RECALC_PERSISTENT); - ret = true; - } - - dict_sys.mutex_lock(); - - table->stats_bg_flag = BG_STAT_NONE; - - dict_table_close(table, TRUE, FALSE); - - dict_sys.mutex_unlock(); - return ret; + return update_now; } #ifdef UNIV_DEBUG @@ -423,8 +387,12 @@ static std::mutex dict_stats_mutex; static void dict_stats_func(void*) { - while (dict_stats_process_entry_from_recalc_pool()) {} - dict_defrag_process_entries_from_defrag_pool(); + THD *thd= innobase_create_background_thd("InnoDB statistics"); + set_current_thd(thd); + while (dict_stats_process_entry_from_recalc_pool(thd)) {} + dict_defrag_process_entries_from_defrag_pool(); + set_current_thd(nullptr); + innobase_destroy_background_thd(thd); } diff --git a/storage/innobase/dict/drop.cc b/storage/innobase/dict/drop.cc index b2aab6992bb..0093601f32f 100644 --- a/storage/innobase/dict/drop.cc +++ b/storage/innobase/dict/drop.cc @@ -59,7 +59,6 @@ that would cause the InnoDB to hang or to intentionally crash. (d) The only changes to the data dictionary cache that are performed before transaction commit and must be rolled back explicitly are as follows: (d1) fts_optimize_add_table() to undo fts_optimize_remove_table() -(d2) stats_bg_flag= BG_STAT_NONE to undo dict_stats_stop_bg() */ #include "trx0purge.h" @@ -78,10 +77,10 @@ before transaction commit and must be rolled back explicitly are as follows: @return error code */ dberr_t trx_t::drop_table_foreign(const table_name_t &name) { - ut_d(dict_sys.assert_locked()); + ut_ad(dict_sys.locked()); ut_ad(state == TRX_STATE_ACTIVE); ut_ad(dict_operation); - ut_ad(dict_operation_lock_mode == RW_X_LATCH); + ut_ad(dict_operation_lock_mode); if (!dict_sys.sys_foreign || !dict_sys.sys_foreign_cols) return DB_SUCCESS; @@ -108,7 +107,7 @@ dberr_t trx_t::drop_table_foreign(const table_name_t &name) " DELETE FROM SYS_FOREIGN WHERE ID=fid;\n" "END LOOP;\n" "CLOSE fk;\n" - "END;\n", FALSE, this); + "END;\n", this); } /** Try to drop the statistics for a persistent table. @@ -116,8 +115,8 @@ dberr_t trx_t::drop_table_foreign(const table_name_t &name) @return error code */ dberr_t trx_t::drop_table_statistics(const table_name_t &name) { - ut_d(dict_sys.assert_locked()); - ut_ad(dict_operation_lock_mode == RW_X_LATCH); + ut_ad(dict_sys.locked()); + ut_ad(dict_operation_lock_mode); if (strstr(name.m_name, "/" TEMP_FILE_PREFIX_INNODB) || !strcmp(name.m_name, TABLE_STATS_NAME) || @@ -143,12 +142,11 @@ dberr_t trx_t::drop_table_statistics(const table_name_t &name) @return error code */ dberr_t trx_t::drop_table(const dict_table_t &table) { - ut_d(dict_sys.assert_locked()); + ut_ad(dict_sys.locked()); ut_ad(state == TRX_STATE_ACTIVE); ut_ad(dict_operation); - ut_ad(dict_operation_lock_mode == RW_X_LATCH); + ut_ad(dict_operation_lock_mode); ut_ad(!table.is_temporary()); - ut_ad(!(table.stats_bg_flag & BG_STAT_IN_PROGRESS)); /* The table must be exclusively locked by this transaction. */ ut_ad(table.get_ref_count() <= 1); ut_ad(table.n_lock_x_or_s == 1); @@ -182,7 +180,7 @@ dberr_t trx_t::drop_table(const dict_table_t &table) "BEGIN\n" "DELETE FROM SYS_VIRTUAL" " WHERE TABLE_ID=:id;\n" - "END;\n", FALSE, this)) + "END;\n", this)) return err; } @@ -224,7 +222,7 @@ dberr_t trx_t::drop_table(const dict_table_t &table) "END LOOP;\n" "CLOSE idx;\n" - "END;\n", FALSE, this); + "END;\n", this); } /** Commit the transaction, possibly after drop_table(). @@ -235,13 +233,13 @@ void trx_t::commit(std::vector &deleted) commit_persist(); if (dict_operation) { - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); for (const auto &p : mod_tables) { if (p.second.is_dropped()) { dict_table_t *table= p.first; - dict_stats_recalc_pool_del(table); + dict_stats_recalc_pool_del(table->id, true); dict_stats_defrag_pool_del(table, nullptr); if (btr_defragment_active) btr_defragment_remove_table(table); diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index 30aed48c97c..fdeb5832052 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -2054,7 +2054,7 @@ to the .err log. This function is used to open a tablespace when we start mysqld after the dictionary has been booted, and also in IMPORT TABLESPACE. NOTE that we assume this operation is used either at the database startup -or under the protection of the dictionary mutex, so that two users cannot +or under the protection of dict_sys.latch, so that two users cannot race here. This operation does not leave the file associated with the tablespace open, but closes it after we have looked at the space id in it. diff --git a/storage/innobase/fts/fts0config.cc b/storage/innobase/fts/fts0config.cc index 09cce53f8db..4566224e171 100644 --- a/storage/innobase/fts/fts0config.cc +++ b/storage/innobase/fts/fts0config.cc @@ -119,7 +119,7 @@ fts_config_get_value( trx->op_info = "getting FTS config value"; error = fts_eval_sql(trx, graph); - fts_que_graph_free(graph); + que_graph_free(graph); return(error); } @@ -226,7 +226,7 @@ fts_config_set_value( error = fts_eval_sql(trx, graph); - fts_que_graph_free_check_lock(fts_table, NULL, graph); + que_graph_free(graph); n_rows_updated = trx->undo_no - undo_no; @@ -252,7 +252,7 @@ fts_config_set_value( error = fts_eval_sql(trx, graph); - fts_que_graph_free_check_lock(fts_table, NULL, graph); + que_graph_free(graph); } return(error); diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index 7b6ca048271..5d75bcb37bd 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -159,6 +159,7 @@ const fts_index_selector_t fts_index_selector[] = { /** Default config values for FTS indexes on a table. */ static const char* fts_config_table_insert_values_sql = + "PROCEDURE P() IS\n" "BEGIN\n" "\n" "INSERT INTO $config_table VALUES('" @@ -174,7 +175,8 @@ static const char* fts_config_table_insert_values_sql = FTS_TOTAL_DELETED_COUNT "', '0');\n" "" /* Note: 0 == FTS_TABLE_STATE_RUNNING */ "INSERT INTO $config_table VALUES ('" - FTS_TABLE_STATE "', '0');\n"; + FTS_TABLE_STATE "', '0');\n" + "END;\n"; /** FTS tokenize parmameter for plugin parser */ struct fts_tokenize_param_t { @@ -182,14 +184,6 @@ struct fts_tokenize_param_t { ulint add_pos; /*!< Added position for tokens */ }; -/** Free a query graph */ -void fts_que_graph_free(que_t *graph) -{ - dict_sys.mutex_lock(); - que_graph_free(graph); - dict_sys.mutex_unlock(); -} - /** Run SYNC on the table, i.e., write out data from the cache to the FTS auxiliary INDEX table and clear the cache at the end. @param[in,out] sync sync state @@ -455,7 +449,7 @@ fts_load_user_stopword( fts_stopword_t* stopword_info) /*!< in: Stopword info */ { if (!fts->dict_locked) { - dict_sys.mutex_lock(); + dict_sys.lock(SRW_LOCK_CALL); } /* Validate the user table existence in the right format */ @@ -464,7 +458,7 @@ fts_load_user_stopword( if (!stopword_info->charset) { cleanup: if (!fts->dict_locked) { - dict_sys.mutex_unlock(); + dict_sys.unlock(); } return ret; @@ -489,8 +483,9 @@ cleanup: pars_info_bind_function(info, "my_func", fts_read_stopword, stopword_info); - que_t* graph = fts_parse_sql_no_dict_lock( + que_t* graph = pars_sql( info, + "PROCEDURE P() IS\n" "DECLARE FUNCTION my_func;\n" "DECLARE CURSOR c IS" " SELECT value" @@ -504,7 +499,8 @@ cleanup: " EXIT;\n" " END IF;\n" "END LOOP;\n" - "CLOSE c;"); + "CLOSE c;" + "END;\n"); for (;;) { dberr_t error = fts_eval_sql(trx, graph); @@ -881,41 +877,6 @@ fts_drop_index( return(err); } -/****************************************************************//** -Free the query graph but check whether dict_sys.mutex is already -held */ -void -fts_que_graph_free_check_lock( -/*==========================*/ - fts_table_t* fts_table, /*!< in: FTS table */ - const fts_index_cache_t*index_cache, /*!< in: FTS index cache */ - que_t* graph) /*!< in: query graph */ -{ - bool has_dict = FALSE; - - if (fts_table && fts_table->table) { - ut_ad(fts_table->table->fts); - - has_dict = fts_table->table->fts->dict_locked; - } else if (index_cache) { - ut_ad(index_cache->index->table->fts); - - has_dict = index_cache->index->table->fts->dict_locked; - } - - if (!has_dict) { - dict_sys.mutex_lock(); - } - - dict_sys.assert_locked(); - - que_graph_free(graph); - - if (!has_dict) { - dict_sys.mutex_unlock(); - } -} - /****************************************************************//** Create an FTS index cache. */ CHARSET_INFO* @@ -1063,18 +1024,14 @@ fts_cache_clear( if (index_cache->ins_graph[j] != NULL) { - fts_que_graph_free_check_lock( - NULL, index_cache, - index_cache->ins_graph[j]); + que_graph_free(index_cache->ins_graph[j]); index_cache->ins_graph[j] = NULL; } if (index_cache->sel_graph[j] != NULL) { - fts_que_graph_free_check_lock( - NULL, index_cache, - index_cache->sel_graph[j]); + que_graph_free(index_cache->sel_graph[j]); index_cache->sel_graph[j] = NULL; } @@ -1414,7 +1371,7 @@ fts_cache_add_doc( @retval DB_FAIL if the table did not exist */ static dberr_t fts_drop_table(trx_t *trx, const char *table_name, bool rename) { - if (dict_table_t *table= dict_table_open_on_name(table_name, TRUE, FALSE, + if (dict_table_t *table= dict_table_open_on_name(table_name, true, DICT_ERR_IGNORE_DROP)) { table->release(); @@ -1546,24 +1503,20 @@ static dberr_t fts_lock_table(trx_t *trx, const char *table_name) { ut_ad(purge_sys.must_wait_FTS()); - if (dict_table_t *table= dict_table_open_on_name(table_name, false, false, + if (dict_table_t *table= dict_table_open_on_name(table_name, false, DICT_ERR_IGNORE_DROP)) { dberr_t err= lock_table_for_trx(table, trx, LOCK_X); /* Wait for purge threads to stop using the table. */ - dict_sys.mutex_lock(); for (uint n= 15; table->get_ref_count() > 1; ) { - dict_sys.mutex_unlock(); if (!--n) { err= DB_LOCK_WAIT_TIMEOUT; goto fail; } std::this_thread::sleep_for(std::chrono::milliseconds(50)); - dict_sys.mutex_lock(); } - dict_sys.mutex_unlock(); fail: table->release(); return err; @@ -1636,8 +1589,7 @@ dberr_t fts_lock_tables(trx_t *trx, const dict_table_t &table) } /** Drops the common ancillary tables needed for supporting an FTS index -on the given table. row_mysql_lock_data_dictionary must have been called -before this. +on the given table. @param trx transaction to drop fts common table @param fts_table table with an FTS index @param rename whether to rename before dropping @@ -1696,8 +1648,7 @@ dberr_t fts_drop_index_tables(trx_t *trx, const dict_index_t &index) /****************************************************************//** Drops FTS ancillary tables needed for supporting an FTS index -on the given table. row_mysql_lock_data_dictionary must have been called -before this. +on the given table. @return DB_SUCCESS or error code */ static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t @@ -1838,8 +1789,7 @@ fts_create_one_common_table( } /** Creates the common auxiliary tables needed for supporting an FTS index -on the given table. row_mysql_lock_data_dictionary must have been called -before this. +on the given table. The following tables are created. CREATE TABLE $FTS_PREFIX_DELETED (doc_id BIGINT UNSIGNED, UNIQUE CLUSTERED INDEX on doc_id) @@ -1905,7 +1855,7 @@ fts_create_common_tables( fts_get_table_name(&fts_table, fts_name, true); pars_info_bind_id(info, "config_table", fts_name); - graph = fts_parse_sql_no_dict_lock( + graph = pars_sql( info, fts_config_table_insert_values_sql); error = fts_eval_sql(trx, graph); @@ -2017,8 +1967,7 @@ fts_create_one_index_table( } /** Creates the column specific ancillary tables needed for supporting an -FTS index on the given table. row_mysql_lock_data_dictionary must have -been called before this. +FTS index on the given table. All FTS AUX Index tables have the following schema. CREAT TABLE $FTS_PREFIX_INDEX_[1-6]( @@ -2049,8 +1998,7 @@ fts_create_index_tables(trx_t* trx, const dict_index_t* index, table_id_t id) dict_table_t* new_table; /* Create the FTS auxiliary tables that are specific - to an FTS index. We need to preserve the table_id %s - which fts_parse_sql_no_dict_lock() will fill in for us. */ + to an FTS index. */ fts_table.suffix = fts_get_suffix(i); new_table = fts_create_one_index_table( @@ -2605,7 +2553,7 @@ retry: error = fts_eval_sql(trx, graph); - fts_que_graph_free_check_lock(&fts_table, NULL, graph); + que_graph_free(graph); // FIXME: We need to retry deadlock errors if (error != DB_SUCCESS) { @@ -2721,7 +2669,7 @@ fts_update_sync_doc_id( error = fts_eval_sql(trx, graph); - fts_que_graph_free_check_lock(&fts_table, NULL, graph); + que_graph_free(graph); if (local_trx) { if (UNIV_LIKELY(error == DB_SUCCESS)) { @@ -2798,7 +2746,6 @@ fts_delete( { que_t* graph; fts_table_t fts_table; - dberr_t error = DB_SUCCESS; doc_id_t write_doc_id; dict_table_t* table = ftt->table; doc_id_t doc_id = row->doc_id; @@ -2809,7 +2756,7 @@ fts_delete( /* we do not index Documents whose Doc ID value is 0 */ if (doc_id == FTS_NULL_DOC_ID) { ut_ad(!DICT_TF2_FLAG_IS_SET(table, DICT_TF2_FTS_HAS_DOC_ID)); - return(error); + return DB_SUCCESS; } ut_a(row->state == FTS_DELETE || row->state == FTS_MODIFY); @@ -2844,29 +2791,20 @@ fts_delete( } /* Note the deleted document for OPTIMIZE to purge. */ - if (error == DB_SUCCESS) { - char table_name[MAX_FULL_NAME_LEN]; + char table_name[MAX_FULL_NAME_LEN]; - trx->op_info = "adding doc id to FTS DELETED"; + trx->op_info = "adding doc id to FTS DELETED"; - info->graph_owns_us = TRUE; + fts_table.suffix = "DELETED"; - fts_table.suffix = "DELETED"; + fts_get_table_name(&fts_table, table_name); + pars_info_bind_id(info, "deleted", table_name); - fts_get_table_name(&fts_table, table_name); - pars_info_bind_id(info, "deleted", table_name); + graph = fts_parse_sql(&fts_table, info, + "BEGIN INSERT INTO $deleted VALUES (:doc_id);"); - graph = fts_parse_sql( - &fts_table, - info, - "BEGIN INSERT INTO $deleted VALUES (:doc_id);"); - - error = fts_eval_sql(trx, graph); - - fts_que_graph_free(graph); - } else { - pars_info_free(info); - } + dberr_t error = fts_eval_sql(trx, graph); + que_graph_free(graph); /* Increment the total deleted count, this is used to calculate the number of documents indexed. */ @@ -3738,7 +3676,7 @@ fts_doc_fetch_by_doc_id( trx->free(); if (!get_doc) { - fts_que_graph_free(graph); + que_graph_free(graph); } return(error); @@ -3867,7 +3805,7 @@ fts_sync_add_deleted_cache( error = fts_eval_sql(sync->trx, graph); } - fts_que_graph_free(graph); + que_graph_free(graph); return(error); } @@ -4135,7 +4073,7 @@ fts_sync_commit( } /* Avoid assertion in trx_t::free(). */ - trx->dict_operation_lock_mode = 0; + trx->dict_operation_lock_mode = false; trx->free(); return(error); @@ -4166,18 +4104,14 @@ fts_sync_rollback( if (index_cache->ins_graph[j] != NULL) { - fts_que_graph_free_check_lock( - NULL, index_cache, - index_cache->ins_graph[j]); + que_graph_free(index_cache->ins_graph[j]); index_cache->ins_graph[j] = NULL; } if (index_cache->sel_graph[j] != NULL) { - fts_que_graph_free_check_lock( - NULL, index_cache, - index_cache->sel_graph[j]); + que_graph_free(index_cache->sel_graph[j]); index_cache->sel_graph[j] = NULL; } @@ -4189,7 +4123,7 @@ fts_sync_rollback( fts_sql_rollback(trx); /* Avoid assertion in trx_t::free(). */ - trx->dict_operation_lock_mode = 0; + trx->dict_operation_lock_mode = false; trx->free(); } @@ -4741,7 +4675,7 @@ fts_get_docs_clear( ut_a(get_doc->index_cache); - fts_que_graph_free(get_doc->get_document_graph); + que_graph_free(get_doc->get_document_graph); get_doc->get_document_graph = NULL; } } @@ -4889,7 +4823,7 @@ fts_get_rows_count( } } - fts_que_graph_free(graph); + que_graph_free(graph); trx->free(); @@ -4989,7 +4923,7 @@ fts_savepoint_free( /* The default savepoint name must be NULL. */ if (ftt->docs_added_graph) { - fts_que_graph_free(ftt->docs_added_graph); + que_graph_free(ftt->docs_added_graph); } /* NOTE: We are responsible for free'ing the node */ @@ -6038,8 +5972,6 @@ fts_init_index( fts_cache_t* cache = table->fts->cache; bool need_init = false; - dict_sys.assert_not_locked(); - /* First check cache->get_docs is initialized */ if (!has_cache_lock) { mysql_mutex_lock(&cache->lock); @@ -6103,9 +6035,9 @@ func_exit: } if (need_init) { - dict_sys.mutex_lock(); + dict_sys.lock(SRW_LOCK_CALL); /* Register the table with the optimize thread. */ fts_optimize_add_table(table); - dict_sys.mutex_unlock(); + dict_sys.unlock(); } } diff --git a/storage/innobase/fts/fts0opt.cc b/storage/innobase/fts/fts0opt.cc index 64179947832..da24cd54aec 100644 --- a/storage/innobase/fts/fts0opt.cc +++ b/storage/innobase/fts/fts0opt.cc @@ -892,7 +892,7 @@ fts_index_fetch_words( } } - fts_que_graph_free(graph); + que_graph_free(graph); /* Check if max word to fetch is exceeded */ if (optim->zip->n_words >= n_words) { @@ -1005,7 +1005,7 @@ fts_table_fetch_doc_ids( error = fts_eval_sql(trx, graph); fts_sql_commit(trx); - fts_que_graph_free(graph); + que_graph_free(graph); if (error == DB_SUCCESS) { ib_vector_sort(doc_ids->doc_ids, fts_doc_id_cmp); @@ -1459,7 +1459,7 @@ fts_optimize_write_word( " when deleting a word from the FTS index."; } - fts_que_graph_free(graph); + que_graph_free(graph); graph = NULL; /* Even if the operation needs to be rolled back and redone, @@ -1491,7 +1491,7 @@ fts_optimize_write_word( } if (graph != NULL) { - fts_que_graph_free(graph); + que_graph_free(graph); } return(error); @@ -1603,8 +1603,21 @@ fts_optimize_create( optim->fts_index_table.table = table; /* The common prefix for all this parent table's aux tables. */ - optim->name_prefix = fts_get_table_name_prefix( - &optim->fts_common_table); + char table_id[FTS_AUX_MIN_TABLE_ID_LENGTH]; + const size_t table_id_len = 1 + + size_t(fts_get_table_id(&optim->fts_common_table, table_id)); + dict_sys.freeze(SRW_LOCK_CALL); + /* Include the separator as well. */ + const size_t dbname_len = table->name.dblen() + 1; + ut_ad(dbname_len > 1); + const size_t prefix_name_len = dbname_len + 4 + table_id_len; + char* prefix_name = static_cast( + ut_malloc_nokey(prefix_name_len)); + memcpy(prefix_name, table->name.m_name, dbname_len); + dict_sys.unfreeze(); + memcpy(prefix_name + dbname_len, "FTS_", 4); + memcpy(prefix_name + dbname_len + 4, table_id, table_id_len); + optim->name_prefix =prefix_name; return(optim); } @@ -1816,7 +1829,7 @@ fts_optimize_words( charset, word->f_str, word->f_len) && graph) { - fts_que_graph_free(graph); + que_graph_free(graph); graph = NULL; } } @@ -1835,7 +1848,7 @@ fts_optimize_words( } if (graph != NULL) { - fts_que_graph_free(graph); + que_graph_free(graph); } } @@ -2068,7 +2081,7 @@ fts_optimize_purge_deleted_doc_ids( } } - fts_que_graph_free(graph); + que_graph_free(graph); return(error); } @@ -2105,7 +2118,7 @@ fts_optimize_purge_deleted_doc_id_snapshot( graph = fts_parse_sql(NULL, info, fts_end_delete_sql); error = fts_eval_sql(optim->trx, graph); - fts_que_graph_free(graph); + que_graph_free(graph); return(error); } @@ -2173,7 +2186,7 @@ fts_optimize_create_deleted_doc_id_snapshot( error = fts_eval_sql(optim->trx, graph); - fts_que_graph_free(graph); + que_graph_free(graph); if (error != DB_SUCCESS) { fts_sql_rollback(optim->trx); @@ -2589,7 +2602,6 @@ fts_optimize_remove_table( if (table->fts->in_queue) { - dict_sys.assert_not_locked(); fts_msg_t *msg= fts_optimize_create_msg(FTS_MSG_DEL_TABLE, nullptr); pthread_cond_t cond; pthread_cond_init(&cond, nullptr); @@ -2786,7 +2798,7 @@ static void fts_optimize_sync_table(dict_table_t *table, std::this_thread::sleep_for(std::chrono::seconds(6));); if (mdl_ticket) - dict_table_close(sync_table, false, false, fts_opt_thd, mdl_ticket); + dict_table_close(sync_table, false, fts_opt_thd, mdl_ticket); } /**********************************************************************//** @@ -2937,7 +2949,7 @@ fts_optimize_init(void) /* Add fts tables to fts_slots which could be skipped during dict_load_table_one() because fts_optimize_thread wasn't even started. */ - dict_sys.mutex_lock(); + dict_sys.freeze(SRW_LOCK_CALL); for (dict_table_t* table = UT_LIST_GET_FIRST(dict_sys.table_LRU); table != NULL; table = UT_LIST_GET_NEXT(table_LRU, table)) { @@ -2952,7 +2964,7 @@ fts_optimize_init(void) fts_optimize_new_table(table); table->fts->in_queue = true; } - dict_sys.mutex_unlock(); + dict_sys.unfreeze(); pthread_cond_init(&fts_opt_shutdown_cond, nullptr); last_check_sync_time = time(NULL); @@ -2966,13 +2978,13 @@ fts_optimize_shutdown() /* If there is an ongoing activity on dictionary, such as srv_master_evict_from_table_cache(), wait for it */ - dict_sys.mutex_lock(); + dict_sys.freeze(SRW_LOCK_CALL); mysql_mutex_lock(&fts_optimize_wq->mutex); /* Tells FTS optimizer system that we are exiting from optimizer thread, message send their after will not be processed */ fts_opt_start_shutdown = true; - dict_sys.mutex_unlock(); + dict_sys.unfreeze(); /* We tell the OPTIMIZE thread to switch to state done, we can't delete the work queue here because the add thread needs diff --git a/storage/innobase/fts/fts0que.cc b/storage/innobase/fts/fts0que.cc index 594faf971ad..ee9c291b02a 100644 --- a/storage/innobase/fts/fts0que.cc +++ b/storage/innobase/fts/fts0que.cc @@ -1193,7 +1193,7 @@ fts_query_difference( query->error = error; } - fts_que_graph_free(graph); + que_graph_free(graph); } /* The size can't increase. */ @@ -1317,7 +1317,7 @@ fts_query_intersect( query->error = error; } - fts_que_graph_free(graph); + que_graph_free(graph); if (query->error == DB_SUCCESS) { /* Make the intesection (rb tree) the current doc id @@ -1437,7 +1437,7 @@ fts_query_union( query->error = error; } - fts_que_graph_free(graph); + que_graph_free(graph); if (query->error == DB_SUCCESS) { @@ -2331,7 +2331,7 @@ fts_query_total_docs_containing_term( } } - fts_que_graph_free(graph); + que_graph_free(graph); return(error); } @@ -2413,7 +2413,7 @@ fts_query_terms_in_document( } } - fts_que_graph_free(graph); + que_graph_free(graph); return(error); } @@ -2504,7 +2504,7 @@ fts_query_is_in_proximity_range( /* Free the prepared statement. */ if (get_doc.get_document_graph) { - fts_que_graph_free(get_doc.get_document_graph); + que_graph_free(get_doc.get_document_graph); get_doc.get_document_graph = NULL; } @@ -2594,7 +2594,7 @@ fts_query_search_phrase( func_exit: /* Free the prepared statement. */ if (get_doc.get_document_graph) { - fts_que_graph_free(get_doc.get_document_graph); + que_graph_free(get_doc.get_document_graph); get_doc.get_document_graph = NULL; } @@ -2809,7 +2809,7 @@ fts_query_phrase_search( query->error = error; } - fts_que_graph_free(graph); + que_graph_free(graph); graph = NULL; fts_query_cache(query, token); @@ -3786,7 +3786,7 @@ fts_query_free( { if (query->read_nodes_graph) { - fts_que_graph_free(query->read_nodes_graph); + que_graph_free(query->read_nodes_graph); } if (query->root) { diff --git a/storage/innobase/fts/fts0sql.cc b/storage/innobase/fts/fts0sql.cc index 2d41776eb12..1970f6f584f 100644 --- a/storage/innobase/fts/fts0sql.cc +++ b/storage/innobase/fts/fts0sql.cc @@ -84,46 +84,23 @@ fts_get_table_id( return(len); } -/** Construct the name of an internal FTS table for the given table. -@param[in] fts_table metadata on fulltext-indexed table -@param[in] dict_locked whether dict_sys.mutex is being held -@return the prefix, must be freed with ut_free() */ -char* fts_get_table_name_prefix(const fts_table_t* fts_table) -{ - char table_id[FTS_AUX_MIN_TABLE_ID_LENGTH]; - const size_t table_id_len = size_t(fts_get_table_id(fts_table, - table_id)) + 1; - dict_sys.mutex_lock(); - /* Include the separator as well. */ - const size_t dbname_len = fts_table->table->name.dblen() + 1; - ut_ad(dbname_len > 1); - const size_t prefix_name_len = dbname_len + 4 + table_id_len; - char* prefix_name = static_cast( - ut_malloc_nokey(prefix_name_len)); - memcpy(prefix_name, fts_table->table->name.m_name, dbname_len); - dict_sys.mutex_unlock(); - memcpy(prefix_name + dbname_len, "FTS_", 4); - memcpy(prefix_name + dbname_len + 4, table_id, table_id_len); - return prefix_name; -} - /** Construct the name of an internal FTS table for the given table. @param[in] fts_table metadata on fulltext-indexed table @param[out] table_name a name up to MAX_FULL_NAME_LEN -@param[in] dict_locked whether dict_sys.mutex is being held */ +@param[in] dict_locked whether dict_sys.latch is being held */ void fts_get_table_name(const fts_table_t* fts_table, char* table_name, bool dict_locked) { if (!dict_locked) { - dict_sys.mutex_lock(); + dict_sys.freeze(SRW_LOCK_CALL); } - dict_sys.assert_locked(); + ut_ad(dict_sys.frozen()); /* Include the separator as well. */ const size_t dbname_len = fts_table->table->name.dblen() + 1; ut_ad(dbname_len > 1); memcpy(table_name, fts_table->table->name.m_name, dbname_len); if (!dict_locked) { - dict_sys.mutex_unlock(); + dict_sys.unfreeze(); } memcpy(table_name += dbname_len, "FTS_", 4); table_name += 4; @@ -153,14 +130,14 @@ fts_parse_sql( if (!dict_locked) { /* The InnoDB SQL parser is not re-entrant. */ - dict_sys.mutex_lock(); + dict_sys.lock(SRW_LOCK_CALL); } graph = pars_sql(info, str); ut_a(graph); if (!dict_locked) { - dict_sys.mutex_unlock(); + dict_sys.unlock(); } ut_free(str); @@ -168,30 +145,6 @@ fts_parse_sql( return(graph); } -/******************************************************************//** -Parse an SQL string. -@return query graph */ -que_t* -fts_parse_sql_no_dict_lock( -/*=======================*/ - pars_info_t* info, /*!< in: info struct, or NULL */ - const char* sql) /*!< in: SQL string to evaluate */ -{ - char* str; - que_t* graph; - - dict_sys.assert_locked(); - - str = ut_str3cat(fts_sql_begin, sql, fts_sql_end); - - graph = pars_sql(info, str); - ut_a(graph); - - ut_free(str); - - return(graph); -} - /******************************************************************//** Evaluate an SQL query graph. @return DB_SUCCESS or error code */ diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 5b94db7edc4..1984115f1ac 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -503,7 +503,6 @@ static mysql_pfs_key_t pending_checkpoint_mutex_key; # ifdef UNIV_PFS_MUTEX mysql_pfs_key_t buf_pool_mutex_key; mysql_pfs_key_t dict_foreign_err_mutex_key; -mysql_pfs_key_t dict_sys_mutex_key; mysql_pfs_key_t fil_system_mutex_key; mysql_pfs_key_t flush_list_mutex_key; mysql_pfs_key_t fts_cache_mutex_key; @@ -545,7 +544,6 @@ static PSI_mutex_info all_innodb_mutexes[] = { PSI_KEY(pending_checkpoint_mutex), PSI_KEY(buf_pool_mutex), PSI_KEY(dict_foreign_err_mutex), - PSI_KEY(dict_sys_mutex), PSI_KEY(recalc_pool_mutex), PSI_KEY(fil_system_mutex), PSI_KEY(flush_list_mutex), @@ -1339,28 +1337,12 @@ static void innodb_drop_database(handlerton*, char *path) innobase_casedn_str(namebuf); #endif /* _WIN32 */ - trx_t *trx= innobase_trx_allocate(current_thd); -retry: - row_mysql_lock_data_dictionary(trx); - - for (auto i= dict_sys.table_id_hash.n_cells; i--; ) - { - for (dict_table_t *table= static_cast - (dict_sys.table_id_hash.array[i].node); table; table= table->id_hash) - { - ut_ad(table->cached); - if (!strncmp(table->name.m_name, namebuf, len) && - !dict_stats_stop_bg(table)) - { - row_mysql_unlock_data_dictionary(trx); - std::this_thread::sleep_for(std::chrono::milliseconds(250)); - goto retry; - } - } - } - + THD * const thd= current_thd; + trx_t *trx= innobase_trx_allocate(thd); dberr_t err= DB_SUCCESS; + dict_sys.lock(SRW_LOCK_CALL); + for (auto i= dict_sys.table_id_hash.n_cells; i--; ) { for (dict_table_t *next, *table= static_cast @@ -1387,20 +1369,56 @@ retry: } } + dict_sys.unlock(); + + dict_table_t *table_stats, *index_stats; + MDL_ticket *mdl_table= nullptr, *mdl_index= nullptr; + table_stats= dict_table_open_on_name(TABLE_STATS_NAME, false, + DICT_ERR_IGNORE_NONE); + if (table_stats) + { + dict_sys.freeze(SRW_LOCK_CALL); + table_stats= dict_acquire_mdl_shared(table_stats, + thd, &mdl_table); + dict_sys.unfreeze(); + } + index_stats= dict_table_open_on_name(INDEX_STATS_NAME, false, + DICT_ERR_IGNORE_NONE); + if (index_stats) + { + dict_sys.freeze(SRW_LOCK_CALL); + index_stats= dict_acquire_mdl_shared(index_stats, + thd, &mdl_index); + dict_sys.unfreeze(); + } + trx_start_for_ddl(trx); + uint errors= 0; char db[NAME_LEN + 1]; strconvert(&my_charset_filename, namebuf, len, system_charset_info, db, sizeof db, &errors); - if (errors); - else if (dict_stats_delete(db, trx)) + if (!errors && table_stats && index_stats && + !strcmp(table_stats->name.m_name, TABLE_STATS_NAME) && + !strcmp(index_stats->name.m_name, INDEX_STATS_NAME) && + lock_table_for_trx(table_stats, trx, LOCK_X) == DB_SUCCESS && + lock_table_for_trx(index_stats, trx, LOCK_X) == DB_SUCCESS) { - /* Ignore this error. Leaving garbage statistics behind is a - lesser evil. Carry on to try to remove any garbage tables. */ - trx->rollback(); - trx_start_for_ddl(trx); + row_mysql_lock_data_dictionary(trx); + if (dict_stats_delete(db, trx)) + { + /* Ignore this error. Leaving garbage statistics behind is a + lesser evil. Carry on to try to remove any garbage tables. */ + trx->rollback(); + trx_start_for_ddl(trx); + } + row_mysql_unlock_data_dictionary(trx); } + if (err == DB_SUCCESS) + err= lock_sys_tables(trx); + row_mysql_lock_data_dictionary(trx); + static const char drop_database[] = "PROCEDURE DROP_DATABASE_PROC () IS\n" "fk CHAR;\n" @@ -1469,7 +1487,7 @@ retry: ? innodb_drop_database_fk : innodb_drop_database_ignore_fk, &report); pars_info_add_str_literal(pinfo, "db", namebuf); - err= que_eval_sql(pinfo, drop_database, false, trx); + err= que_eval_sql(pinfo, drop_database, trx); if (err == DB_SUCCESS && report.violated) err= DB_CANNOT_DROP_CONSTRAINT; } @@ -1483,8 +1501,12 @@ retry: ib::error() << "DROP DATABASE " << namebuf << ": " << err; } else - trx_commit_for_mysql(trx); + trx->commit(); + if (table_stats) + dict_table_close(table_stats, true, thd, mdl_table); + if (index_stats) + dict_table_close(index_stats, true, thd, mdl_index); row_mysql_unlock_data_dictionary(trx); trx->free(); @@ -1775,6 +1797,15 @@ MYSQL_THD innobase_create_background_thd(const char* name) return thd; } +extern "C" void thd_increment_pending_ops(MYSQL_THD); + +THD *innodb_thd_increment_pending_ops(THD *thd) +{ + if (!thd || THDVAR(thd, background_thread)) + return nullptr; + thd_increment_pending_ops(thd); + return thd; +} /** Destroy a background purge thread THD. @param[in] thd MYSQL_THD to destroy */ @@ -1852,7 +1883,7 @@ thd_has_edited_nontrans_tables( /******************************************************************//** Returns the lock wait timeout for the current connection. @return the lock wait timeout, in seconds */ -uint +uint& thd_lock_wait_timeout( /*==================*/ THD* thd) /*!< in: thread handle, or NULL to query @@ -1932,12 +1963,12 @@ static int innodb_check_version(handlerton *hton, const char *path, char norm_path[FN_REFLEN]; normalize_table_name(norm_path, path); - if (dict_table_t *table= dict_table_open_on_name(norm_path, false, false, + if (dict_table_t *table= dict_table_open_on_name(norm_path, false, DICT_ERR_IGNORE_NONE)) { const trx_id_t trx_id= table->def_trx_id; DBUG_ASSERT(trx_id <= create_id); - dict_table_close(table, false, false); + dict_table_close(table); DBUG_PRINT("info", ("create_id: %llu trx_id: %llu", create_id, trx_id)); DBUG_RETURN(create_id != trx_id); } @@ -2009,24 +2040,25 @@ static void drop_garbage_tables_after_restore() trx_start_for_ddl(trx); std::vector deleted; - row_mysql_lock_data_dictionary(trx); dberr_t err= DB_TABLE_NOT_FOUND; + row_mysql_lock_data_dictionary(trx); if (dict_table_t *table= dict_sys.load_table ({reinterpret_cast(pcur.old_rec), len}, DICT_ERR_IGNORE_DROP)) { - ut_ad(table->stats_bg_flag == BG_STAT_NONE); table->acquire(); + row_mysql_unlock_data_dictionary(trx); err= lock_table_for_trx(table, trx, LOCK_X); if (err == DB_SUCCESS && (table->flags2 & (DICT_TF2_FTS_HAS_DOC_ID | DICT_TF2_FTS))) { - dict_sys.unlock(); fts_optimize_remove_table(table); err= fts_lock_tables(trx, *table); - dict_sys.lock(SRW_LOCK_CALL); } + if (err == DB_SUCCESS) + err= lock_sys_tables(trx); + row_mysql_lock_data_dictionary(trx); table->release(); if (err == DB_SUCCESS) @@ -3031,7 +3063,7 @@ ha_innobase::update_thd( trx_t* trx = check_trx_exists(thd); - ut_ad(trx->dict_operation_lock_mode == 0); + ut_ad(!trx->dict_operation_lock_mode); ut_ad(!trx->dict_operation); if (m_prebuilt->trx != trx) { @@ -3183,7 +3215,7 @@ static bool innobase_query_caching_table_check( const char* norm_name) { dict_table_t* table = dict_table_open_on_name( - norm_name, FALSE, FALSE, DICT_ERR_IGNORE_FK_NOKEY); + norm_name, false, DICT_ERR_IGNORE_FK_NOKEY); if (table == NULL) { return false; @@ -3194,7 +3226,7 @@ static bool innobase_query_caching_table_check( bool allow = innobase_query_caching_table_check_low(table, trx); - dict_table_close(table, FALSE, FALSE); + dict_table_close(table); if (allow) { /* If the isolation level is high, assign a read view for the @@ -4435,7 +4467,7 @@ innobase_commit( trx_t* trx = check_trx_exists(thd); - ut_ad(trx->dict_operation_lock_mode == 0); + ut_ad(!trx->dict_operation_lock_mode); ut_ad(!trx->dict_operation); /* Transaction is deregistered only in a commit or a rollback. If @@ -4524,7 +4556,7 @@ innobase_rollback( trx_t* trx = check_trx_exists(thd); - ut_ad(trx->dict_operation_lock_mode == 0); + ut_ad(!trx->dict_operation_lock_mode); ut_ad(!trx->dict_operation); /* Reset the number AUTO-INC rows required */ @@ -4889,14 +4921,14 @@ static void innobase_kill_query(handlerton*, THD *thd, enum thd_kill_levels) if (trx_t* trx= thd_to_trx(thd)) { ut_ad(trx->mysql_thd == thd); + if (!trx->lock.wait_lock); #ifdef WITH_WSREP - if (trx->is_wsrep() && wsrep_thd_is_aborting(thd)) + else if (trx->is_wsrep() && wsrep_thd_is_aborting(thd)) /* if victim has been signaled by BF thread and/or aborting is already progressing, following query aborting is not necessary any more. - Also, BF thread should own trx mutex for the victim. */ - DBUG_VOID_RETURN; + Also, BF thread should own trx mutex for the victim. */; #endif /* WITH_WSREP */ - if (trx->lock.wait_lock) + else lock_sys_t::cancel(trx); } @@ -5492,7 +5524,7 @@ is done when the table first opened. @param[in,out] s_templ InnoDB template structure @param[in] add_v new virtual columns added along with add index call -@param[in] locked true if dict_sys mutex is held */ +@param[in] locked true if dict_sys.latch is held */ void innobase_build_v_templ( const TABLE* table, @@ -5515,12 +5547,18 @@ innobase_build_v_templ( ut_ad(n_v_col > 0); if (!locked) { - dict_sys.mutex_lock(); + dict_sys.lock(SRW_LOCK_CALL); } +#if 0 + /* This does not (need to) hold for ctx->new_table in + alter_rebuild_apply_log() */ + ut_ad(dict_sys.locked()); +#endif + if (s_templ->vtempl) { if (!locked) { - dict_sys.mutex_unlock(); + dict_sys.unlock(); } DBUG_VOID_RETURN; } @@ -5626,7 +5664,7 @@ innobase_build_v_templ( } if (!locked) { - dict_sys.mutex_unlock(); + dict_sys.unlock(); } s_templ->db_name = table->s->db.str; @@ -5849,7 +5887,7 @@ ha_innobase::open(const char* name, int, uint) or force recovery can still use it, but not others. */ ib_table->file_unreadable = true; ib_table->corrupted = true; - dict_table_close(ib_table, FALSE, FALSE); + ib_table->release(); set_my_errno(ENOENT); DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE); } @@ -5896,7 +5934,7 @@ ha_innobase::open(const char* name, int, uint) ret_err = HA_ERR_DECRYPTION_FAILED; } - dict_table_close(ib_table, FALSE, FALSE); + ib_table->release(); DBUG_RETURN(ret_err); } } @@ -5914,7 +5952,7 @@ ha_innobase::open(const char* name, int, uint) key_used_on_scan = m_primary_key; if (ib_table->n_v_cols) { - dict_sys.mutex_lock(); + dict_sys.lock(SRW_LOCK_CALL); if (ib_table->vc_templ == NULL) { ib_table->vc_templ = UT_NEW_NOKEY(dict_vcol_templ_t()); innobase_build_v_templ( @@ -5922,7 +5960,7 @@ ha_innobase::open(const char* name, int, uint) true); } - dict_sys.mutex_unlock(); + dict_sys.unlock(); } if (!check_index_consistency(table, ib_table)) { @@ -6099,8 +6137,9 @@ ha_innobase::open_dict_table( dict_err_ignore_t ignore_err) { DBUG_ENTER("ha_innobase::open_dict_table"); - dict_table_t* ib_table = dict_table_open_on_name(norm_name, FALSE, - TRUE, ignore_err); + /* FIXME: try_drop_aborted */ + dict_table_t* ib_table = dict_table_open_on_name(norm_name, false, + ignore_err); if (NULL == ib_table && is_partition) { /* MySQL partition engine hard codes the file name @@ -6137,9 +6176,9 @@ ha_innobase::open_dict_table( normalize_table_name_c_low( par_case_name, table_name, false); #endif + /* FIXME: try_drop_aborted */ ib_table = dict_table_open_on_name( - par_case_name, FALSE, TRUE, - ignore_err); + par_case_name, false, ignore_err); } if (ib_table != NULL) { @@ -6210,7 +6249,7 @@ ha_innobase::close() { DBUG_ENTER("ha_innobase::close"); - row_prebuilt_free(m_prebuilt, FALSE); + row_prebuilt_free(m_prebuilt); if (m_upd_buf != NULL) { ut_ad(m_upd_buf_size != 0); @@ -9848,7 +9887,7 @@ wsrep_append_foreign_key( foreign->referenced_table : foreign->foreign_table)) { WSREP_DEBUG("pulling %s table into cache", (referenced) ? "referenced" : "foreign"); - dict_sys.mutex_lock(); + dict_sys.lock(SRW_LOCK_CALL); if (referenced) { foreign->referenced_table = @@ -9883,7 +9922,7 @@ wsrep_append_foreign_key( TRUE, FALSE); } } - dict_sys.mutex_unlock(); + dict_sys.unlock(); } if ( !((referenced) ? @@ -10593,7 +10632,6 @@ create_table_info_t::create_table_def() table->name.m_name, field->field_name.str); err_col: dict_mem_table_free(table); - ut_ad(trx_state_eq(m_trx, TRX_STATE_NOT_STARTED)); DBUG_RETURN(HA_ERR_GENERIC); } @@ -10761,9 +10799,9 @@ err_col: table->space = fil_system.temp_space; table->add_to_cache(); } else { - if (err == DB_SUCCESS) { - err = row_create_table_for_mysql(table, m_trx); - } + ut_ad(dict_sys.sys_tables_exist()); + + err = row_create_table_for_mysql(table, m_trx); DBUG_EXECUTE_IF("ib_crash_during_create_for_encryption", DBUG_SUICIDE();); @@ -12980,7 +13018,7 @@ create_table_info_t::create_table_update_dict() DBUG_ENTER("create_table_update_dict"); innobase_table = dict_table_open_on_name( - m_table_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE); + m_table_name, false, DICT_ERR_IGNORE_NONE); DBUG_ASSERT(innobase_table != 0); if (innobase_table->fts != NULL) { @@ -13007,13 +13045,13 @@ create_table_info_t::create_table_update_dict() /* Load server stopword into FTS cache */ if (m_flags2 & DICT_TF2_FTS) { if (!innobase_fts_load_stopword(innobase_table, NULL, m_thd)) { - dict_table_close(innobase_table, FALSE, FALSE); + innobase_table->release(); DBUG_RETURN(-1); } - dict_sys.mutex_lock(); + dict_sys.lock(SRW_LOCK_CALL); fts_optimize_add_table(innobase_table); - dict_sys.mutex_unlock(); + dict_sys.unlock(); } if (const Field* ai = m_form->found_next_number_field) { @@ -13058,7 +13096,7 @@ create_table_info_t::create_table_update_dict() innobase_parse_hint_from_comment(m_thd, innobase_table, m_form->s); - dict_table_close(innobase_table, FALSE, FALSE); + dict_table_close(innobase_table); DBUG_RETURN(0); } @@ -13116,18 +13154,27 @@ ha_innobase::create( } const bool own_trx = !trx; + int error = 0; if (own_trx) { info.allocate_trx(); trx = info.trx(); - /* Latch the InnoDB data dictionary exclusively so that no deadlocks - or lock waits can happen in it during a table create operation. - Drop table etc. do this latching in row0mysql.cc. */ - row_mysql_lock_data_dictionary(trx); DBUG_ASSERT(trx_state_eq(trx, TRX_STATE_NOT_STARTED)); } + if (own_trx && !(info.flags2() & DICT_TF2_TEMPORARY)) { + trx_start_for_ddl(trx); + if (dberr_t err = lock_sys_tables(trx)) { + error = convert_error_code_to_mysql(err, 0, nullptr); + } + } + if (own_trx) { + row_mysql_lock_data_dictionary(trx); + } + + if (!error) { + error = info.create_table(own_trx); + } - int error = info.create_table(own_trx); if (error) { /* Drop the being-created table before rollback, so that rollback can possibly rename back a table @@ -13206,15 +13253,18 @@ ha_innobase::discard_or_import_tablespace( } trx_start_if_not_started(m_prebuilt->trx, true); + m_prebuilt->trx->dict_operation = true; /* Obtain an exclusive lock on the table. */ - dberr_t err = row_mysql_lock_table( - m_prebuilt->trx, m_prebuilt->table, LOCK_X, - discard ? "setting table lock for DISCARD TABLESPACE" - : "setting table lock for IMPORT TABLESPACE"); + dberr_t err = lock_table_for_trx(m_prebuilt->table, + m_prebuilt->trx, LOCK_X); + if (err == DB_SUCCESS) { + err = lock_sys_tables(m_prebuilt->trx); + } if (err != DB_SUCCESS) { /* unable to lock the table: do nothing */ + m_prebuilt->trx->commit(); } else if (discard) { /* Discarding an already discarded tablespace should be an @@ -13231,7 +13281,6 @@ ha_innobase::discard_or_import_tablespace( err = row_discard_tablespace_for_mysql( m_prebuilt->table, m_prebuilt->trx); - } else if (m_prebuilt->table->is_readable()) { /* Commit the transaction in order to release the table lock. */ @@ -13260,8 +13309,7 @@ ha_innobase::discard_or_import_tablespace( } } - /* Commit the transaction in order to release the table lock. */ - trx_commit_for_mysql(m_prebuilt->trx); + ut_ad(m_prebuilt->trx->state == TRX_STATE_NOT_STARTED); if (discard || err != DB_SUCCESS) { DBUG_RETURN(convert_error_code_to_mysql( @@ -13272,12 +13320,12 @@ ha_innobase::discard_or_import_tablespace( btr_cur_instant_init(). */ table_id_t id = m_prebuilt->table->id; ut_ad(id); - dict_sys.mutex_lock(); - dict_table_close(m_prebuilt->table, TRUE, FALSE); + dict_sys.lock(SRW_LOCK_CALL); + m_prebuilt->table->release(); dict_sys.remove(m_prebuilt->table); m_prebuilt->table = dict_table_open_on_id(id, TRUE, DICT_TABLE_OP_NORMAL); - dict_sys.mutex_unlock(); + dict_sys.unlock(); if (!m_prebuilt->table) { err = DB_TABLE_NOT_FOUND; } else { @@ -13328,7 +13376,6 @@ int ha_innobase::delete_table(const char *name) trx_t *parent_trx= check_trx_exists(thd); dict_table_t *table; - for (;;) { char norm_name[FN_REFLEN]; normalize_table_name(norm_name, name); @@ -13349,10 +13396,6 @@ int ha_innobase::delete_table(const char *name) dict_sys.unlock(); DBUG_RETURN(HA_ERR_NO_SUCH_TABLE); } - - if (dict_stats_stop_bg(table)) - break; - dict_sys.unlock(); } if (table->is_temporary()) @@ -13390,9 +13433,13 @@ int ha_innobase::delete_table(const char *name) trx_start_for_ddl(trx); } + dict_table_t *table_stats= nullptr, *index_stats= nullptr; + MDL_ticket *mdl_table= nullptr, *mdl_index= nullptr; dberr_t err= lock_table_for_trx(table, trx, LOCK_X); + const bool fts= err == DB_SUCCESS && (table->flags2 & (DICT_TF2_FTS_HAS_DOC_ID | DICT_TF2_FTS)); + const enum_sql_command sqlcom= enum_sql_command(thd_sql_command(thd)); if (fts) { @@ -13401,16 +13448,73 @@ int ha_innobase::delete_table(const char *name) err= fts_lock_tables(trx, *table); } +#ifdef WITH_PARTITION_STORAGE_ENGINE + const bool rollback_add_partition= + (sqlcom == SQLCOM_ALTER_TABLE && table->name.part()); + + if (rollback_add_partition) + { + if (!fts) + purge_sys.stop_FTS(); + /* This looks like the rollback of ALTER TABLE...ADD PARTITION + that was caused by MDL timeout. We could have written undo log + for inserting the data into the new partitions. */ + if (table->stat_persistent != DICT_STATS_PERSISTENT_OFF) + { + /* We do not really know if we are holding MDL_EXCLUSIVE. Even + though this code is handling the case that we are not holding + it, we might actually hold it. We want to avoid a deadlock + with dict_stats_process_entry_from_recalc_pool(). */ + dict_stats_recalc_pool_del(table->id, true); + /* If statistics calculation is still using this table, we will + catch it below while waiting for purge to stop using this table. */ + } + } +#endif + + if (err == DB_SUCCESS && dict_stats_is_persistent_enabled(table) && + !table->is_stats_table()) + { + table_stats= dict_table_open_on_name(TABLE_STATS_NAME, false, + DICT_ERR_IGNORE_NONE); + if (table_stats) + { + dict_sys.freeze(SRW_LOCK_CALL); + table_stats= dict_acquire_mdl_shared(table_stats, + thd, &mdl_table); + dict_sys.unfreeze(); + } + + index_stats= dict_table_open_on_name(INDEX_STATS_NAME, false, + DICT_ERR_IGNORE_NONE); + if (index_stats) + { + dict_sys.freeze(SRW_LOCK_CALL); + index_stats= dict_acquire_mdl_shared(index_stats, + thd, &mdl_index); + dict_sys.unfreeze(); + } + + if (table_stats && index_stats && + !strcmp(table_stats->name.m_name, TABLE_STATS_NAME) && + !strcmp(index_stats->name.m_name, INDEX_STATS_NAME) && + !(err= lock_table_for_trx(table_stats, trx, LOCK_X))) + err= lock_table_for_trx(index_stats, trx, LOCK_X); + } + + if (err == DB_SUCCESS) + err= lock_sys_tables(trx); + dict_sys.lock(SRW_LOCK_CALL); - trx->dict_operation_lock_mode= RW_X_LATCH; + if (!table->release() && err == DB_SUCCESS) { /* Wait for purge threads to stop using the table. */ for (uint n= 15;;) { - row_mysql_unlock_data_dictionary(trx); + dict_sys.unlock(); std::this_thread::sleep_for(std::chrono::milliseconds(50)); - row_mysql_lock_data_dictionary(trx); + dict_sys.lock(SRW_LOCK_CALL); if (!--n) { @@ -13422,11 +13526,13 @@ int ha_innobase::delete_table(const char *name) } } + trx->dict_operation_lock_mode= true; + if (err != DB_SUCCESS) { err_exit: + trx->dict_operation_lock_mode= false; trx->rollback(); - trx->dict_operation_lock_mode= 0; switch (err) { case DB_CANNOT_DROP_CONSTRAINT: case DB_LOCK_WAIT_TIMEOUT: @@ -13434,12 +13540,19 @@ err_exit: default: ib::error() << "DROP TABLE " << table->name << ": " << err; } - table->stats_bg_flag= BG_STAT_NONE; if (fts) { fts_optimize_add_table(table); purge_sys.resume_FTS(); } +#ifdef WITH_PARTITION_STORAGE_ENGINE + else if (rollback_add_partition) + purge_sys.resume_FTS(); +#endif + if (table_stats) + dict_table_close(table_stats, true, thd, mdl_table); + if (index_stats) + dict_table_close(index_stats, true, thd, mdl_index); dict_sys.unlock(); if (trx != parent_trx) trx->free(); @@ -13448,7 +13561,7 @@ err_exit: if (!table->no_rollback() && trx->check_foreigns) { - const bool drop_db= thd_sql_command(thd) == SQLCOM_DROP_DB; + const bool drop_db= sqlcom == SQLCOM_DROP_DB; for (auto foreign : table->referenced_set) { /* We should allow dropping a referenced table if creating @@ -13477,7 +13590,7 @@ err_exit: if (!table->no_rollback()) { err= trx->drop_table_foreign(table->name); - if (err == DB_SUCCESS) + if (err == DB_SUCCESS && table_stats && index_stats) err= trx->drop_table_statistics(table->name); if (err != DB_SUCCESS) goto err_exit; @@ -13489,14 +13602,22 @@ err_exit: std::vector deleted; trx->commit(deleted); + if (table_stats) + dict_table_close(table_stats, true, thd, mdl_table); + if (index_stats) + dict_table_close(index_stats, true, thd, mdl_index); row_mysql_unlock_data_dictionary(trx); for (pfs_os_file_t d : deleted) os_file_close(d); log_write_up_to(trx->commit_lsn, true); if (trx != parent_trx) trx->free(); - if (fts) - purge_sys.resume_FTS(); + if (!fts) +#ifdef WITH_PARTITION_STORAGE_ENGINE + if (!rollback_add_partition) +#endif + DBUG_RETURN(0); + purge_sys.resume_FTS(); DBUG_RETURN(0); } @@ -13506,7 +13627,7 @@ err_exit: @param[in] to new table name @param[in] use_fk whether to enforce FOREIGN KEY @return DB_SUCCESS or error code */ -inline dberr_t innobase_rename_table(trx_t *trx, const char *from, +static dberr_t innobase_rename_table(trx_t *trx, const char *from, const char *to, bool use_fk) { dberr_t error; @@ -13618,7 +13739,7 @@ int ha_innobase::truncate() info.options|= HA_LEX_CREATE_TMP_TABLE; btr_drop_temporary_table(*ib_table); m_prebuilt->table = nullptr; - row_prebuilt_free(m_prebuilt, false); + row_prebuilt_free(m_prebuilt); m_prebuilt = nullptr; my_free(m_upd_buf); m_upd_buf = nullptr; @@ -13657,6 +13778,9 @@ int ha_innobase::truncate() heap, ib_table->name.m_name, ib_table->id); const char* name = mem_heap_strdup(heap, ib_table->name.m_name); + dict_table_t *table_stats = nullptr, *index_stats = nullptr; + MDL_ticket *mdl_table = nullptr, *mdl_index = nullptr; + dberr_t error = lock_table_for_trx(ib_table, trx, LOCK_X); const bool fts = error == DB_SUCCESS && ib_table->flags2 & (DICT_TF2_FTS_HAS_DOC_ID | DICT_TF2_FTS); @@ -13667,8 +13791,6 @@ int ha_innobase::truncate() error = fts_lock_tables(trx, *ib_table); } - row_mysql_lock_data_dictionary(trx); - dict_stats_wait_bg_to_stop_using_table(ib_table, trx); /* Wait for purge threads to stop using the table. */ for (uint n = 15; ib_table->get_ref_count() > 1; ) { if (!--n) { @@ -13676,11 +13798,42 @@ int ha_innobase::truncate() break; } - row_mysql_unlock_data_dictionary(trx); std::this_thread::sleep_for(std::chrono::milliseconds(50)); - row_mysql_lock_data_dictionary(trx); } + if (error == DB_SUCCESS && dict_stats_is_persistent_enabled(ib_table) + && !ib_table->is_stats_table()) { + table_stats= dict_table_open_on_name(TABLE_STATS_NAME, false, + DICT_ERR_IGNORE_NONE); + if (table_stats) { + dict_sys.freeze(SRW_LOCK_CALL); + table_stats = dict_acquire_mdl_shared( + table_stats, m_user_thd, &mdl_table); + dict_sys.unfreeze(); + } + index_stats = dict_table_open_on_name(INDEX_STATS_NAME, false, + DICT_ERR_IGNORE_NONE); + if (index_stats) { + dict_sys.freeze(SRW_LOCK_CALL); + index_stats = dict_acquire_mdl_shared( + index_stats, m_user_thd, &mdl_index); + dict_sys.unfreeze(); + } + + if (table_stats && index_stats + && !strcmp(table_stats->name.m_name, TABLE_STATS_NAME) + && !strcmp(index_stats->name.m_name, INDEX_STATS_NAME) && + !(error = lock_table_for_trx(table_stats, trx, LOCK_X))) { + error = lock_table_for_trx(index_stats, trx, LOCK_X); + } + } + + if (error == DB_SUCCESS) { + error = lock_sys_tables(trx); + } + + row_mysql_lock_data_dictionary(trx); + if (error == DB_SUCCESS) { error = innobase_rename_table(trx, ib_table->name.m_name, temp_name, false); @@ -13716,7 +13869,7 @@ int ha_innobase::truncate() if (err) { reload: m_prebuilt->table = dict_table_open_on_name( - name, false, false, DICT_ERR_IGNORE_NONE); + name, false, DICT_ERR_IGNORE_NONE); m_prebuilt->table->def_trx_id = def_trx_id; } else { row_prebuilt_t* prebuilt = m_prebuilt; @@ -13733,7 +13886,7 @@ reload: m_prebuilt->stored_select_lock_type = stored_lock; m_prebuilt->table->update_time = update_time; - row_prebuilt_free(prebuilt, false); + row_prebuilt_free(prebuilt); my_free(upd_buf); } else { /* Revert to the old table. */ @@ -13748,6 +13901,14 @@ reload: trx->free(); mem_heap_free(heap); + + if (table_stats) { + dict_table_close(table_stats, false, m_user_thd, mdl_table); + } + if (index_stats) { + dict_table_close(index_stats, false, m_user_thd, mdl_index); + } + DBUG_RETURN(err); } @@ -13771,23 +13932,69 @@ ha_innobase::rename_table( } trx_t* trx = innobase_trx_allocate(thd); + trx_start_for_ddl(trx); + + dict_table_t *table_stats = nullptr, *index_stats = nullptr; + MDL_ticket *mdl_table = nullptr, *mdl_index = nullptr; + char norm_from[MAX_FULL_NAME_LEN]; + char norm_to[MAX_FULL_NAME_LEN]; + + normalize_table_name(norm_from, from); + normalize_table_name(norm_to, to); + + dberr_t error = DB_SUCCESS; + + if (strcmp(norm_from, TABLE_STATS_NAME) + && strcmp(norm_from, INDEX_STATS_NAME) + && strcmp(norm_to, TABLE_STATS_NAME) + && strcmp(norm_to, INDEX_STATS_NAME)) { + table_stats = dict_table_open_on_name(TABLE_STATS_NAME, false, + DICT_ERR_IGNORE_NONE); + if (table_stats) { + dict_sys.freeze(SRW_LOCK_CALL); + table_stats = dict_acquire_mdl_shared( + table_stats, thd, &mdl_table); + dict_sys.unfreeze(); + } + index_stats = dict_table_open_on_name(INDEX_STATS_NAME, false, + DICT_ERR_IGNORE_NONE); + if (index_stats) { + dict_sys.freeze(SRW_LOCK_CALL); + index_stats = dict_acquire_mdl_shared( + index_stats, thd, &mdl_index); + dict_sys.unfreeze(); + } + + if (table_stats && index_stats + && !strcmp(table_stats->name.m_name, TABLE_STATS_NAME) + && !strcmp(index_stats->name.m_name, INDEX_STATS_NAME) && + !(error = lock_table_for_trx(table_stats, trx, LOCK_X))) { + error = lock_table_for_trx(index_stats, trx, LOCK_X); + } + } + + if (error == DB_SUCCESS) { + error = lock_table_for_trx(dict_sys.sys_tables, trx, LOCK_X); + if (error == DB_SUCCESS) { + error = lock_table_for_trx(dict_sys.sys_foreign, trx, + LOCK_X); + if (error == DB_SUCCESS) { + error = lock_table_for_trx( + dict_sys.sys_foreign_cols, + trx, LOCK_X); + } + } + } - /* We are doing a DDL operation. */ - trx->will_lock = true; - trx->dict_operation = true; row_mysql_lock_data_dictionary(trx); - dberr_t error = innobase_rename_table(trx, from, to, true); + if (error == DB_SUCCESS) { + error = innobase_rename_table(trx, from, to, true); + } DEBUG_SYNC(thd, "after_innobase_rename_table"); - if (error == DB_SUCCESS) { - char norm_from[MAX_FULL_NAME_LEN]; - char norm_to[MAX_FULL_NAME_LEN]; - - normalize_table_name(norm_from, from); - normalize_table_name(norm_to, to); - + if (error == DB_SUCCESS && table_stats && index_stats) { error = dict_stats_rename_table(norm_from, norm_to, trx); if (error == DB_DUPLICATE_KEY) { /* The duplicate may also occur in @@ -13804,6 +14011,12 @@ ha_innobase::rename_table( trx->rollback(); } + if (table_stats) { + dict_table_close(table_stats, true, thd, mdl_table); + } + if (index_stats) { + dict_table_close(index_stats, true, thd, mdl_index); + } row_mysql_unlock_data_dictionary(trx); if (error == DB_SUCCESS) { log_write_up_to(trx->commit_lsn, true); @@ -14298,8 +14511,6 @@ ha_innobase::info_low( DEBUG_SYNC_C("ha_innobase_info_low"); - dict_sys.assert_not_locked(); - /* If we are forcing recovery at a high level, we will suppress statistics calculation on tables, because that may crash the server if an index is badly corrupted. */ @@ -14328,15 +14539,11 @@ ha_innobase::info_low( m_prebuilt->trx->op_info = "updating table statistics"; if (dict_stats_is_persistent_enabled(ib_table)) { - if (is_analyze) { - row_mysql_lock_data_dictionary( - m_prebuilt->trx); - dict_stats_recalc_pool_del(ib_table); - dict_stats_wait_bg_to_stop_using_table( - ib_table, m_prebuilt->trx); - row_mysql_unlock_data_dictionary( - m_prebuilt->trx); + if (!srv_read_only_mode) { + dict_stats_recalc_pool_del( + ib_table->id, false); + } opt = DICT_STATS_RECALC_PERSISTENT; } else { /* This is e.g. 'SHOW INDEXES', fetch @@ -14349,13 +14556,6 @@ ha_innobase::info_low( ret = dict_stats_update(ib_table, opt); - if (opt == DICT_STATS_RECALC_PERSISTENT) { - dict_sys.mutex_lock(); - ib_table->stats_bg_flag - &= byte(~BG_STAT_SHOULD_QUIT); - dict_sys.mutex_unlock(); - } - if (ret != DB_SUCCESS) { m_prebuilt->trx->op_info = ""; DBUG_RETURN(HA_ERR_GENERIC); @@ -14830,8 +15030,7 @@ ha_innobase::check( index = dict_table_get_first_index(m_prebuilt->table); if (!index->is_corrupted()) { - dict_set_corrupted( - index, m_prebuilt->trx, "CHECK TABLE"); + dict_set_corrupted(index, "CHECK TABLE", false); } push_warning_printf(m_user_thd, @@ -14912,9 +15111,9 @@ ha_innobase::check( "dict_set_index_corrupted", if (!index->is_primary()) { m_prebuilt->index_usable = FALSE; - // row_mysql_lock_data_dictionary(m_prebuilt->trx); - dict_set_corrupted(index, m_prebuilt->trx, "dict_set_index_corrupted"); - // row_mysql_unlock_data_dictionary(m_prebuilt->trx); + dict_set_corrupted(index, + "dict_set_index_corrupted", + false); }); if (UNIV_UNLIKELY(!m_prebuilt->index_usable)) { @@ -14976,8 +15175,8 @@ ha_innobase::check( " index %s is corrupted.", index->name()); is_ok = false; - dict_set_corrupted( - index, m_prebuilt->trx, "CHECK TABLE-check index"); + dict_set_corrupted(index, "CHECK TABLE-check index", + false); } @@ -14992,9 +15191,8 @@ ha_innobase::check( " entries, should be " ULINTPF ".", index->name(), n_rows, n_rows_in_table); is_ok = false; - dict_set_corrupted( - index, m_prebuilt->trx, - "CHECK TABLE; Wrong count"); + dict_set_corrupted(index, "CHECK TABLE; Wrong count", + false); } } @@ -15155,12 +15353,9 @@ get_foreign_key_info( /* Load referenced table to update FK referenced key name. */ if (foreign->referenced_table == NULL) { - dict_table_t* ref_table; - - dict_sys.assert_locked(); - ref_table = dict_table_open_on_name( + dict_table_t* ref_table = dict_table_open_on_name( foreign->referenced_table_name_lookup, - TRUE, FALSE, DICT_ERR_IGNORE_NONE); + true, DICT_ERR_IGNORE_NONE); if (ref_table == NULL) { @@ -15173,8 +15368,7 @@ get_foreign_key_info( << foreign->foreign_table_name; } } else { - - dict_table_close(ref_table, TRUE, FALSE); + dict_table_close(ref_table, true); } } @@ -15212,7 +15406,7 @@ ha_innobase::get_foreign_key_list( m_prebuilt->trx->op_info = "getting list of foreign keys"; - dict_sys.mutex_lock(); + dict_sys.lock(SRW_LOCK_CALL); for (dict_foreign_set::iterator it = m_prebuilt->table->foreign_set.begin(); @@ -15229,7 +15423,7 @@ ha_innobase::get_foreign_key_list( } } - dict_sys.mutex_unlock(); + dict_sys.unlock(); m_prebuilt->trx->op_info = ""; @@ -15250,7 +15444,7 @@ ha_innobase::get_parent_foreign_key_list( m_prebuilt->trx->op_info = "getting list of referencing foreign keys"; - dict_sys.mutex_lock(); + dict_sys.freeze(SRW_LOCK_CALL); for (dict_foreign_set::iterator it = m_prebuilt->table->referenced_set.begin(); @@ -15267,7 +15461,7 @@ ha_innobase::get_parent_foreign_key_list( } } - dict_sys.mutex_unlock(); + dict_sys.unfreeze(); m_prebuilt->trx->op_info = ""; @@ -17096,10 +17290,10 @@ static int innodb_ft_aux_table_validate(THD *thd, st_mysql_sys_var*, if (const char* table_name = value->val_str(value, buf, &len)) { if (dict_table_t* table = dict_table_open_on_name( - table_name, FALSE, TRUE, DICT_ERR_IGNORE_NONE)) { + table_name, false, DICT_ERR_IGNORE_NONE)) { const table_id_t id = dict_table_has_fts_index(table) ? table->id : 0; - dict_table_close(table, FALSE, FALSE); + dict_table_close(table); if (id) { innodb_ft_aux_table_id = id; if (table_name == buf) { @@ -19798,9 +19992,8 @@ TABLE* innobase_init_vc_templ(dict_table_t* table) DBUG_RETURN(NULL); } - dict_sys.mutex_lock(); - innobase_build_v_templ(mysql_table, table, table->vc_templ, NULL, true); - dict_sys.mutex_unlock(); + innobase_build_v_templ(mysql_table, table, table->vc_templ, NULL, + false); DBUG_RETURN(mysql_table); } diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 683b0110375..60b32736474 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -486,7 +486,7 @@ inline bool dict_table_t::instant_column(const dict_table_t& table, DBUG_ASSERT(table.n_cols + table.n_dropped() >= n_cols + n_dropped()); DBUG_ASSERT(!table.persistent_autoinc || persistent_autoinc == table.persistent_autoinc); - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); { const char* end = table.col_names; @@ -731,7 +731,7 @@ inline void dict_table_t::rollback_instant( const char* old_v_col_names, const ulint* col_map) { - ut_d(dict_sys.assert_locked()); + ut_ad(dict_sys.locked()); if (cols == old_cols) { /* Alter fails before instant operation happens. @@ -2052,11 +2052,7 @@ ha_innobase::check_if_supported_inplace_alter( DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); } - if (!dict_sys.sys_tables_exist()) { - ha_alter_info->unsupported_reason - = "missing InnoDB system tables"; - DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); - } + ut_ad(dict_sys.sys_tables_exist()); /* Only support online add foreign key constraint when check_foreigns is turned off */ @@ -2639,7 +2635,7 @@ innobase_init_foreign( ulint referenced_num_field) /*!< in: number of referenced columns */ { - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); if (constraint_name) { ulint db_len; @@ -3043,7 +3039,7 @@ innobase_get_foreign_key_info( add_fk[num_fk] = dict_mem_foreign_create(); - dict_sys.mutex_lock(); + dict_sys.lock(SRW_LOCK_CALL); referenced_table_name = dict_get_referenced_table( table->name.m_name, @@ -3059,11 +3055,9 @@ innobase_get_foreign_key_info( referenced_table = NULL;); if (!referenced_table && trx->check_foreigns) { - dict_sys.mutex_unlock(); my_error(ER_FK_CANNOT_OPEN_PARENT, MYF(0), fk_key->ref_table.str); - - goto err_exit; + goto err_exit_unlock; } if (fk_key->ref_columns.elements > 0) { @@ -3092,12 +3086,11 @@ innobase_get_foreign_key_info( /* Check whether there exist such index in the the index create clause */ if (!referenced_index) { - dict_sys.mutex_unlock(); my_error(ER_FK_NO_INDEX_PARENT, MYF(0), fk_key->name.str ? fk_key->name.str : "", fk_key->ref_table.str); - goto err_exit; + goto err_exit_unlock; } } else { ut_a(!trx->check_foreigns); @@ -3107,10 +3100,9 @@ innobase_get_foreign_key_info( } else { /* Not possible to add a foreign key without a referenced column */ - dict_sys.mutex_unlock(); my_error(ER_CANNOT_ADD_FOREIGN, MYF(0), fk_key->ref_table.str); - goto err_exit; + goto err_exit_unlock; } if (!innobase_init_foreign( @@ -3119,15 +3111,14 @@ innobase_get_foreign_key_info( num_col, referenced_table_name, referenced_table, referenced_index, referenced_column_names, referenced_num_col)) { - dict_sys.mutex_unlock(); my_error( ER_DUP_CONSTRAINT_NAME, MYF(0), "FOREIGN KEY", add_fk[num_fk]->id); - goto err_exit; + goto err_exit_unlock; } - dict_sys.mutex_unlock(); + dict_sys.unlock(); correct_option = innobase_set_foreign_key_option( add_fk[num_fk], fk_key); @@ -3158,6 +3149,8 @@ innobase_get_foreign_key_info( *n_add_fk = num_fk; DBUG_RETURN(true); +err_exit_unlock: + dict_sys.unlock(); err_exit: for (ulint i = 0; i <= num_fk; i++) { if (add_fk[i]) { @@ -4073,8 +4066,8 @@ online_retry_drop_indexes_low( dict_table_t* table, /*!< in/out: table */ trx_t* trx) /*!< in/out: transaction */ { - dict_sys.assert_locked(); - ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); + ut_ad(dict_sys.locked()); + ut_ad(trx->dict_operation_lock_mode); ut_ad(trx->dict_operation); /* We can have table->n_ref_count > 1, because other threads @@ -4108,65 +4101,34 @@ static void commit_unlock_and_unlink(trx_t *trx) unlock_and_close_files(deleted, trx); } -/********************************************************************//** +/** Drop any indexes that we were not able to free previously due to -open table handles. */ -static MY_ATTRIBUTE((nonnull)) -void -online_retry_drop_indexes( -/*======================*/ - dict_table_t* table, /*!< in/out: table */ - THD* user_thd) /*!< in/out: MySQL connection */ +open table handles. +@param table InnoDB table +@param thd connection handle +*/ +static void online_retry_drop_indexes(dict_table_t *table, THD *thd) { - if (table->drop_aborted) { - trx_t* trx = innobase_trx_allocate(user_thd); + if (table->drop_aborted) + { + trx_t *trx= innobase_trx_allocate(thd); - trx_start_for_ddl(trx); + trx_start_for_ddl(trx); + if (lock_sys_tables(trx) == DB_SUCCESS) + { + row_mysql_lock_data_dictionary(trx); + online_retry_drop_indexes_low(table, trx); + commit_unlock_and_unlink(trx); + } + else + trx->commit(); + trx->free(); + } - row_mysql_lock_data_dictionary(trx); - online_retry_drop_indexes_low(table, trx); - commit_unlock_and_unlink(trx); - trx->free(); - } - - ut_d(dict_sys.mutex_lock()); - ut_d(dict_table_check_for_dup_indexes(table, CHECK_ALL_COMPLETE)); - ut_d(dict_sys.mutex_unlock()); - ut_ad(!table->drop_aborted); -} - -/********************************************************************//** -Commit a dictionary transaction and drop any indexes that we were not -able to free previously due to open table handles. */ -static MY_ATTRIBUTE((nonnull)) -void -online_retry_drop_indexes_with_trx( -/*===============================*/ - dict_table_t* table, /*!< in/out: table */ - trx_t* trx) /*!< in/out: transaction */ -{ - ut_ad(trx_state_eq(trx, TRX_STATE_NOT_STARTED)); - - ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); - - /* Now that the dictionary is being locked, check if we can - drop any incompletely created indexes that may have been left - behind in rollback_inplace_alter_table() earlier. */ - if (table->drop_aborted) { - trx_start_for_ddl(trx); - - online_retry_drop_indexes_low(table, trx); - std::vector deleted; - trx->commit(deleted); - /* FIXME: We are holding the data dictionary latch here - while waiting for the files to be actually deleted. - However, we should never have any deleted files here, - because they would be related to ADD FULLTEXT INDEX, - and that operation is never supported online. */ - for (pfs_os_file_t d : deleted) { - os_file_close(d); - } - } + ut_d(dict_sys.freeze(SRW_LOCK_CALL)); + ut_d(dict_table_check_for_dup_indexes(table, CHECK_ALL_COMPLETE)); + ut_d(dict_sys.unfreeze()); + ut_ad(!table->drop_aborted); } /** Determines if InnoDB is dropping a foreign key constraint. @@ -4212,7 +4174,7 @@ innobase_check_foreigns_low( bool drop) { dict_foreign_t* foreign; - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); /* Check if any FOREIGN KEY constraints are defined on this column. */ @@ -4810,8 +4772,8 @@ innobase_update_gis_column_type( DBUG_ENTER("innobase_update_gis_column_type"); DBUG_ASSERT(trx->dict_operation); - ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); - ut_d(dict_sys.assert_locked()); + ut_ad(trx->dict_operation_lock_mode); + ut_ad(dict_sys.locked()); info = pars_info_create(); @@ -4827,8 +4789,7 @@ innobase_update_gis_column_type( "BEGIN\n" "UPDATE SYS_COLUMNS SET MTYPE=:mtype\n" "WHERE TABLE_ID=:tableid AND NAME=:name;\n" - "END;\n", - false, trx); + "END;\n", trx); trx->error_state = DB_SUCCESS; trx->op_info = ""; @@ -5147,8 +5108,7 @@ static bool innobase_insert_sys_virtual( "PROCEDURE P () IS\n" "BEGIN\n" "INSERT INTO SYS_VIRTUAL VALUES (:id, :pos, :base_pos);\n" - "END;\n", - FALSE, trx)) { + "END;\n", trx)) { my_error(ER_INTERNAL_ERROR, MYF(0), "InnoDB: ADD COLUMN...VIRTUAL"); return true; @@ -5197,7 +5157,7 @@ static bool innodb_insert_sys_columns( "NAME=:name, MTYPE=:mtype, PRTYPE=:prtype, " "LEN=:len, PREC=:base\n" "WHERE TABLE_ID=:id AND POS=:pos;\n" - "END;\n", FALSE, trx)) { + "END;\n", trx)) { my_error(ER_INTERNAL_ERROR, MYF(0), "InnoDB: Updating SYS_COLUMNS failed"); return true; @@ -5212,7 +5172,7 @@ static bool innodb_insert_sys_columns( "BEGIN\n" "INSERT INTO SYS_COLUMNS VALUES" "(:id,:pos,:name,:mtype,:prtype,:len,:base);\n" - "END;\n", FALSE, trx)) { + "END;\n", trx)) { my_error(ER_INTERNAL_ERROR, MYF(0), "InnoDB: Insert into SYS_COLUMNS failed"); return true; @@ -5270,7 +5230,7 @@ static bool innodb_update_cols(const dict_table_t* table, ulint n, trx_t* trx) "BEGIN\n" "UPDATE SYS_TABLES SET N_COLS = :n" " WHERE ID = :id;\n" - "END;\n", FALSE, trx)) { + "END;\n", trx)) { my_error(ER_INTERNAL_ERROR, MYF(0), "InnoDB: Updating SYS_TABLES.N_COLS failed"); return true; @@ -5325,7 +5285,7 @@ static bool innobase_instant_drop_cols(table_id_t id, ulint pos, trx_t* trx) "DELETE FROM SYS_COLUMNS WHERE\n" "TABLE_ID = :id AND POS >= :pos;\n" "DELETE FROM SYS_VIRTUAL WHERE TABLE_ID = :id;\n" - "END;\n", FALSE, trx); + "END;\n", trx); if (err != DB_SUCCESS) { my_error(ER_INTERNAL_ERROR, MYF(0), "InnoDB: DELETE from SYS_COLUMNS/SYS_VIRTUAL failed"); @@ -5363,8 +5323,7 @@ innobase_update_v_pos_sys_columns( "SET POS = :val\n" "WHERE POS = :pos\n" "AND TABLE_ID = :id;\n" - "END;\n", - FALSE, trx); + "END;\n", trx); return(error); } @@ -5397,8 +5356,7 @@ innobase_update_v_pos_sys_virtual( "SET POS = :val\n" "WHERE POS = :pos\n" "AND TABLE_ID = :id;\n" - "END;\n", - FALSE, trx); + "END;\n", trx); return(error); } @@ -5432,8 +5390,7 @@ innobase_drop_one_virtual_sys_columns( "DELETE FROM SYS_COLUMNS\n" "WHERE TABLE_ID = :id\n" "AND NAME = :name;\n" - "END;\n", - FALSE, trx); + "END;\n", trx); if (error != DB_SUCCESS) { return(error); @@ -5491,8 +5448,7 @@ innobase_drop_one_virtual_sys_virtual( "DELETE FROM SYS_VIRTUAL\n" "WHERE TABLE_ID = :id\n" "AND POS = :pos;\n" - "END;\n", - FALSE, trx); + "END;\n", trx); return(error); } @@ -6256,7 +6212,6 @@ prepare_inplace_alter_table_dict( create_table_info_t info(ctx->prebuilt->trx->mysql_thd, altered_table, ha_alter_info->create_info, NULL, NULL, srv_file_per_table); - ut_d(bool stats_wait = false); /* The primary index would be rebuilt if a FTS Doc ID column is to be added, and the primary index definition @@ -6310,6 +6265,10 @@ acquire_lock: } } + if (error == DB_SUCCESS) { + error = lock_sys_tables(ctx->trx); + } + if (error != DB_SUCCESS) { table_lock_failed = true; goto error_handling; @@ -6320,16 +6279,6 @@ acquire_lock: row_mysql_lock_data_dictionary(ctx->trx); dict_locked = true; - - /* Wait for background stats processing to stop using the table that - we are going to alter. We know bg stats will not start using it again - until we are holding the data dict locked and we are holding it here - at least until checking ut_ad(user_table->n_ref_count == 1) below. - XXX what may happen if bg stats opens the table after we - have unlocked data dictionary below? */ - dict_stats_wait_bg_to_stop_using_table(user_table, ctx->trx); - ut_d(stats_wait = true); - online_retry_drop_indexes_low(ctx->new_table, ctx->trx); ut_d(dict_table_check_for_dup_indexes( @@ -6352,8 +6301,20 @@ new_clustered_failed: ut_ad(user_table->get_ref_count() == 1); - online_retry_drop_indexes_with_trx( - user_table, ctx->trx); + if (user_table->drop_aborted) { + row_mysql_unlock_data_dictionary(ctx->trx); + trx_start_for_ddl(ctx->trx); + if (lock_sys_tables(ctx->trx) == DB_SUCCESS) { + row_mysql_lock_data_dictionary( + ctx->trx); + online_retry_drop_indexes_low( + user_table, ctx->trx); + commit_unlock_and_unlink(ctx->trx); + } else { + ctx->trx->commit(); + } + row_mysql_lock_data_dictionary(ctx->trx); + } if (ctx->need_rebuild()) { if (ctx->new_table) { @@ -6626,8 +6587,8 @@ wrong_column_name: ha_alter_info, ctx->new_table, ctx->trx); if (error != DB_SUCCESS) { ut_ad(error == DB_ERROR); - error = DB_UNSUPPORTED; - goto error_handling; + my_error(ER_TABLE_CANT_HANDLE_SPKEYS, MYF(0), "SYS_COLUMNS"); + goto error_handled; } } @@ -7055,8 +7016,8 @@ error_handling_drop_uncached: if (fts_index) { ut_ad(ctx->trx->dict_operation); - ut_ad(ctx->trx->dict_operation_lock_mode == RW_X_LATCH); - ut_d(dict_sys.assert_locked()); + ut_ad(ctx->trx->dict_operation_lock_mode); + ut_ad(dict_sys.locked()); DICT_TF2_FLAG_SET(ctx->new_table, DICT_TF2_FTS); if (ctx->need_rebuild()) { @@ -7148,27 +7109,12 @@ error_handling: case DB_DUPLICATE_KEY: my_error(ER_DUP_KEY, MYF(0), "SYS_INDEXES"); break; - case DB_UNSUPPORTED: - my_error(ER_TABLE_CANT_HANDLE_SPKEYS, MYF(0), "SYS_COLUMNS"); - break; default: my_error_innodb(error, table_name, user_table->flags); } ctx->trx->rollback(); -error_handled: - - ctx->prebuilt->trx->error_info = NULL; - ctx->trx->error_state = DB_SUCCESS; - - if (!dict_locked) { - row_mysql_lock_data_dictionary(ctx->trx); - if (table_lock_failed) { - goto err_exit; - } - } - if (ctx->need_rebuild()) { /* Free the log for online table rebuild, if one was allocated. */ @@ -7188,17 +7134,48 @@ error_handled: clust_index->lock.x_unlock(); } - /* n_ref_count must be 1, because purge cannot + ctx->prebuilt->trx->error_info = NULL; + ctx->trx->error_state = DB_SUCCESS; + + if (false) { +error_handled: + ut_ad(!table_lock_failed); + ut_ad(ctx->trx->state == TRX_STATE_ACTIVE); + ut_ad(!ctx->trx->undo_no); + ut_ad(dict_locked); + } else if (table_lock_failed) { + if (!dict_locked) { + row_mysql_lock_data_dictionary(ctx->trx); + } + goto err_exit; + } else { + ut_ad(ctx->trx->state == TRX_STATE_NOT_STARTED); + if (new_clustered && !user_table->drop_aborted) { + goto err_exit; + } + if (dict_locked) { + row_mysql_unlock_data_dictionary(ctx->trx); + } + trx_start_for_ddl(ctx->trx); + dberr_t err= lock_sys_tables(ctx->trx); + row_mysql_lock_data_dictionary(ctx->trx); + if (err != DB_SUCCESS) { + goto err_exit; + } + } + + /* n_ref_count must be 1, because background threads cannot be executing on this very table as we are - holding dict_sys.latch X-latch. */ - ut_ad(!stats_wait || ctx->online || user_table->get_ref_count() == 1); + holding MDL_EXCLUSIVE. */ + ut_ad(ctx->online || user_table->get_ref_count() == 1); if (new_clustered) { - online_retry_drop_indexes_with_trx(user_table, ctx->trx); + online_retry_drop_indexes_low(user_table, ctx->trx); + commit_unlock_and_unlink(ctx->trx); + row_mysql_lock_data_dictionary(ctx->trx); } else { - trx_start_for_ddl(ctx->trx); row_merge_drop_indexes(ctx->trx, user_table, true); - trx_commit_for_mysql(ctx->trx); + ctx->trx->commit(); } ut_d(dict_table_check_for_dup_indexes(user_table, CHECK_ALL_COMPLETE)); @@ -7342,8 +7319,8 @@ rename_index_try( trx_t* trx) { DBUG_ENTER("rename_index_try"); - ut_d(dict_sys.assert_locked()); - ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); + ut_ad(dict_sys.locked()); + ut_ad(trx->dict_operation_lock_mode); pars_info_t* pinfo; dberr_t err; @@ -7370,8 +7347,7 @@ rename_index_try( "WHERE\n" "ID = :index_id AND\n" "TABLE_ID = :table_id;\n" - "END;\n", - FALSE, trx); /* pinfo is freed by que_eval_sql() */ + "END;\n", trx); /* pinfo is freed by que_eval_sql() */ DBUG_EXECUTE_IF( "ib_rename_index_fail1", @@ -7400,7 +7376,7 @@ void innobase_rename_index_cache(dict_index_t* index, const char* new_name) { DBUG_ENTER("innobase_rename_index_cache"); - ut_d(dict_sys.assert_locked()); + ut_ad(dict_sys.locked()); size_t old_name_len = strlen(index->name); size_t new_name_len = strlen(new_name); @@ -7559,14 +7535,14 @@ ha_innobase::prepare_inplace_alter_table( } #endif /* UNIV_DEBUG */ - ut_d(dict_sys.mutex_lock()); + ut_d(dict_sys.freeze(SRW_LOCK_CALL)); ut_d(dict_table_check_for_dup_indexes( m_prebuilt->table, CHECK_ABORTED_OK)); - ut_d(dict_sys.mutex_unlock()); + ut_d(dict_sys.unfreeze()); if (!(ha_alter_info->handler_flags & ~INNOBASE_INPLACE_IGNORE)) { /* Nothing to do */ - DBUG_ASSERT(m_prebuilt->trx->dict_operation_lock_mode == 0); + DBUG_ASSERT(!m_prebuilt->trx->dict_operation_lock_mode); DBUG_RETURN(false); } @@ -7646,7 +7622,7 @@ ha_innobase::prepare_inplace_alter_table( ha_alter_info->key_info_buffer, ha_alter_info->key_count)) { err_exit_no_heap: - DBUG_ASSERT(m_prebuilt->trx->dict_operation_lock_mode == 0); + DBUG_ASSERT(!m_prebuilt->trx->dict_operation_lock_mode); online_retry_drop_indexes(m_prebuilt->table, m_user_thd); DBUG_RETURN(true); } @@ -8105,7 +8081,7 @@ err_exit: == ALTER_OPTIONS && !alter_options_need_rebuild(ha_alter_info, table))) { - DBUG_ASSERT(m_prebuilt->trx->dict_operation_lock_mode == 0); + DBUG_ASSERT(!m_prebuilt->trx->dict_operation_lock_mode); online_retry_drop_indexes(m_prebuilt->table, m_user_thd); if (heap) { @@ -8507,10 +8483,10 @@ oom: KEY* dup_key; all_done: case DB_SUCCESS: - ut_d(dict_sys.mutex_lock()); + ut_d(dict_sys.freeze(SRW_LOCK_CALL)); ut_d(dict_table_check_for_dup_indexes( m_prebuilt->table, CHECK_PARTIAL_OK)); - ut_d(dict_sys.mutex_unlock()); + ut_d(dict_sys.unfreeze()); /* prebuilt->table->n_ref_count can be anything here, given that we hold at most a shared lock on the table. */ goto ok_exit; @@ -8571,7 +8547,7 @@ innobase_online_rebuild_log_free( dict_table_t* table) { dict_index_t* clust_index = dict_table_get_first_index(table); - ut_d(dict_sys.assert_locked()); + ut_ad(dict_sys.locked()); clust_index->lock.x_lock(SRW_LOCK_CALL); if (clust_index->online_log) { @@ -8723,6 +8699,9 @@ inline bool rollback_inplace_alter_table(Alter_inplace_info *ha_alter_info, if (index->type & DICT_FTS) err= fts_lock_index_tables(ctx->trx, *index); } + if (err == DB_SUCCESS) + err= lock_sys_tables(ctx->trx); + row_mysql_lock_data_dictionary(ctx->trx); /* Detach ctx->new_table from dict_index_t::online_log. */ innobase_online_rebuild_log_free(ctx->old_table); @@ -8749,18 +8728,28 @@ inline bool rollback_inplace_alter_table(Alter_inplace_info *ha_alter_info, { DBUG_ASSERT(!(ha_alter_info->handler_flags & ALTER_ADD_PK_INDEX)); DBUG_ASSERT(ctx->old_table == prebuilt->table); + uint &innodb_lock_wait_timeout= + thd_lock_wait_timeout(ctx->trx->mysql_thd); + const uint save_timeout= innodb_lock_wait_timeout; + innodb_lock_wait_timeout= ~0U; /* infinite */ + if (fts_exist) { for (ulint a= 0; a < ctx->num_to_add_index; a++) { const dict_index_t *index = ctx->add_index[a]; - // FIXME: skip fts_drop_index_tables() if we failed to acquire locks if (index->type & DICT_FTS) - fts_lock_index_tables(ctx->trx, *index); + ut_a(!fts_lock_index_tables(ctx->trx, *index)); } - // FIXME: skip fts_drop_tables() if we failed to acquire locks - fts_lock_common_tables(ctx->trx, *ctx->new_table); + ut_a(!fts_lock_common_tables(ctx->trx, *ctx->new_table)); + ut_a(!lock_sys_tables(ctx->trx)); } + else + { + ut_a(!lock_table_for_trx(dict_sys.sys_indexes, ctx->trx, LOCK_X)); + ut_a(!lock_table_for_trx(dict_sys.sys_fields, ctx->trx, LOCK_X)); + } + innodb_lock_wait_timeout= save_timeout; row_mysql_lock_data_dictionary(ctx->trx); ctx->rollback_instant(); innobase_rollback_sec_index(ctx->old_table, table, @@ -8776,10 +8765,10 @@ inline bool rollback_inplace_alter_table(Alter_inplace_info *ha_alter_info, purge_sys.resume_FTS(); if (ctx->old_table->fts) { - dict_sys.mutex_lock(); + dict_sys.lock(SRW_LOCK_CALL); ut_ad(fts_check_cached_index(ctx->old_table)); fts_optimize_add_table(ctx->old_table); - dict_sys.mutex_unlock(); + dict_sys.unlock(); } goto free_and_exit; } @@ -8849,8 +8838,8 @@ innobase_drop_foreign_try( DBUG_ENTER("innobase_drop_foreign_try"); DBUG_ASSERT(trx->dict_operation); - ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); - ut_d(dict_sys.assert_locked()); + ut_ad(trx->dict_operation_lock_mode); + ut_ad(dict_sys.locked()); /* Drop the constraint from the data dictionary. */ static const char sql[] = @@ -8867,7 +8856,7 @@ innobase_drop_foreign_try( pars_info_add_str_literal(info, "id", foreign_id); trx->op_info = "dropping foreign key constraint from dictionary"; - error = que_eval_sql(info, sql, FALSE, trx); + error = que_eval_sql(info, sql, trx); trx->op_info = ""; DBUG_EXECUTE_IF("ib_drop_foreign_error", @@ -8905,8 +8894,8 @@ innobase_rename_column_try( DBUG_ENTER("innobase_rename_column_try"); DBUG_ASSERT(trx->dict_operation); - ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); - ut_d(dict_sys.assert_locked()); + ut_ad(trx->dict_operation_lock_mode); + ut_ad(dict_sys.locked()); if (ctx.need_rebuild()) { goto rename_foreign; @@ -8952,8 +8941,7 @@ innobase_rename_column_try( "UPDATE SYS_FIELDS SET COL_NAME=:new\n" "WHERE INDEX_ID=:indexid\n" "AND POS=:nth;\n" - "END;\n", - FALSE, trx); + "END;\n", trx); DBUG_EXECUTE_IF("ib_rename_column_error", error = DB_OUT_OF_FILE_SPACE;); @@ -8983,8 +8971,7 @@ innobase_rename_column_try( "UPDATE SYS_FIELDS SET COL_NAME=:new\n" "WHERE INDEX_ID=:indexid\n" "AND POS=:nth;\n" - "END;\n", - FALSE, trx); + "END;\n", trx); if (error != DB_SUCCESS) { goto err_exit; @@ -9045,8 +9032,7 @@ rename_foreign: "UPDATE SYS_FOREIGN_COLS\n" "SET FOR_COL_NAME=:new\n" "WHERE ID=:id AND POS=:nth;\n" - "END;\n", - FALSE, trx); + "END;\n", trx); if (error != DB_SUCCESS) { goto err_exit; @@ -9087,8 +9073,7 @@ rename_foreign: "UPDATE SYS_FOREIGN_COLS\n" "SET REF_COL_NAME=:new\n" "WHERE ID=:id AND POS=:nth;\n" - "END;\n", - FALSE, trx); + "END;\n", trx); if (error != DB_SUCCESS) { goto err_exit; @@ -9223,8 +9208,8 @@ innobase_rename_or_enlarge_column_try( DBUG_ASSERT(!ctx->need_rebuild()); DBUG_ASSERT(trx->dict_operation); - ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); - ut_d(dict_sys.assert_locked()); + ut_ad(trx->dict_operation_lock_mode); + ut_ad(dict_sys.locked()); ulint n_base; @@ -9650,7 +9635,7 @@ innobase_update_foreign_cache( DBUG_ENTER("innobase_update_foreign_cache"); - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); user_table = ctx->old_table; @@ -9764,8 +9749,7 @@ vers_change_field_try( "BEGIN\n" "UPDATE SYS_COLUMNS SET PRTYPE=:prtype\n" "WHERE TABLE_ID=:tableid AND POS=:pos;\n" - "END;\n", - false, trx); + "END;\n", trx); if (error != DB_SUCCESS) { my_error_innodb(error, table_name, 0); @@ -9902,7 +9886,7 @@ commit_try_rebuild( DBUG_ENTER("commit_try_rebuild"); DBUG_ASSERT(ctx->need_rebuild()); - DBUG_ASSERT(trx->dict_operation_lock_mode == RW_X_LATCH); + DBUG_ASSERT(trx->dict_operation_lock_mode); DBUG_ASSERT(!(ha_alter_info->handler_flags & ALTER_DROP_FOREIGN_KEY) || ctx->num_to_drop_fk > 0); @@ -10108,8 +10092,7 @@ innobase_page_compression_try( "BEGIN\n" "UPDATE SYS_TABLES SET TYPE=:type\n" "WHERE ID=:id;\n" - "END;\n", - false, trx); + "END;\n", trx); if (error != DB_SUCCESS) { my_error_innodb(error, table_name, 0); @@ -10170,7 +10153,7 @@ commit_try_norebuild( { DBUG_ENTER("commit_try_norebuild"); DBUG_ASSERT(!ctx->need_rebuild()); - DBUG_ASSERT(trx->dict_operation_lock_mode == RW_X_LATCH); + DBUG_ASSERT(trx->dict_operation_lock_mode); DBUG_ASSERT(!(ha_alter_info->handler_flags & ALTER_DROP_FOREIGN_KEY) || ctx->num_to_drop_fk > 0); @@ -10265,7 +10248,7 @@ commit_try_norebuild( pars_info_t* info = pars_info_create(); pars_info_add_ull_literal(info, "indexid", index->id); - error = que_eval_sql(info, drop_index, FALSE, trx); + error = que_eval_sql(info, drop_index, trx); if (error == DB_SUCCESS && index->type & DICT_FTS) { DBUG_ASSERT(index->table->fts); @@ -10928,38 +10911,56 @@ lock_fail: } } - /* Latch the InnoDB data dictionary exclusively so that no deadlocks - or lock waits can happen in it during the data dictionary operation. */ - row_mysql_lock_data_dictionary(trx); - - /* Prevent the background statistics collection from accessing - the tables. */ - for (;;) { - bool retry = false; - - for (inplace_alter_handler_ctx** pctx = ctx_array; - *pctx; pctx++) { - ha_innobase_inplace_ctx* ctx - = static_cast(*pctx); - - DBUG_ASSERT(new_clustered == ctx->need_rebuild()); - - if (new_clustered - && !dict_stats_stop_bg(ctx->old_table)) { - retry = true; - } - - if (!dict_stats_stop_bg(ctx->new_table)) { - retry = true; - } + dict_table_t *table_stats = nullptr, *index_stats = nullptr; + MDL_ticket *mdl_table = nullptr, *mdl_index = nullptr; + dberr_t error = DB_SUCCESS; + if (!ctx0->old_table->is_stats_table() && + !ctx0->new_table->is_stats_table()) { + table_stats = dict_table_open_on_name( + TABLE_STATS_NAME, false, DICT_ERR_IGNORE_NONE); + if (table_stats) { + dict_sys.freeze(SRW_LOCK_CALL); + table_stats = dict_acquire_mdl_shared( + table_stats, m_user_thd, &mdl_table); + dict_sys.unfreeze(); + } + index_stats = dict_table_open_on_name( + INDEX_STATS_NAME, false, DICT_ERR_IGNORE_NONE); + if (index_stats) { + dict_sys.freeze(SRW_LOCK_CALL); + index_stats = dict_acquire_mdl_shared( + index_stats, m_user_thd, &mdl_index); + dict_sys.unfreeze(); } - if (!retry) { - break; + if (table_stats && index_stats + && !strcmp(table_stats->name.m_name, TABLE_STATS_NAME) + && !strcmp(index_stats->name.m_name, INDEX_STATS_NAME) + && !(error = lock_table_for_trx(table_stats, + trx, LOCK_X))) { + error = lock_table_for_trx(index_stats, trx, LOCK_X); } - - DICT_BG_YIELD(trx); } + if (error == DB_SUCCESS) { + error = lock_sys_tables(trx); + } + if (error != DB_SUCCESS) { + if (table_stats) { + dict_table_close(table_stats, false, m_user_thd, + mdl_table); + } + if (index_stats) { + dict_table_close(index_stats, false, m_user_thd, + mdl_index); + } + my_error_innodb(error, table_share->table_name.str, 0); + if (fts_exist) { + purge_sys.resume_FTS(); + } + DBUG_RETURN(true); + } + + row_mysql_lock_data_dictionary(trx); /* Apply the changes to the data dictionary tables, for all partitions. */ @@ -10973,6 +10974,14 @@ lock_fail: fail: trx->rollback(); ut_ad(!trx->fts_trx); + if (table_stats) { + dict_table_close(table_stats, true, m_user_thd, + mdl_table); + } + if (index_stats) { + dict_table_close(index_stats, true, m_user_thd, + mdl_index); + } row_mysql_unlock_data_dictionary(trx); if (fts_exist) { purge_sys.resume_FTS(); @@ -11020,6 +11029,13 @@ fail: #endif } + if (table_stats) { + dict_table_close(table_stats, true, m_user_thd, mdl_table); + } + if (index_stats) { + dict_table_close(index_stats, true, m_user_thd, mdl_index); + } + /* Commit or roll back the changes to the data dictionary. */ DEBUG_SYNC(m_user_thd, "innodb_alter_inplace_before_commit"); @@ -11033,7 +11049,9 @@ fail: ut_ad(ctx->new_table->get_ref_count() == 1); const bool own = m_prebuilt == ctx->prebuilt; trx_t* const user_trx = m_prebuilt->trx; - row_prebuilt_free(ctx->prebuilt, true); + ctx->prebuilt->table->release(); + ctx->prebuilt->table = nullptr; + row_prebuilt_free(ctx->prebuilt); /* Rebuild the prebuilt object. */ ctx->prebuilt = row_create_prebuilt( ctx->new_table, altered_table->s->reclength); @@ -11069,9 +11087,6 @@ fail: ha_alter_info->inplace_alter_table_committed = purge_sys.resume_SYS; purge_sys.stop_SYS(); trx->commit(deleted); - log_write_up_to(trx->commit_lsn, true); - DBUG_EXECUTE_IF("innodb_alter_commit_crash_after_commit", - DBUG_SUICIDE();); /* At this point, the changes to the persistent storage have been committed or rolled back. What remains to be done is to @@ -11165,6 +11180,9 @@ foreign_fail: } unlock_and_close_files(deleted, trx); + log_write_up_to(trx->commit_lsn, true); + DBUG_EXECUTE_IF("innodb_alter_commit_crash_after_commit", + DBUG_SUICIDE();); trx->free(); if (fts_exist) { purge_sys.resume_FTS(); @@ -11217,6 +11235,9 @@ foreign_fail: } unlock_and_close_files(deleted, trx); + log_write_up_to(trx->commit_lsn, true); + DBUG_EXECUTE_IF("innodb_alter_commit_crash_after_commit", + DBUG_SUICIDE();); trx->free(); if (fts_exist) { purge_sys.resume_FTS(); diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc index 9acfad100d0..e4d53b32c7f 100644 --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc @@ -1335,12 +1335,12 @@ i_s_cmp_per_index_fill_low( RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str); /* Create a snapshot of the stats so we do not bump into lock - order violations with dict_sys.mutex below. */ + order violations with dict_sys.latch below. */ mysql_mutex_lock(&page_zip_stat_per_index_mutex); page_zip_stat_per_index_t snap (page_zip_stat_per_index); mysql_mutex_unlock(&page_zip_stat_per_index_mutex); - dict_sys.mutex_lock(); + dict_sys.freeze(SRW_LOCK_CALL); page_zip_stat_per_index_t::iterator iter; ulint i; @@ -1393,18 +1393,18 @@ i_s_cmp_per_index_fill_low( status = 1; break; } - /* Release and reacquire the dict mutex to allow other + /* Release and reacquire the dict_sys.latch to allow other threads to proceed. This could eventually result in the contents of INFORMATION_SCHEMA.innodb_cmp_per_index being inconsistent, but it is an acceptable compromise. */ if (i == 1000) { - dict_sys.mutex_unlock(); + dict_sys.unfreeze(); i = 0; - dict_sys.mutex_lock(); + dict_sys.freeze(SRW_LOCK_CALL); } } - dict_sys.mutex_unlock(); + dict_sys.unfreeze(); if (reset) { page_zip_reset_stat_per_index(); @@ -2410,7 +2410,7 @@ i_s_fts_deleted_generic_fill( DBUG_RETURN(0); } else if (!dict_table_has_fts_index(user_table) || !user_table->is_readable()) { - dict_table_close(user_table, false, false, thd, mdl_ticket); + dict_table_close(user_table, false, thd, mdl_ticket); DBUG_RETURN(0); } @@ -2425,7 +2425,7 @@ i_s_fts_deleted_generic_fill( fts_table_fetch_doc_ids(trx, &fts_table, deleted); - dict_table_close(user_table, false, false, thd, mdl_ticket); + dict_table_close(user_table, false, thd, mdl_ticket); trx->free(); @@ -2782,7 +2782,7 @@ i_s_fts_index_cache_fill( } if (!user_table->fts || !user_table->fts->cache) { - dict_table_close(user_table, false, false, thd, mdl_ticket); + dict_table_close(user_table, false, thd, mdl_ticket); DBUG_RETURN(0); } @@ -2807,7 +2807,7 @@ i_s_fts_index_cache_fill( } mysql_mutex_unlock(&cache->lock); - dict_table_close(user_table, false, false, thd, mdl_ticket); + dict_table_close(user_table, false, thd, mdl_ticket); DBUG_RETURN(ret); } @@ -2964,7 +2964,7 @@ i_s_fts_index_table_fill_selected( } } - fts_que_graph_free(graph); + que_graph_free(graph); trx->free(); @@ -3238,7 +3238,7 @@ i_s_fts_index_table_fill( } } - dict_table_close(user_table, false, false, thd, mdl_ticket); + dict_table_close(user_table, false, thd, mdl_ticket); ut_free(conv_str.f_str); @@ -3374,7 +3374,7 @@ i_s_fts_config_fill( } if (!dict_table_has_fts_index(user_table)) { - dict_table_close(user_table, false, false, thd, mdl_ticket); + dict_table_close(user_table, false, thd, mdl_ticket); DBUG_RETURN(0); } @@ -3431,7 +3431,7 @@ i_s_fts_config_fill( fts_sql_commit(trx); - dict_table_close(user_table, false, false, thd, mdl_ticket); + dict_table_close(user_table, false, thd, mdl_ticket); trx->free(); @@ -3973,7 +3973,7 @@ i_s_innodb_buffer_page_fill( if (page_info->page_type == I_S_PAGE_TYPE_INDEX) { bool ret = false; - dict_sys.mutex_lock(); + dict_sys.freeze(SRW_LOCK_CALL); const dict_index_t* index = dict_index_get_if_in_cache_low( @@ -3998,7 +3998,7 @@ i_s_innodb_buffer_page_fill( system_charset_info); } - dict_sys.mutex_unlock(); + dict_sys.unfreeze(); OK(ret); @@ -4476,7 +4476,7 @@ i_s_innodb_buf_page_lru_fill( if (page_info->page_type == I_S_PAGE_TYPE_INDEX) { bool ret = false; - dict_sys.mutex_lock(); + dict_sys.freeze(SRW_LOCK_CALL); const dict_index_t* index = dict_index_get_if_in_cache_low( @@ -4501,7 +4501,7 @@ i_s_innodb_buf_page_lru_fill( system_charset_info); } - dict_sys.mutex_unlock(); + dict_sys.unfreeze(); OK(ret); @@ -4854,8 +4854,8 @@ i_s_sys_tables_fill_table( DBUG_RETURN(0); } - dict_sys.mutex_lock(); - mtr_start(&mtr); + mtr.start(); + dict_sys.lock(SRW_LOCK_CALL); for (const rec_t *rec = dict_startscan_system(&pcur, &mtr, dict_sys.sys_tables); @@ -4871,7 +4871,7 @@ i_s_sys_tables_fill_table( information from SYS_TABLES row */ err_msg = i_s_sys_tables_rec(pcur, rec, &table_rec); mtr.commit(); - dict_sys.mutex_unlock(); + dict_sys.unlock(); if (!err_msg) { i_s_dict_fill_sys_tables(thd, table_rec, @@ -4887,12 +4887,12 @@ i_s_sys_tables_fill_table( } /* Get the next record */ - dict_sys.mutex_lock(); mtr.start(); + dict_sys.lock(SRW_LOCK_CALL); } mtr.commit(); - dict_sys.mutex_unlock(); + dict_sys.unlock(); DBUG_RETURN(0); } @@ -5095,9 +5095,8 @@ i_s_sys_tables_fill_table_stats( DBUG_RETURN(0); } - dict_sys.freeze(); - dict_sys.mutex_lock(); - mtr_start(&mtr); + mtr.start(); + dict_sys.lock(SRW_LOCK_CALL); rec = dict_startscan_system(&pcur, &mtr, dict_sys.sys_tables); @@ -5110,33 +5109,35 @@ i_s_sys_tables_fill_table_stats( this SYS_TABLES record */ err_msg = i_s_sys_tables_rec(pcur, nullptr, &table_rec); - ulint ref_count = table_rec ? table_rec->get_ref_count() : 0; - dict_sys.mutex_unlock(); - - if (table_rec != NULL) { - ut_ad(err_msg == NULL); + if (UNIV_LIKELY(!err_msg)) { + bool evictable = dict_sys.prevent_eviction(table_rec); + ulint ref_count = table_rec->get_ref_count(); + dict_sys.unlock(); i_s_dict_fill_sys_tablestats(thd, table_rec, ref_count, tables->table); + if (!evictable) { + table_rec = nullptr; + } } else { - ut_ad(err_msg != NULL); + ut_ad(!table_rec); + dict_sys.unlock(); push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_CANT_FIND_SYSTEM_REC, "%s", err_msg); } - dict_sys.unfreeze(); - /* Get the next record */ - dict_sys.freeze(); - dict_sys.mutex_lock(); + mtr.start(); + dict_sys.lock(SRW_LOCK_CALL); + if (table_rec) { + dict_sys.allow_eviction(table_rec); + } - mtr_start(&mtr); rec = dict_getnext_system(&pcur, &mtr); } - mtr_commit(&mtr); - dict_sys.mutex_unlock(); - dict_sys.unfreeze(); + mtr.commit(); + dict_sys.unlock(); DBUG_RETURN(0); } @@ -5329,7 +5330,7 @@ i_s_sys_indexes_fill_table( } heap = mem_heap_create(1000); - dict_sys.mutex_lock(); + dict_sys.lock(SRW_LOCK_CALL); mtr_start(&mtr); /* Start scan the SYS_INDEXES table */ @@ -5350,8 +5351,8 @@ i_s_sys_indexes_fill_table( rec, DICT_FLD__SYS_INDEXES__SPACE, &space_id); space_id = space_id == 4 ? mach_read_from_4(field) : ULINT_UNDEFINED; - mtr_commit(&mtr); - dict_sys.mutex_unlock(); + mtr.commit(); + dict_sys.unlock(); if (!err_msg) { if (int err = i_s_dict_fill_sys_indexes( @@ -5369,13 +5370,13 @@ i_s_sys_indexes_fill_table( mem_heap_empty(heap); /* Get the next record */ - dict_sys.mutex_lock(); - mtr_start(&mtr); + mtr.start(); + dict_sys.lock(SRW_LOCK_CALL); rec = dict_getnext_system(&pcur, &mtr); } - mtr_commit(&mtr); - dict_sys.mutex_unlock(); + mtr.commit(); + dict_sys.unlock(); mem_heap_free(heap); DBUG_RETURN(0); @@ -5548,8 +5549,8 @@ i_s_sys_columns_fill_table( } heap = mem_heap_create(1000); - dict_sys.mutex_lock(); - mtr_start(&mtr); + mtr.start(); + dict_sys.lock(SRW_LOCK_CALL); rec = dict_startscan_system(&pcur, &mtr, dict_sys.sys_columns); @@ -5565,8 +5566,8 @@ i_s_sys_columns_fill_table( &table_id, &col_name, &nth_v_col); - mtr_commit(&mtr); - dict_sys.mutex_unlock(); + mtr.commit(); + dict_sys.unlock(); if (!err_msg) { i_s_dict_fill_sys_columns(thd, table_id, col_name, @@ -5581,17 +5582,18 @@ i_s_sys_columns_fill_table( mem_heap_empty(heap); /* Get the next record */ - dict_sys.mutex_lock(); - mtr_start(&mtr); + mtr.start(); + dict_sys.lock(SRW_LOCK_CALL); rec = dict_getnext_system(&pcur, &mtr); } - mtr_commit(&mtr); - dict_sys.mutex_unlock(); + mtr.commit(); + dict_sys.unlock(); mem_heap_free(heap); DBUG_RETURN(0); } + /*******************************************************************//** Bind the dynamic table INFORMATION_SCHEMA.innodb_sys_columns @return 0 on success */ @@ -5741,8 +5743,8 @@ i_s_sys_virtual_fill_table( DBUG_RETURN(0); } - dict_sys.mutex_lock(); - mtr_start(&mtr); + mtr.start(); + dict_sys.lock(SRW_LOCK_CALL); rec = dict_startscan_system(&pcur, &mtr, dict_sys.sys_virtual); @@ -5756,8 +5758,8 @@ i_s_sys_virtual_fill_table( &table_id, &pos, &base_pos); - mtr_commit(&mtr); - dict_sys.mutex_unlock(); + mtr.commit(); + dict_sys.unlock(); if (!err_msg) { i_s_dict_fill_sys_virtual(thd, table_id, pos, base_pos, @@ -5769,13 +5771,13 @@ i_s_sys_virtual_fill_table( } /* Get the next record */ - dict_sys.mutex_lock(); - mtr_start(&mtr); + mtr.start(); + dict_sys.lock(SRW_LOCK_CALL); rec = dict_getnext_system(&pcur, &mtr); } - mtr_commit(&mtr); - dict_sys.mutex_unlock(); + mtr.commit(); + dict_sys.unlock(); DBUG_RETURN(0); } @@ -5927,13 +5929,13 @@ i_s_sys_fields_fill_table( } heap = mem_heap_create(1000); - dict_sys.mutex_lock(); - mtr_start(&mtr); + mtr.start(); /* will save last index id so that we know whether we move to the next index. This is used to calculate prefix length */ last_id = 0; + dict_sys.lock(SRW_LOCK_CALL); rec = dict_startscan_system(&pcur, &mtr, dict_sys.sys_fields); while (rec) { @@ -5947,8 +5949,8 @@ i_s_sys_fields_fill_table( err_msg = dict_process_sys_fields_rec(heap, rec, &field_rec, &pos, &index_id, last_id); - mtr_commit(&mtr); - dict_sys.mutex_unlock(); + mtr.commit(); + dict_sys.unlock(); if (!err_msg) { i_s_dict_fill_sys_fields(thd, index_id, &field_rec, @@ -5963,13 +5965,13 @@ i_s_sys_fields_fill_table( mem_heap_empty(heap); /* Get the next record */ - dict_sys.mutex_lock(); - mtr_start(&mtr); + mtr.start(); + dict_sys.lock(SRW_LOCK_CALL); rec = dict_getnext_system(&pcur, &mtr); } - mtr_commit(&mtr); - dict_sys.mutex_unlock(); + mtr.commit(); + dict_sys.unlock(); mem_heap_free(heap); DBUG_RETURN(0); @@ -6130,8 +6132,8 @@ i_s_sys_foreign_fill_table( } heap = mem_heap_create(1000); - dict_sys.mutex_lock(); - mtr_start(&mtr); + mtr.start(); + dict_sys.lock(SRW_LOCK_CALL); rec = dict_startscan_system(&pcur, &mtr, dict_sys.sys_foreign); @@ -6143,8 +6145,8 @@ i_s_sys_foreign_fill_table( a SYS_FOREIGN row */ err_msg = dict_process_sys_foreign_rec(heap, rec, &foreign_rec); - mtr_commit(&mtr); - dict_sys.mutex_unlock(); + mtr.commit(); + dict_sys.unlock(); if (!err_msg) { i_s_dict_fill_sys_foreign(thd, &foreign_rec, @@ -6158,13 +6160,13 @@ i_s_sys_foreign_fill_table( mem_heap_empty(heap); /* Get the next record */ - mtr_start(&mtr); - dict_sys.mutex_lock(); + mtr.start(); + dict_sys.lock(SRW_LOCK_CALL); rec = dict_getnext_system(&pcur, &mtr); } - mtr_commit(&mtr); - dict_sys.mutex_unlock(); + mtr.commit(); + dict_sys.unlock(); mem_heap_free(heap); DBUG_RETURN(0); @@ -6323,8 +6325,8 @@ i_s_sys_foreign_cols_fill_table( } heap = mem_heap_create(1000); - dict_sys.mutex_lock(); - mtr_start(&mtr); + mtr.start(); + dict_sys.lock(SRW_LOCK_CALL); rec = dict_startscan_system(&pcur, &mtr, dict_sys.sys_foreign_cols); @@ -6339,8 +6341,8 @@ i_s_sys_foreign_cols_fill_table( err_msg = dict_process_sys_foreign_col_rec( heap, rec, &name, &for_col_name, &ref_col_name, &pos); - mtr_commit(&mtr); - dict_sys.mutex_unlock(); + mtr.commit(); + dict_sys.unlock(); if (!err_msg) { i_s_dict_fill_sys_foreign_cols( @@ -6355,13 +6357,13 @@ i_s_sys_foreign_cols_fill_table( mem_heap_empty(heap); /* Get the next record */ - dict_sys.mutex_lock(); - mtr_start(&mtr); + mtr.start(); + dict_sys.lock(SRW_LOCK_CALL); rec = dict_getnext_system(&pcur, &mtr); } - mtr_commit(&mtr); - dict_sys.mutex_unlock(); + mtr.commit(); + dict_sys.unlock(); mem_heap_free(heap); DBUG_RETURN(0); diff --git a/storage/innobase/include/dict0defrag_bg.h b/storage/innobase/include/dict0defrag_bg.h index 3aea41b0bb8..0edc6304788 100644 --- a/storage/innobase/include/dict0defrag_bg.h +++ b/storage/innobase/include/dict0defrag_bg.h @@ -90,11 +90,8 @@ dict_defrag_process_entries_from_defrag_pool(); /*********************************************************************//** Save defragmentation result. @return DB_SUCCESS or error code */ -dberr_t -dict_stats_save_defrag_summary( -/*============================*/ - dict_index_t* index) /*!< in: index */ - MY_ATTRIBUTE((warn_unused_result)); +dberr_t dict_stats_save_defrag_summary(dict_index_t *index, THD *thd) + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Save defragmentation stats for a given index. diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index a68eea3652c..505fe76b008 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -152,11 +152,12 @@ dict_table_open_on_id(table_id_t table_id, bool dict_locked, MDL_ticket **mdl= nullptr) MY_ATTRIBUTE((warn_unused_result)); +/** Decrement the count of open handles */ +void dict_table_close(dict_table_t *table); + /** Decrements the count of open handles of a table. @param[in,out] table table -@param[in] dict_locked data dictionary locked -@param[in] try_drop try to drop any orphan indexes after - an aborted online index creation +@param[in] dict_locked whether dict_sys.latch is being held @param[in] thd thread to release MDL @param[in] mdl metadata lock or NULL if the thread is a foreground one. */ @@ -164,7 +165,6 @@ void dict_table_close( dict_table_t* table, bool dict_locked, - bool try_drop, THD* thd = NULL, MDL_ticket* mdl = NULL); @@ -467,16 +467,14 @@ NOTE! This is a high-level function to be used mainly from outside the 'dict' directory. Inside this directory dict_table_get_low is usually the appropriate function. @param[in] table_name Table name -@param[in] dict_locked TRUE=data dictionary locked -@param[in] try_drop TRUE=try to drop any orphan indexes after - an aborted online index creation +@param[in] dict_locked whether dict_sys.latch is being held exclusively @param[in] ignore_err error to be ignored when loading the table -@return table, NULL if does not exist */ +@return table +@retval nullptr if does not exist */ dict_table_t* dict_table_open_on_name( const char* table_name, - ibool dict_locked, - ibool try_drop, + bool dict_locked, dict_err_ignore_t ignore_err) MY_ATTRIBUTE((warn_unused_result)); @@ -931,8 +929,8 @@ dict_table_copy_types( const dict_table_t* table) /*!< in: table */ MY_ATTRIBUTE((nonnull)); /**********************************************************************//** -Looks for an index with the given id. NOTE that we do not reserve -the dictionary mutex: this function is for emergency purposes like +Looks for an index with the given id. NOTE that we do not acquire +dict_sys.latch: this function is for emergency purposes like printing info of a corrupt database page! @return index or NULL if not found from cache */ dict_index_t* @@ -1143,7 +1141,6 @@ dict_field_get_col( /**********************************************************************//** Returns an index object if it is found in the dictionary cache. -Assumes that dict_sys.mutex is already being held. @return index, NULL if not found */ dict_index_t* dict_index_get_if_in_cache_low( @@ -1349,27 +1346,17 @@ extern mysql_mutex_t dict_foreign_err_mutex; /** InnoDB data dictionary cache */ class dict_sys_t { - /** The my_hrtime_coarse().val of the oldest mutex_lock_wait() start, or 0 */ - std::atomic mutex_wait_start; + /** The my_hrtime_coarse().val of the oldest lock_wait() start, or 0 */ + std::atomic latch_ex_wait_start; - /** @brief the data dictionary rw-latch protecting dict_sys - - Table create, drop, etc. reserve this in X-mode (along with - acquiring dict_sys.mutex); implicit or - backround operations that are not fully covered by MDL - (rollback, foreign key checks) reserve this in S-mode. - - This latch also prevents lock waits when accessing the InnoDB - data dictionary tables. @see trx_t::dict_operation_lock_mode */ + /** the rw-latch protecting the data dictionary cache */ MY_ALIGNED(CACHE_LINE_SIZE) srw_lock latch; #ifdef UNIV_DEBUG /** whether latch is being held in exclusive mode (by any thread) */ bool latch_ex; + /** number of S-latch holders */ + Atomic_counter latch_readers; #endif - /** Mutex protecting dict_sys. Whenever latch is acquired - exclusively, also the mutex will be acquired. - FIXME: merge the mutex and the latch, once MDEV-23484 has been fixed */ - mysql_mutex_t mutex; public: /** Indexes of SYS_TABLE[] */ enum @@ -1426,7 +1413,7 @@ private: /** The synchronization interval of row_id */ static constexpr size_t ROW_ID_WRITE_MARGIN= 256; public: - /** Diagnostic message for exceeding the mutex_lock_wait() timeout */ + /** Diagnostic message for exceeding the lock_wait() timeout */ static const char fatal_msg[]; /** @return A new value for GEN_CLUST_INDEX(DB_ROW_ID) */ @@ -1454,7 +1441,7 @@ public: (should only happen during the rollback of CREATE...SELECT) */ dict_table_t *acquire_temporary_table(table_id_t id) { - mysql_mutex_assert_owner(&mutex); + ut_ad(frozen()); dict_table_t *table; ulint fold = ut_fold_ull(id); HASH_SEARCH(id_hash, &temp_id_hash, fold, dict_table_t*, table, @@ -1474,7 +1461,7 @@ public: @retval nullptr if not cached */ dict_table_t *find_table(table_id_t id) { - mysql_mutex_assert_owner(&mutex); + ut_ad(frozen()); dict_table_t *table; ulint fold= ut_fold_ull(id); HASH_SEARCH(id_hash, &table_id_hash, fold, dict_table_t*, table, @@ -1508,7 +1495,7 @@ public: { ut_ad(table); ut_ad(table->can_be_evicted == in_lru); - mysql_mutex_assert_owner(&mutex); + ut_ad(frozen()); for (const dict_table_t* t= in_lru ? table_LRU.start : table_non_LRU.start; t; t = UT_LIST_GET_NEXT(table_LRU, t)) { @@ -1524,72 +1511,101 @@ public: } #endif - /** Move a table to the non-LRU list from the LRU list. */ - void prevent_eviction(dict_table_t *table) + /** Move a table to the non-LRU list from the LRU list. + @return whether the table was evictable */ + bool prevent_eviction(dict_table_t *table) { + ut_d(locked()); ut_ad(find(table)); - if (table->can_be_evicted) - { - table->can_be_evicted= false; - UT_LIST_REMOVE(table_LRU, table); - UT_LIST_ADD_LAST(table_non_LRU, table); - } + if (!table->can_be_evicted) + return false; + table->can_be_evicted= false; + UT_LIST_REMOVE(table_LRU, table); + UT_LIST_ADD_LAST(table_non_LRU, table); + return true; + } + /** Move a table from the non-LRU list to the LRU list. */ + void allow_eviction(dict_table_t *table) + { + ut_d(locked()); + ut_ad(find(table)); + ut_ad(!table->can_be_evicted); + table->can_be_evicted= true; + UT_LIST_REMOVE(table_non_LRU, table); + UT_LIST_ADD_FIRST(table_LRU, table); } - /** Acquire a reference to a cached table. */ - inline void acquire(dict_table_t *table); - /** Assert that the mutex is locked */ - void assert_locked() const { mysql_mutex_assert_owner(&mutex); } - /** Assert that the mutex is not locked */ - void assert_not_locked() const { mysql_mutex_assert_not_owner(&mutex); } -#ifdef SAFE_MUTEX - bool mutex_is_locked() const { return mysql_mutex_is_owner(&mutex); } +#ifdef UNIV_DEBUG + /** @return whether any thread (not necessarily the current thread) + is holding the latch; that is, this check may return false + positives */ + bool frozen() const { return latch_readers || locked(); } + /** @return whether any thread (not necessarily the current thread) + is holding the exclusive latch; that is, this check may return false + positives */ + bool locked() const { return latch_ex; } #endif private: - /** Acquire the mutex */ - ATTRIBUTE_NOINLINE void mutex_lock_wait(); + /** Acquire the exclusive latch */ + ATTRIBUTE_NOINLINE + void lock_wait(SRW_LOCK_ARGS(const char *file, unsigned line)); public: - /** @return the my_hrtime_coarse().val of the oldest mutex_lock_wait() start, + /** @return the my_hrtime_coarse().val of the oldest lock_wait() start, assuming that requests are served on a FIFO basis */ ulonglong oldest_wait() const - { return mutex_wait_start.load(std::memory_order_relaxed); } + { return latch_ex_wait_start.load(std::memory_order_relaxed); } -#ifdef HAVE_PSI_MUTEX_INTERFACE - /** Acquire the mutex */ - ATTRIBUTE_NOINLINE void mutex_lock(); - /** Release the mutex */ - ATTRIBUTE_NOINLINE void mutex_unlock(); + /** Exclusively lock the dictionary cache. */ + void lock(SRW_LOCK_ARGS(const char *file, unsigned line)) + { + if (latch.wr_lock_try()) + { + ut_ad(!latch_readers); + ut_ad(!latch_ex); + ut_d(latch_ex= true); + } + else + lock_wait(SRW_LOCK_ARGS(file, line)); + } + +#ifdef UNIV_PFS_RWLOCK + /** Unlock the data dictionary cache. */ + ATTRIBUTE_NOINLINE void unlock(); + /** Acquire a shared lock on the dictionary cache. */ + ATTRIBUTE_NOINLINE void freeze(const char *file, unsigned line); + /** Release a shared lock on the dictionary cache. */ + ATTRIBUTE_NOINLINE void unfreeze(); #else - /** Acquire the mutex */ - void mutex_lock() { if (mysql_mutex_trylock(&mutex)) mutex_lock_wait(); } - - /** Release the mutex */ - void mutex_unlock() { mysql_mutex_unlock(&mutex); } -#endif - - /** Lock the data dictionary cache. */ - void lock(SRW_LOCK_ARGS(const char *file, unsigned line)); - /** Unlock the data dictionary cache. */ void unlock() { ut_ad(latch_ex); + ut_ad(!latch_readers); ut_d(latch_ex= false); - mutex_unlock(); latch.wr_unlock(); } - - /** Prevent modifications of the data dictionary */ - void freeze() { latch.rd_lock(SRW_LOCK_CALL); ut_ad(!latch_ex); } - /** Allow modifications of the data dictionary */ - void unfreeze() { ut_ad(!latch_ex); latch.rd_unlock(); } + /** Acquire a shared lock on the dictionary cache. */ + void freeze() + { + latch.rd_lock(); + ut_ad(!latch_ex); + ut_d(latch_readers++); + } + /** Release a shared lock on the dictionary cache. */ + void unfreeze() + { + ut_ad(!latch_ex); + ut_ad(latch_readers--); + latch.rd_unlock(); + } +#endif /** Estimate the used memory occupied by the data dictionary table and index objects. @return number of bytes occupied */ - ulint rough_size() const + TPOOL_SUPPRESS_TSAN ulint rough_size() const { - /* No mutex; this is a very crude approximation anyway */ + /* No latch; this is a very crude approximation anyway */ ulint size = UT_LIST_GET_LEN(table_LRU) + UT_LIST_GET_LEN(table_non_LRU); size *= sizeof(dict_table_t) + sizeof(dict_index_t) * 2 @@ -1612,7 +1628,7 @@ public: @retval nullptr if not found */ dict_table_t *find_table(const span &name) const { - assert_locked(); + ut_ad(frozen()); for (dict_table_t *table= static_cast (HASH_GET_FIRST(&table_hash, table_hash.calc_hash (my_crc32c(0, name.data(), name.size())))); @@ -1641,9 +1657,6 @@ public: /** the data dictionary cache */ extern dict_sys_t dict_sys; -#define dict_sys_lock() dict_sys.lock(SRW_LOCK_CALL) -#define dict_sys_unlock() dict_sys.unlock() - /*********************************************************************//** Converts a database and table name from filesystem encoding (e.g. d@i1b/a@q1b@1Kc, same format as used in dict_table_t::name) in two @@ -1670,16 +1683,13 @@ dict_table_is_corrupted( const dict_table_t* table) /*!< in: table */ MY_ATTRIBUTE((nonnull, warn_unused_result)); -/**********************************************************************//** -Flags an index and table corrupted both in the data dictionary cache -and in the system table SYS_INDEXES. */ -void -dict_set_corrupted( -/*===============*/ - dict_index_t* index, /*!< in/out: index */ - trx_t* trx, /*!< in/out: transaction */ - const char* ctx) /*!< in: context */ - ATTRIBUTE_COLD __attribute__((nonnull)); +/** Flag an index and table corrupted both in the data dictionary cache +and in the system table SYS_INDEXES. +@param index index to be flagged as corrupted +@param ctx context (for error log reporting) +@param dict_locked whether dict_sys.latch is held in exclusive mode */ +void dict_set_corrupted(dict_index_t *index, const char *ctx, bool dict_locked) + ATTRIBUTE_COLD __attribute__((nonnull)); /** Flags an index corrupted in the data dictionary cache only. This is used mostly to mark a corrupted index when index's own dictionary diff --git a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic index 07f4309f90d..8af2d93f831 100644 --- a/storage/innobase/include/dict0dict.ic +++ b/storage/innobase/include/dict0dict.ic @@ -1139,7 +1139,7 @@ dict_table_is_file_per_table( /** Acquire the table handle. */ inline void dict_table_t::acquire() { - dict_sys.assert_locked(); + ut_ad(dict_sys.frozen()); n_ref_count++; } diff --git a/storage/innobase/include/dict0load.h b/storage/innobase/include/dict0load.h index 591dd30f211..072773694a9 100644 --- a/storage/innobase/include/dict0load.h +++ b/storage/innobase/include/dict0load.h @@ -53,12 +53,9 @@ We also scan the biggest space id, and store it to fil_system. */ void dict_check_tablespaces_and_store_max_id(); /** Make sure the data_file_name is saved in dict_table_t if needed. -@param[in] table Table object -@param[in] dict_mutex_own true if dict_sys.mutex is owned already */ -void -dict_get_and_save_data_dir_path( - dict_table_t* table, - bool dict_mutex_own); +@param[in,out] table Table object +@param[in] dict_locked dict_sys.frozen() */ +void dict_get_and_save_data_dir_path(dict_table_t* table, bool dict_locked); /***********************************************************************//** Loads a table object based on the table id. diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index 335a4236dde..0826f9158e6 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -1026,8 +1026,7 @@ struct dict_index_t { /*!< enum online_index_status. Transitions from ONLINE_INDEX_COMPLETE (to ONLINE_INDEX_CREATION) are protected - by dict_sys.latch and - dict_sys.mutex. Other changes are + by dict_sys.latch. Other changes are protected by index->lock. */ unsigned uncommitted:1; /*!< a flag that is set for secondary indexes @@ -1935,7 +1934,7 @@ struct dict_table_t { inline size_t get_overflow_field_local_len() const; /** Parse the table file name into table name and database name. - @tparam dict_locked whether dict_sys.mutex is being held + @tparam dict_locked whether dict_sys.lock() was called @param[in,out] db_name database name buffer @param[in,out] tbl_name table name buffer @param[out] db_name_len database name length @@ -2178,7 +2177,7 @@ public: dict_foreign_set referenced_set; /** Statistics for query optimization. Mostly protected by - dict_sys.mutex. @{ */ + dict_sys.latch and stats_mutex_lock(). @{ */ /** TRUE if statistics have been calculated the first time after database startup or table creation. */ @@ -2245,24 +2244,6 @@ public: any latch, because this is only used for heuristics. */ ib_uint64_t stat_modified_counter; - /** Background stats thread is not working on this table. */ - #define BG_STAT_NONE 0 - - /** Set in 'stats_bg_flag' when the background stats code is working - on this table. The DROP TABLE code waits for this to be cleared before - proceeding. */ - #define BG_STAT_IN_PROGRESS (1 << 0) - - /** Set in 'stats_bg_flag' when DROP TABLE starts waiting on - BG_STAT_IN_PROGRESS to be cleared. The background stats thread will - detect this and will eventually quit sooner. */ - #define BG_STAT_SHOULD_QUIT (1 << 1) - - /** The state of the background stats thread wrt this table. - See BG_STAT_NONE, BG_STAT_IN_PROGRESS and BG_STAT_SHOULD_QUIT. - Writes are covered by dict_sys.mutex. Dirty reads are possible. */ - byte stats_bg_flag; - bool stats_error_printed; /*!< Has persistent stats error beein already printed for this table ? */ @@ -2376,7 +2357,7 @@ public: /** @return whether the name is mysql.innodb_index_stats or mysql.innodb_table_stats */ - inline bool is_stats_table() const; + bool is_stats_table() const; /** Create metadata. @param name table name diff --git a/storage/innobase/include/dict0stats.h b/storage/innobase/include/dict0stats.h index 7112238c9b6..cdc5ec1bffb 100644 --- a/storage/innobase/include/dict0stats.h +++ b/storage/innobase/include/dict0stats.h @@ -140,19 +140,21 @@ dict_stats_update( /** Execute DELETE FROM mysql.innodb_table_stats @param database_name database name @param table_name table name -@param trx transaction (nullptr=start and commit a new one) +@param trx transaction @return DB_SUCCESS or error code */ dberr_t dict_stats_delete_from_table_stats(const char *database_name, const char *table_name, - trx_t *trx= nullptr); + trx_t *trx) + MY_ATTRIBUTE((nonnull)); /** Execute DELETE FROM mysql.innodb_index_stats @param database_name database name @param table_name table name -@param trx transaction (nullptr=start and commit a new one) +@param trx transaction @return DB_SUCCESS or error code */ dberr_t dict_stats_delete_from_index_stats(const char *database_name, const char *table_name, - trx_t *trx= nullptr); + trx_t *trx) + MY_ATTRIBUTE((nonnull)); /** Execute DELETE FROM mysql.innodb_index_stats @param database_name database name @param table_name table name @@ -203,9 +205,7 @@ storage. @param[in] stat_value value of the stat @param[in] sample_size n pages sampled or NULL @param[in] stat_description description of the stat -@param[in,out] trx in case of NULL the function will -allocate and free the trx object. If it is not NULL then it will be -rolled back only in the case of error, but not freed. +@param[in,out] trx transaction @return DB_SUCCESS or error code */ dberr_t dict_stats_save_index_stat( @@ -215,7 +215,8 @@ dict_stats_save_index_stat( ib_uint64_t stat_value, ib_uint64_t* sample_size, const char* stat_description, - trx_t* trx); + trx_t* trx) + MY_ATTRIBUTE((nonnull(1, 3, 6, 7))); /** Report an error if updating table statistics failed because .ibd file is missing, table decryption failed or table is corrupted. diff --git a/storage/innobase/include/dict0stats.ic b/storage/innobase/include/dict0stats.ic index 68592404253..e49153eb099 100644 --- a/storage/innobase/include/dict0stats.ic +++ b/storage/innobase/include/dict0stats.ic @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. -Copyright (c) 2017, 2020, MariaDB Corporation. +Copyright (c) 2017, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -75,7 +75,7 @@ dict_stats_is_persistent_enabled(const dict_table_t* table) + dict_stats_update(DICT_STATS_RECALC_TRANSIENT) on a table that has just been PS-enabled. This is acceptable. Avoiding this would mean that we would have to - protect the stat_persistent with dict_sys.mutex like the + hold dict_sys.latch or stats_mutex_lock() like for accessing the other ::stat_ members which would be too big performance penalty, especially when this function is called from dict_stats_update_if_needed(). */ diff --git a/storage/innobase/include/dict0stats_bg.h b/storage/innobase/include/dict0stats_bg.h index e9318a0116d..f047d404693 100644 --- a/storage/innobase/include/dict0stats_bg.h +++ b/storage/innobase/include/dict0stats_bg.h @@ -39,59 +39,10 @@ extern mysql_pfs_key_t recalc_pool_mutex_key; extern my_bool innodb_dict_stats_disabled_debug; #endif /* UNIV_DEBUG */ -/*****************************************************************//** -Delete a given table from the auto recalc pool. -dict_stats_recalc_pool_del() */ -void -dict_stats_recalc_pool_del( -/*=======================*/ - const dict_table_t* table); /*!< in: table to remove */ +/** Delete a table from the auto recalc pool, and ensure that +no statistics are being updated on it. */ +void dict_stats_recalc_pool_del(table_id_t id, bool have_mdl_exclusive); -/** Yield the data dictionary latch when waiting -for the background thread to stop accessing a table. -@param trx transaction holding the data dictionary locks */ -#define DICT_BG_YIELD(trx) do { \ - row_mysql_unlock_data_dictionary(trx); \ - std::this_thread::sleep_for(std::chrono::milliseconds(250)); \ - row_mysql_lock_data_dictionary(trx); \ -} while (0) - -/*****************************************************************//** -Request the background collection of statistics to stop for a table. -@retval true when no background process is active -@retval false when it is not safe to modify the table definition */ -UNIV_INLINE -bool -dict_stats_stop_bg( -/*===============*/ - dict_table_t* table) /*!< in/out: table */ -{ - ut_ad(!srv_read_only_mode); - dict_sys.assert_locked(); - - if (!(table->stats_bg_flag & BG_STAT_IN_PROGRESS)) { - return(true); - } - - table->stats_bg_flag |= BG_STAT_SHOULD_QUIT; - return(false); -} - -/*****************************************************************//** -Wait until background stats thread has stopped using the specified table. -The caller must have locked the data dictionary using -row_mysql_lock_data_dictionary() and this function may unlock it temporarily -and restore the lock before it exits. -The background stats thread is guaranteed not to start using the specified -table after this function returns and before the caller unlocks the data -dictionary because it sets the BG_STAT_IN_PROGRESS bit in table->stats_bg_flag -under dict_sys.mutex. */ -void -dict_stats_wait_bg_to_stop_using_table( -/*===================================*/ - dict_table_t* table, /*!< in/out: table */ - trx_t* trx); /*!< in/out: transaction to use for - unlocking/locking the data dict */ /*****************************************************************//** Initialize global variables needed for the operation of dict_stats_thread(). Must be called before dict_stats task is started. */ diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index 2269ff80ae0..2838abde333 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -1595,7 +1595,7 @@ right in it. If does not succeed, prints an error message to the .err log. This function is used to open a tablespace when we start up mysqld, and also in IMPORT TABLESPACE. NOTE that we assume this operation is used either at the database startup -or under the protection of the dictionary mutex, so that two users cannot +or under the protection of dict_sys.latch, so that two users cannot race here. This operation does not leave the file associated with the tablespace open, but closes it after we have looked at the space id in it. diff --git a/storage/innobase/include/fts0fts.h b/storage/innobase/include/fts0fts.h index 95b5131a526..6f9ceca1c0c 100644 --- a/storage/innobase/include/fts0fts.h +++ b/storage/innobase/include/fts0fts.h @@ -318,7 +318,7 @@ public: /** Whether the ADDED table record sync-ed after crash recovery */ unsigned added_synced:1; - /** Whether the table holds dict_sys.mutex */ + /** Whether the table holds dict_sys.latch */ unsigned dict_locked:1; /** Work queue for scheduling jobs for the FTS 'Add' thread, or NULL @@ -377,9 +377,6 @@ extern ulong fts_min_token_size; need a sync to free some memory */ extern bool fts_need_sync; -/** Free a query graph */ -void fts_que_graph_free(que_t *graph); - /******************************************************************//** Create a FTS cache. */ fts_cache_t* @@ -450,8 +447,7 @@ fts_trx_free( fts_trx_t* fts_trx); /*!< in, own: FTS trx */ /** Creates the common auxiliary tables needed for supporting an FTS index -on the given table. row_mysql_lock_data_dictionary must have been called -before this. +on the given table. The following tables are created. CREATE TABLE $FTS_PREFIX_DELETED (doc_id BIGINT UNSIGNED, UNIQUE CLUSTERED INDEX on doc_id) @@ -474,8 +470,7 @@ fts_create_common_tables( bool skip_doc_id_index) MY_ATTRIBUTE((nonnull, warn_unused_result)); /** Creates the column specific ancillary tables needed for supporting an -FTS index on the given table. row_mysql_lock_data_dictionary must have -been called before this. +FTS index on the given table. All FTS AUX Index tables have the following schema. CREAT TABLE $FTS_PREFIX_INDEX_[1-6]( @@ -740,16 +735,6 @@ FTS auxiliary INDEX table and clear the cache at the end. @return DB_SUCCESS on success, error code on failure. */ dberr_t fts_sync_table(dict_table_t* table, bool wait = true); -/****************************************************************//** -Free the query graph but check whether dict_sys.mutex is already -held */ -void -fts_que_graph_free_check_lock( -/*==========================*/ - fts_table_t* fts_table, /*!< in: FTS table */ - const fts_index_cache_t*index_cache, /*!< in: FTS index cache */ - que_t* graph); /*!< in: query graph */ - /****************************************************************//** Create an FTS index cache. */ CHARSET_INFO* diff --git a/storage/innobase/include/fts0priv.h b/storage/innobase/include/fts0priv.h index fbe2acdc712..a8647b4dd1d 100644 --- a/storage/innobase/include/fts0priv.h +++ b/storage/innobase/include/fts0priv.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2020, MariaDB Corporation. +Copyright (c) 2017, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -135,7 +135,7 @@ fts_eval_sql( /** Construct the name of an internal FTS table for the given table. @param[in] fts_table metadata on fulltext-indexed table @param[out] table_name a name up to MAX_FULL_NAME_LEN -@param[in] dict_locked whether dict_sys.mutex is being held */ +@param[in] dict_locked whether dict_sys.latch is being held */ void fts_get_table_name(const fts_table_t* fts_table, char* table_name, bool dict_locked = false) MY_ATTRIBUTE((nonnull)); @@ -295,16 +295,6 @@ fts_trx_table_id_cmp( #define fts_sql_commit(trx) trx_commit_for_mysql(trx) #define fts_sql_rollback(trx) (trx)->rollback() /******************************************************************//** -Parse an SQL string. %s is replaced with the table's id. Don't acquire -the dict mutex -@return query graph */ -que_t* -fts_parse_sql_no_dict_lock( -/*=======================*/ - pars_info_t* info, /*!< in: parser info */ - const char* sql) /*!< in: SQL string to evaluate */ - MY_ATTRIBUTE((nonnull(2), malloc, warn_unused_result)); -/******************************************************************//** Get value from config table. The caller must ensure that enough space is allocated for value to hold the column contents @return DB_SUCCESS or error code */ @@ -469,12 +459,6 @@ fts_get_table_id( FTS_AUX_MIN_TABLE_ID_LENGTH bytes long */ MY_ATTRIBUTE((nonnull, warn_unused_result)); -/** Construct the name of an internal FTS table for the given table. -@param[in] fts_table metadata on fulltext-indexed table -@param[in] dict_locked whether dict_sys.mutex is being held -@return the prefix, must be freed with ut_free() */ -char* fts_get_table_name_prefix(const fts_table_t* fts_table) - MY_ATTRIBUTE((nonnull, malloc, warn_unused_result)); /******************************************************************//** Add node positions. */ void diff --git a/storage/innobase/include/ha_prototypes.h b/storage/innobase/include/ha_prototypes.h index 9a2786f9e69..2dd7c571386 100644 --- a/storage/innobase/include/ha_prototypes.h +++ b/storage/innobase/include/ha_prototypes.h @@ -207,6 +207,14 @@ but can be used for comparison. */ extern "C" unsigned long long thd_start_utime(const MYSQL_THD thd); + +/** + Indicate the start of an async operation in a foreground thread. +@param thd current_thd +@return thd +@retval nullptr if this is not a foreground thread */ +THD *innodb_thd_increment_pending_ops(THD *thd); + /** Determines the current SQL statement. Thread unsafe, can only be called from the thread owning the THD. @param[in] thd MySQL thread handle @@ -242,7 +250,7 @@ const char *thd_innodb_tmpdir(THD *thd); /******************************************************************//** Returns the lock wait timeout for the current connection. @return the lock wait timeout, in seconds */ -uint +uint& thd_lock_wait_timeout( /*==================*/ THD* thd); /*!< in: thread handle, or NULL to query diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h index 9b83cf6ee1a..42e8bf4ad22 100644 --- a/storage/innobase/include/lock0lock.h +++ b/storage/innobase/include/lock0lock.h @@ -221,6 +221,17 @@ state was stored on the infimum of a page. whose infimum stored the lock state; lock bits are reset on the infimum */ void lock_rec_restore_from_page_infimum(const buf_block_t &block, const rec_t *rec, page_id_t donator); + +/** +Create a table lock, without checking for deadlocks or lock compatibility. +@param table table on which the lock is created +@param type_mode lock type and mode +@param trx transaction +@param c_lock conflicting lock +@return the created lock object */ +lock_t *lock_table_create(dict_table_t *table, unsigned type_mode, trx_t *trx, + lock_t *c_lock= nullptr); + /*********************************************************************//** Checks if locks of other transactions prevent an immediate insert of a record. If they do, first tests if the query thread should anyway @@ -393,6 +404,12 @@ lock_table_for_trx( enum lock_mode mode) MY_ATTRIBUTE((nonnull, warn_unused_result)); +/** Exclusively lock the data dictionary tables. +@param trx dictionary transaction +@return error code +@retval DB_SUCCESS on success */ +dberr_t lock_sys_tables(trx_t *trx); + /*************************************************************//** Removes a granted record lock of a transaction from the queue and grants locks to other transactions waiting in the queue if they now are entitled diff --git a/storage/innobase/include/log0log.h b/storage/innobase/include/log0log.h index ca792f9e439..a651a56e8a0 100644 --- a/storage/innobase/include/log0log.h +++ b/storage/innobase/include/log0log.h @@ -77,7 +77,7 @@ log_reserve_and_write_fast( Checks if there is need for a log buffer flush or a new checkpoint, and does this if yes. Any database operation should call this when it has modified more than about 4 pages. NOTE that this function may only be called when the -OS thread owns no synchronization objects except the dictionary mutex. */ +OS thread owns no synchronization objects except dict_sys.latch. */ UNIV_INLINE void log_free_check(void); diff --git a/storage/innobase/include/log0log.ic b/storage/innobase/include/log0log.ic index aebe511d659..c29c0bfa55f 100644 --- a/storage/innobase/include/log0log.ic +++ b/storage/innobase/include/log0log.ic @@ -294,7 +294,7 @@ log_reserve_and_write_fast( Checks if there is need for a log buffer flush or a new checkpoint, and does this if yes. Any database operation should call this when it has modified more than about 4 pages. NOTE that this function may only be called when the -OS thread owns no synchronization objects except the dictionary mutex. */ +OS thread owns no synchronization objects except dict_sys.latch. */ UNIV_INLINE void log_free_check(void) diff --git a/storage/innobase/include/pars0pars.h b/storage/innobase/include/pars0pars.h index bef446184a1..16823ce1461 100644 --- a/storage/innobase/include/pars0pars.h +++ b/storage/innobase/include/pars0pars.h @@ -390,13 +390,6 @@ pars_info_t* pars_info_create(void); /*==================*/ -/****************************************************************//** -Free info struct and everything it contains. */ -void -pars_info_free( -/*===========*/ - pars_info_t* info); /*!< in, own: info struct */ - /****************************************************************//** Add bound literal. */ void @@ -559,11 +552,10 @@ struct pars_info_t { (pars_bound_lit_t*) */ ib_vector_t* bound_ids; /*!< bound ids, or NULL (pars_bound_id_t*) */ - - ibool graph_owns_us; /*!< if TRUE (which is the default), - que_graph_free() will free us */ }; +inline void pars_info_free(pars_info_t *info) { mem_heap_free(info->heap); } + /** User-supplied function and argument. */ struct pars_user_func_t { const char* name; /*!< function name */ diff --git a/storage/innobase/include/que0que.h b/storage/innobase/include/que0que.h index 1a30ea45194..f0aed6d22f4 100644 --- a/storage/innobase/include/que0que.h +++ b/storage/innobase/include/que0que.h @@ -207,9 +207,6 @@ que_eval_sql( /*=========*/ pars_info_t* info, /*!< in: info struct, or NULL */ const char* sql, /*!< in: SQL string */ - bool reserve_dict_mutex, - /*!< in: whether to acquire/release - dict_sys.mutex around call to pars_sql. */ trx_t* trx); /*!< in: trx */ /**********************************************************************//** diff --git a/storage/innobase/include/row0merge.h b/storage/innobase/include/row0merge.h index c2a474abe4d..e9e250435f0 100644 --- a/storage/innobase/include/row0merge.h +++ b/storage/innobase/include/row0merge.h @@ -145,17 +145,6 @@ row_merge_dup_report( const dfield_t* entry) /*!< in: duplicate index entry */ MY_ATTRIBUTE((nonnull)); -/*********************************************************************//** -Drop indexes that were created before an error occurred. -The data dictionary must have been locked exclusively by the caller, -because the transaction will not be committed. */ -void -row_merge_drop_indexes_dict( -/*========================*/ - trx_t* trx, /*!< in/out: dictionary transaction */ - table_id_t table_id)/*!< in: table identifier */ - MY_ATTRIBUTE((nonnull)); - /** Drop indexes that were created before an error occurred. The data dictionary must have been locked exclusively by the caller, because the transaction will not be committed. diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h index 998de196dd9..ed51a3a3d90 100644 --- a/storage/innobase/include/row0mysql.h +++ b/storage/innobase/include/row0mysql.h @@ -182,13 +182,8 @@ row_create_prebuilt( dict_table_t* table, /*!< in: Innobase table handle */ ulint mysql_row_len); /*!< in: length in bytes of a row in the MySQL format */ -/********************************************************************//** -Free a prebuilt struct for a MySQL table handle. */ -void -row_prebuilt_free( -/*==============*/ - row_prebuilt_t* prebuilt, /*!< in, own: prebuilt struct */ - ibool dict_locked); /*!< in: TRUE=data dictionary locked */ +/** Free a prebuilt struct for a TABLE handle. */ +void row_prebuilt_free(row_prebuilt_t *prebuilt); /*********************************************************************//** Updates the transaction pointers in query graphs stored in the prebuilt struct. */ @@ -305,30 +300,24 @@ row_update_cascade_for_mysql( or set null operation */ dict_table_t* table) /*!< in: table where we do the operation */ MY_ATTRIBUTE((nonnull, warn_unused_result)); -/*********************************************************************//** -Locks the data dictionary exclusively for performing a table create or other -data dictionary modification operation. */ -void -row_mysql_lock_data_dictionary_func( -/*================================*/ -#ifdef UNIV_PFS_RWLOCK - const char* file, /*!< in: file name */ - unsigned line, /*!< in: line number */ -#endif - trx_t* trx); /*!< in/out: transaction */ -#ifdef UNIV_PFS_RWLOCK -#define row_mysql_lock_data_dictionary(trx) \ - row_mysql_lock_data_dictionary_func(__FILE__, __LINE__, trx) -#else -#define row_mysql_lock_data_dictionary row_mysql_lock_data_dictionary_func -#endif -/*********************************************************************//** -Unlocks the data dictionary exclusive lock. */ -void -row_mysql_unlock_data_dictionary( -/*=============================*/ - trx_t* trx); /*!< in/out: transaction */ +/** Lock the data dictionary cache exclusively. */ +#define row_mysql_lock_data_dictionary(trx) \ + do { \ + ut_ad(!trx->dict_operation_lock_mode); \ + dict_sys.lock(SRW_LOCK_CALL); \ + trx->dict_operation_lock_mode = true; \ + } while (0) + +/** Unlock the data dictionary. */ +#define row_mysql_unlock_data_dictionary(trx) \ + do { \ + ut_ad(!lock_trx_has_sys_table_locks(trx)); \ + ut_ad(trx->dict_operation_lock_mode); \ + trx->dict_operation_lock_mode = false; \ + dict_sys.unlock(); \ + } while (0) + /*********************************************************************//** Creates a table for MySQL. On failure the transaction will be rolled back and the 'table' object will be freed. @@ -362,18 +351,6 @@ row_create_index_for_mysql( uint32_t key_id) /*!< in: encryption key_id */ MY_ATTRIBUTE((warn_unused_result)); -/*********************************************************************//** -Sets an exclusive lock on a table. -@return error code or DB_SUCCESS */ -dberr_t -row_mysql_lock_table( -/*=================*/ - trx_t* trx, /*!< in/out: transaction */ - dict_table_t* table, /*!< in: table to lock */ - enum lock_mode mode, /*!< in: LOCK_X or LOCK_S */ - const char* op_info) /*!< in: string for trx->op_info */ - MY_ATTRIBUTE((nonnull, warn_unused_result)); - /*********************************************************************//** Discards the tablespace of a table which stored in an .ibd file. Discarding means that this function deletes the .ibd file and assigns a new table id for diff --git a/storage/innobase/include/row0purge.h b/storage/innobase/include/row0purge.h index 091d80adec5..34af658cb12 100644 --- a/storage/innobase/include/row0purge.h +++ b/storage/innobase/include/row0purge.h @@ -226,7 +226,7 @@ public: } innobase_reset_background_thd(purge_thd); - dict_table_close(table, false, false, purge_thd, mdl_ticket); + dict_table_close(table, false, purge_thd, mdl_ticket); table= nullptr; mdl_ticket= nullptr; } diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h index 96289f2aa39..d64fd019b85 100644 --- a/storage/innobase/include/trx0trx.h +++ b/storage/innobase/include/trx0trx.h @@ -122,11 +122,18 @@ void trx_start_internal_low(trx_t *trx, bool read_write); (t)->start_file = __FILE__; \ trx_start_internal_low(t, true); \ } while (false) +#define trx_start_internal_read_only(t) \ + do { \ + (t)->start_line = __LINE__; \ + (t)->start_file = __FILE__; \ + trx_start_internal_low(t, false); \ + } while (false) #else #define trx_start_if_not_started(t, rw) \ trx_start_if_not_started_low((t), rw) #define trx_start_internal(t) trx_start_internal_low(t, true) +#define trx_start_internal_read_only(t) trx_start_internal_low(t, false) #define trx_start_if_not_started_xa(t, rw) \ trx_start_if_not_started_xa_low((t), (rw)) @@ -725,11 +732,9 @@ public: ulint duplicates; /*!< TRX_DUP_IGNORE | TRX_DUP_REPLACE */ bool dict_operation; /**< whether this modifies InnoDB data dictionary */ - ib_uint32_t dict_operation_lock_mode; - /*!< 0, RW_S_LATCH, or RW_X_LATCH: - the latch mode trx currently holds - on dict_sys.latch. Protected - by dict_sys.latch. */ + /** whether dict_sys.latch is held exclusively; protected by + dict_sys.latch */ + bool dict_operation_lock_mode; /** wall-clock time of the latest transition to TRX_STATE_ACTIVE; used for diagnostic purposes only */ diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i index cc2ccd0ebaf..f851db62d18 100644 --- a/storage/innobase/include/univ.i +++ b/storage/innobase/include/univ.i @@ -537,7 +537,6 @@ typedef unsigned int mysql_pfs_key_t; # ifdef UNIV_PFS_MUTEX extern mysql_pfs_key_t buf_pool_mutex_key; extern mysql_pfs_key_t dict_foreign_err_mutex_key; -extern mysql_pfs_key_t dict_sys_mutex_key; extern mysql_pfs_key_t fil_system_mutex_key; extern mysql_pfs_key_t flush_list_mutex_key; extern mysql_pfs_key_t fts_cache_mutex_key; diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index dccad0f3442..41da85dcc98 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -1264,17 +1264,11 @@ lock_rec_enqueue_waiting( trx_t* trx = thr_get_trx(thr); ut_ad(trx->mutex_is_owner()); - - if (UNIV_UNLIKELY(trx->dict_operation_lock_mode == RW_X_LATCH)) { - ut_ad(!strcmp(index->table->name.m_name, TABLE_STATS_NAME) - || !strcmp(index->table->name.m_name, INDEX_STATS_NAME)); -instant_timeout: - trx->error_state = DB_LOCK_WAIT_TIMEOUT; - return DB_LOCK_WAIT_TIMEOUT; - } + ut_ad(!trx->dict_operation_lock_mode); if (trx->mysql_thd && thd_lock_wait_timeout(trx->mysql_thd) == 0) { - goto instant_timeout; + trx->error_state = DB_LOCK_WAIT_TIMEOUT; + return DB_LOCK_WAIT_TIMEOUT; } /* Enqueue the lock request that will wait to be granted, note that @@ -1491,6 +1485,12 @@ lock_rec_lock( static_cast(LOCK_MODE_MASK & mode))) return DB_SUCCESS; + /* During CREATE TABLE, we will write to newly created FTS_*_CONFIG + on which no lock has been created yet. */ + ut_ad(!trx->dict_operation_lock_mode || + (strstr(index->table->name.m_name, "/FTS_") && + strstr(index->table->name.m_name, "_CONFIG") + sizeof("_CONFIG") == + index->table->name.m_name + strlen(index->table->name.m_name) + 1)); MONITOR_ATOMIC_INC(MONITOR_NUM_RECLOCK_REQ); const page_id_t id{block->page.id()}; LockGuard g{lock_sys.rec_hash, id}; @@ -1701,7 +1701,6 @@ dberr_t lock_wait(que_thr_t *thr) /* InnoDB system transactions may use the global value of innodb_lock_wait_timeout, because trx->mysql_thd == NULL. */ const ulong innodb_lock_wait_timeout= trx_lock_wait_timeout_get(trx); - const bool no_timeout= innodb_lock_wait_timeout >= 100000000; const my_hrtime_t suspend_time= my_hrtime_coarse(); ut_ad(!trx->dict_operation_lock_mode); @@ -1757,6 +1756,14 @@ dberr_t lock_wait(que_thr_t *thr) timespec abstime; set_timespec_time_nsec(abstime, suspend_time.val * 1000); abstime.MY_tv_sec+= innodb_lock_wait_timeout; + /* Dictionary transactions must wait be immune to lock wait timeouts + for locks on data dictionary tables. Here we check only for + SYS_TABLES, SYS_COLUMNS, SYS_INDEXES, SYS_FIELDS. Locks on further + tables SYS_FOREIGN, SYS_FOREIGN_COLS, SYS_VIRTUAL will only be + acquired while holding an exclusive lock on one of the 4 tables. */ + const bool no_timeout= innodb_lock_wait_timeout >= 100000000 || + ((type_mode & LOCK_TABLE) && + wait_lock->un_member.tab_lock.table->id <= DICT_FIELDS_ID); thd_wait_begin(trx->mysql_thd, (type_mode & LOCK_TABLE) ? THD_WAIT_TABLE_LOCK : THD_WAIT_ROW_LOCK); dberr_t error_state= DB_SUCCESS; @@ -1803,7 +1810,10 @@ dberr_t lock_wait(que_thr_t *thr) break; default: ut_ad(error_state != DB_LOCK_WAIT_TIMEOUT); - if (trx_is_interrupted(trx)) + /* Dictionary transactions must ignore KILL, because they could + be executed as part of a multi-transaction DDL operation, + such as rollback_inplace_alter_table() or ha_innobase::delete_table(). */ + if (!trx->dict_operation && trx_is_interrupted(trx)) /* innobase_kill_query() can only set trx->error_state=DB_INTERRUPTED for any transaction that is attached to a connection. */ error_state= DB_INTERRUPTED; @@ -3072,20 +3082,15 @@ void lock_rec_restore_from_page_infimum(const buf_block_t &block, /*========================= TABLE LOCKS ==============================*/ -/*********************************************************************//** -Creates a table lock object and adds it as the last in the lock queue -of the table. Does NOT check for deadlocks or lock compatibility. -@return own: new lock object */ -UNIV_INLINE -lock_t* -lock_table_create( -/*==============*/ - dict_table_t* table, /*!< in/out: database table - in dictionary cache */ - unsigned type_mode,/*!< in: lock mode possibly ORed with - LOCK_WAIT */ - trx_t* trx, /*!< in: trx */ - lock_t* c_lock) /*!< in: conflicting lock */ +/** +Create a table lock, without checking for deadlocks or lock compatibility. +@param table table on which the lock is created +@param type_mode lock type and mode +@param trx transaction +@param c_lock conflicting lock +@return the created lock object */ +lock_t *lock_table_create(dict_table_t *table, unsigned type_mode, trx_t *trx, + lock_t *c_lock) { lock_t* lock; @@ -3094,6 +3099,12 @@ lock_table_create( ut_ad(!trx->is_wsrep() || lock_sys.is_writer()); ut_ad(trx->state == TRX_STATE_ACTIVE || trx->is_recovered); ut_ad(!trx->is_autocommit_non_locking()); + /* During CREATE TABLE, we will write to newly created FTS_*_CONFIG + on which no lock has been created yet. */ + ut_ad(!trx->dict_operation_lock_mode + || (strstr(table->name.m_name, "/FTS_") + && strstr(table->name.m_name, "_CONFIG") + sizeof("_CONFIG") + == table->name.m_name + strlen(table->name.m_name) + 1)); switch (LOCK_MODE_MASK & type_mode) { case LOCK_AUTO_INC: @@ -3310,13 +3321,7 @@ lock_table_enqueue_waiting( trx_t* trx = thr_get_trx(thr); ut_ad(trx->mutex_is_owner()); - - if (UNIV_UNLIKELY(trx->dict_operation_lock_mode == RW_X_LATCH)) { - ut_ad(!strcmp(table->name.m_name, TABLE_STATS_NAME) - || !strcmp(table->name.m_name, INDEX_STATS_NAME)); - trx->error_state = DB_LOCK_WAIT_TIMEOUT; - return DB_LOCK_WAIT_TIMEOUT; - } + ut_ad(!trx->dict_operation_lock_mode); #ifdef WITH_WSREP if (trx->is_wsrep() && trx->lock.was_chosen_as_deadlock_victim) { @@ -3478,7 +3483,7 @@ void lock_table_resurrect(dict_table_t *table, trx_t *trx, lock_mode mode) ut_ad(!lock_table_other_has_incompatible(trx, LOCK_WAIT, table, mode)); trx->mutex_lock(); - lock_table_create(table, mode, trx, nullptr); + lock_table_create(table, mode, trx); } trx->mutex_unlock(); } @@ -3619,6 +3624,28 @@ run_again: return(err); } +/** Exclusively lock the data dictionary tables. +@param trx dictionary transaction +@return error code +@retval DB_SUCCESS on success */ +dberr_t lock_sys_tables(trx_t *trx) +{ + dberr_t err; + if (!(err= lock_table_for_trx(dict_sys.sys_tables, trx, LOCK_X)) && + !(err= lock_table_for_trx(dict_sys.sys_columns, trx, LOCK_X)) && + !(err= lock_table_for_trx(dict_sys.sys_indexes, trx, LOCK_X)) && + !(err= lock_table_for_trx(dict_sys.sys_fields, trx, LOCK_X))) + { + if (dict_sys.sys_foreign) + err= lock_table_for_trx(dict_sys.sys_foreign, trx, LOCK_X); + if (!err && dict_sys.sys_foreign_cols) + err= lock_table_for_trx(dict_sys.sys_foreign_cols, trx, LOCK_X); + if (!err && dict_sys.sys_virtual) + err= lock_table_for_trx(dict_sys.sys_virtual, trx, LOCK_X); + } + return err; +} + /*=========================== LOCK RELEASE ==============================*/ /*************************************************************//** @@ -3785,7 +3812,7 @@ void lock_release(trx_t *trx) #if defined SAFE_MUTEX && defined UNIV_DEBUG std::set to_evict; if (innodb_evict_tables_on_commit_debug && !trx->is_recovered) - if (!trx->dict_operation_lock_mode && !trx->dict_operation) + if (!!trx->dict_operation) for (const auto& p: trx->mod_tables) if (!p.first->is_temporary()) to_evict.emplace(p.first->id); @@ -3846,7 +3873,7 @@ released: #if defined SAFE_MUTEX && defined UNIV_DEBUG if (to_evict.empty()) return; - dict_sys.mutex_lock(); + dict_sys.lock(SRW_LOCK_CALL); LockMutexGuard g{SRW_LOCK_CALL}; for (const table_id_t id : to_evict) { @@ -3854,7 +3881,7 @@ released: if (!table->get_ref_count() && !UT_LIST_GET_LEN(table->locks)) dict_sys.remove(table, true); } - dict_sys.mutex_unlock(); + dict_sys.unlock(); #endif } @@ -5531,8 +5558,14 @@ void lock_sys_t::cancel(trx_t *trx) mysql_mutex_lock(&lock_sys.wait_mutex); if (lock_t *lock= trx->lock.wait_lock) { - trx->error_state= DB_INTERRUPTED; - cancel(trx, lock, false); + /* Dictionary transactions must be immune to KILL, because they + may be executed as part of a multi-transaction DDL operation, such + as rollback_inplace_alter_table() or ha_innobase::delete_table(). */ + if (!trx->dict_operation) + { + trx->error_state= DB_INTERRUPTED; + cancel(trx, lock, false); + } } lock_sys.deadlock_check(); mysql_mutex_unlock(&lock_sys.wait_mutex); diff --git a/storage/innobase/pars/pars0pars.cc b/storage/innobase/pars/pars0pars.cc index 74c33b0cd9c..61614007bd4 100644 --- a/storage/innobase/pars/pars0pars.cc +++ b/storage/innobase/pars/pars0pars.cc @@ -766,7 +766,7 @@ pars_retrieve_table_def( sym_node->token_type = SYM_TABLE_REF_COUNTED; sym_node->table = dict_table_open_on_name( - sym_node->name, TRUE, FALSE, DICT_ERR_IGNORE_NONE); + sym_node->name, true, DICT_ERR_IGNORE_NONE); ut_a(sym_node->table != NULL); } @@ -1973,7 +1973,7 @@ pars_sql( heap = mem_heap_create(16000); /* Currently, the parser is not reentrant: */ - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); pars_sym_tab_global = sym_tab_create(heap); @@ -2051,27 +2051,13 @@ pars_info_create(void) heap = mem_heap_create(512); - info = static_cast(mem_heap_alloc(heap, sizeof(*info))); + info = static_cast(mem_heap_zalloc(heap, sizeof(*info))); info->heap = heap; - info->funcs = NULL; - info->bound_lits = NULL; - info->bound_ids = NULL; - info->graph_owns_us = TRUE; return(info); } -/****************************************************************//** -Free info struct and everything it contains. */ -void -pars_info_free( -/*===========*/ - pars_info_t* info) /*!< in, own: info struct */ -{ - mem_heap_free(info->heap); -} - /****************************************************************//** Add bound literal. */ void diff --git a/storage/innobase/pars/pars0sym.cc b/storage/innobase/pars/pars0sym.cc index b65021a375a..035415849a7 100644 --- a/storage/innobase/pars/pars0sym.cc +++ b/storage/innobase/pars/pars0sym.cc @@ -67,8 +67,6 @@ sym_tab_free_private( sym_node_t* sym; func_node_t* func; - dict_sys.assert_locked(); - for (sym = UT_LIST_GET_FIRST(sym_tab->sym_list); sym != NULL; sym = UT_LIST_GET_NEXT(sym_list, sym)) { @@ -76,8 +74,7 @@ sym_tab_free_private( /* Close the tables opened in pars_retrieve_table_def(). */ if (sym->token_type == SYM_TABLE_REF_COUNTED) { - - dict_table_close(sym->table, TRUE, FALSE); + sym->table->release(); sym->table = NULL; sym->resolved = FALSE; diff --git a/storage/innobase/que/que0que.cc b/storage/innobase/que/que0que.cc index d97466a9219..642a852b473 100644 --- a/storage/innobase/que/que0que.cc +++ b/storage/innobase/que/que0que.cc @@ -435,7 +435,7 @@ que_graph_free( sym_tab_free_private(graph->sym_tab); } - if (graph->info && graph->info->graph_owns_us) { + if (graph->info) { pars_info_free(graph->info); } @@ -748,9 +748,6 @@ que_eval_sql( /*=========*/ pars_info_t* info, /*!< in: info struct, or NULL */ const char* sql, /*!< in: SQL string */ - bool reserve_dict_mutex, - /*!< in: whether to acquire/release - dict_sys.mutex around call to pars_sql. */ trx_t* trx) /*!< in: trx */ { que_thr_t* thr; @@ -761,16 +758,8 @@ que_eval_sql( ut_a(trx->error_state == DB_SUCCESS); - if (reserve_dict_mutex) { - dict_sys.mutex_lock(); - } - graph = pars_sql(info, sql); - if (reserve_dict_mutex) { - dict_sys.mutex_unlock(); - } - graph->trx = trx; trx->graph = NULL; @@ -778,15 +767,7 @@ que_eval_sql( que_run_threads(thr); - if (reserve_dict_mutex) { - dict_sys.mutex_lock(); - } - que_graph_free(graph); - if (reserve_dict_mutex) { - dict_sys.mutex_unlock(); - } - DBUG_RETURN(trx->error_state); } diff --git a/storage/innobase/row/row0ftsort.cc b/storage/innobase/row/row0ftsort.cc index 1cae41c8987..792a9b46e8a 100644 --- a/storage/innobase/row/row0ftsort.cc +++ b/storage/innobase/row/row0ftsort.cc @@ -1634,10 +1634,10 @@ row_fts_merge_insert( /* Get aux index */ fts_get_table_name(&fts_table, aux_table_name); - aux_table = dict_table_open_on_name(aux_table_name, FALSE, FALSE, + aux_table = dict_table_open_on_name(aux_table_name, false, DICT_ERR_IGNORE_NONE); ut_ad(aux_table != NULL); - dict_table_close(aux_table, FALSE, FALSE); + aux_table->release(); aux_index = dict_table_get_first_index(aux_table); ut_ad(!aux_index->is_instant()); diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index b22aed3e9ca..203cbb5ceed 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -40,6 +40,7 @@ Created 2012-02-08 by Sunny Bains. #include "row0quiesce.h" #include "fil0pagecompress.h" #include "trx0undo.h" +#include "lock0lock.h" #ifdef HAVE_LZO #include "lzo/lzo1x.h" #endif @@ -1439,8 +1440,6 @@ row_import::set_root_by_heuristic() UNIV_NOTHROW " the tablespace has " << m_n_indexes << " indexes"; } - dict_sys.mutex_lock(); - ulint i = 0; dberr_t err = DB_SUCCESS; @@ -1479,8 +1478,6 @@ row_import::set_root_by_heuristic() UNIV_NOTHROW } } - dict_sys.mutex_unlock(); - return(err); } @@ -2187,11 +2184,8 @@ dberr_t row_import_cleanup( /*===============*/ row_prebuilt_t* prebuilt, /*!< in/out: prebuilt from handler */ - trx_t* trx, /*!< in/out: transaction for import */ dberr_t err) /*!< in: error code */ { - ut_a(prebuilt->trx != trx); - if (err != DB_SUCCESS) { dict_table_t* table = prebuilt->table; table->file_unreadable = true; @@ -2205,10 +2199,6 @@ row_import_cleanup( ib::info() << "Discarding tablespace of table " << table->name << ": " << err; - if (!trx->dict_operation_lock_mode) { - row_mysql_lock_data_dictionary(trx); - } - for (dict_index_t* index = UT_LIST_GET_FIRST(table->indexes); index; index = UT_LIST_GET_NEXT(indexes, index)) { @@ -2216,15 +2206,13 @@ row_import_cleanup( } } - ut_a(trx->dict_operation_lock_mode == RW_X_LATCH); - DBUG_EXECUTE_IF("ib_import_before_commit_crash", DBUG_SUICIDE();); - trx_commit_for_mysql(trx); + prebuilt->trx->commit(); - row_mysql_unlock_data_dictionary(trx); - - trx->free(); + if (prebuilt->trx->dict_operation_lock_mode) { + row_mysql_unlock_data_dictionary(prebuilt->trx); + } prebuilt->trx->op_info = ""; @@ -2242,10 +2230,9 @@ dberr_t row_import_error( /*=============*/ row_prebuilt_t* prebuilt, /*!< in/out: prebuilt from handler */ - trx_t* trx, /*!< in/out: transaction for import */ dberr_t err) /*!< in: error code */ { - if (!trx_is_interrupted(trx)) { + if (!trx_is_interrupted(prebuilt->trx)) { char table_name[MAX_FULL_NAME_LEN + 1]; innobase_format_name( @@ -2253,12 +2240,12 @@ row_import_error( prebuilt->table->name.m_name); ib_senderrf( - trx->mysql_thd, IB_LOG_LEVEL_WARN, + prebuilt->trx->mysql_thd, IB_LOG_LEVEL_WARN, ER_INNODB_IMPORT_ERROR, table_name, (ulong) err, ut_strerr(err)); } - return(row_import_cleanup(prebuilt, trx, err)); + return row_import_cleanup(prebuilt, err); } /*****************************************************************//** @@ -3339,7 +3326,7 @@ dberr_t row_import_update_discarded_flag(trx_t* trx, table_id_t table_id, pars_info_bind_function( info, "my_func", row_import_set_discarded, &discard); - dberr_t err = que_eval_sql(info, sql, false, trx); + dberr_t err = que_eval_sql(info, sql, trx); ut_a(discard.n_recs == 1); ut_a(discard.flags2 != ULINT32_UNDEFINED); @@ -4002,9 +3989,9 @@ row_import_for_mysql( row_prebuilt_t* prebuilt) /*!< in: prebuilt struct in MySQL */ { dberr_t err; - trx_t* trx; ib_uint64_t autoinc = 0; char* filepath = NULL; + trx_t* trx = prebuilt->trx; /* The caller assured that this is not read_only_mode and that no temorary tablespace is being imported. */ @@ -4013,22 +4000,12 @@ row_import_for_mysql( ut_ad(table->space_id); ut_ad(table->space_id < SRV_SPACE_ID_UPPER_BOUND); - ut_ad(prebuilt->trx); + ut_ad(trx); + ut_ad(trx->state == TRX_STATE_ACTIVE); ut_ad(!table->is_readable()); ibuf_delete_for_discarded_space(table->space_id); - trx_start_if_not_started(prebuilt->trx, true); - - trx = trx_create(); - - trx->dict_operation = true; - - trx_start_if_not_started(trx, true); - - /* So that we can send error messages to the user. */ - trx->mysql_thd = prebuilt->trx->mysql_thd; - /* Assign an undo segment for the transaction, so that the transaction will be recovered after a crash. */ @@ -4043,21 +4020,19 @@ row_import_for_mysql( DBUG_EXECUTE_IF("ib_import_undo_assign_failure", err = DB_TOO_MANY_CONCURRENT_TRXS;); - if (err != DB_SUCCESS) { - - return(row_import_cleanup(prebuilt, trx, err)); - - } else if (trx->rsegs.m_redo.undo == 0) { - + if (err == DB_SUCCESS && !trx->has_logged_persistent()) { err = DB_TOO_MANY_CONCURRENT_TRXS; - return(row_import_cleanup(prebuilt, trx, err)); + } + if (err != DB_SUCCESS) { + return row_import_cleanup(prebuilt, err); } - prebuilt->trx->op_info = "read meta-data file"; + trx->op_info = "read meta-data file"; row_import cfg; + THD* thd = trx->mysql_thd; - err = row_import_read_cfg(table, trx->mysql_thd, cfg); + err = row_import_read_cfg(table, thd, cfg); /* Check if the table column definitions match the contents of the config file. */ @@ -4067,7 +4042,7 @@ row_import_for_mysql( /* We have a schema file, try and match it with our data dictionary. */ - err = cfg.match_schema(trx->mysql_thd); + err = cfg.match_schema(thd); /* Update index->page and SYS_INDEXES.PAGE_NO to match the B-tree root page numbers in the tablespace. Use the index @@ -4091,13 +4066,13 @@ row_import_for_mysql( cfg.m_zip_size = 0; if (UT_LIST_GET_LEN(table->indexes) > 1) { - ib_errf(trx->mysql_thd, IB_LOG_LEVEL_ERROR, + ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_INTERNAL_ERROR, "Drop all secondary indexes before importing " "table %s when .cfg file is missing.", table->name.m_name); err = DB_ERROR; - return row_import_error(prebuilt, trx, err); + return row_import_error(prebuilt, err); } FetchIndexRootPages fetchIndexRootPages(table, trx); @@ -4121,10 +4096,10 @@ row_import_for_mysql( } if (err != DB_SUCCESS) { - return(row_import_error(prebuilt, trx, err)); + return row_import_error(prebuilt, err); } - prebuilt->trx->op_info = "importing tablespace"; + trx->op_info = "importing tablespace"; ib::info() << "Phase I - Update all pages"; @@ -4166,17 +4141,15 @@ row_import_for_mysql( if (err != DB_DECRYPTION_FAILED) { - ib_errf(trx->mysql_thd, IB_LOG_LEVEL_ERROR, + ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_INTERNAL_ERROR, "Cannot reset LSNs in table %s : %s", table_name, ut_strerr(err)); } - return(row_import_cleanup(prebuilt, trx, err)); + return row_import_cleanup(prebuilt, err); } - row_mysql_lock_data_dictionary(trx); - /* If the table is stored in a remote tablespace, we need to determine that filepath from the link file and system tables. Find the space ID in SYS_TABLES since this is an ALTER TABLE. */ @@ -4198,13 +4171,10 @@ row_import_for_mysql( ); if (filepath == NULL) { - row_mysql_unlock_data_dictionary(trx); - return(row_import_cleanup(prebuilt, trx, DB_OUT_OF_MEMORY)); + return row_import_cleanup(prebuilt, DB_OUT_OF_MEMORY); } /* Open the tablespace so that we can access via the buffer pool. - We set the 2nd param (fix_dict = true) here because we already - have locked dict_sys.latch and dict_sys.mutex. The tablespace is initially opened as a temporary one, because we will not be writing any redo log for it before we have invoked fil_space_t::set_imported() to declare it a persistent tablespace. */ @@ -4218,27 +4188,21 @@ row_import_for_mysql( err = DB_TABLESPACE_NOT_FOUND; table->space = NULL;); if (!table->space) { - row_mysql_unlock_data_dictionary(trx); - - ib_senderrf(trx->mysql_thd, IB_LOG_LEVEL_ERROR, + ib_senderrf(thd, IB_LOG_LEVEL_ERROR, ER_GET_ERRMSG, err, ut_strerr(err), filepath); - - ut_free(filepath); - - return(row_import_cleanup(prebuilt, trx, err)); } - row_mysql_unlock_data_dictionary(trx); - ut_free(filepath); - err = ibuf_check_bitmap_on_import(trx, table->space); + if (err == DB_SUCCESS) { + err = ibuf_check_bitmap_on_import(trx, table->space); + } DBUG_EXECUTE_IF("ib_import_check_bitmap_failure", err = DB_CORRUPTION;); if (err != DB_SUCCESS) { - return(row_import_cleanup(prebuilt, trx, err)); + return row_import_cleanup(prebuilt, err); } /* The first index must always be the clustered index. */ @@ -4246,7 +4210,7 @@ row_import_for_mysql( dict_index_t* index = dict_table_get_first_index(table); if (!dict_index_is_clust(index)) { - return(row_import_error(prebuilt, trx, DB_CORRUPTION)); + return row_import_error(prebuilt, DB_CORRUPTION); } /* Update the Btree segment headers for index node and @@ -4258,7 +4222,7 @@ row_import_for_mysql( err = DB_CORRUPTION;); if (err != DB_SUCCESS) { - return(row_import_error(prebuilt, trx, err)); + return row_import_error(prebuilt, err); } else if (cfg.requires_purge(index->name)) { /* Purge any delete-marked records that couldn't be @@ -4277,7 +4241,7 @@ row_import_for_mysql( DBUG_EXECUTE_IF("ib_import_cluster_failure", err = DB_CORRUPTION;); if (err != DB_SUCCESS) { - return(row_import_error(prebuilt, trx, err)); + return row_import_error(prebuilt, err); } /* For secondary indexes, purge any records that couldn't be purged @@ -4290,7 +4254,7 @@ row_import_for_mysql( err = DB_CORRUPTION;); if (err != DB_SUCCESS) { - return(row_import_error(prebuilt, trx, err)); + return row_import_error(prebuilt, err); } /* Ensure that the next available DB_ROW_ID is not smaller than @@ -4329,13 +4293,13 @@ row_import_for_mysql( err = row_import_update_index_root(trx, table, false); if (err != DB_SUCCESS) { - return(row_import_error(prebuilt, trx, err)); + return row_import_error(prebuilt, err); } err = row_import_update_discarded_flag(trx, table->id, false); if (err != DB_SUCCESS) { - return(row_import_error(prebuilt, trx, err)); + return row_import_error(prebuilt, err); } table->file_unreadable = false; @@ -4351,5 +4315,5 @@ row_import_for_mysql( btr_write_autoinc(dict_table_get_first_index(table), autoinc); } - return(row_import_cleanup(prebuilt, trx, err)); + return row_import_cleanup(prebuilt, err); } diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index 3d1f07093fd..6f228142cba 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -1944,14 +1944,14 @@ row_ins_check_foreign_constraints( ref_table = dict_table_open_on_name( foreign->referenced_table_name_lookup, - FALSE, FALSE, DICT_ERR_IGNORE_NONE); + false, DICT_ERR_IGNORE_NONE); } err = row_ins_check_foreign_constraint( TRUE, foreign, table, ref_tuple, thr); - if (ref_table != NULL) { - dict_table_close(ref_table, FALSE, FALSE); + if (ref_table) { + dict_table_close(ref_table); } } } @@ -3040,9 +3040,7 @@ row_ins_sec_index_entry_low( if (!index->is_committed()) { ut_ad(!thr_get_trx(thr) ->dict_operation_lock_mode); - dict_sys.mutex_lock(); - dict_set_corrupted_index_cache_only(index); - dict_sys.mutex_unlock(); + index->type |= DICT_CORRUPT; /* Do not return any error to the caller. The duplicate will be reported by ALTER TABLE or CREATE UNIQUE INDEX. diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index c6bd09e43fd..53e3016180a 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -3678,14 +3678,14 @@ row_merge_drop_index_dict( pars_info_t* info; ut_ad(!srv_read_only_mode); - ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); + ut_ad(trx->dict_operation_lock_mode); ut_ad(trx->dict_operation); - ut_d(dict_sys.assert_locked()); + ut_ad(dict_sys.locked()); info = pars_info_create(); pars_info_add_ull_literal(info, "indexid", index_id); trx->op_info = "dropping index from dictionary"; - error = que_eval_sql(info, sql, FALSE, trx); + error = que_eval_sql(info, sql, trx); if (error != DB_SUCCESS) { /* Even though we ensure that DDL transactions are WAIT @@ -3704,6 +3704,7 @@ row_merge_drop_index_dict( Drop indexes that were created before an error occurred. The data dictionary must have been locked exclusively by the caller, because the transaction will not be committed. */ +static void row_merge_drop_indexes_dict( /*========================*/ @@ -3740,9 +3741,9 @@ row_merge_drop_indexes_dict( pars_info_t* info; ut_ad(!srv_read_only_mode); - ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); + ut_ad(trx->dict_operation_lock_mode); ut_ad(trx->dict_operation); - ut_d(dict_sys.assert_locked()); + ut_ad(dict_sys.locked()); /* It is possible that table->n_ref_count > 1 when locked=TRUE. In this case, all code that should have an open @@ -3754,7 +3755,7 @@ row_merge_drop_indexes_dict( info = pars_info_create(); pars_info_add_ull_literal(info, "tableid", table_id); trx->op_info = "dropping indexes"; - error = que_eval_sql(info, sql, FALSE, trx); + error = que_eval_sql(info, sql, trx); switch (error) { case DB_SUCCESS: @@ -3813,9 +3814,9 @@ row_merge_drop_indexes( dict_index_t* next_index; ut_ad(!srv_read_only_mode); - ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); + ut_ad(trx->dict_operation_lock_mode); ut_ad(trx->dict_operation); - ut_d(dict_sys.assert_locked()); + ut_ad(dict_sys.locked()); index = dict_table_get_first_index(table); ut_ad(dict_index_is_clust(index)); @@ -3829,18 +3830,10 @@ row_merge_drop_indexes( handle to the table be waiting for the next statement to execute, or waiting for a meta-data lock. - A concurrent purge will be prevented by dict_sys.latch. */ + A concurrent purge will be prevented by MDL. */ if (!locked && (table->get_ref_count() > 1 || table->has_lock_other_than(alter_trx))) { - /* We will have to drop the indexes later, when the - table is guaranteed to be no longer in use. Mark the - indexes as incomplete and corrupted, so that other - threads will stop using them. Let dict_table_close() - or crash recovery or the next invocation of - prepare_inplace_alter_table() take care of dropping - the indexes. */ - while ((index = dict_table_get_next_index(index)) != NULL) { ut_ad(!dict_index_is_clust(index)); @@ -3900,7 +3893,7 @@ row_merge_drop_indexes( index->lock.x_unlock(); DEBUG_SYNC_C("merge_drop_index_after_abort"); - /* covered by dict_sys.mutex */ + /* covered by dict_sys.latch */ MONITOR_INC(MONITOR_BACKGROUND_DROP_INDEX); /* fall through */ case ONLINE_INDEX_ABORTED: @@ -3967,7 +3960,7 @@ row_merge_drop_indexes( break; case ONLINE_INDEX_ABORTED: case ONLINE_INDEX_ABORTED_DROPPED: - /* covered by dict_sys.mutex */ + /* covered by dict_sys.latch */ MONITOR_DEC(MONITOR_BACKGROUND_DROP_INDEX); } @@ -4036,7 +4029,7 @@ static ibool row_merge_drop_fts(void *node, void *trx) (mach_read_from_8(static_cast(index_id->data)))); auto pinfo= pars_info_create(); pars_info_add_str_literal(pinfo, "name", buf); - que_eval_sql(pinfo, sql, false, static_cast(trx)); + que_eval_sql(pinfo, sql, static_cast(trx)); } return true; @@ -4094,7 +4087,10 @@ void row_merge_drop_temp_indexes() indexes, so that the data dictionary information can be checked when accessing the tablename.ibd files. */ trx_t* trx = trx_create(); + trx_start_for_ddl(trx); trx->op_info = "dropping partially created indexes"; + dberr_t error = lock_sys_tables(trx); + row_mysql_lock_data_dictionary(trx); /* Ensure that this transaction will be rolled back and locks will be released, if the server gets killed before the commit @@ -4105,8 +4101,11 @@ void row_merge_drop_temp_indexes() pars_info_t* pinfo = pars_info_create(); pars_info_bind_function(pinfo, "drop_fts", row_merge_drop_fts, trx); + if (error == DB_SUCCESS) { + error = que_eval_sql(pinfo, sql, trx); + } - if (dberr_t error = que_eval_sql(pinfo, sql, FALSE, trx)) { + if (error) { /* Even though we ensure that DDL transactions are WAIT and DEADLOCK free, we could encounter other errors e.g., DB_TOO_MANY_CONCURRENT_TRXS. */ @@ -4246,7 +4245,7 @@ row_merge_rename_index_to_add( "WHERE TABLE_ID = :tableid AND ID = :indexid;\n" "END;\n"; - ut_a(trx->dict_operation_lock_mode == RW_X_LATCH); + ut_ad(trx->dict_operation_lock_mode); ut_ad(trx->dict_operation); trx->op_info = "renaming index to add"; @@ -4254,7 +4253,7 @@ row_merge_rename_index_to_add( pars_info_add_ull_literal(info, "tableid", table_id); pars_info_add_ull_literal(info, "indexid", index_id); - err = que_eval_sql(info, rename_index, FALSE, trx); + err = que_eval_sql(info, rename_index, trx); if (err != DB_SUCCESS) { /* Even though we ensure that DDL transactions are WAIT diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index a5c8f7047b6..45ec06e452d 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -905,13 +905,8 @@ row_create_prebuilt( DBUG_RETURN(prebuilt); } -/********************************************************************//** -Free a prebuilt struct for a MySQL table handle. */ -void -row_prebuilt_free( -/*==============*/ - row_prebuilt_t* prebuilt, /*!< in, own: prebuilt struct */ - ibool dict_locked) /*!< in: TRUE=data dictionary locked */ +/** Free a prebuilt struct for a TABLE handle. */ +void row_prebuilt_free(row_prebuilt_t *prebuilt) { DBUG_ENTER("row_prebuilt_free"); @@ -971,7 +966,7 @@ row_prebuilt_free( rtr_clean_rtr_info(prebuilt->rtr_info, true); } if (prebuilt->table) { - dict_table_close(prebuilt->table, dict_locked, FALSE); + dict_table_close(prebuilt->table); } mem_heap_free(prebuilt->heap); @@ -1273,7 +1268,7 @@ row_insert_for_mysql( /* Mark the table corrupted for the clustered index */ dict_index_t* index = dict_table_get_first_index(table); ut_ad(dict_index_is_clust(index)); - dict_set_corrupted(index, trx, "INSERT TABLE"); }); + dict_set_corrupted(index, "INSERT TABLE", false); }); if (dict_table_is_corrupted(table)) { @@ -1421,7 +1416,8 @@ error_exit: srv_stats.n_rows_inserted.inc(size_t(trx->id)); } - /* Not protected by dict_sys.mutex for performance + /* Not protected by dict_sys.latch or table->stats_mutex_lock() + for performance reasons, we would rather get garbage in stat_n_rows (which is just an estimate anyway) than protecting the following code with a latch. */ @@ -1758,7 +1754,8 @@ row_update_for_mysql(row_prebuilt_t* prebuilt) ut_ad(is_delete == (node->is_delete == PLAIN_DELETE)); if (is_delete) { - /* Not protected by dict_sys.mutex for performance + /* Not protected by dict_sys.latch + or prebuilt->table->stats_mutex_lock() for performance reasons, we would rather get garbage in stat_n_rows (which is just an estimate anyway) than protecting the following code with a latch. */ @@ -2105,7 +2102,8 @@ row_update_cascade_for_mysql( bool stats; if (node->is_delete == PLAIN_DELETE) { - /* Not protected by dict_sys.mutex for + /* Not protected by dict_sys.latch + or node->table->stats_mutex_lock() for performance reasons, we would rather get garbage in stat_n_rows (which is just an estimate anyway) than @@ -2134,36 +2132,6 @@ row_update_cascade_for_mysql( } } -/*********************************************************************//** -Locks the data dictionary exclusively for performing a table create or other -data dictionary modification operation. */ -void -row_mysql_lock_data_dictionary_func( -/*================================*/ -#ifdef UNIV_PFS_RWLOCK - const char* file, /*!< in: file name */ - unsigned line, /*!< in: line number */ -#endif - trx_t* trx) /*!< in/out: transaction */ -{ - ut_ad(trx->dict_operation_lock_mode == 0); - dict_sys.lock(SRW_LOCK_ARGS(file, line)); - trx->dict_operation_lock_mode = RW_X_LATCH; -} - -/*********************************************************************//** -Unlocks the data dictionary exclusive lock. */ -void -row_mysql_unlock_data_dictionary( -/*=============================*/ - trx_t* trx) /*!< in/out: transaction */ -{ - ut_ad(lock_trx_has_sys_table_locks(trx) == NULL); - ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); - trx->dict_operation_lock_mode = 0; - dict_sys.unlock(); -} - /*********************************************************************//** Creates a table for MySQL. On failure the transaction will be rolled back and the 'table' object will be freed. @@ -2179,10 +2147,11 @@ row_create_table_for_mysql( tab_node_t* node; mem_heap_t* heap; que_thr_t* thr; - dberr_t err; - ut_d(dict_sys.assert_locked()); - ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); + ut_ad(trx->state == TRX_STATE_ACTIVE); + ut_ad(dict_sys.sys_tables_exist()); + ut_ad(dict_sys.locked()); + ut_ad(trx->dict_operation_lock_mode); DEBUG_SYNC_C("create_table"); @@ -2191,16 +2160,8 @@ row_create_table_for_mysql( dict_mem_table_free(table); return DB_ERROR; ); - if (!dict_sys.sys_tables_exist()) { - sql_print_error("InnoDB: Some system tables are missing"); - dict_mem_table_free(table); - return DB_ERROR; - } - trx->op_info = "creating table"; - trx_start_if_not_started_xa(trx, true); - heap = mem_heap_create(512); trx->dict_operation = true; @@ -2214,7 +2175,7 @@ row_create_table_for_mysql( que_run_threads(thr); - err = trx->error_state; + dberr_t err = trx->error_state; if (err != DB_SUCCESS) { trx->error_state = DB_SUCCESS; @@ -2256,7 +2217,7 @@ row_create_index_for_mysql( ulint len; dict_table_t* table = index->table; - ut_d(dict_sys.assert_locked()); + ut_ad(dict_sys.locked()); for (i = 0; i < index->n_def; i++) { /* Check that prefix_len and actual length @@ -2280,14 +2241,14 @@ row_create_index_for_mysql( } } - trx->op_info = "creating index"; - /* For temp-table we avoid insertion into SYSTEM TABLES to maintain performance and so we have separate path that directly just updates dictonary cache. */ if (!table->is_temporary()) { - trx_start_if_not_started_xa(trx, true); - trx->dict_operation = true; + ut_ad(trx->state == TRX_STATE_ACTIVE); + ut_ad(trx->dict_operation); + trx->op_info = "creating index"; + /* Note that the space id where we store the index is inherited from the table in dict_build_index_def_step() in dict0crea.cc. */ @@ -2315,6 +2276,8 @@ row_create_index_for_mysql( if (index && (index->type & DICT_FTS)) { err = fts_create_index_tables(trx, index, table->id); } + + trx->op_info = ""; } else { dict_build_index_def(table, index, trx); @@ -2336,8 +2299,6 @@ row_create_index_for_mysql( } } - trx->op_info = ""; - return(err); } @@ -2377,7 +2338,7 @@ row_mysql_table_id_reassign( " WHERE TABLE_ID = :old_id;\n" "UPDATE SYS_VIRTUAL SET TABLE_ID = :new_id\n" " WHERE TABLE_ID = :old_id;\n" - "END;\n", FALSE, trx); + "END;\n", trx); return(err); } @@ -2545,7 +2506,6 @@ dberr_t row_discard_tablespace_for_mysql(dict_table_t *table, trx_t *trx) if (err != DB_SUCCESS) { rollback: - table->stats_bg_flag= BG_STAT_NONE; if (fts_exist) { purge_sys.resume_FTS(); @@ -2557,12 +2517,10 @@ rollback: } row_mysql_lock_data_dictionary(trx); - dict_stats_wait_bg_to_stop_using_table(table, trx); - trx->op_info = "discarding tablespace"; trx->dict_operation= true; - /* Serialize data dictionary operations with dictionary mutex: + /* We serialize data dictionary operations with dict_sys.latch: this is to avoid deadlocks during data dictionary operations */ err= row_discard_tablespace_foreign_key_checks(trx, table); @@ -2606,54 +2564,6 @@ rollback: return err; } -/*********************************************************************//** -Sets an exclusive lock on a table. -@return error code or DB_SUCCESS */ -dberr_t -row_mysql_lock_table( -/*=================*/ - trx_t* trx, /*!< in/out: transaction */ - dict_table_t* table, /*!< in: table to lock */ - enum lock_mode mode, /*!< in: LOCK_X or LOCK_S */ - const char* op_info) /*!< in: string for trx->op_info */ -{ - mem_heap_t* heap; - que_thr_t* thr; - dberr_t err; - sel_node_t* node; - - ut_ad(mode == LOCK_X || mode == LOCK_S); - - heap = mem_heap_create(512); - - trx->op_info = op_info; - - node = sel_node_create(heap); - thr = pars_complete_graph_for_exec(node, trx, heap, NULL); - thr->graph->state = QUE_FORK_ACTIVE; - - /* We use the select query graph as the dummy graph needed - in the lock module call */ - - thr = que_fork_get_first_thr( - static_cast(que_node_get_parent(thr))); - - do { - thr->run_node = thr; - thr->prev_node = thr->common.parent; - - err = lock_table(table, mode, thr); - - trx->error_state = err; - } while (err != DB_SUCCESS - && row_mysql_handle_errors(&err, trx, thr, NULL)); - - que_graph_free(thr->graph); - trx->op_info = ""; - - return(err); -} - /****************************************************************//** Delete a single constraint. @return error code or DB_SUCCESS */ @@ -2673,8 +2583,7 @@ row_delete_constraint_low( "BEGIN\n" "DELETE FROM SYS_FOREIGN_COLS WHERE ID = :id;\n" "DELETE FROM SYS_FOREIGN WHERE ID = :id;\n" - "END;\n" - , FALSE, trx)); + "END;\n", trx)); } /****************************************************************//** @@ -2729,12 +2638,11 @@ row_rename_table_for_mysql( ulint n_constraints_to_drop = 0; ibool old_is_tmp, new_is_tmp; pars_info_t* info = NULL; - char* is_part = NULL; ut_a(old_name != NULL); ut_a(new_name != NULL); ut_ad(trx->state == TRX_STATE_ACTIVE); - ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); + ut_ad(trx->dict_operation_lock_mode); if (high_level_read_only) { return(DB_READ_ONLY); @@ -2745,17 +2653,9 @@ row_rename_table_for_mysql( old_is_tmp = dict_table_t::is_temporary_name(old_name); new_is_tmp = dict_table_t::is_temporary_name(new_name); - table = dict_table_open_on_name(old_name, true, false, + table = dict_table_open_on_name(old_name, true, DICT_ERR_IGNORE_FK_NOKEY); - /* We look for pattern #P# to see if the table is partitioned - MySQL table. */ -#ifdef _WIN32 - is_part = strstr((char *)old_name, (char *)"#p#"); -#else - is_part = strstr((char *)old_name, (char *)"#P#"); -#endif /* _WIN32 */ - /* MariaDB partition engine hard codes the file name separator as "#P#" and "#SP#". The text case is fixed even if lower_case_table_names is set to 1 or 2. InnoDB always @@ -2772,7 +2672,8 @@ row_rename_table_for_mysql( sensitive platform in Windows, we might need to check the existence of table name without lowering case them in the system table. */ - if (!table && is_part && lower_case_table_names == 1) { + if (!table && lower_case_table_names == 1 + && strstr(old_name, table_name_t::part_suffix)) { char par_case_name[MAX_FULL_NAME_LEN + 1]; #ifndef _WIN32 /* Check for the table using lower @@ -2790,7 +2691,7 @@ row_rename_table_for_mysql( normalize_table_name_c_low( par_case_name, old_name, FALSE); #endif - table = dict_table_open_on_name(par_case_name, true, false, + table = dict_table_open_on_name(par_case_name, true, DICT_ERR_IGNORE_FK_NOKEY); } @@ -2850,8 +2751,7 @@ row_rename_table_for_mysql( "UPDATE SYS_TABLES" " SET NAME = :new_table_name\n" " WHERE NAME = :old_table_name;\n" - "END;\n" - , FALSE, trx); + "END;\n", trx); if (err != DB_SUCCESS) { // Assume the caller guarantees destination name doesn't exist. @@ -2969,8 +2869,7 @@ row_rename_table_for_mysql( "WHERE REF_NAME = :old_table_name\n" " AND TO_BINARY(REF_NAME)\n" " = TO_BINARY(:old_table_name);\n" - "END;\n" - , FALSE, trx); + "END;\n", trx); } else if (n_constraints_to_drop > 0) { /* Drop some constraints of tmp tables. */ diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc index d07288a9e23..4588c1d2b0a 100644 --- a/storage/innobase/row/row0purge.cc +++ b/storage/innobase/row/row0purge.cc @@ -108,19 +108,17 @@ row_purge_remove_clust_if_poss_low( dict_index_t* index = dict_table_get_first_index(node->table); table_id_t table_id = 0; index_id_t index_id = 0; - MDL_ticket* mdl_ticket = nullptr; dict_table_t *table = nullptr; pfs_os_file_t f = OS_FILE_CLOSED; if (table_id) { retry: purge_sys.check_stop_FTS(); - dict_sys.mutex_lock(); + dict_sys.lock(SRW_LOCK_CALL); table = dict_table_open_on_id( - table_id, true, DICT_TABLE_OP_OPEN_ONLY_IF_CACHED, - node->purge_thd, &mdl_ticket); + table_id, true, DICT_TABLE_OP_OPEN_ONLY_IF_CACHED); if (!table) { - dict_sys.mutex_unlock(); + dict_sys.unlock(); } else if (table->n_rec_locks) { for (dict_index_t* ind = UT_LIST_GET_FIRST( table->indexes); ind; @@ -143,9 +141,8 @@ removed: mtr.commit(); close_and_exit: if (table) { - dict_table_close(table, true, false, - node->purge_thd, mdl_ticket); - dict_sys.mutex_unlock(); + dict_table_close(table, true); + dict_sys.unlock(); } return success; } @@ -175,16 +172,8 @@ close_and_exit: table->space = nullptr; table->file_unreadable = true; } + dict_sys.unlock(); table = nullptr; - dict_sys.mutex_unlock(); - if (!mdl_ticket); - else if (MDL_context* mdl_context = - static_cast( - thd_mdl_context(node-> - purge_thd))) { - mdl_context->release_lock(mdl_ticket); - mdl_ticket = nullptr; - } } f = fil_delete_tablespace(space_id); } @@ -192,9 +181,8 @@ close_and_exit: mtr.commit(); if (table) { - dict_table_close(table, true, false, - node->purge_thd, mdl_ticket); - dict_sys.mutex_unlock(); + dict_table_close(table, true); + dict_sys.unlock(); table = nullptr; } diff --git a/storage/innobase/row/row0quiesce.cc b/storage/innobase/row/row0quiesce.cc index 74c7b9b35fc..0d941feb0a1 100644 --- a/storage/innobase/row/row0quiesce.cc +++ b/storage/innobase/row/row0quiesce.cc @@ -486,8 +486,6 @@ row_quiesce_table_has_fts_index( { bool exists = false; - dict_sys.mutex_lock(); - for (const dict_index_t* index = UT_LIST_GET_FIRST(table->indexes); index != 0; index = UT_LIST_GET_NEXT(indexes, index)) { @@ -498,8 +496,6 @@ row_quiesce_table_has_fts_index( } } - dict_sys.mutex_unlock(); - return(exists); } @@ -671,8 +667,6 @@ row_quiesce_set_state( dict_index_t* clust_index = dict_table_get_first_index(table); - row_mysql_lock_data_dictionary(trx); - for (dict_index_t* index = dict_table_get_next_index(clust_index); index != NULL; index = dict_table_get_next_index(index)) { @@ -702,8 +696,6 @@ row_quiesce_set_state( index->lock.x_unlock(); } - row_mysql_unlock_data_dictionary(trx); - return(DB_SUCCESS); } diff --git a/storage/innobase/row/row0uins.cc b/storage/innobase/row/row0uins.cc index 704c067fc43..c826d632969 100644 --- a/storage/innobase/row/row0uins.cc +++ b/storage/innobase/row/row0uins.cc @@ -73,12 +73,11 @@ row_undo_ins_remove_clust_rec( dict_index_t* index = node->pcur.btr_cur.index; bool online; table_id_t table_id = 0; - const bool dict_locked = node->trx->dict_operation_lock_mode - == RW_X_LATCH; + const bool dict_locked = node->trx->dict_operation_lock_mode; restart: MDL_ticket* mdl_ticket = nullptr; ut_ad(!table_id || dict_locked - || node->trx->dict_operation_lock_mode == 0); + || !node->trx->dict_operation_lock_mode); dict_table_t *table = table_id ? dict_table_open_on_id(table_id, dict_locked, DICT_TABLE_OP_OPEN_ONLY_IF_CACHED, @@ -147,8 +146,7 @@ restart: completed. At this point, any corresponding operation to the metadata record will have been rolled back. */ ut_ad(!online); - ut_ad(node->trx->dict_operation_lock_mode - == RW_X_LATCH); + ut_ad(node->trx->dict_operation_lock_mode); ut_ad(node->rec_type == TRX_UNDO_INSERT_REC); if (rec_get_n_fields_old(rec) != DICT_NUM_FIELDS__SYS_COLUMNS @@ -162,8 +160,7 @@ restart: break; case DICT_INDEXES_ID: ut_ad(!online); - ut_ad(node->trx->dict_operation_lock_mode - == RW_X_LATCH); + ut_ad(node->trx->dict_operation_lock_mode); ut_ad(node->rec_type == TRX_UNDO_INSERT_REC); if (!table_id) { table_id = mach_read_from_8(rec); @@ -182,7 +179,7 @@ restart: lock_release_on_rollback(node->trx, table); if (!dict_locked) { - dict_sys.mutex_lock(); + dict_sys.lock(SRW_LOCK_CALL); } if (table->release()) { dict_sys.remove(table); @@ -192,7 +189,7 @@ restart: table->file_unreadable = true; } if (!dict_locked) { - dict_sys.mutex_unlock(); + dict_sys.unlock(); } table = nullptr; if (!mdl_ticket); @@ -272,7 +269,7 @@ func_exit: btr_pcur_commit_specify_mtr(&node->pcur, &mtr); if (UNIV_LIKELY_NULL(table)) { - dict_table_close(table, dict_locked, false, + dict_table_close(table, dict_locked, node->trx->mysql_thd, mdl_ticket); } @@ -432,9 +429,9 @@ static bool row_undo_ins_parse_undo_rec(undo_node_t* node, bool dict_locked) node->table = dict_table_open_on_id(table_id, dict_locked, DICT_TABLE_OP_NORMAL); } else if (!dict_locked) { - dict_sys.mutex_lock(); + dict_sys.freeze(SRW_LOCK_CALL); node->table = dict_sys.acquire_temporary_table(table_id); - dict_sys.mutex_unlock(); + dict_sys.unfreeze(); } else { node->table = dict_sys.acquire_temporary_table(table_id); } @@ -486,7 +483,7 @@ close_table: would probably be better to just drop all temporary tables (and temporary undo log records) of the current connection, instead of doing this rollback. */ - dict_table_close(node->table, dict_locked, FALSE); + dict_table_close(node->table, dict_locked); node->table = NULL; return false; } else { @@ -610,7 +607,7 @@ row_undo_ins( que_thr_t* thr) /*!< in: query thread */ { dberr_t err; - bool dict_locked = node->trx->dict_operation_lock_mode == RW_X_LATCH; + const bool dict_locked = node->trx->dict_operation_lock_mode; if (!row_undo_ins_parse_undo_rec(node, dict_locked)) { return DB_SUCCESS; @@ -642,21 +639,19 @@ row_undo_ins( log_free_check(); - if (node->table->id == DICT_INDEXES_ID) { - ut_ad(!node->table->is_temporary()); - if (!dict_locked) { - dict_sys.mutex_lock(); - } + if (!dict_locked && node->table->id == DICT_INDEXES_ID) { + dict_sys.lock(SRW_LOCK_CALL); err = row_undo_ins_remove_clust_rec(node); - if (!dict_locked) { - dict_sys.mutex_unlock(); - } + dict_sys.unlock(); } else { + ut_ad(node->table->id != DICT_INDEXES_ID + || !node->table->is_temporary()); err = row_undo_ins_remove_clust_rec(node); } if (err == DB_SUCCESS && node->table->stat_initialized) { - /* Not protected by dict_sys.mutex for + /* Not protected by dict_sys.latch + or table->stats_mutex_lock() for performance reasons, we would rather get garbage in stat_n_rows (which is just an estimate anyway) than protecting the following code with a latch. */ @@ -665,7 +660,7 @@ row_undo_ins( /* Do not attempt to update statistics when executing ROLLBACK in the InnoDB SQL interpreter, because in that case we would - already be holding dict_sys.mutex, which + already be holding dict_sys.latch, which would be acquired when updating statistics. */ if (!dict_locked) { dict_stats_update_if_needed(node->table, @@ -685,7 +680,7 @@ row_undo_ins( break; } - dict_table_close(node->table, dict_locked, FALSE); + dict_table_close(node->table, dict_locked); node->table = NULL; diff --git a/storage/innobase/row/row0umod.cc b/storage/innobase/row/row0umod.cc index ba675c927eb..751c4e73401 100644 --- a/storage/innobase/row/row0umod.cc +++ b/storage/innobase/row/row0umod.cc @@ -1215,9 +1215,9 @@ static bool row_undo_mod_parse_undo_rec(undo_node_t* node, bool dict_locked) node->table = dict_table_open_on_id(table_id, dict_locked, DICT_TABLE_OP_NORMAL); } else if (!dict_locked) { - dict_sys.mutex_lock(); + dict_sys.freeze(SRW_LOCK_CALL); node->table = dict_sys.acquire_temporary_table(table_id); - dict_sys.mutex_unlock(); + dict_sys.unfreeze(); } else { node->table = dict_sys.acquire_temporary_table(table_id); } @@ -1239,7 +1239,7 @@ close_table: would probably be better to just drop all temporary tables (and temporary undo log records) of the current connection, instead of doing this rollback. */ - dict_table_close(node->table, dict_locked, FALSE); + dict_table_close(node->table, dict_locked); node->table = NULL; return false; } @@ -1327,8 +1327,7 @@ row_undo_mod( { dberr_t err; ut_ad(thr_get_trx(thr) == node->trx); - const bool dict_locked = node->trx->dict_operation_lock_mode - == RW_X_LATCH; + const bool dict_locked = node->trx->dict_operation_lock_mode; if (!row_undo_mod_parse_undo_rec(node, dict_locked)) { return DB_SUCCESS; @@ -1391,7 +1390,7 @@ rollback_clust: /* Do not attempt to update statistics when executing ROLLBACK in the InnoDB SQL interpreter, because in that case we would - already be holding dict_sys.mutex, which + already be holding dict_sys.latch, which would be acquired when updating statistics. */ if (update_statistics && !dict_locked) { dict_stats_update_if_needed(node->table, @@ -1402,7 +1401,7 @@ rollback_clust: } } - dict_table_close(node->table, dict_locked, FALSE); + dict_table_close(node->table, dict_locked); node->table = NULL; diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc index ee88ee7a4a6..9d8a19a8dff 100644 --- a/storage/innobase/row/row0upd.cc +++ b/storage/innobase/row/row0upd.cc @@ -162,7 +162,7 @@ wsrep_row_upd_index_is_foreign( /* No MDL protects dereferencing the members of table->foreign_set. */ const bool no_lock= !trx->dict_operation_lock_mode; if (no_lock) - dict_sys.freeze(); + dict_sys.freeze(SRW_LOCK_CALL); auto end= table->foreign_set.end(); const bool is_referenced= end != @@ -249,14 +249,14 @@ row_upd_check_references_constraints( ref_table = dict_table_open_on_name( foreign->foreign_table_name_lookup, - FALSE, FALSE, DICT_ERR_IGNORE_NONE); + false, DICT_ERR_IGNORE_NONE); } err = row_ins_check_foreign_constraint( FALSE, foreign, table, entry, thr); - if (ref_table != NULL) { - dict_table_close(ref_table, FALSE, FALSE); + if (ref_table) { + dict_table_close(ref_table); } if (err != DB_SUCCESS) { @@ -332,7 +332,7 @@ wsrep_row_upd_check_foreign_constraints( foreign->referenced_table = dict_table_open_on_name( foreign->referenced_table_name_lookup, - FALSE, FALSE, DICT_ERR_IGNORE_NONE); + false, DICT_ERR_IGNORE_NONE); opened = (foreign->referenced_table) ? TRUE : FALSE; } @@ -345,8 +345,8 @@ wsrep_row_upd_check_foreign_constraints( TRUE, foreign, table, entry, thr); if (foreign->referenced_table) { - if (opened == TRUE) { - dict_table_close(foreign->referenced_table, FALSE, FALSE); + if (opened) { + dict_table_close(foreign->referenced_table); opened = FALSE; } } diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc index f9daaf2ebf6..088b98eba38 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -1297,7 +1297,7 @@ void srv_monitor_task(void*) || waited == threshold / 2 || waited == threshold / 4 * 3) { ib::warn() << "Long wait (" << waited - << " seconds) for dict_sys.mutex"; + << " seconds) for dict_sys.latch"; } } } @@ -1371,8 +1371,6 @@ void purge_sys_t::stop_SYS() /** Stop purge during FLUSH TABLES FOR EXPORT */ void purge_sys_t::stop() { - dict_sys.assert_not_locked(); - for (;;) { latch.wr_lock(SRW_LOCK_CALL); @@ -1974,7 +1972,7 @@ ulint srv_get_task_queue_length() void srv_purge_shutdown() { if (purge_sys.enabled()) { - if (!srv_fast_shutdown) + if (!srv_fast_shutdown && !opt_bootstrap) srv_update_purge_thread_count(innodb_purge_threads_MAX); while(!srv_purge_should_exit()) { ut_a(!purge_sys.paused()); diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index 4a6c7ed42a0..bb0b9882419 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -174,7 +174,7 @@ struct TrxFactory { trx->rw_trx_hash_pins = 0; trx_init(trx); - trx->dict_operation_lock_mode = 0; + trx->dict_operation_lock_mode = false; trx->detailed_error = reinterpret_cast( ut_zalloc_nokey(MAX_DETAILED_ERROR_LEN)); @@ -215,7 +215,7 @@ struct TrxFactory { ut_a(trx->lock.wait_lock == NULL); ut_a(trx->lock.wait_thr == NULL); - ut_a(trx->dict_operation_lock_mode == 0); + ut_a(!trx->dict_operation_lock_mode); if (trx->lock.lock_heap != NULL) { mem_heap_free(trx->lock.lock_heap); @@ -604,10 +604,10 @@ trx_resurrect_table_locks( if (dict_table_t* table = dict_table_open_on_id( p.first, FALSE, DICT_TABLE_OP_LOAD_TABLESPACE)) { if (!table->is_readable()) { - dict_sys.mutex_lock(); - dict_table_close(table, TRUE, FALSE); + dict_sys.lock(SRW_LOCK_CALL); + table->release(); dict_sys.remove(table); - dict_sys.mutex_unlock(); + dict_sys.unlock(); continue; } @@ -622,7 +622,7 @@ trx_resurrect_table_locks( "resurrect " << ib::hex(trx->id) << " lock on " << table->name); - dict_table_close(table, FALSE, FALSE); + table->release(); } } } @@ -1114,7 +1114,7 @@ trx_finalize_for_fts( trx->fts_trx = NULL; } -extern "C" MYSQL_THD thd_increment_pending_ops(); + extern "C" void thd_decrement_pending_ops(MYSQL_THD); @@ -1123,11 +1123,11 @@ extern "C" void thd_decrement_pending_ops(MYSQL_THD); /* If required, initiates write and optionally flush of the log to disk - @param[in] lsn - lsn up to which logs are to be flushed. - @param[in] trx_state - if trx_state is PREPARED, the function will + @param lsn LSN up to which logs are to be flushed. + @param trx transaction; if trx->state is PREPARED, the function will also wait for the flush to complete. */ -static void trx_flush_log_if_needed_low(lsn_t lsn, trx_state_t trx_state) +static void trx_flush_log_if_needed_low(lsn_t lsn, const trx_t *trx) { if (!srv_flush_log_at_trx_commit) return; @@ -1138,25 +1138,23 @@ static void trx_flush_log_if_needed_low(lsn_t lsn, trx_state_t trx_state) const bool flush= srv_file_flush_method != SRV_NOSYNC && (srv_flush_log_at_trx_commit & 1); - if (trx_state == TRX_STATE_PREPARED) + if (trx->state == TRX_STATE_PREPARED) { /* XA, which is used with binlog as well. Be conservative, use synchronous wait.*/ +sync: log_write_up_to(lsn, flush); return; } completion_callback cb; - if ((cb.m_param = thd_increment_pending_ops())) + if ((cb.m_param = innodb_thd_increment_pending_ops(trx->mysql_thd))) { cb.m_callback = (void (*)(void *)) thd_decrement_pending_ops; log_write_up_to(lsn, flush, false, &cb); } else - { - /* No THD, synchronous write */ - log_write_up_to(lsn, flush); - } + goto sync; } /**********************************************************************//** @@ -1171,7 +1169,7 @@ trx_flush_log_if_needed( trx_t* trx) /*!< in/out: transaction */ { trx->op_info = "flushing log"; - trx_flush_log_if_needed_low(lsn,trx->state); + trx_flush_log_if_needed_low(lsn, trx); trx->op_info = ""; } @@ -1199,18 +1197,17 @@ void trx_t::evict_table(table_id_t table_id, bool reset_only) { ut_ad(in_rollback); - dict_table_t* table = dict_table_open_on_id( - table_id, true, DICT_TABLE_OP_OPEN_ONLY_IF_CACHED); + dict_table_t* table = dict_sys.find_table(table_id); if (!table) { return; } table->def_trx_id = 0; - if (!table->release()) { + if (auto ref_count = table->get_ref_count()) { /* This must be a DDL operation that is being rolled back in an active connection. */ - ut_a(table->get_ref_count() == 1); + ut_a(ref_count == 1); ut_ad(!is_recovered); ut_ad(mysql_thd); return; diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_spatial.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_spatial.result index fa42d4a1fd3..5c66485da7a 100644 --- a/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_spatial.result +++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_spatial.result @@ -114,7 +114,8 @@ VALUES ('hiiragi', ST_GeomFromText('POINT(139.711517 35.647701)')); ALTER TABLE shops ADD SPATIAL KEY location_index (location); SELECT id, name, ST_AsText(location) AS location_text FROM shops -WHERE MBRContains(ST_GeomFromText('LineString(139.7727 35.6684, 139.7038 35.7121)'), location); +WHERE MBRContains(ST_GeomFromText('LineString(139.7727 35.6684, 139.7038 35.7121)'), location) +ORDER BY id; id name location_text 14 tetsuji POINT(139.76857 35.680912) 19 daruma POINT(139.770599 35.681461) diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_spatial.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_spatial.test index 727557f88fa..c762b7ff157 100644 --- a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_spatial.test +++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_spatial.test @@ -142,7 +142,8 @@ INSERT INTO shops (name, location) ALTER TABLE shops ADD SPATIAL KEY location_index (location); SELECT id, name, ST_AsText(location) AS location_text FROM shops - WHERE MBRContains(ST_GeomFromText('LineString(139.7727 35.6684, 139.7038 35.7121)'), location); + WHERE MBRContains(ST_GeomFromText('LineString(139.7727 35.6684, 139.7038 35.7121)'), location) + ORDER BY id; DROP TABLE shops;