diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2017-12-12 09:35:18 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2017-12-12 09:57:17 +0200 |
commit | 34841d2305b6bbe2c0b496add905b1dd478dafbe (patch) | |
tree | 85b31de5caf44a9024d73e41fbdbdadb29ff5526 | |
parent | 62eaf7b657fd25bb4457049c81fb929314d6eb1d (diff) | |
parent | a285e68018018ef3959f6381aa61347b73902997 (diff) | |
download | mariadb-git-34841d2305b6bbe2c0b496add905b1dd478dafbe.tar.gz |
Merge bb-10.2-ext into 10.3
147 files changed, 1777 insertions, 975 deletions
diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index 45b332a6cd6..7e824cadf40 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -34,9 +34,9 @@ char *host= NULL, *user= 0, *opt_password= 0, *default_charset= (char*) MYSQL_AUTODETECT_CHARSET_NAME; -char truncated_var_names[MAX_MYSQL_VAR][MAX_TRUNC_LENGTH]; -char ex_var_names[MAX_MYSQL_VAR][FN_REFLEN]; -ulonglong last_values[MAX_MYSQL_VAR]; +char truncated_var_names[MAX_MYSQL_VAR+100][MAX_TRUNC_LENGTH]; +char ex_var_names[MAX_MYSQL_VAR+100][FN_REFLEN]; +ulonglong last_values[MAX_MYSQL_VAR+100]; static int interval=0; static my_bool option_force=0,interrupted=0,new_line=0, opt_compress= 0, opt_local= 0, opt_relative= 0, opt_verbose= 0, @@ -885,7 +885,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) return -1; } - DBUG_ASSERT(mysql_num_rows(res) < MAX_MYSQL_VAR); + DBUG_ASSERT(mysql_num_rows(res) < MAX_MYSQL_VAR+100); if (!opt_vertical) print_header(res); diff --git a/cmake/maintainer.cmake b/cmake/maintainer.cmake index bd2cfd7097c..77f55837fdb 100644 --- a/cmake/maintainer.cmake +++ b/cmake/maintainer.cmake @@ -51,7 +51,7 @@ IF(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang") ENDIF() # Set warning flags for G++/Clang++ IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") - SET(MY_MAINTAINER_CXX_WARNINGS "${MY_CXX_WARNING_FLAGS}") + SET(MY_MAINTAINER_CXX_WARNINGS "${MY_CXX_WARNING_FLAGS} -Wnon-virtual-dtor") ENDIF() IF(MYSQL_MAINTAINER_MODE MATCHES "ON") diff --git a/include/atomic/gcc_builtins.h b/include/atomic/gcc_builtins.h index 99e6f628b50..e2c3b10c267 100644 --- a/include/atomic/gcc_builtins.h +++ b/include/atomic/gcc_builtins.h @@ -40,18 +40,18 @@ #define my_atomic_add64_explicit(P, A, O) __atomic_fetch_add((P), (A), (O)) #define my_atomic_cas32_weak_explicit(P, E, D, S, F) \ - __atomic_compare_exchange_n((P), (E), (D), true, (S), (F)) + __atomic_compare_exchange_n((P), (E), (D), 1, (S), (F)) #define my_atomic_cas64_weak_explicit(P, E, D, S, F) \ - __atomic_compare_exchange_n((P), (E), (D), true, (S), (F)) + __atomic_compare_exchange_n((P), (E), (D), 1, (S), (F)) #define my_atomic_casptr_weak_explicit(P, E, D, S, F) \ - __atomic_compare_exchange_n((P), (E), (D), true, (S), (F)) + __atomic_compare_exchange_n((P), (E), (D), 1, (S), (F)) #define my_atomic_cas32_strong_explicit(P, E, D, S, F) \ - __atomic_compare_exchange_n((P), (E), (D), false, (S), (F)) + __atomic_compare_exchange_n((P), (E), (D), 0, (S), (F)) #define my_atomic_cas64_strong_explicit(P, E, D, S, F) \ - __atomic_compare_exchange_n((P), (E), (D), false, (S), (F)) + __atomic_compare_exchange_n((P), (E), (D), 0, (S), (F)) #define my_atomic_casptr_strong_explicit(P, E, D, S, F) \ - __atomic_compare_exchange_n((P), (E), (D), false, (S), (F)) + __atomic_compare_exchange_n((P), (E), (D), 0, (S), (F)) #define my_atomic_store32(P, D) __atomic_store_n((P), (D), __ATOMIC_SEQ_CST) #define my_atomic_store64(P, D) __atomic_store_n((P), (D), __ATOMIC_SEQ_CST) diff --git a/include/atomic/generic-msvc.h b/include/atomic/generic-msvc.h index 56fa4f66fcd..d5eaa4738c7 100644 --- a/include/atomic/generic-msvc.h +++ b/include/atomic/generic-msvc.h @@ -137,30 +137,4 @@ static inline void my_atomic_storeptr(void * volatile *a, void *v) *a= v; } - -/* - my_yield_processor (equivalent of x86 PAUSE instruction) should be used - to improve performance on hyperthreaded CPUs. Intel recommends to use it in - spin loops also on non-HT machines to reduce power consumption (see e.g - http://softwarecommunity.intel.com/articles/eng/2004.htm) - - Running benchmarks for spinlocks implemented with InterlockedCompareExchange - and YieldProcessor shows that much better performance is achieved by calling - YieldProcessor in a loop - that is, yielding longer. On Intel boxes setting - loop count in the range 200-300 brought best results. - */ -#define YIELD_LOOPS 200 - -static inline int my_yield_processor() -{ - int i; - for (i=0; i<YIELD_LOOPS; i++) - { - YieldProcessor(); - } - return 1; -} - -#define LF_BACKOFF my_yield_processor() - #endif /* ATOMIC_MSC_INCLUDED */ diff --git a/include/lf.h b/include/lf.h index 1825de62b43..a9d7e9ee688 100644 --- a/include/lf.h +++ b/include/lf.h @@ -17,6 +17,7 @@ #define INCLUDE_LF_INCLUDED #include <my_atomic.h> +#include <my_cpu.h> C_MODE_START diff --git a/include/my_atomic.h b/include/my_atomic.h index 32c9d6b4736..896dc2b5c33 100644 --- a/include/my_atomic.h +++ b/include/my_atomic.h @@ -116,16 +116,6 @@ #include "atomic/gcc_sync.h" #endif - -/* - the macro below defines (as an expression) the code that - will be run in spin-loops. Intel manuals recummend to have PAUSE there. - It is expected to be defined in include/atomic/ *.h files -*/ -#ifndef LF_BACKOFF -#define LF_BACKOFF (1) -#endif - #if SIZEOF_LONG == 4 #define my_atomic_addlong(A,B) my_atomic_add32((int32*) (A), (B)) #define my_atomic_loadlong(A) my_atomic_load32((int32*) (A)) diff --git a/include/my_cpu.h b/include/my_cpu.h index e255de85960..f2e26fca70c 100644 --- a/include/my_cpu.h +++ b/include/my_cpu.h @@ -1,3 +1,5 @@ +#ifndef MY_CPU_INCLUDED +#define MY_CPU_INCLUDED /* Copyright (c) 2013, MariaDB foundation Ab and SkySQL This program is free software; you can redistribute it and/or modify @@ -43,3 +45,58 @@ #define HMT_medium_high() #define HMT_high() #endif + + +static inline void MY_RELAX_CPU(void) +{ +#ifdef HAVE_PAUSE_INSTRUCTION + /* + According to the gcc info page, asm volatile means that the + instruction has important side-effects and must not be removed. + Also asm volatile may trigger a memory barrier (spilling all registers + to memory). + */ +#ifdef __SUNPRO_CC + asm ("pause" ); +#else + __asm__ __volatile__ ("pause"); +#endif + +#elif defined(HAVE_FAKE_PAUSE_INSTRUCTION) + __asm__ __volatile__ ("rep; nop"); +#elif defined _WIN32 + /* + In the Win32 API, the x86 PAUSE instruction is executed by calling + the YieldProcessor macro defined in WinNT.h. It is a CPU architecture- + independent way by using YieldProcessor. + */ + YieldProcessor(); +#elif defined(_ARCH_PWR8) + __ppc_get_timebase(); +#else + int32 var, oldval = 0; + my_atomic_cas32_strong_explicit(&var, &oldval, 1, MY_MEMORY_ORDER_RELAXED, + MY_MEMORY_ORDER_RELAXED); +#endif +} + + +/* + LF_BACKOFF should be used to improve performance on hyperthreaded CPUs. Intel + recommends to use it in spin loops also on non-HT machines to reduce power + consumption (see e.g http://softwarecommunity.intel.com/articles/eng/2004.htm) + + Running benchmarks for spinlocks implemented with InterlockedCompareExchange + and YieldProcessor shows that much better performance is achieved by calling + YieldProcessor in a loop - that is, yielding longer. On Intel boxes setting + loop count in the range 200-300 brought best results. +*/ + +static inline int LF_BACKOFF(void) +{ + int i; + for (i= 0; i < 200; i++) + MY_RELAX_CPU(); + return 1; +} +#endif diff --git a/mysql-test/include/ctype_like_range_mdev14350.inc b/mysql-test/include/ctype_like_range_mdev14350.inc new file mode 100644 index 00000000000..89ecc0201cd --- /dev/null +++ b/mysql-test/include/ctype_like_range_mdev14350.inc @@ -0,0 +1,14 @@ +--echo # +--echo # MDEV-14350 Index use with collation utf8mb4_unicode_nopad_ci on LIKE pattern with wrong results +--echo # + +CREATE OR REPLACE TABLE t1 AS SELECT SPACE(50) AS a, SPACE (50) AS b; +ALTER TABLE t1 ADD KEY(a), ADD KEY(b); +SHOW CREATE TABLE t1; +INSERT INTO t1 VALUES ('111', '111'); +INSERT INTO t1 VALUES ('222', '222'); +INSERT INTO t1 VALUES ('333', '333'); +INSERT INTO t1 VALUES ('444', '444'); +SELECT * FROM t1 WHERE a LIKE '111%'; +SELECT * FROM t1 IGNORE INDEX (a) WHERE a LIKE '111%'; +DROP TABLE t1; diff --git a/mysql-test/r/commit_1innodb.result b/mysql-test/r/commit_1innodb.result index e57d2ef1dcf..7d21540b548 100644 --- a/mysql-test/r/commit_1innodb.result +++ b/mysql-test/r/commit_1innodb.result @@ -230,7 +230,7 @@ insert into t2 (a) values (1023); do (f2(23)); Warnings: Error 1062 Duplicate entry '23' for key 'a' -Note 4093 At line 4 in test.f2 +Note 4094 At line 4 in test.f2 select * from t2; a 1023 diff --git a/mysql-test/r/create_drop_binlog.result b/mysql-test/r/create_drop_binlog.result index c880df7b39f..9dd5d43125b 100644 --- a/mysql-test/r/create_drop_binlog.result +++ b/mysql-test/r/create_drop_binlog.result @@ -160,7 +160,7 @@ Note 1050 Table 'v1' already exists DROP VIEW IF EXISTS v1; DROP VIEW IF EXISTS v1; Warnings: -Note 4091 Unknown VIEW: 'test.v1' +Note 4092 Unknown VIEW: 'test.v1' SHOW BINLOG EVENTS; Log_name Pos Event_type Server_id End_log_pos Info # # Format_desc 1 # VER diff --git a/mysql-test/r/create_drop_view.result b/mysql-test/r/create_drop_view.result index 8dc10297bdb..9d7e42552bf 100644 --- a/mysql-test/r/create_drop_view.result +++ b/mysql-test/r/create_drop_view.result @@ -55,5 +55,5 @@ id DROP VIEW IF EXISTS v1; DROP VIEW IF EXISTS v1; Warnings: -Note 4091 Unknown VIEW: 'test.v1' +Note 4092 Unknown VIEW: 'test.v1' DROP TABLE t1; diff --git a/mysql-test/r/ctype_latin1.result b/mysql-test/r/ctype_latin1.result index f9e0ae5a455..085b8b22f67 100644 --- a/mysql-test/r/ctype_latin1.result +++ b/mysql-test/r/ctype_latin1.result @@ -8804,6 +8804,31 @@ DROP TABLE t1; # End of ctype_pad.inc # SET STORAGE_ENGINE=Default; +SET NAMES latin1; +# +# MDEV-14350 Index use with collation utf8mb4_unicode_nopad_ci on LIKE pattern with wrong results +# +CREATE OR REPLACE TABLE t1 AS SELECT SPACE(50) AS a, SPACE (50) AS b; +ALTER TABLE t1 ADD KEY(a), ADD KEY(b); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(50) DEFAULT NULL, + `b` varchar(50) DEFAULT NULL, + KEY `a` (`a`), + KEY `b` (`b`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES ('111', '111'); +INSERT INTO t1 VALUES ('222', '222'); +INSERT INTO t1 VALUES ('333', '333'); +INSERT INTO t1 VALUES ('444', '444'); +SELECT * FROM t1 WHERE a LIKE '111%'; +a b +111 111 +SELECT * FROM t1 IGNORE INDEX (a) WHERE a LIKE '111%'; +a b +111 111 +DROP TABLE t1; # # End of 10.2 tests # diff --git a/mysql-test/r/ctype_like_range.result b/mysql-test/r/ctype_like_range.result index f8032d0ae86..d8e621fd056 100644 --- a/mysql-test/r/ctype_like_range.result +++ b/mysql-test/r/ctype_like_range.result @@ -4430,5 +4430,50 @@ a_ 6100 61FF a% 61000000000000000000 61FFFFFFFFFFFFFFFFFF DROP TABLE t1; # +# MDEV-14350 Index use with collation utf8mb4_unicode_nopad_ci on LIKE pattern with wrong results +# +CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET latin1 COLLATE latin1_swedish_nopad_ci); +INSERT INTO t1 VALUES ('111%'); +SELECT a, HEX(LIKE_RANGE_MIN(a,200)) FROM t1; +a HEX(LIKE_RANGE_MIN(a,200)) +111% 313131 +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf8 COLLATE utf8_general_nopad_ci); +INSERT INTO t1 VALUES ('111%'); +SELECT a, HEX(LIKE_RANGE_MIN(a,200)) FROM t1; +a HEX(LIKE_RANGE_MIN(a,200)) +111% 313131 +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf8 COLLATE utf8_unicode_nopad_ci); +INSERT INTO t1 VALUES ('111%'); +SELECT a, HEX(LIKE_RANGE_MIN(a,200)) FROM t1; +a HEX(LIKE_RANGE_MIN(a,200)) +111% 313131 +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_nopad_ci); +INSERT INTO t1 VALUES ('111%'); +SELECT a, HEX(LIKE_RANGE_MIN(a,200)) FROM t1; +a HEX(LIKE_RANGE_MIN(a,200)) +111% 313131 +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET ucs2 COLLATE ucs2_unicode_nopad_ci); +INSERT INTO t1 VALUES ('111%'); +SELECT a, HEX(LIKE_RANGE_MIN(a,200)) FROM t1; +a HEX(LIKE_RANGE_MIN(a,200)) +111% 003100310031 +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf16 COLLATE utf16_unicode_nopad_ci); +INSERT INTO t1 VALUES ('111%'); +SELECT a, HEX(LIKE_RANGE_MIN(a,200)) FROM t1; +a HEX(LIKE_RANGE_MIN(a,200)) +111% 003100310031 +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf32 COLLATE utf32_unicode_nopad_ci); +INSERT INTO t1 VALUES ('111%'); +SELECT a, HEX(LIKE_RANGE_MIN(a,200)) FROM t1; +a HEX(LIKE_RANGE_MIN(a,200)) +111% 000000310000003100000031 +DROP TABLE t1; +# # End of 10.2 tests # diff --git a/mysql-test/r/ctype_ucs2_uca.result b/mysql-test/r/ctype_ucs2_uca.result index 48ec25b32e3..44a623842c6 100644 --- a/mysql-test/r/ctype_ucs2_uca.result +++ b/mysql-test/r/ctype_ucs2_uca.result @@ -559,6 +559,32 @@ DROP TABLE t1; # End of ctype_pad.inc # SET STORAGE_ENGINE=Default; +SET NAMES utf8, collation_connection=ucs2_unicode_520_nopad_ci; +# +# MDEV-14350 Index use with collation utf8mb4_unicode_nopad_ci on LIKE pattern with wrong results +# +CREATE OR REPLACE TABLE t1 AS SELECT SPACE(50) AS a, SPACE (50) AS b; +ALTER TABLE t1 ADD KEY(a), ADD KEY(b); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(50) CHARACTER SET ucs2 COLLATE ucs2_unicode_520_nopad_ci DEFAULT NULL, + `b` varchar(50) CHARACTER SET ucs2 COLLATE ucs2_unicode_520_nopad_ci DEFAULT NULL, + KEY `a` (`a`), + KEY `b` (`b`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES ('111', '111'); +INSERT INTO t1 VALUES ('222', '222'); +INSERT INTO t1 VALUES ('333', '333'); +INSERT INTO t1 VALUES ('444', '444'); +SELECT * FROM t1 WHERE a LIKE '111%'; +a b +111 111 +SELECT * FROM t1 IGNORE INDEX (a) WHERE a LIKE '111%'; +a b +111 111 +DROP TABLE t1; +SET NAMES utf8; # # End of 10.2 tests # diff --git a/mysql-test/r/ctype_utf16_uca.result b/mysql-test/r/ctype_utf16_uca.result index 1105225ed87..0cb9c4c74c1 100644 --- a/mysql-test/r/ctype_utf16_uca.result +++ b/mysql-test/r/ctype_utf16_uca.result @@ -7866,6 +7866,32 @@ DROP TABLE t1; # End of ctype_pad.inc # SET STORAGE_ENGINE=Default; +SET NAMES utf8, collation_connection=utf16_unicode_520_nopad_ci; +# +# MDEV-14350 Index use with collation utf8mb4_unicode_nopad_ci on LIKE pattern with wrong results +# +CREATE OR REPLACE TABLE t1 AS SELECT SPACE(50) AS a, SPACE (50) AS b; +ALTER TABLE t1 ADD KEY(a), ADD KEY(b); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(50) CHARACTER SET utf16 COLLATE utf16_unicode_520_nopad_ci DEFAULT NULL, + `b` varchar(50) CHARACTER SET utf16 COLLATE utf16_unicode_520_nopad_ci DEFAULT NULL, + KEY `a` (`a`), + KEY `b` (`b`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES ('111', '111'); +INSERT INTO t1 VALUES ('222', '222'); +INSERT INTO t1 VALUES ('333', '333'); +INSERT INTO t1 VALUES ('444', '444'); +SELECT * FROM t1 WHERE a LIKE '111%'; +a b +111 111 +SELECT * FROM t1 IGNORE INDEX (a) WHERE a LIKE '111%'; +a b +111 111 +DROP TABLE t1; +SET NAMES utf8; # # End of 10.2 tests # diff --git a/mysql-test/r/ctype_utf32_uca.result b/mysql-test/r/ctype_utf32_uca.result index 097da3d7c16..a112918c0c3 100644 --- a/mysql-test/r/ctype_utf32_uca.result +++ b/mysql-test/r/ctype_utf32_uca.result @@ -7886,6 +7886,32 @@ DROP TABLE t1; # End of ctype_pad.inc # SET STORAGE_ENGINE=Default; +SET NAMES utf8, collation_connection=utf32_unicode_520_nopad_ci; +# +# MDEV-14350 Index use with collation utf8mb4_unicode_nopad_ci on LIKE pattern with wrong results +# +CREATE OR REPLACE TABLE t1 AS SELECT SPACE(50) AS a, SPACE (50) AS b; +ALTER TABLE t1 ADD KEY(a), ADD KEY(b); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(50) CHARACTER SET utf32 COLLATE utf32_unicode_520_nopad_ci DEFAULT NULL, + `b` varchar(50) CHARACTER SET utf32 COLLATE utf32_unicode_520_nopad_ci DEFAULT NULL, + KEY `a` (`a`), + KEY `b` (`b`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES ('111', '111'); +INSERT INTO t1 VALUES ('222', '222'); +INSERT INTO t1 VALUES ('333', '333'); +INSERT INTO t1 VALUES ('444', '444'); +SELECT * FROM t1 WHERE a LIKE '111%'; +a b +111 111 +SELECT * FROM t1 IGNORE INDEX (a) WHERE a LIKE '111%'; +a b +111 111 +DROP TABLE t1; +SET NAMES utf8; # # End of 10.2 tests # diff --git a/mysql-test/r/ctype_utf8_uca.result b/mysql-test/r/ctype_utf8_uca.result index c8107da3b6f..23e9802b61a 100644 --- a/mysql-test/r/ctype_utf8_uca.result +++ b/mysql-test/r/ctype_utf8_uca.result @@ -559,6 +559,31 @@ DROP TABLE t1; # End of ctype_pad.inc # SET STORAGE_ENGINE=Default; +SET NAMES utf8 COLLATE utf8_unicode_nopad_ci; +# +# MDEV-14350 Index use with collation utf8mb4_unicode_nopad_ci on LIKE pattern with wrong results +# +CREATE OR REPLACE TABLE t1 AS SELECT SPACE(50) AS a, SPACE (50) AS b; +ALTER TABLE t1 ADD KEY(a), ADD KEY(b); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_nopad_ci DEFAULT NULL, + `b` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_nopad_ci DEFAULT NULL, + KEY `a` (`a`), + KEY `b` (`b`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES ('111', '111'); +INSERT INTO t1 VALUES ('222', '222'); +INSERT INTO t1 VALUES ('333', '333'); +INSERT INTO t1 VALUES ('444', '444'); +SELECT * FROM t1 WHERE a LIKE '111%'; +a b +111 111 +SELECT * FROM t1 IGNORE INDEX (a) WHERE a LIKE '111%'; +a b +111 111 +DROP TABLE t1; # # End of 10.2 tests # diff --git a/mysql-test/r/ctype_utf8mb4_uca.result b/mysql-test/r/ctype_utf8mb4_uca.result index ca7f1a3d7d4..0712ca63abd 100644 --- a/mysql-test/r/ctype_utf8mb4_uca.result +++ b/mysql-test/r/ctype_utf8mb4_uca.result @@ -6576,6 +6576,32 @@ DROP TABLE t1; # End of ctype_pad.inc # SET STORAGE_ENGINE=Default; +SET NAMES utf8mb4 COLLATE utf8mb4_unicode_520_nopad_ci; +# +# MDEV-14350 Index use with collation utf8mb4_unicode_nopad_ci on LIKE pattern with wrong results +# +CREATE OR REPLACE TABLE t1 AS SELECT SPACE(50) AS a, SPACE (50) AS b; +ALTER TABLE t1 ADD KEY(a), ADD KEY(b); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_nopad_ci DEFAULT NULL, + `b` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_nopad_ci DEFAULT NULL, + KEY `a` (`a`), + KEY `b` (`b`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES ('111', '111'); +INSERT INTO t1 VALUES ('222', '222'); +INSERT INTO t1 VALUES ('333', '333'); +INSERT INTO t1 VALUES ('444', '444'); +SELECT * FROM t1 WHERE a LIKE '111%'; +a b +111 111 +SELECT * FROM t1 IGNORE INDEX (a) WHERE a LIKE '111%'; +a b +111 111 +DROP TABLE t1; +SET NAMES utf8mb4; # # End of 10.2 tests # diff --git a/mysql-test/r/custom_aggregate_functions.result b/mysql-test/r/custom_aggregate_functions.result index ca8612ba652..c2fdc271140 100644 --- a/mysql-test/r/custom_aggregate_functions.result +++ b/mysql-test/r/custom_aggregate_functions.result @@ -15,9 +15,9 @@ select f1(sal) from t1 where id>= 1; f1(sal) 0 Warnings: -Note 4093 At line 5 in test.f1 -Note 4093 At line 5 in test.f1 -Note 4093 At line 5 in test.f1 +Note 4094 At line 5 in test.f1 +Note 4094 At line 5 in test.f1 +Note 4094 At line 5 in test.f1 select * from t2; sal 5000 @@ -802,9 +802,9 @@ select f5() from t2; f5() 192000 Warnings: -Note 4093 At line 6 in test.f5 -Note 4093 At line 6 in test.f5 -Note 4093 At line 6 in test.f5 +Note 4094 At line 6 in test.f5 +Note 4094 At line 6 in test.f5 +Note 4094 At line 6 in test.f5 create aggregate function f6(x INT) returns INT begin declare z int default 0; @@ -820,8 +820,8 @@ select f6(sal) from t2; f6(sal) 128000 Warnings: -Note 4093 At line 6 in test.f6 -Note 4093 At line 6 in test.f6 +Note 4094 At line 6 in test.f6 +Note 4094 At line 6 in test.f6 select id, f1(sal) from t1 where id>= 1 group by id; id f1(sal) 1 7000 @@ -913,19 +913,19 @@ select f7(sal) from t1; f7(sal) 64000 Warnings: -Note 4093 At line 9 in test.f7 -Note 4093 At line 9 in test.f7 -Note 4093 At line 9 in test.f7 -Note 4093 At line 9 in test.f7 -Note 4093 At line 9 in test.f7 -Note 4093 At line 9 in test.f7 -Note 4093 At line 9 in test.f7 -Note 4093 At line 9 in test.f7 -Note 4093 At line 9 in test.f7 -Note 4093 At line 9 in test.f7 -Note 4093 At line 9 in test.f7 -Note 4093 At line 9 in test.f7 -Note 4093 At line 9 in test.f7 +Note 4094 At line 9 in test.f7 +Note 4094 At line 9 in test.f7 +Note 4094 At line 9 in test.f7 +Note 4094 At line 9 in test.f7 +Note 4094 At line 9 in test.f7 +Note 4094 At line 9 in test.f7 +Note 4094 At line 9 in test.f7 +Note 4094 At line 9 in test.f7 +Note 4094 At line 9 in test.f7 +Note 4094 At line 9 in test.f7 +Note 4094 At line 9 in test.f7 +Note 4094 At line 9 in test.f7 +Note 4094 At line 9 in test.f7 drop table t1; drop table t2; drop table t3; diff --git a/mysql-test/r/drop.result b/mysql-test/r/drop.result index 37005fb017e..88e070af88c 100644 --- a/mysql-test/r/drop.result +++ b/mysql-test/r/drop.result @@ -209,10 +209,10 @@ Note 1051 Unknown table 'test.table1' Note 1051 Unknown table 'test.table2' DROP VIEW IF EXISTS view1,view2,view3,view4; Warnings: -Note 4091 Unknown VIEW: 'test.view1' -Note 4091 Unknown VIEW: 'test.view2' -Note 4091 Unknown VIEW: 'test.view3' -Note 4091 Unknown VIEW: 'test.view4' +Note 4092 Unknown VIEW: 'test.view1' +Note 4092 Unknown VIEW: 'test.view2' +Note 4092 Unknown VIEW: 'test.view3' +Note 4092 Unknown VIEW: 'test.view4' # Test error message when trigger does not find table CREATE TABLE table1(a int); diff --git a/mysql-test/r/get_diagnostics.result b/mysql-test/r/get_diagnostics.result index 63ed6867096..732be7c0283 100644 --- a/mysql-test/r/get_diagnostics.result +++ b/mysql-test/r/get_diagnostics.result @@ -590,7 +590,7 @@ DROP PROCEDURE p1; SHOW WARNINGS; Level Code Message Error 54321 MESSAGE_TEXT text -Note 4093 At line 16 in test.p1 +Note 4094 At line 16 in test.p1 CREATE PROCEDURE p1() BEGIN DECLARE var INT; diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index d2118fb56fe..5f9e682d63d 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -1428,7 +1428,7 @@ Warnings: Note 1305 FUNCTION test.test_function does not exist drop view if exists v1; Warnings: -Note 4091 Unknown VIEW: 'test.v1' +Note 4092 Unknown VIEW: 'test.v1' create table test (col1 varchar(30)); create function test_function() returns varchar(30) begin diff --git a/mysql-test/r/profiling.result b/mysql-test/r/profiling.result index bc8dd162481..6590d89bc89 100644 --- a/mysql-test/r/profiling.result +++ b/mysql-test/r/profiling.result @@ -415,7 +415,7 @@ select @@profiling; drop table if exists t1, t2, t3; drop view if exists v1; Warnings: -Note 4091 Unknown VIEW: 'test.v1' +Note 4092 Unknown VIEW: 'test.v1' drop function if exists f1; set session profiling = OFF; set global profiling_history_size= @start_value; diff --git a/mysql-test/r/signal.result b/mysql-test/r/signal.result index 09493f0da30..905842bfb1c 100644 --- a/mysql-test/r/signal.result +++ b/mysql-test/r/signal.result @@ -1715,7 +1715,7 @@ show warnings $$ Level Code Message Warning 1012 Raising a warning Error 5555 RESIGNAL to not found -Note 4093 At line 9 in test.test_resignal +Note 4094 At line 9 in test.test_resignal drop procedure test_resignal $$ create procedure test_resignal() begin @@ -1740,7 +1740,7 @@ show warnings $$ Level Code Message Warning 1012 Raising a warning Error 5555 RESIGNAL to error -Note 4093 At line 9 in test.test_resignal +Note 4094 At line 9 in test.test_resignal drop procedure test_resignal $$ create procedure test_resignal() begin @@ -1789,7 +1789,7 @@ show warnings $$ Level Code Message Error 1012 Raising a not found Error 5555 RESIGNAL to not found -Note 4093 At line 9 in test.test_resignal +Note 4094 At line 9 in test.test_resignal drop procedure test_resignal $$ create procedure test_resignal() begin @@ -1814,7 +1814,7 @@ show warnings $$ Level Code Message Error 1012 Raising a not found Error 5555 RESIGNAL to error -Note 4093 At line 9 in test.test_resignal +Note 4094 At line 9 in test.test_resignal drop procedure test_resignal $$ create procedure test_resignal() begin @@ -1863,7 +1863,7 @@ show warnings $$ Level Code Message Error 1012 Raising an error Error 5555 RESIGNAL to not found -Note 4093 At line 9 in test.test_resignal +Note 4094 At line 9 in test.test_resignal drop procedure test_resignal $$ create procedure test_resignal() begin @@ -1888,7 +1888,7 @@ show warnings $$ Level Code Message Error 1012 Raising an error Error 5555 RESIGNAL to error -Note 4093 At line 9 in test.test_resignal +Note 4094 At line 9 in test.test_resignal drop procedure test_resignal $$ create procedure test_resignal() begin @@ -1931,7 +1931,7 @@ show warnings $$ Level Code Message Warning 1264 Out of range value for column 'a' at row 1 Error 5555 RESIGNAL to a not found -Note 4093 At line 8 in test.test_resignal +Note 4094 At line 8 in test.test_resignal drop procedure test_resignal $$ create procedure test_resignal() begin @@ -1953,7 +1953,7 @@ show warnings $$ Level Code Message Warning 1264 Out of range value for column 'a' at row 1 Error 5555 RESIGNAL to an error -Note 4093 At line 8 in test.test_resignal +Note 4094 At line 8 in test.test_resignal drop procedure test_resignal $$ create procedure test_resignal() begin @@ -2004,7 +2004,7 @@ show warnings $$ Level Code Message Error 1329 No data - zero rows fetched, selected, or processed Error 5555 RESIGNAL to a not found -Note 4093 At line 10 in test.test_resignal +Note 4094 At line 10 in test.test_resignal drop procedure test_resignal $$ create procedure test_resignal() begin @@ -2030,7 +2030,7 @@ show warnings $$ Level Code Message Error 1329 No data - zero rows fetched, selected, or processed Error 5555 RESIGNAL to an error -Note 4093 At line 10 in test.test_resignal +Note 4094 At line 10 in test.test_resignal drop procedure test_resignal $$ create procedure test_resignal() begin @@ -2073,7 +2073,7 @@ show warnings $$ Level Code Message Error 1051 Unknown table 'test.no_such_table' Error 5555 RESIGNAL to a not found -Note 4093 At line 8 in test.test_resignal +Note 4094 At line 8 in test.test_resignal drop procedure test_resignal $$ create procedure test_resignal() begin @@ -2095,7 +2095,7 @@ show warnings $$ Level Code Message Error 1051 Unknown table 'test.no_such_table' Error 5555 RESIGNAL to an error -Note 4093 At line 8 in test.test_resignal +Note 4094 At line 8 in test.test_resignal drop procedure test_resignal $$ # # More complex cases @@ -2142,7 +2142,7 @@ ERROR 42000: Hi, I am a useless error message show warnings $$ Level Code Message Error 9999 Hi, I am a useless error message -Note 4093 At line 7 in test.peter_p2 +Note 4094 At line 7 in test.peter_p2 drop procedure peter_p1 $$ drop procedure peter_p2 $$ CREATE PROCEDURE peter_p1 () @@ -2198,16 +2198,16 @@ Level Code Message Error 1231 Variable 'sql_mode' can't be set to the value of 'NULL' Error 1232 Variable 'sql_mode' can't be set to the value of 'NULL' Error 9999 Variable 'sql_mode' can't be set to the value of 'NULL' -Note 4093 At line 8 in test.peter_p1 +Note 4094 At line 8 in test.peter_p1 ERROR 42000: Hi, I am a useless error message show warnings $$ Level Code Message Error 1231 Variable 'sql_mode' can't be set to the value of 'NULL' Error 1232 Variable 'sql_mode' can't be set to the value of 'NULL' Error 9999 Variable 'sql_mode' can't be set to the value of 'NULL' -Note 4093 At line 8 in test.peter_p1 +Note 4094 At line 8 in test.peter_p1 Error 9999 Hi, I am a useless error message -Note 4093 At line 10 in test.peter_p2 +Note 4094 At line 10 in test.peter_p2 drop procedure peter_p1 $$ drop procedure peter_p2 $$ drop procedure if exists peter_p3 $$ @@ -2225,7 +2225,7 @@ show warnings $$ Level Code Message Error 1 Original Error 2 Original -Note 4093 At line 4 in test.peter_p3 +Note 4094 At line 4 in test.peter_p3 drop procedure peter_p3 $$ drop table t_warn; drop table t_cursor; diff --git a/mysql-test/r/signal_demo3.result b/mysql-test/r/signal_demo3.result index 1d597aaf71c..fe425f6412d 100644 --- a/mysql-test/r/signal_demo3.result +++ b/mysql-test/r/signal_demo3.result @@ -79,23 +79,23 @@ show warnings; Level Code Message Error 1051 Unknown table 'demo.oops_it_is_not_here' Error 1644 Oops in proc_9 -Note 4093 At line 4 in demo.proc_9 +Note 4094 At line 4 in demo.proc_9 Error 1644 Oops in proc_8 -Note 4093 At line 4 in demo.proc_8 +Note 4094 At line 4 in demo.proc_8 Error 1644 Oops in proc_7 -Note 4093 At line 4 in demo.proc_7 +Note 4094 At line 4 in demo.proc_7 Error 1644 Oops in proc_6 -Note 4093 At line 4 in demo.proc_6 +Note 4094 At line 4 in demo.proc_6 Error 1644 Oops in proc_5 -Note 4093 At line 4 in demo.proc_5 +Note 4094 At line 4 in demo.proc_5 Error 1644 Oops in proc_4 -Note 4093 At line 4 in demo.proc_4 +Note 4094 At line 4 in demo.proc_4 Error 1644 Oops in proc_3 -Note 4093 At line 4 in demo.proc_3 +Note 4094 At line 4 in demo.proc_3 Error 1644 Oops in proc_2 -Note 4093 At line 4 in demo.proc_2 +Note 4094 At line 4 in demo.proc_2 Error 1644 Oops in proc_1 -Note 4093 At line 4 in demo.proc_1 +Note 4094 At line 4 in demo.proc_1 SET @@session.max_error_count = 5; SELECT @@session.max_error_count; @@session.max_error_count @@ -104,11 +104,11 @@ call proc_1(); ERROR 45000: Oops in proc_1 show warnings; Level Code Message -Note 4093 At line 4 in demo.proc_3 +Note 4094 At line 4 in demo.proc_3 Error 1644 Oops in proc_2 -Note 4093 At line 4 in demo.proc_2 +Note 4094 At line 4 in demo.proc_2 Error 1644 Oops in proc_1 -Note 4093 At line 4 in demo.proc_1 +Note 4094 At line 4 in demo.proc_1 SET @@session.max_error_count = 7; SELECT @@session.max_error_count; @@session.max_error_count @@ -117,13 +117,13 @@ call proc_1(); ERROR 45000: Oops in proc_1 show warnings; Level Code Message -Note 4093 At line 4 in demo.proc_4 +Note 4094 At line 4 in demo.proc_4 Error 1644 Oops in proc_3 -Note 4093 At line 4 in demo.proc_3 +Note 4094 At line 4 in demo.proc_3 Error 1644 Oops in proc_2 -Note 4093 At line 4 in demo.proc_2 +Note 4094 At line 4 in demo.proc_2 Error 1644 Oops in proc_1 -Note 4093 At line 4 in demo.proc_1 +Note 4094 At line 4 in demo.proc_1 SET @@session.max_error_count = 9; SELECT @@session.max_error_count; @@session.max_error_count @@ -132,15 +132,15 @@ call proc_1(); ERROR 45000: Oops in proc_1 show warnings; Level Code Message -Note 4093 At line 4 in demo.proc_5 +Note 4094 At line 4 in demo.proc_5 Error 1644 Oops in proc_4 -Note 4093 At line 4 in demo.proc_4 +Note 4094 At line 4 in demo.proc_4 Error 1644 Oops in proc_3 -Note 4093 At line 4 in demo.proc_3 +Note 4094 At line 4 in demo.proc_3 Error 1644 Oops in proc_2 -Note 4093 At line 4 in demo.proc_2 +Note 4094 At line 4 in demo.proc_2 Error 1644 Oops in proc_1 -Note 4093 At line 4 in demo.proc_1 +Note 4094 At line 4 in demo.proc_1 drop database demo; SET @@global.max_error_count = @start_global_value; SELECT @@global.max_error_count; diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index ad4b18fc37a..fc43bdf17e9 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -1990,8 +1990,8 @@ Warning 1264 Out of range value for column 'a' at row 1 Note 1292 Truncated incorrect INTEGER value: '222222 ' Warning 1264 Out of range value for column 'b' at row 1 Error 1048 Column 'c' cannot be null -Note 4093 At line 6 in test.t1_bi -Note 4093 At line 2 in test.p1 +Note 4094 At line 6 in test.t1_bi +Note 4094 At line 2 in test.p1 DROP TABLE t1; DROP TABLE t2; diff --git a/mysql-test/r/sp-group.result b/mysql-test/r/sp-group.result index 800d83f1f74..ce8dccfa2c9 100644 --- a/mysql-test/r/sp-group.result +++ b/mysql-test/r/sp-group.result @@ -3,7 +3,7 @@ Warnings: Note 1051 Unknown table 'test.t1' drop view if exists view_t1; Warnings: -Note 4091 Unknown VIEW: 'test.view_t1' +Note 4092 Unknown VIEW: 'test.view_t1' SET sql_mode=ONLY_FULL_GROUP_BY; CREATE TABLE t1 ( pk INT, diff --git a/mysql-test/r/sp-row.result b/mysql-test/r/sp-row.result index adb67030feb..d3be7c2a9b9 100644 --- a/mysql-test/r/sp-row.result +++ b/mysql-test/r/sp-row.result @@ -210,7 +210,7 @@ SELECT a=1; END; $$ CALL p1(); -ERROR 21000: Operand should contain 2 column(s) +ERROR HY000: Illegal parameter data types row and int for operation '=' DROP PROCEDURE p1; CREATE PROCEDURE p1() BEGIN @@ -219,7 +219,7 @@ SELECT 1=a; END; $$ CALL p1(); -ERROR 21000: Operand should contain 1 column(s) +ERROR HY000: Illegal parameter data types int and row for operation '=' DROP PROCEDURE p1; # # Passing the entire ROW to a stored function diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 3b8f35e0c79..5aac66a384b 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -3211,7 +3211,7 @@ drop procedure bug10961| DROP PROCEDURE IF EXISTS bug6866| DROP VIEW IF EXISTS tv| Warnings: -Note 4091 Unknown VIEW: 'test.tv' +Note 4092 Unknown VIEW: 'test.tv' DROP TABLE IF EXISTS tt1,tt2,tt3| Warnings: Note 1051 Unknown table 'test.tt1' @@ -7823,7 +7823,7 @@ ERROR 23000: Duplicate entry '2' for key 'PRIMARY' show warnings; Level Code Message Error 1062 Duplicate entry '2' for key 'PRIMARY' -Note 4093 At line 5 in test.p1 +Note 4094 At line 5 in test.p1 select * from t1; id 1 @@ -8291,6 +8291,63 @@ rec=(10) c rec=(20) DROP PROCEDURE p1; +# +# MDEV-14228 MariaDB crashes with function +# +CREATE TABLE t1 (c VARCHAR(16), KEY(c)); +INSERT INTO t1 VALUES ('foo'); +CREATE FUNCTION f1() RETURNS VARCHAR(16) +BEGIN +DECLARE v VARCHAR(16); +FOR v IN (SELECT DISTINCT c FROM t1) +DO +IF (v = 'bar') THEN +SELECT 1 INTO @a; +END IF; +END FOR; +RETURN 'qux'; +END $$ +SELECT f1(); +ERROR HY000: Illegal parameter data types row and varchar for operation '=' +DROP FUNCTION f1; +CREATE FUNCTION f1() RETURNS VARCHAR(16) +BEGIN +DECLARE v ROW TYPE OF t1; +IF v = 'bar' THEN +RETURN 'eq'; +END IF; +RETURN 'ne'; +END $$ +SELECT f1(); +ERROR HY000: Illegal parameter data types row and varchar for operation '=' +DROP FUNCTION f1; +CREATE FUNCTION f1() RETURNS VARCHAR(16) +BEGIN +DECLARE v ROW(a INT); +IF v = 'bar' THEN +RETURN 'eq'; +END IF; +RETURN 'ne'; +END $$ +SELECT f1(); +ERROR HY000: Illegal parameter data types row and varchar for operation '=' +DROP FUNCTION f1; +DROP TABLE t1; +BEGIN NOT ATOMIC +DECLARE v ROW(a INT); +SELECT v IN ('a','b'); +END $$ +ERROR HY000: Illegal parameter data types row and varchar for operation 'in' +BEGIN NOT ATOMIC +DECLARE v ROW(a INT); +SELECT 'a' IN (v,'b'); +END $$ +ERROR HY000: Illegal parameter data types varchar and row for operation 'in' +BEGIN NOT ATOMIC +DECLARE v ROW(a INT); +SELECT 'a' IN ('b',v); +END $$ +ERROR HY000: Illegal parameter data types varchar and row for operation 'in' # Test affected rows from an sp create table t1 (a int); create procedure p1() diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 8e46fa91c2c..f9b53940df4 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -384,10 +384,10 @@ Warnings: Note 1003 /* select#1 */ select 'joce' AS `pseudo`,(/* select#2 */ select 'test' from `test`.`t8` where 1) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where 1 SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM t8 WHERE pseudo='joce'); -ERROR 21000: Operand should contain 1 column(s) +ERROR HY000: Illegal parameter data types varchar and row for operation '=' SELECT pseudo FROM t8 WHERE pseudo=(SELECT * FROM t8 WHERE pseudo='joce'); -ERROR 21000: Operand should contain 1 column(s) +ERROR HY000: Illegal parameter data types varchar and row for operation '=' SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'); pseudo joce @@ -2865,13 +2865,13 @@ drop table t1, t2; create table t1 (a int, b int); insert into t1 values (1,2); select 1 = (select * from t1); -ERROR 21000: Operand should contain 1 column(s) +ERROR HY000: Illegal parameter data types int and row for operation '=' select (select * from t1) = 1; -ERROR 21000: Operand should contain 2 column(s) +ERROR HY000: Illegal parameter data types row and int for operation '=' select (1,2) = (select a from t1); -ERROR 21000: Operand should contain 2 column(s) +ERROR HY000: Illegal parameter data types row and int for operation '=' select (select a from t1) = (1,2); -ERROR 21000: Operand should contain 1 column(s) +ERROR HY000: Illegal parameter data types int and row for operation '=' select (1,2,3) = (select * from t1); ERROR 21000: Operand should contain 3 column(s) select (select * from t1) = (1,2,3); diff --git a/mysql-test/r/subselect_no_exists_to_in.result b/mysql-test/r/subselect_no_exists_to_in.result index 51fe0aa80df..5c8230e7493 100644 --- a/mysql-test/r/subselect_no_exists_to_in.result +++ b/mysql-test/r/subselect_no_exists_to_in.result @@ -388,10 +388,10 @@ Warnings: Note 1003 /* select#1 */ select 'joce' AS `pseudo`,(/* select#2 */ select 'test' from `test`.`t8` where 1) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where 1 SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM t8 WHERE pseudo='joce'); -ERROR 21000: Operand should contain 1 column(s) +ERROR HY000: Illegal parameter data types varchar and row for operation '=' SELECT pseudo FROM t8 WHERE pseudo=(SELECT * FROM t8 WHERE pseudo='joce'); -ERROR 21000: Operand should contain 1 column(s) +ERROR HY000: Illegal parameter data types varchar and row for operation '=' SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'); pseudo joce @@ -2868,13 +2868,13 @@ drop table t1, t2; create table t1 (a int, b int); insert into t1 values (1,2); select 1 = (select * from t1); -ERROR 21000: Operand should contain 1 column(s) +ERROR HY000: Illegal parameter data types int and row for operation '=' select (select * from t1) = 1; -ERROR 21000: Operand should contain 2 column(s) +ERROR HY000: Illegal parameter data types row and int for operation '=' select (1,2) = (select a from t1); -ERROR 21000: Operand should contain 2 column(s) +ERROR HY000: Illegal parameter data types row and int for operation '=' select (select a from t1) = (1,2); -ERROR 21000: Operand should contain 1 column(s) +ERROR HY000: Illegal parameter data types int and row for operation '=' select (1,2,3) = (select * from t1); ERROR 21000: Operand should contain 3 column(s) select (select * from t1) = (1,2,3); diff --git a/mysql-test/r/subselect_no_mat.result b/mysql-test/r/subselect_no_mat.result index 6381e1939db..8b395fae5ce 100644 --- a/mysql-test/r/subselect_no_mat.result +++ b/mysql-test/r/subselect_no_mat.result @@ -391,10 +391,10 @@ Warnings: Note 1003 /* select#1 */ select 'joce' AS `pseudo`,(/* select#2 */ select 'test' from `test`.`t8` where 1) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where 1 SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM t8 WHERE pseudo='joce'); -ERROR 21000: Operand should contain 1 column(s) +ERROR HY000: Illegal parameter data types varchar and row for operation '=' SELECT pseudo FROM t8 WHERE pseudo=(SELECT * FROM t8 WHERE pseudo='joce'); -ERROR 21000: Operand should contain 1 column(s) +ERROR HY000: Illegal parameter data types varchar and row for operation '=' SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'); pseudo joce @@ -2871,13 +2871,13 @@ drop table t1, t2; create table t1 (a int, b int); insert into t1 values (1,2); select 1 = (select * from t1); -ERROR 21000: Operand should contain 1 column(s) +ERROR HY000: Illegal parameter data types int and row for operation '=' select (select * from t1) = 1; -ERROR 21000: Operand should contain 2 column(s) +ERROR HY000: Illegal parameter data types row and int for operation '=' select (1,2) = (select a from t1); -ERROR 21000: Operand should contain 2 column(s) +ERROR HY000: Illegal parameter data types row and int for operation '=' select (select a from t1) = (1,2); -ERROR 21000: Operand should contain 1 column(s) +ERROR HY000: Illegal parameter data types int and row for operation '=' select (1,2,3) = (select * from t1); ERROR 21000: Operand should contain 3 column(s) select (select * from t1) = (1,2,3); diff --git a/mysql-test/r/subselect_no_opts.result b/mysql-test/r/subselect_no_opts.result index 1a56c333887..fbc5fccfb9b 100644 --- a/mysql-test/r/subselect_no_opts.result +++ b/mysql-test/r/subselect_no_opts.result @@ -387,10 +387,10 @@ Warnings: Note 1003 /* select#1 */ select 'joce' AS `pseudo`,(/* select#2 */ select 'test' from `test`.`t8` where 1) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where 1 SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM t8 WHERE pseudo='joce'); -ERROR 21000: Operand should contain 1 column(s) +ERROR HY000: Illegal parameter data types varchar and row for operation '=' SELECT pseudo FROM t8 WHERE pseudo=(SELECT * FROM t8 WHERE pseudo='joce'); -ERROR 21000: Operand should contain 1 column(s) +ERROR HY000: Illegal parameter data types varchar and row for operation '=' SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'); pseudo joce @@ -2867,13 +2867,13 @@ drop table t1, t2; create table t1 (a int, b int); insert into t1 values (1,2); select 1 = (select * from t1); -ERROR 21000: Operand should contain 1 column(s) +ERROR HY000: Illegal parameter data types int and row for operation '=' select (select * from t1) = 1; -ERROR 21000: Operand should contain 2 column(s) +ERROR HY000: Illegal parameter data types row and int for operation '=' select (1,2) = (select a from t1); -ERROR 21000: Operand should contain 2 column(s) +ERROR HY000: Illegal parameter data types row and int for operation '=' select (select a from t1) = (1,2); -ERROR 21000: Operand should contain 1 column(s) +ERROR HY000: Illegal parameter data types int and row for operation '=' select (1,2,3) = (select * from t1); ERROR 21000: Operand should contain 3 column(s) select (select * from t1) = (1,2,3); diff --git a/mysql-test/r/subselect_no_scache.result b/mysql-test/r/subselect_no_scache.result index 26aee4269b6..446d2649d1f 100644 --- a/mysql-test/r/subselect_no_scache.result +++ b/mysql-test/r/subselect_no_scache.result @@ -390,10 +390,10 @@ Warnings: Note 1003 /* select#1 */ select 'joce' AS `pseudo`,(/* select#2 */ select 'test' from `test`.`t8` where 1) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where 1 SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM t8 WHERE pseudo='joce'); -ERROR 21000: Operand should contain 1 column(s) +ERROR HY000: Illegal parameter data types varchar and row for operation '=' SELECT pseudo FROM t8 WHERE pseudo=(SELECT * FROM t8 WHERE pseudo='joce'); -ERROR 21000: Operand should contain 1 column(s) +ERROR HY000: Illegal parameter data types varchar and row for operation '=' SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'); pseudo joce @@ -2871,13 +2871,13 @@ drop table t1, t2; create table t1 (a int, b int); insert into t1 values (1,2); select 1 = (select * from t1); -ERROR 21000: Operand should contain 1 column(s) +ERROR HY000: Illegal parameter data types int and row for operation '=' select (select * from t1) = 1; -ERROR 21000: Operand should contain 2 column(s) +ERROR HY000: Illegal parameter data types row and int for operation '=' select (1,2) = (select a from t1); -ERROR 21000: Operand should contain 2 column(s) +ERROR HY000: Illegal parameter data types row and int for operation '=' select (select a from t1) = (1,2); -ERROR 21000: Operand should contain 1 column(s) +ERROR HY000: Illegal parameter data types int and row for operation '=' select (1,2,3) = (select * from t1); ERROR 21000: Operand should contain 3 column(s) select (select * from t1) = (1,2,3); diff --git a/mysql-test/r/subselect_no_semijoin.result b/mysql-test/r/subselect_no_semijoin.result index e962add85c8..97ff454cf51 100644 --- a/mysql-test/r/subselect_no_semijoin.result +++ b/mysql-test/r/subselect_no_semijoin.result @@ -387,10 +387,10 @@ Warnings: Note 1003 /* select#1 */ select 'joce' AS `pseudo`,(/* select#2 */ select 'test' from `test`.`t8` where 1) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where 1 SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM t8 WHERE pseudo='joce'); -ERROR 21000: Operand should contain 1 column(s) +ERROR HY000: Illegal parameter data types varchar and row for operation '=' SELECT pseudo FROM t8 WHERE pseudo=(SELECT * FROM t8 WHERE pseudo='joce'); -ERROR 21000: Operand should contain 1 column(s) +ERROR HY000: Illegal parameter data types varchar and row for operation '=' SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'); pseudo joce @@ -2867,13 +2867,13 @@ drop table t1, t2; create table t1 (a int, b int); insert into t1 values (1,2); select 1 = (select * from t1); -ERROR 21000: Operand should contain 1 column(s) +ERROR HY000: Illegal parameter data types int and row for operation '=' select (select * from t1) = 1; -ERROR 21000: Operand should contain 2 column(s) +ERROR HY000: Illegal parameter data types row and int for operation '=' select (1,2) = (select a from t1); -ERROR 21000: Operand should contain 2 column(s) +ERROR HY000: Illegal parameter data types row and int for operation '=' select (select a from t1) = (1,2); -ERROR 21000: Operand should contain 1 column(s) +ERROR HY000: Illegal parameter data types int and row for operation '=' select (1,2,3) = (select * from t1); ERROR 21000: Operand should contain 3 column(s) select (select * from t1) = (1,2,3); diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 120a13254a0..7133047f8af 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -5166,7 +5166,7 @@ CREATE TABLE t4 (i4 INT); INSERT INTO t4 VALUES (1),(2); DROP VIEW IF EXISTS v1; Warnings: -Note 4091 Unknown VIEW: 'test.v1' +Note 4092 Unknown VIEW: 'test.v1' CREATE VIEW v1 AS select coalesce(j1,i3) AS v1_field1 from t2 join t3 left join t1 on ( i1 = i2 ); CREATE VIEW v2 AS select v1_field1 from t4 join v1; prepare my_stmt from "select v1_field1 from v2"; diff --git a/mysql-test/r/warnings.result b/mysql-test/r/warnings.result index d808479e8ef..410ea9b28e7 100644 --- a/mysql-test/r/warnings.result +++ b/mysql-test/r/warnings.result @@ -353,7 +353,7 @@ ERROR 23000: Duplicate entry '11' for key 'a' SHOW WARNINGS; Level Code Message -Note 4093 At line 4 in test.f1 +Note 4094 At line 4 in test.f1 Error 1062 Duplicate entry '11' for key 'a' DROP TABLE t1; diff --git a/mysql-test/suite/compat/oracle/r/sp-row.result b/mysql-test/suite/compat/oracle/r/sp-row.result index f95817420f1..9557a24a1da 100644 --- a/mysql-test/suite/compat/oracle/r/sp-row.result +++ b/mysql-test/suite/compat/oracle/r/sp-row.result @@ -232,7 +232,7 @@ SELECT a=1; END; $$ CALL p1(); -ERROR 21000: Operand should contain 2 column(s) +ERROR HY000: Illegal parameter data types row and int for operation '=' DROP PROCEDURE p1; CREATE PROCEDURE p1() AS @@ -242,7 +242,7 @@ SELECT 1=a; END; $$ CALL p1(); -ERROR 21000: Operand should contain 1 column(s) +ERROR HY000: Illegal parameter data types int and row for operation '=' DROP PROCEDURE p1; # # Passing the entire ROW to a stored function diff --git a/mysql-test/suite/compat/oracle/r/sp.result b/mysql-test/suite/compat/oracle/r/sp.result index 2bf4f50e6d5..2f565b0a183 100644 --- a/mysql-test/suite/compat/oracle/r/sp.result +++ b/mysql-test/suite/compat/oracle/r/sp.result @@ -2432,3 +2432,66 @@ a b DROP PROCEDURE p1; DROP VIEW v1; DROP TABLE t1; +# +# MDEV-14228 MariaDB crashes with function +# +CREATE TABLE t1 (c VARCHAR(16), KEY(c)); +INSERT INTO t1 VALUES ('foo'); +CREATE FUNCTION f1() RETURN VARCHAR(16) +IS +v VARCHAR2(16); +BEGIN +FOR v IN (SELECT DISTINCT c FROM t1) +LOOP +IF (v = 'bar') THEN +SELECT 1 INTO @a; +END IF; +END LOOP; +RETURN 'qux'; +END $$ +SELECT f1(); +ERROR HY000: Illegal parameter data types row and varchar for operation '=' +DROP FUNCTION f1; +CREATE FUNCTION f1() RETURN VARCHAR(16) +IS +v t1%ROWTYPE; +BEGIN +IF v = 'bar' THEN +NULL; +END IF; +RETURN 'qux'; +END $$ +SELECT f1(); +ERROR HY000: Illegal parameter data types row and varchar for operation '=' +DROP FUNCTION f1; +CREATE FUNCTION f1() RETURN VARCHAR(16) +IS +v ROW(a INT); +BEGIN +IF v = 'bar' THEN +NULL; +END IF; +RETURN 'qux'; +END $$ +SELECT f1(); +ERROR HY000: Illegal parameter data types row and varchar for operation '=' +DROP FUNCTION f1; +DROP TABLE t1; +DECLARE +v ROW(a INT); +BEGIN +SELECT v IN ('a','b'); +END $$ +ERROR HY000: Illegal parameter data types row and varchar for operation 'in' +DECLARE +v ROW(a INT); +BEGIN +SELECT 'a' IN (v,'b'); +END $$ +ERROR HY000: Illegal parameter data types varchar and row for operation 'in' +DECLARE +v ROW(a INT); +BEGIN +SELECT 'a' IN ('b',v); +END $$ +ERROR HY000: Illegal parameter data types varchar and row for operation 'in' diff --git a/mysql-test/suite/compat/oracle/t/sp-row.test b/mysql-test/suite/compat/oracle/t/sp-row.test index b26cae5a5c6..469494ad228 100644 --- a/mysql-test/suite/compat/oracle/t/sp-row.test +++ b/mysql-test/suite/compat/oracle/t/sp-row.test @@ -295,7 +295,7 @@ BEGIN END; $$ DELIMITER ;$$ ---error ER_OPERAND_COLUMNS +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION CALL p1(); DROP PROCEDURE p1; @@ -309,7 +309,7 @@ BEGIN END; $$ DELIMITER ;$$ ---error ER_OPERAND_COLUMNS +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION CALL p1(); DROP PROCEDURE p1; diff --git a/mysql-test/suite/compat/oracle/t/sp.test b/mysql-test/suite/compat/oracle/t/sp.test index e7adbb5403a..693569d184c 100644 --- a/mysql-test/suite/compat/oracle/t/sp.test +++ b/mysql-test/suite/compat/oracle/t/sp.test @@ -2260,3 +2260,90 @@ CALL p1(); DROP PROCEDURE p1; DROP VIEW v1; DROP TABLE t1; + + +--echo # +--echo # MDEV-14228 MariaDB crashes with function +--echo # + +CREATE TABLE t1 (c VARCHAR(16), KEY(c)); +INSERT INTO t1 VALUES ('foo'); + +DELIMITER $$; +CREATE FUNCTION f1() RETURN VARCHAR(16) +IS + v VARCHAR2(16); +BEGIN + FOR v IN (SELECT DISTINCT c FROM t1) + LOOP + IF (v = 'bar') THEN + SELECT 1 INTO @a; + END IF; + END LOOP; + RETURN 'qux'; +END $$ +DELIMITER ;$$ +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT f1(); +DROP FUNCTION f1; + +DELIMITER $$; +CREATE FUNCTION f1() RETURN VARCHAR(16) +IS + v t1%ROWTYPE; +BEGIN + IF v = 'bar' THEN + NULL; + END IF; + RETURN 'qux'; +END $$ +DELIMITER ;$$ +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT f1(); +DROP FUNCTION f1; + +DELIMITER $$; +CREATE FUNCTION f1() RETURN VARCHAR(16) +IS + v ROW(a INT); +BEGIN + IF v = 'bar' THEN + NULL; + END IF; + RETURN 'qux'; +END $$ +DELIMITER ;$$ +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT f1(); +DROP FUNCTION f1; + +DROP TABLE t1; + + +DELIMITER $$; +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +DECLARE + v ROW(a INT); +BEGIN + SELECT v IN ('a','b'); +END $$ +DELIMITER ;$$ + +DELIMITER $$; +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +DECLARE + v ROW(a INT); +BEGIN + SELECT 'a' IN (v,'b'); +END $$ +DELIMITER ;$$ + +DELIMITER $$; +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +DECLARE + v ROW(a INT); +BEGIN + SELECT 'a' IN ('b',v); +END $$ +DELIMITER ;$$ + diff --git a/mysql-test/suite/funcs_1/r/innodb_views.result b/mysql-test/suite/funcs_1/r/innodb_views.result index 93fd45dc9f9..01ad3e3dda7 100644 --- a/mysql-test/suite/funcs_1/r/innodb_views.result +++ b/mysql-test/suite/funcs_1/r/innodb_views.result @@ -4314,7 +4314,7 @@ CREATE VIEW v2 AS Select * from test.v1; ERROR 42S02: Table 'test.v1' doesn't exist DROP VIEW IF EXISTS v2; Warnings: -Note 4091 Unknown VIEW: 'test.v2' +Note 4092 Unknown VIEW: 'test.v2' Testcase 3.3.1.25 -------------------------------------------------------------------------------- @@ -7566,7 +7566,7 @@ Call sp1() ; ERROR 42000: PROCEDURE test.sp1 does not exist Drop view if exists test.v1 ; Warnings: -Note 4091 Unknown VIEW: 'test.v1' +Note 4092 Unknown VIEW: 'test.v1' Drop procedure sp1 ; ERROR 42000: PROCEDURE test.sp1 does not exist @@ -21312,7 +21312,7 @@ CREATE VIEW v1 AS SELECT f1 FROM t1; DROP VIEW IF EXISTS v1; DROP VIEW IF EXISTS v1; Warnings: -Note 4091 Unknown VIEW: 'test.v1' +Note 4092 Unknown VIEW: 'test.v1' Testcase 3.3.1.68 -------------------------------------------------------------------------------- diff --git a/mysql-test/suite/funcs_1/r/memory_views.result b/mysql-test/suite/funcs_1/r/memory_views.result index 1b167b611df..de0acb3a9f3 100644 --- a/mysql-test/suite/funcs_1/r/memory_views.result +++ b/mysql-test/suite/funcs_1/r/memory_views.result @@ -4315,7 +4315,7 @@ CREATE VIEW v2 AS Select * from test.v1; ERROR 42S02: Table 'test.v1' doesn't exist DROP VIEW IF EXISTS v2; Warnings: -Note 4091 Unknown VIEW: 'test.v2' +Note 4092 Unknown VIEW: 'test.v2' Testcase 3.3.1.25 -------------------------------------------------------------------------------- @@ -7567,7 +7567,7 @@ Call sp1() ; ERROR 42000: PROCEDURE test.sp1 does not exist Drop view if exists test.v1 ; Warnings: -Note 4091 Unknown VIEW: 'test.v1' +Note 4092 Unknown VIEW: 'test.v1' Drop procedure sp1 ; ERROR 42000: PROCEDURE test.sp1 does not exist @@ -21314,7 +21314,7 @@ CREATE VIEW v1 AS SELECT f1 FROM t1; DROP VIEW IF EXISTS v1; DROP VIEW IF EXISTS v1; Warnings: -Note 4091 Unknown VIEW: 'test.v1' +Note 4092 Unknown VIEW: 'test.v1' Testcase 3.3.1.68 -------------------------------------------------------------------------------- diff --git a/mysql-test/suite/funcs_1/r/myisam_views-big.result b/mysql-test/suite/funcs_1/r/myisam_views-big.result index ff7d0a595ab..2a547ddf256 100644 --- a/mysql-test/suite/funcs_1/r/myisam_views-big.result +++ b/mysql-test/suite/funcs_1/r/myisam_views-big.result @@ -4784,7 +4784,7 @@ CREATE VIEW v2 AS Select * from test.v1; ERROR 42S02: Table 'test.v1' doesn't exist DROP VIEW IF EXISTS v2; Warnings: -Note 4091 Unknown VIEW: 'test.v2' +Note 4092 Unknown VIEW: 'test.v2' Testcase 3.3.1.25 -------------------------------------------------------------------------------- @@ -8387,7 +8387,7 @@ Call sp1() ; ERROR 42000: PROCEDURE test.sp1 does not exist Drop view if exists test.v1 ; Warnings: -Note 4091 Unknown VIEW: 'test.v1' +Note 4092 Unknown VIEW: 'test.v1' Drop procedure sp1 ; ERROR 42000: PROCEDURE test.sp1 does not exist @@ -22989,7 +22989,7 @@ CREATE VIEW v1 AS SELECT f1 FROM t1; DROP VIEW IF EXISTS v1; DROP VIEW IF EXISTS v1; Warnings: -Note 4091 Unknown VIEW: 'test.v1' +Note 4092 Unknown VIEW: 'test.v1' Testcase 3.3.1.68 -------------------------------------------------------------------------------- diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index 193b9f87d56..793d389c5d3 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -57,6 +57,8 @@ galera_as_slave : MDEV-13549 Galera test failures 10.1 galera_var_innodb_disallow_writes : MDEV-10949 galera_kill_applier : race condition at the start of the test GAL-480 : "Lost connection to MySQL" -MW-328A : "Found wrong usage of mutex" -MW-328B : "Found wrong usage of mutex" -MW-328C : "Found wrong usage of mutex" +MW-328C: MDEV-13549 Galera test failures 10.1 +MW-328A: MDEV-13549 Galera test failures 10.1 +MW-328B: MDEV-13549 Galera test failures 10.1 +MW-328: MDEV-13549 Galera test failures 10.1 +galera_suspend_slave: MDEV-13549 Galera test failures 10.1 diff --git a/mysql-test/suite/galera/r/MW-388.result b/mysql-test/suite/galera/r/MW-388.result index 17d347a11fb..a2cf02712bb 100644 --- a/mysql-test/suite/galera/r/MW-388.result +++ b/mysql-test/suite/galera/r/MW-388.result @@ -1,3 +1,4 @@ +connection node_1; CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 CHAR(255)) Engine=InnoDB; CREATE PROCEDURE insert_proc () BEGIN @@ -9,37 +10,40 @@ INSERT INTO t1 VALUES (1, 'node 1'),(2, 'node 1'); INSERT INTO t1 VALUES (3, 'node 1'); END| SET GLOBAL wsrep_slave_threads = 2; -SET GLOBAL DEBUG = "d,sync.wsrep_apply_cb"; -Warnings: -Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead +SET GLOBAL DEBUG_DBUG = "d,sync.wsrep_apply_cb"; +connection node_2; INSERT INTO t1 VALUES (1, 'node 2');; +connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1; +connection node_1a; SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached"; +connection node_1; SET SESSION wsrep_sync_wait = 0; SET SESSION DEBUG_SYNC = 'wsrep_after_replication SIGNAL wsrep_after_replication_reached WAIT_FOR wsrep_after_replication_continue'; CALL insert_proc ();; +connection node_1a; SET SESSION DEBUG_SYNC = "now WAIT_FOR wsrep_after_replication_reached"; -SET GLOBAL DEBUG = ""; -Warnings: -Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead +SET GLOBAL DEBUG_DBUG = ""; SET DEBUG_SYNC = "now SIGNAL wsrep_after_replication_continue"; SET DEBUG_SYNC = "now SIGNAL signal.wsrep_apply_cb"; +connection node_2; +connection node_1; SELECT @errno = 1213; @errno = 1213 -1 +0 SELECT * FROM t1; f1 f2 1 node 2 3 node 1 +connection node_2; SELECT * FROM t1; f1 f2 1 node 2 3 node 1 +connection node_1; SET GLOBAL wsrep_slave_threads = DEFAULT; DROP TABLE t1; DROP PROCEDURE insert_proc; -SET GLOBAL debug = NULL; -Warnings: -Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead +SET GLOBAL debug_dbug = NULL; SET debug_sync='RESET'; SELECT @@debug_sync; @@debug_sync diff --git a/mysql-test/suite/galera/r/galera_bf_lock_wait.result b/mysql-test/suite/galera/r/galera_bf_lock_wait.result new file mode 100644 index 00000000000..7ec524da888 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_bf_lock_wait.result @@ -0,0 +1,23 @@ +CREATE TABLE t1 ENGINE=InnoDB select 1 as a, 1 as b union select 2, 2; +ALTER TABLE t1 add primary key(a); +CREATE PROCEDURE p1() +BEGIN +DECLARE CONTINUE HANDLER FOR SQLEXCEPTION rollback; +WHILE 1 DO +start transaction; +update t1 set b=connection_id() where a=1; +commit; +END WHILE; +END| +connect node_1_p1, 127.0.0.1, root, , test, $NODE_MYPORT_1; +call p1; +connect node_1_p2, 127.0.0.1, root, , test, $NODE_MYPORT_1; +call p1; +connect node_2_p1, 127.0.0.1, root, , test, $NODE_MYPORT_2; +call p1; +connect node_2_p2, 127.0.0.1, root, , test, $NODE_MYPORT_2; +call p1; +connection default; +checking error log for 'BF lock wait long' message for 10 times every 10 seconds ... +drop table t1; +drop procedure p1; diff --git a/mysql-test/suite/galera/t/MW-388.test b/mysql-test/suite/galera/t/MW-388.test index 209695dca80..de1ac52bf3e 100644 --- a/mysql-test/suite/galera/t/MW-388.test +++ b/mysql-test/suite/galera/t/MW-388.test @@ -30,7 +30,7 @@ DELIMITER ;| # commit cut is not processed and therefore does not advance # local monitor, and our INSERT remains stuck there. SET GLOBAL wsrep_slave_threads = 2; -SET GLOBAL DEBUG = "d,sync.wsrep_apply_cb"; +SET GLOBAL DEBUG_DBUG = "d,sync.wsrep_apply_cb"; --connection node_2 --send INSERT INTO t1 VALUES (1, 'node 2'); @@ -48,7 +48,7 @@ SET SESSION DEBUG_SYNC = 'wsrep_after_replication SIGNAL wsrep_after_replication SET SESSION DEBUG_SYNC = "now WAIT_FOR wsrep_after_replication_reached"; -SET GLOBAL DEBUG = ""; +SET GLOBAL DEBUG_DBUG = ""; SET DEBUG_SYNC = "now SIGNAL wsrep_after_replication_continue"; SET DEBUG_SYNC = "now SIGNAL signal.wsrep_apply_cb"; @@ -69,7 +69,7 @@ SET GLOBAL wsrep_slave_threads = DEFAULT; DROP TABLE t1; DROP PROCEDURE insert_proc; -SET GLOBAL debug = NULL; +SET GLOBAL debug_dbug = NULL; SET debug_sync='RESET'; # Make sure no pending signals are leftover to surprise subsequent tests. diff --git a/mysql-test/suite/galera/t/galera_bf_lock_wait.test b/mysql-test/suite/galera/t/galera_bf_lock_wait.test new file mode 100644 index 00000000000..e3a9077a888 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_bf_lock_wait.test @@ -0,0 +1,52 @@ +--source include/galera_cluster.inc +--source include/big_test.inc + +CREATE TABLE t1 ENGINE=InnoDB select 1 as a, 1 as b union select 2, 2; +ALTER TABLE t1 add primary key(a); + +DELIMITER |; + +CREATE PROCEDURE p1() +BEGIN + DECLARE CONTINUE HANDLER FOR SQLEXCEPTION rollback; + WHILE 1 DO + start transaction; + update t1 set b=connection_id() where a=1; + commit; + END WHILE; +END| + + +DELIMITER ;| + +--connect node_1_p1, 127.0.0.1, root, , test, $NODE_MYPORT_1 +send call p1; +--connect node_1_p2, 127.0.0.1, root, , test, $NODE_MYPORT_1 +send call p1; +--connect node_2_p1, 127.0.0.1, root, , test, $NODE_MYPORT_2 +send call p1; +--connect node_2_p2, 127.0.0.1, root, , test, $NODE_MYPORT_2 +send call p1; + +connection default; +let $counter=10; +let $sleep_period=10; + +echo checking error log for 'BF lock wait long' message for $counter times every $sleep_period seconds ...; +while($counter > 0) +{ +--disable_query_log +--disable_result_log + eval do sleep($sleep_period); +--enable_query_log +--enable_result_log + +# use error 0,1 instead if want test to continue + --error 1 + exec grep 'BF lock wait long' $MYSQLTEST_VARDIR/log/mysqld.*.err; + dec $counter; +} + +drop table t1; +drop procedure p1; + diff --git a/mysql-test/suite/innodb/r/innodb_max_recordsize_32k.result b/mysql-test/suite/innodb/r/innodb_max_recordsize_32k.result index c2bb0ba0aa8..117b7e4418e 100644 --- a/mysql-test/suite/innodb/r/innodb_max_recordsize_32k.result +++ b/mysql-test/suite/innodb/r/innodb_max_recordsize_32k.result @@ -2,14 +2,7 @@ call mtr.add_suppression('InnoDB: Cannot add field.*because after adding it, the SELECT @@innodb_page_size; @@innodb_page_size 32768 -SET GLOBAL innodb_file_per_table=ON; -SET @@innodb_strict_mode=ON; -SELECT @@innodb_file_per_table; -@@innodb_file_per_table -1 -SELECT @@innodb_strict_mode; -@@innodb_strict_mode -1 +SET innodb_strict_mode=ON; CREATE TABLE tab5(col1 CHAR (255), col2 CHAR (255), col3 CHAR(255),col4 CHAR(255), col5 CHAR(255), col6 CHAR(255), col7 CHAR(255), col8 CHAR(255), col9 CHAR(255),col10 CHAR(255), col11 CHAR(255), col12 CHAR(255), col13 CHAR(255),col14 CHAR(255),col15 CHAR(255),col16 CHAR(255), col17 CHAR(255), @@ -333,11 +326,9 @@ FLUSH TABLE t; ANALYZE TABLE t; Table Op Msg_type Msg_text test.t analyze status OK -SELECT stat_value FROM mysql.innodb_index_stats where database_name = 'test' and table_name= 't' and stat_name='n_leaf_pages'; -stat_value -6 -SELECT clustered_index_size from mysql.innodb_table_stats where database_name = 'test' and table_name= 't'; -clustered_index_size +SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS +WHERE name = 'test/t'; +clust_index_size 7 DROP TABLE t; CREATE TABLE t(col BLOB) ENGINE=InnoDB ROW_FORMAT=REDUNDANT; @@ -355,11 +346,9 @@ FLUSH TABLE t; ANALYZE TABLE t; Table Op Msg_type Msg_text test.t analyze status OK -SELECT stat_value FROM mysql.innodb_index_stats where database_name = 'test' and table_name= 't' and stat_name='n_leaf_pages'; -stat_value -4 -SELECT clustered_index_size from mysql.innodb_table_stats where database_name = 'test' and table_name= 't'; -clustered_index_size +SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS +WHERE name = 'test/t'; +clust_index_size 5 DROP TABLE t; CREATE TABLE t(col BLOB) ENGINE=InnoDB ROW_FORMAT=COMPACT; @@ -377,11 +366,8 @@ FLUSH TABLE t; ANALYZE TABLE t; Table Op Msg_type Msg_text test.t analyze status OK -SELECT stat_value FROM mysql.innodb_index_stats where database_name = 'test' and table_name= 't' and stat_name='n_leaf_pages'; -stat_value -4 -SELECT clustered_index_size from mysql.innodb_table_stats where database_name = 'test' and table_name= 't'; -clustered_index_size +SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS +WHERE name = 'test/t'; +clust_index_size 5 DROP TABLE t; -# Success diff --git a/mysql-test/suite/innodb/r/innodb_max_recordsize_64k.result b/mysql-test/suite/innodb/r/innodb_max_recordsize_64k.result index 31dcae834bf..de957023ff8 100644 --- a/mysql-test/suite/innodb/r/innodb_max_recordsize_64k.result +++ b/mysql-test/suite/innodb/r/innodb_max_recordsize_64k.result @@ -2,14 +2,7 @@ call mtr.add_suppression('InnoDB: Cannot add field.*because after adding it, the SELECT @@innodb_page_size; @@innodb_page_size 65536 -SET GLOBAL innodb_file_per_table=ON; -SET @@innodb_strict_mode=ON; -SELECT @@innodb_file_per_table; -@@innodb_file_per_table -1 -SELECT @@innodb_strict_mode; -@@innodb_strict_mode -1 +SET innodb_strict_mode=ON; CREATE TABLE tab5(col1 CHAR (255), col2 CHAR (255), col3 CHAR(255),col4 CHAR(255), col5 CHAR(255), col6 CHAR(255), col7 CHAR(255), col8 CHAR(255), col9 CHAR(255),col10 CHAR(255), col11 CHAR(255), col12 CHAR(255), col13 CHAR(255),col14 CHAR(255),col15 CHAR(255),col16 CHAR(255), col17 CHAR(255), @@ -536,11 +529,9 @@ FLUSH TABLE t; ANALYZE TABLE t; Table Op Msg_type Msg_text test.t analyze status OK -SELECT stat_value FROM mysql.innodb_index_stats where database_name = 'test' and table_name= 't' and stat_name='n_leaf_pages'; -stat_value -4 -SELECT clustered_index_size from mysql.innodb_table_stats where database_name = 'test' and table_name= 't'; -clustered_index_size +SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS +WHERE name = 'test/t'; +clust_index_size 5 DROP TABLE t; CREATE TABLE t(col BLOB) ENGINE=InnoDB ROW_FORMAT=REDUNDANT; @@ -558,11 +549,9 @@ FLUSH TABLE t; ANALYZE TABLE t; Table Op Msg_type Msg_text test.t analyze status OK -SELECT stat_value FROM mysql.innodb_index_stats where database_name = 'test' and table_name= 't' and stat_name='n_leaf_pages'; -stat_value -3 -SELECT clustered_index_size from mysql.innodb_table_stats where database_name = 'test' and table_name= 't'; -clustered_index_size +SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS +WHERE name = 'test/t'; +clust_index_size 4 DROP TABLE t; CREATE TABLE t(col BLOB) ENGINE=InnoDB ROW_FORMAT=COMPACT; @@ -580,11 +569,8 @@ FLUSH TABLE t; ANALYZE TABLE t; Table Op Msg_type Msg_text test.t analyze status OK -SELECT stat_value FROM mysql.innodb_index_stats where database_name = 'test' and table_name= 't' and stat_name='n_leaf_pages'; -stat_value -3 -SELECT clustered_index_size from mysql.innodb_table_stats where database_name = 'test' and table_name= 't'; -clustered_index_size +SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS +WHERE name = 'test/t'; +clust_index_size 4 DROP TABLE t; -# Success diff --git a/mysql-test/suite/innodb/r/lock_deleted.result b/mysql-test/suite/innodb/r/lock_deleted.result new file mode 100644 index 00000000000..0fcb8bd5aa8 --- /dev/null +++ b/mysql-test/suite/innodb/r/lock_deleted.result @@ -0,0 +1,57 @@ +connect stop_purge, localhost, root,,; +START TRANSACTION WITH CONSISTENT SNAPSHOT; +connect delete, localhost, root,,; +connection default; +CREATE TABLE t1(a INT PRIMARY KEY, b INT UNIQUE) ENGINE=InnoDB; +INSERT INTO t1 VALUES(1,1); +DELETE FROM t1; +SET DEBUG_SYNC='row_ins_sec_index_unique SIGNAL inserted WAIT_FOR locked'; +BEGIN; +INSERT INTO t1 VALUES(1,1); +connection delete; +SET DEBUG_SYNC='now WAIT_FOR inserted'; +SET DEBUG_SYNC='innodb_row_search_for_mysql_exit SIGNAL locked'; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +BEGIN; +DELETE FROM t1 WHERE b=1; +connection default; +connection delete; +COMMIT; +connection default; +SET DEBUG_SYNC='RESET'; +ROLLBACK; +SET DEBUG_SYNC='row_ins_sec_index_unique SIGNAL inserted WAIT_FOR locked'; +BEGIN; +INSERT INTO t1 VALUES(1,1); +connection delete; +SET DEBUG_SYNC='now WAIT_FOR inserted'; +SET DEBUG_SYNC='innodb_row_search_for_mysql_exit SIGNAL locked'; +SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +BEGIN; +DELETE FROM t1 WHERE b=1; +connection default; +connection delete; +COMMIT; +connection default; +SET DEBUG_SYNC='RESET'; +ROLLBACK; +SET DEBUG_SYNC='row_ins_sec_index_unique SIGNAL inserted WAIT_FOR locked'; +BEGIN; +SET innodb_lock_wait_timeout=1; +INSERT INTO t1 VALUES(1,1); +connection delete; +SET DEBUG_SYNC='now WAIT_FOR inserted'; +SET DEBUG_SYNC='innodb_row_search_for_mysql_exit SIGNAL locked'; +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +BEGIN; +DELETE FROM t1 WHERE b=1; +connection default; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +COMMIT; +SET DEBUG_SYNC='RESET'; +connection delete; +COMMIT; +disconnect delete; +disconnect stop_purge; +connection default; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/innodb_max_recordsize_32k.opt b/mysql-test/suite/innodb/t/innodb_max_recordsize_32k.opt index f543bd0da39..587a2d7e6c1 100644 --- a/mysql-test/suite/innodb/t/innodb_max_recordsize_32k.opt +++ b/mysql-test/suite/innodb/t/innodb_max_recordsize_32k.opt @@ -1,3 +1,4 @@ --innodb-page-size=32K --innodb_buffer_pool_size=32M ---innodb-stats-persistent=ON +--skip-innodb-stats-persistent +--innodb-sys-tablestats diff --git a/mysql-test/suite/innodb/t/innodb_max_recordsize_32k.test b/mysql-test/suite/innodb/t/innodb_max_recordsize_32k.test index 138917593da..aa816a9b0e8 100644 --- a/mysql-test/suite/innodb/t/innodb_max_recordsize_32k.test +++ b/mysql-test/suite/innodb/t/innodb_max_recordsize_32k.test @@ -6,16 +6,7 @@ call mtr.add_suppression('InnoDB: Cannot add field.*because after adding it, the # Check page size 32k SELECT @@innodb_page_size; -let $innodb_file_per_table = `SELECT @@innodb_file_per_table`; -let $innodb_strict_mode = `SELECT @@innodb_strict_mode`; - ---disable_warnings -SET GLOBAL innodb_file_per_table=ON; -SET @@innodb_strict_mode=ON; ---enable_warnings - -SELECT @@innodb_file_per_table; -SELECT @@innodb_strict_mode; +SET innodb_strict_mode=ON; # Check the error when the max record length > 16K for innodb_page_size=32k --error ER_TOO_BIG_ROWSIZE @@ -356,9 +347,8 @@ INSERT INTO t VALUES (REPEAT('a',65535)); SELECT LENGTH(col) FROM t; FLUSH TABLE t; ANALYZE TABLE t; -# retrieve the number of leaf pages -SELECT stat_value FROM mysql.innodb_index_stats where database_name = 'test' and table_name= 't' and stat_name='n_leaf_pages'; -SELECT clustered_index_size from mysql.innodb_table_stats where database_name = 'test' and table_name= 't'; +SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS +WHERE name = 'test/t'; DROP TABLE t; CREATE TABLE t(col BLOB) ENGINE=InnoDB ROW_FORMAT=REDUNDANT; @@ -369,9 +359,8 @@ INSERT INTO t VALUES (REPEAT('a',65535)); SELECT LENGTH(col) FROM t; FLUSH TABLE t; ANALYZE TABLE t; -# retrieve the number of leaf pages -SELECT stat_value FROM mysql.innodb_index_stats where database_name = 'test' and table_name= 't' and stat_name='n_leaf_pages'; -SELECT clustered_index_size from mysql.innodb_table_stats where database_name = 'test' and table_name= 't'; +SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS +WHERE name = 'test/t'; DROP TABLE t; CREATE TABLE t(col BLOB) ENGINE=InnoDB ROW_FORMAT=COMPACT; @@ -382,18 +371,6 @@ INSERT INTO t VALUES (REPEAT('a',65535)); SELECT LENGTH(col) FROM t; FLUSH TABLE t; ANALYZE TABLE t; -# retrieve the number of leaf pages -SELECT stat_value FROM mysql.innodb_index_stats where database_name = 'test' and table_name= 't' and stat_name='n_leaf_pages'; -SELECT clustered_index_size from mysql.innodb_table_stats where database_name = 'test' and table_name= 't'; +SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS +WHERE name = 'test/t'; DROP TABLE t; - -# cleanup ---disable_query_log ---disable_warnings -eval SET GLOBAL INNODB_FILE_PER_TABLE=$innodb_file_per_table; -eval SET GLOBAL INNODB_STRICT_MODE=$innodb_strict_mode; ---enable_warnings ---enable_query_log - ---echo # Success - diff --git a/mysql-test/suite/innodb/t/innodb_max_recordsize_64k.opt b/mysql-test/suite/innodb/t/innodb_max_recordsize_64k.opt index 8c9b8ae1e48..1a8442b841f 100644 --- a/mysql-test/suite/innodb/t/innodb_max_recordsize_64k.opt +++ b/mysql-test/suite/innodb/t/innodb_max_recordsize_64k.opt @@ -1,3 +1,4 @@ --innodb-page-size=64K --innodb_buffer_pool_size=32M ---innodb-stats-persistent=ON +--skip-innodb-stats-persistent +--innodb-sys-tablestats diff --git a/mysql-test/suite/innodb/t/innodb_max_recordsize_64k.test b/mysql-test/suite/innodb/t/innodb_max_recordsize_64k.test index 7b830096afa..598cc3d77bf 100644 --- a/mysql-test/suite/innodb/t/innodb_max_recordsize_64k.test +++ b/mysql-test/suite/innodb/t/innodb_max_recordsize_64k.test @@ -6,16 +6,7 @@ call mtr.add_suppression('InnoDB: Cannot add field.*because after adding it, the # Check page size 64k SELECT @@innodb_page_size; -let $innodb_file_per_table = `SELECT @@innodb_file_per_table`; -let $innodb_strict_mode = `SELECT @@innodb_strict_mode`; - ---disable_warnings -SET GLOBAL innodb_file_per_table=ON; -SET @@innodb_strict_mode=ON; ---enable_warnings - -SELECT @@innodb_file_per_table; -SELECT @@innodb_strict_mode; +SET innodb_strict_mode=ON; # Check the error when the max record length > 32K for innodb_page_size=64k --error ER_TOO_BIG_ROWSIZE @@ -560,9 +551,8 @@ INSERT INTO t VALUES (REPEAT('a',65535)); SELECT LENGTH(col) FROM t; FLUSH TABLE t; ANALYZE TABLE t; -# retrieve the number of leaf pages -SELECT stat_value FROM mysql.innodb_index_stats where database_name = 'test' and table_name= 't' and stat_name='n_leaf_pages'; -SELECT clustered_index_size from mysql.innodb_table_stats where database_name = 'test' and table_name= 't'; +SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS +WHERE name = 'test/t'; DROP TABLE t; CREATE TABLE t(col BLOB) ENGINE=InnoDB ROW_FORMAT=REDUNDANT; @@ -573,9 +563,8 @@ INSERT INTO t VALUES (REPEAT('a',65535)); SELECT LENGTH(col) FROM t; FLUSH TABLE t; ANALYZE TABLE t; -# retrieve the number of leaf pages -SELECT stat_value FROM mysql.innodb_index_stats where database_name = 'test' and table_name= 't' and stat_name='n_leaf_pages'; -SELECT clustered_index_size from mysql.innodb_table_stats where database_name = 'test' and table_name= 't'; +SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS +WHERE name = 'test/t'; DROP TABLE t; CREATE TABLE t(col BLOB) ENGINE=InnoDB ROW_FORMAT=COMPACT; @@ -586,18 +575,6 @@ INSERT INTO t VALUES (REPEAT('a',65535)); SELECT LENGTH(col) FROM t; FLUSH TABLE t; ANALYZE TABLE t; -# retrieve the number of leaf pages -SELECT stat_value FROM mysql.innodb_index_stats where database_name = 'test' and table_name= 't' and stat_name='n_leaf_pages'; -SELECT clustered_index_size from mysql.innodb_table_stats where database_name = 'test' and table_name= 't'; +SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS +WHERE name = 'test/t'; DROP TABLE t; - -# cleanup ---disable_query_log ---disable_warnings -eval SET GLOBAL INNODB_FILE_PER_TABLE=$innodb_file_per_table; -eval SET GLOBAL INNODB_STRICT_MODE=$innodb_strict_mode; ---enable_warnings ---enable_query_log - ---echo # Success - diff --git a/mysql-test/suite/innodb/t/lock_deleted.test b/mysql-test/suite/innodb/t/lock_deleted.test new file mode 100644 index 00000000000..8dbad90d354 --- /dev/null +++ b/mysql-test/suite/innodb/t/lock_deleted.test @@ -0,0 +1,72 @@ +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc + +--source include/count_sessions.inc + +connect(stop_purge, localhost, root,,); +START TRANSACTION WITH CONSISTENT SNAPSHOT; +connect(delete, localhost, root,,); +connection default; + +CREATE TABLE t1(a INT PRIMARY KEY, b INT UNIQUE) ENGINE=InnoDB; +INSERT INTO t1 VALUES(1,1); +DELETE FROM t1; + +let $i=2; +while ($i) { +let $iso= `SELECT CASE $i WHEN 1 THEN 'UNCOMMITTED' ELSE 'COMMITTED' END`; + +SET DEBUG_SYNC='row_ins_sec_index_unique SIGNAL inserted WAIT_FOR locked'; +BEGIN; +send INSERT INTO t1 VALUES(1,1); + +connection delete; +SET DEBUG_SYNC='now WAIT_FOR inserted'; +SET DEBUG_SYNC='innodb_row_search_for_mysql_exit SIGNAL locked'; +eval SET SESSION TRANSACTION ISOLATION LEVEL READ $iso; +BEGIN; +send DELETE FROM t1 WHERE b=1; + +connection default; +reap; +connection delete; +reap; +COMMIT; + +connection default; +SET DEBUG_SYNC='RESET'; +ROLLBACK; + +dec $i; +} + +SET DEBUG_SYNC='row_ins_sec_index_unique SIGNAL inserted WAIT_FOR locked'; +BEGIN; +SET innodb_lock_wait_timeout=1; +send INSERT INTO t1 VALUES(1,1); + +connection delete; +SET DEBUG_SYNC='now WAIT_FOR inserted'; +SET DEBUG_SYNC='innodb_row_search_for_mysql_exit SIGNAL locked'; +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +BEGIN; +send DELETE FROM t1 WHERE b=1; + +connection default; +--error ER_LOCK_WAIT_TIMEOUT +reap; +COMMIT; +SET DEBUG_SYNC='RESET'; + +connection delete; +reap; +COMMIT; + +disconnect delete; +disconnect stop_purge; + +connection default; +DROP TABLE t1; + +--source include/wait_until_count_sessions.inc diff --git a/mysql-test/suite/perfschema/r/nesting.result b/mysql-test/suite/perfschema/r/nesting.result index 78126d93cc7..37681757973 100644 --- a/mysql-test/suite/perfschema/r/nesting.result +++ b/mysql-test/suite/perfschema/r/nesting.result @@ -125,7 +125,7 @@ relative_event_id relative_end_event_id event_name comment nesting_event_type re 15 15 stage/sql/Starting cleanup (stage) STATEMENT 0 16 16 stage/sql/Freeing items (stage) STATEMENT 0 17 17 wait/io/socket/sql/client_connection send STATEMENT 0 -18 18 wait/synch/mutex/sql/THD::LOCK_thd_data lock STATEMENT 0 +18 18 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STATEMENT 0 19 20 stage/sql/Reset for next command (stage) STATEMENT 0 20 20 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 19 21 21 idle idle NULL NULL @@ -147,7 +147,7 @@ relative_event_id relative_end_event_id event_name comment nesting_event_type re 37 37 stage/sql/Starting cleanup (stage) STATEMENT 22 38 38 stage/sql/Freeing items (stage) STATEMENT 22 39 39 wait/io/socket/sql/client_connection send STATEMENT 22 -40 40 wait/synch/mutex/sql/THD::LOCK_thd_data lock STATEMENT 22 +40 40 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STATEMENT 22 41 42 stage/sql/Reset for next command (stage) STATEMENT 22 42 42 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 41 43 43 idle idle NULL NULL @@ -169,7 +169,7 @@ relative_event_id relative_end_event_id event_name comment nesting_event_type re 59 59 stage/sql/Starting cleanup (stage) STATEMENT 44 60 60 stage/sql/Freeing items (stage) STATEMENT 44 61 61 wait/io/socket/sql/client_connection send STATEMENT 44 -62 62 wait/synch/mutex/sql/THD::LOCK_thd_data lock STATEMENT 44 +62 62 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STATEMENT 44 63 64 stage/sql/Reset for next command (stage) STATEMENT 44 64 64 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 63 65 65 idle idle NULL NULL @@ -194,7 +194,7 @@ select "With a third part to make things complete" as payload NULL NULL 82 82 stage/sql/Starting cleanup (stage) STATEMENT 66 83 85 stage/sql/Freeing items (stage) STATEMENT 66 84 84 wait/io/socket/sql/client_connection send STAGE 83 -85 85 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 83 +85 85 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STAGE 83 86 103 statement/sql/select select "And this is the second part of a multi query" as payload; select "With a third part to make things complete" as payload NULL NULL 87 89 stage/sql/Init (stage) STATEMENT 86 @@ -213,7 +213,7 @@ select "With a third part to make things complete" as payload NULL NULL 100 100 stage/sql/Starting cleanup (stage) STATEMENT 86 101 103 stage/sql/Freeing items (stage) STATEMENT 86 102 102 wait/io/socket/sql/client_connection send STAGE 101 -103 103 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 101 +103 103 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STAGE 101 104 122 statement/sql/select select "With a third part to make things complete" as payload NULL NULL 105 106 stage/sql/Init (stage) STATEMENT 104 106 106 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 105 @@ -230,7 +230,7 @@ select "With a third part to make things complete" as payload NULL NULL 117 117 stage/sql/Starting cleanup (stage) STATEMENT 104 118 118 stage/sql/Freeing items (stage) STATEMENT 104 119 119 wait/io/socket/sql/client_connection send STATEMENT 104 -120 120 wait/synch/mutex/sql/THD::LOCK_thd_data lock STATEMENT 104 +120 120 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STATEMENT 104 121 122 stage/sql/Reset for next command (stage) STATEMENT 104 122 122 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 121 123 123 idle idle NULL NULL @@ -252,7 +252,7 @@ select "With a third part to make things complete" as payload NULL NULL 139 139 stage/sql/Starting cleanup (stage) STATEMENT 124 140 140 stage/sql/Freeing items (stage) STATEMENT 124 141 141 wait/io/socket/sql/client_connection send STATEMENT 124 -142 142 wait/synch/mutex/sql/THD::LOCK_thd_data lock STATEMENT 124 +142 142 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STATEMENT 124 143 144 stage/sql/Reset for next command (stage) STATEMENT 124 144 144 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 143 disconnect con1; diff --git a/mysql-test/suite/perfschema/t/nesting.test b/mysql-test/suite/perfschema/t/nesting.test index 9ab59157f50..d0547d8a932 100644 --- a/mysql-test/suite/perfschema/t/nesting.test +++ b/mysql-test/suite/perfschema/t/nesting.test @@ -39,6 +39,7 @@ update performance_schema.setup_instruments set enabled='YES', timed='YES' 'wait/io/socket/sql/client_connection', 'wait/synch/rwlock/sql/LOCK_grant', 'wait/synch/mutex/sql/THD::LOCK_thd_data', + 'wait/synch/mutex/sql/THD::LOCK_thd_kill', 'wait/io/file/sql/query_log'); update performance_schema.setup_instruments set enabled='YES', timed='YES' diff --git a/mysql-test/suite/rpl/r/rpl_create_drop_view.result b/mysql-test/suite/rpl/r/rpl_create_drop_view.result index 436aa7bc236..facd40a6018 100644 --- a/mysql-test/suite/rpl/r/rpl_create_drop_view.result +++ b/mysql-test/suite/rpl/r/rpl_create_drop_view.result @@ -99,7 +99,7 @@ DROP VIEW v1; ERROR 42S02: Unknown VIEW: 'test.v1' DROP VIEW IF EXISTS v2; Warnings: -Note 4091 Unknown VIEW: 'test.v2' +Note 4092 Unknown VIEW: 'test.v2' # Syncing slave with master connection slave; SELECT * FROM v1; diff --git a/mysql-test/suite/rpl/r/rpl_sp.result b/mysql-test/suite/rpl/r/rpl_sp.result index 486c02eef71..97cc4dad8ad 100644 --- a/mysql-test/suite/rpl/r/rpl_sp.result +++ b/mysql-test/suite/rpl/r/rpl_sp.result @@ -128,7 +128,7 @@ show warnings; Level Code Message Error 1062 Duplicate entry '20' for key 'a' Warning 1196 Some non-transactional changed tables couldn't be rolled back -Note 4093 At line 4 in mysqltest1.foo4 +Note 4094 At line 4 in mysqltest1.foo4 select * from t2; a 20 @@ -291,7 +291,7 @@ end| do fn1(100); Warnings: Error 1062 Duplicate entry '100' for key 'a' -Note 4093 At line 3 in mysqltest1.fn1 +Note 4094 At line 3 in mysqltest1.fn1 Warning 1196 Some non-transactional changed tables couldn't be rolled back select fn1(20); ERROR 23000: Duplicate entry '20' for key 'a' diff --git a/mysql-test/suite/sql_sequence/alter.result b/mysql-test/suite/sql_sequence/alter.result index a1789f02718..3cf085bc948 100644 --- a/mysql-test/suite/sql_sequence/alter.result +++ b/mysql-test/suite/sql_sequence/alter.result @@ -212,7 +212,7 @@ ERROR 42S02: 'test.t1' is not a SEQUENCE drop table t1; alter sequence if exists t1 minvalue=100; Warnings: -Note 4090 Unknown SEQUENCE: 'test.t1' +Note 4091 Unknown SEQUENCE: 'test.t1' alter sequence t1 minvalue=100; ERROR 42S02: Table 'test.t1' doesn't exist create sequence t1; diff --git a/mysql-test/suite/sql_sequence/create.result b/mysql-test/suite/sql_sequence/create.result index b9394da6fcd..015b5ac762b 100644 --- a/mysql-test/suite/sql_sequence/create.result +++ b/mysql-test/suite/sql_sequence/create.result @@ -165,7 +165,7 @@ drop sequence t1; ERROR 42S02: 'test.t1' is not a SEQUENCE drop sequence if exists t1; Warnings: -Note 4090 Unknown SEQUENCE: 'test.t1' +Note 4091 Unknown SEQUENCE: 'test.t1' create sequence t1 start with 10 maxvalue=9; ERROR HY000: Sequence 'test.t1' values are conflicting create sequence t1 minvalue= 100 maxvalue=10; @@ -377,7 +377,7 @@ key key1 (next_not_cached_value) ERROR HY000: Sequence 'test.t1' table structure is invalid (Sequence tables cannot have any keys) drop sequence if exists t1; Warnings: -Note 4090 Unknown SEQUENCE: 'test.t1' +Note 4091 Unknown SEQUENCE: 'test.t1' create sequence t1; create sequence t2; create table t3 (a int) engine=myisam; @@ -387,8 +387,8 @@ CREATE SEQUENCE s1; drop sequence s1; drop sequence if exists t1,t2,t3,t4; Warnings: -Note 4090 Unknown SEQUENCE: 'test.t3' -Note 4090 Unknown SEQUENCE: 'test.t4' +Note 4091 Unknown SEQUENCE: 'test.t3' +Note 4091 Unknown SEQUENCE: 'test.t4' drop table if exists t1,t2,t3; Warnings: Note 1051 Unknown table 'test.t1' @@ -414,9 +414,9 @@ CREATE TABLE t2 (a int); CREATE SEQUENCE s1; drop sequence if exists t1,t2,s1,s2; Warnings: -Note 4090 Unknown SEQUENCE: 'test.t1' -Note 4090 Unknown SEQUENCE: 'test.t2' -Note 4090 Unknown SEQUENCE: 'test.s2' +Note 4091 Unknown SEQUENCE: 'test.t1' +Note 4091 Unknown SEQUENCE: 'test.t2' +Note 4091 Unknown SEQUENCE: 'test.s2' drop table if exists t1,t2; CREATE TEMPORARY SEQUENCE s1; DROP SEQUENCE s1; diff --git a/mysql-test/suite/storage_engine/type_bit_indexes.result b/mysql-test/suite/storage_engine/type_bit_indexes.result index af8ddf7d6c9..e7c0cf656c5 100644 --- a/mysql-test/suite/storage_engine/type_bit_indexes.result +++ b/mysql-test/suite/storage_engine/type_bit_indexes.result @@ -69,7 +69,7 @@ INSERT INTO t1 (a,b,c,d) VALUES (1,0xFFFF,0xFFFFFFFF,0xFFFFFFFFFFFFFFFF); EXPLAIN SELECT HEX(b+c) FROM t1 WHERE c > 1 OR HEX(b) < 0xFFFFFF; id select_type table type possible_keys key key_len ref rows Extra -# # # # # b_c # # # # +# # # # # NULL # # # # SELECT HEX(b+c) FROM t1 WHERE c > 1 OR HEX(b) < 0xFFFFFF; HEX(b+c) 10 @@ -98,7 +98,7 @@ INSERT INTO t1 (a,b,c,d) VALUES (1,0xFFFF,0xFFFFFFFF,0xFFFFFFFFFFFFFFFF); EXPLAIN SELECT DISTINCT a+0 FROM t1 ORDER BY a; id select_type table type possible_keys key key_len ref rows Extra -# # # # # a # # # # +# # # # # NULL # # # # SELECT DISTINCT a+0 FROM t1 ORDER BY a; a+0 0 diff --git a/mysql-test/suite/sys_vars/r/sysvars_innodb.result b/mysql-test/suite/sys_vars/r/sysvars_innodb.result index 9d15f3f5a78..720d6a1458a 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_innodb.result +++ b/mysql-test/suite/sys_vars/r/sysvars_innodb.result @@ -1334,7 +1334,7 @@ NUMERIC_MIN_VALUE NULL NUMERIC_MAX_VALUE NULL NUMERIC_BLOCK_SIZE NULL ENUM_VALUE_LIST fcfs,vats -READ_ONLY NO +READ_ONLY YES COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME INNODB_LOCK_WAIT_TIMEOUT SESSION_VALUE 50 diff --git a/mysql-test/suite/sys_vars/t/wsrep_on_basic.opt b/mysql-test/suite/sys_vars/t/wsrep_on_basic.opt new file mode 100644 index 00000000000..aa1fb6cb155 --- /dev/null +++ b/mysql-test/suite/sys_vars/t/wsrep_on_basic.opt @@ -0,0 +1 @@ +--innodb-lock-schedule-algorithm=FCFS diff --git a/mysql-test/t/ctype_latin1.test b/mysql-test/t/ctype_latin1.test index 8c51bfef2d8..31d4ff7f802 100644 --- a/mysql-test/t/ctype_latin1.test +++ b/mysql-test/t/ctype_latin1.test @@ -411,6 +411,9 @@ let $coll='latin1_nopad_bin'; let $coll_pad='latin1_bin'; --source include/ctype_pad_all_engines.inc +SET NAMES latin1; +--source include/ctype_like_range_mdev14350.inc + --echo # --echo # End of 10.2 tests --echo # diff --git a/mysql-test/t/ctype_like_range.test b/mysql-test/t/ctype_like_range.test index e8784990d36..3055abe5f59 100644 --- a/mysql-test/t/ctype_like_range.test +++ b/mysql-test/t/ctype_like_range.test @@ -155,5 +155,45 @@ SELECT a, HEX(mn), HEX(mx) FROM t1; DROP TABLE t1; --echo # +--echo # MDEV-14350 Index use with collation utf8mb4_unicode_nopad_ci on LIKE pattern with wrong results +--echo # + +CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET latin1 COLLATE latin1_swedish_nopad_ci); +INSERT INTO t1 VALUES ('111%'); +SELECT a, HEX(LIKE_RANGE_MIN(a,200)) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf8 COLLATE utf8_general_nopad_ci); +INSERT INTO t1 VALUES ('111%'); +SELECT a, HEX(LIKE_RANGE_MIN(a,200)) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf8 COLLATE utf8_unicode_nopad_ci); +INSERT INTO t1 VALUES ('111%'); +SELECT a, HEX(LIKE_RANGE_MIN(a,200)) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_nopad_ci); +INSERT INTO t1 VALUES ('111%'); +SELECT a, HEX(LIKE_RANGE_MIN(a,200)) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET ucs2 COLLATE ucs2_unicode_nopad_ci); +INSERT INTO t1 VALUES ('111%'); +SELECT a, HEX(LIKE_RANGE_MIN(a,200)) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf16 COLLATE utf16_unicode_nopad_ci); +INSERT INTO t1 VALUES ('111%'); +SELECT a, HEX(LIKE_RANGE_MIN(a,200)) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf32 COLLATE utf32_unicode_nopad_ci); +INSERT INTO t1 VALUES ('111%'); +SELECT a, HEX(LIKE_RANGE_MIN(a,200)) FROM t1; +DROP TABLE t1; + + +--echo # --echo # End of 10.2 tests --echo # diff --git a/mysql-test/t/ctype_ucs2_uca.test b/mysql-test/t/ctype_ucs2_uca.test index bc6d6150ee6..0aed0956f6c 100644 --- a/mysql-test/t/ctype_ucs2_uca.test +++ b/mysql-test/t/ctype_ucs2_uca.test @@ -16,6 +16,10 @@ let $coll='ucs2_unicode_520_nopad_ci'; let $coll_pad='ucs2_unicode_520_ci'; --source include/ctype_pad_all_engines.inc +SET NAMES utf8, collation_connection=ucs2_unicode_520_nopad_ci; +--source include/ctype_like_range_mdev14350.inc +SET NAMES utf8; + --echo # --echo # End of 10.2 tests --echo # diff --git a/mysql-test/t/ctype_utf16_uca.test b/mysql-test/t/ctype_utf16_uca.test index 95ce74076d0..46d572fbe81 100644 --- a/mysql-test/t/ctype_utf16_uca.test +++ b/mysql-test/t/ctype_utf16_uca.test @@ -238,6 +238,11 @@ let $coll='utf16_unicode_520_nopad_ci'; let $coll_pad='utf16_unicode_520_ci'; --source include/ctype_pad_all_engines.inc +SET NAMES utf8, collation_connection=utf16_unicode_520_nopad_ci; +--source include/ctype_like_range_mdev14350.inc +SET NAMES utf8; + + --echo # --echo # End of 10.2 tests --echo # diff --git a/mysql-test/t/ctype_utf32_uca.test b/mysql-test/t/ctype_utf32_uca.test index e5eb3b6d881..334d8fd1d48 100644 --- a/mysql-test/t/ctype_utf32_uca.test +++ b/mysql-test/t/ctype_utf32_uca.test @@ -260,6 +260,11 @@ let $coll='utf32_unicode_520_nopad_ci'; let $coll_pad='utf32_unicode_520_ci'; --source include/ctype_pad_all_engines.inc +SET NAMES utf8, collation_connection=utf32_unicode_520_nopad_ci; +--source include/ctype_like_range_mdev14350.inc +SET NAMES utf8; + + --echo # --echo # End of 10.2 tests --echo # diff --git a/mysql-test/t/ctype_utf8_uca.test b/mysql-test/t/ctype_utf8_uca.test index 670998a367b..0879b4d2810 100644 --- a/mysql-test/t/ctype_utf8_uca.test +++ b/mysql-test/t/ctype_utf8_uca.test @@ -14,6 +14,9 @@ let $coll='utf8_unicode_520_nopad_ci'; let $coll_pad='utf8_unicode_520_ci'; --source include/ctype_pad_all_engines.inc +SET NAMES utf8 COLLATE utf8_unicode_nopad_ci; +--source include/ctype_like_range_mdev14350.inc + --echo # --echo # End of 10.2 tests diff --git a/mysql-test/t/ctype_utf8mb4_uca.test b/mysql-test/t/ctype_utf8mb4_uca.test index fe76ed45e3f..160cb48bad6 100644 --- a/mysql-test/t/ctype_utf8mb4_uca.test +++ b/mysql-test/t/ctype_utf8mb4_uca.test @@ -100,6 +100,11 @@ let $coll='utf8mb4_unicode_520_nopad_ci'; let $coll_pad='utf8mb4_unicode_520_ci'; --source include/ctype_pad_all_engines.inc +SET NAMES utf8mb4 COLLATE utf8mb4_unicode_520_nopad_ci; +--source include/ctype_like_range_mdev14350.inc +SET NAMES utf8mb4; + + --echo # --echo # End of 10.2 tests --echo # diff --git a/mysql-test/t/sp-row.test b/mysql-test/t/sp-row.test index 5928c8cb76d..837e24c89c0 100644 --- a/mysql-test/t/sp-row.test +++ b/mysql-test/t/sp-row.test @@ -274,7 +274,7 @@ BEGIN END; $$ DELIMITER ;$$ ---error ER_OPERAND_COLUMNS +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION CALL p1(); DROP PROCEDURE p1; @@ -287,7 +287,7 @@ BEGIN END; $$ DELIMITER ;$$ ---error ER_OPERAND_COLUMNS +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION CALL p1(); DROP PROCEDURE p1; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 576512e78a4..733e38351c3 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -9774,6 +9774,85 @@ DELIMITER ;$$ CALL p1(); DROP PROCEDURE p1; +--echo # +--echo # MDEV-14228 MariaDB crashes with function +--echo # + +CREATE TABLE t1 (c VARCHAR(16), KEY(c)); +INSERT INTO t1 VALUES ('foo'); + +DELIMITER $$; +CREATE FUNCTION f1() RETURNS VARCHAR(16) +BEGIN + DECLARE v VARCHAR(16); + FOR v IN (SELECT DISTINCT c FROM t1) + DO + IF (v = 'bar') THEN + SELECT 1 INTO @a; + END IF; + END FOR; + RETURN 'qux'; +END $$ +DELIMITER ;$$ +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT f1(); +DROP FUNCTION f1; + +DELIMITER $$; +CREATE FUNCTION f1() RETURNS VARCHAR(16) +BEGIN + DECLARE v ROW TYPE OF t1; + IF v = 'bar' THEN + RETURN 'eq'; + END IF; + RETURN 'ne'; +END $$ +DELIMITER ;$$ +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT f1(); +DROP FUNCTION f1; + +DELIMITER $$; +CREATE FUNCTION f1() RETURNS VARCHAR(16) +BEGIN + DECLARE v ROW(a INT); + IF v = 'bar' THEN + RETURN 'eq'; + END IF; + RETURN 'ne'; +END $$ +DELIMITER ;$$ +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT f1(); +DROP FUNCTION f1; + +DROP TABLE t1; + + +DELIMITER $$; +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +BEGIN NOT ATOMIC + DECLARE v ROW(a INT); + SELECT v IN ('a','b'); +END $$ +DELIMITER ;$$ + +DELIMITER $$; +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +BEGIN NOT ATOMIC +DECLARE v ROW(a INT); + SELECT 'a' IN (v,'b'); +END $$ +DELIMITER ;$$ + +DELIMITER $$; +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +BEGIN NOT ATOMIC + DECLARE v ROW(a INT); + SELECT 'a' IN ('b',v); +END $$ +DELIMITER ;$$ + --echo # Test affected rows from an sp create table t1 (a int); diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 5e1e1494fee..ce0b949fcac 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -188,10 +188,10 @@ INSERT INTO t8 (pseudo,email) VALUES ('joce','test'); INSERT INTO t8 (pseudo,email) VALUES ('joce1','test1'); INSERT INTO t8 (pseudo,email) VALUES ('2joce1','2test1'); EXPLAIN EXTENDED SELECT pseudo,(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce')) FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'); --- error ER_OPERAND_COLUMNS +-- error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM t8 WHERE pseudo='joce'); --- error ER_OPERAND_COLUMNS +-- error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION SELECT pseudo FROM t8 WHERE pseudo=(SELECT * FROM t8 WHERE pseudo='joce'); SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'); @@ -1834,13 +1834,13 @@ drop table t1, t2; # create table t1 (a int, b int); insert into t1 values (1,2); --- error ER_OPERAND_COLUMNS +-- error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION select 1 = (select * from t1); --- error ER_OPERAND_COLUMNS +-- error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION select (select * from t1) = 1; --- error ER_OPERAND_COLUMNS +-- error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION select (1,2) = (select a from t1); --- error ER_OPERAND_COLUMNS +-- error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION select (select a from t1) = (1,2); -- error ER_OPERAND_COLUMNS select (1,2,3) = (select * from t1); diff --git a/mysys/lf_alloc-pin.c b/mysys/lf_alloc-pin.c index bf2b8a12846..8a96fccf16a 100644 --- a/mysys/lf_alloc-pin.c +++ b/mysys/lf_alloc-pin.c @@ -430,7 +430,7 @@ static void alloc_free(uchar *first, { anext_node(last)= tmp.node; } while (!my_atomic_casptr((void **)(char *)&allocator->top, - (void **)&tmp.ptr, first) && LF_BACKOFF); + (void **)&tmp.ptr, first) && LF_BACKOFF()); } /* @@ -501,7 +501,7 @@ void *lf_alloc_new(LF_PINS *pins) { node= allocator->top; lf_pin(pins, 0, node); - } while (node != allocator->top && LF_BACKOFF); + } while (node != allocator->top && LF_BACKOFF()); if (!node) { node= (void *)my_malloc(allocator->element_size, MYF(MY_WME)); diff --git a/mysys/lf_hash.c b/mysys/lf_hash.c index 430f1007f30..6b3fa78475d 100644 --- a/mysys/lf_hash.c +++ b/mysys/lf_hash.c @@ -102,7 +102,7 @@ retry: do { /* PTR() isn't necessary below, head is a dummy node */ cursor->curr= (LF_SLIST *)(*cursor->prev); lf_pin(pins, 1, cursor->curr); - } while (*cursor->prev != (intptr)cursor->curr && LF_BACKOFF); + } while (*cursor->prev != (intptr)cursor->curr && LF_BACKOFF()); for (;;) { @@ -117,7 +117,7 @@ retry: link= cursor->curr->link; cursor->next= PTR(link); lf_pin(pins, 0, cursor->next); - } while (link != cursor->curr->link && LF_BACKOFF); + } while (link != cursor->curr->link && LF_BACKOFF()); if (!DELETED(link)) { @@ -145,7 +145,7 @@ retry: and remove this deleted node */ if (my_atomic_casptr((void **) cursor->prev, - (void **) &cursor->curr, cursor->next) && LF_BACKOFF) + (void **) &cursor->curr, cursor->next) && LF_BACKOFF()) lf_alloc_free(pins, cursor->curr); else goto retry; diff --git a/mysys/waiting_threads.c b/mysys/waiting_threads.c index df208507590..8e66e0372c1 100644 --- a/mysys/waiting_threads.c +++ b/mysys/waiting_threads.c @@ -618,7 +618,7 @@ retry: { rc= *shared_ptr; lf_pin(arg->thd->pins, 0, rc); - } while (rc != *shared_ptr && LF_BACKOFF); + } while (rc != *shared_ptr && LF_BACKOFF()); if (rc == 0) { diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc index d9db7afe1ab..1572fedff49 100644 --- a/sql/event_scheduler.cc +++ b/sql/event_scheduler.cc @@ -648,14 +648,11 @@ Event_scheduler::stop() state= STOPPING; DBUG_PRINT("info", ("Scheduler thread has id %lu", (ulong) scheduler_thd->thread_id)); - /* Lock from delete */ - mysql_mutex_lock(&scheduler_thd->LOCK_thd_data); /* This will wake up the thread if it waits on Queue's conditional */ sql_print_information("Event Scheduler: Killing the scheduler thread, " "thread id %lu", (ulong) scheduler_thd->thread_id); scheduler_thd->awake(KILL_CONNECTION); - mysql_mutex_unlock(&scheduler_thd->LOCK_thd_data); /* thd could be 0x0, when shutting down */ sql_print_information("Event Scheduler: " diff --git a/sql/item.cc b/sql/item.cc index 4c2a91dcee7..805ddb2918f 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1154,6 +1154,16 @@ bool Item::check_type_can_return_text(const char *opname) const bool Item::check_type_scalar(const char *opname) const { + /* + fixed==true usually means than the Item has an initialized + and reliable data type handler and attributes. + Item_outer_ref is an exception. It copies the data type and the attributes + from the referenced Item in the constructor, but then sets "fixed" to false, + and re-fixes itself again in fix_inner_refs(). + This hack in Item_outer_ref should probably be refactored eventually. + Discuss with Sanja. + */ + DBUG_ASSERT(fixed || type() == REF_ITEM); const Type_handler *handler= type_handler(); if (handler->is_scalar_type()) return false; diff --git a/sql/item_func.cc b/sql/item_func.cc index a8b4a64856e..55d141b9968 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -153,12 +153,19 @@ void Item_func::sync_with_sum_func_and_with_field(List<Item> &list) bool Item_func::check_argument_types_like_args0() const { - uint cols; - if (arg_count == 0) + if (arg_count < 2) return false; - cols= args[0]->cols(); + uint cols= args[0]->cols(); + bool is_scalar= args[0]->type_handler()->is_scalar_type(); for (uint i= 1; i < arg_count; i++) { + if (is_scalar != args[i]->type_handler()->is_scalar_type()) + { + my_error(ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION, MYF(0), + args[0]->type_handler()->name().ptr(), + args[i]->type_handler()->name().ptr(), func_name()); + return true; + } if (args[i]->check_cols(cols)) return true; } diff --git a/sql/my_apc.cc b/sql/my_apc.cc index c86e554e591..9a0310234a2 100644 --- a/sql/my_apc.cc +++ b/sql/my_apc.cc @@ -35,7 +35,7 @@ void Apc_target::init(mysql_mutex_t *target_mutex) { DBUG_ASSERT(!enabled); - LOCK_thd_data_ptr= target_mutex; + LOCK_thd_kill_ptr= target_mutex; #ifndef DBUG_OFF n_calls_processed= 0; #endif @@ -46,7 +46,7 @@ void Apc_target::init(mysql_mutex_t *target_mutex) void Apc_target::enqueue_request(Call_request *qe) { - mysql_mutex_assert_owner(LOCK_thd_data_ptr); + mysql_mutex_assert_owner(LOCK_thd_kill_ptr); if (apc_calls) { Call_request *after= apc_calls->prev; @@ -72,7 +72,7 @@ void Apc_target::enqueue_request(Call_request *qe) void Apc_target::dequeue_request(Call_request *qe) { - mysql_mutex_assert_owner(LOCK_thd_data_ptr); + mysql_mutex_assert_owner(LOCK_thd_kill_ptr); if (apc_calls == qe) { if ((apc_calls= apc_calls->next) == qe) @@ -146,14 +146,14 @@ bool Apc_target::make_apc_call(THD *caller_thd, Apc_call *call, int wait_res= 0; PSI_stage_info old_stage; - caller_thd->ENTER_COND(&apc_request.COND_request, LOCK_thd_data_ptr, + caller_thd->ENTER_COND(&apc_request.COND_request, LOCK_thd_kill_ptr, &stage_show_explain, &old_stage); /* todo: how about processing other errors here? */ while (!apc_request.processed && (wait_res != ETIMEDOUT)) { - /* We own LOCK_thd_data_ptr */ + /* We own LOCK_thd_kill_ptr */ wait_res= mysql_cond_timedwait(&apc_request.COND_request, - LOCK_thd_data_ptr, &abstime); + LOCK_thd_kill_ptr, &abstime); // &apc_request.LOCK_request, &abstime); if (caller_thd->killed) break; @@ -164,7 +164,7 @@ bool Apc_target::make_apc_call(THD *caller_thd, Apc_call *call, /* The wait has timed out, or this thread was KILLed. Remove the request from the queue (ok to do because we own - LOCK_thd_data_ptr) + LOCK_thd_kill_ptr) */ apc_request.processed= TRUE; dequeue_request(&apc_request); @@ -177,7 +177,7 @@ bool Apc_target::make_apc_call(THD *caller_thd, Apc_call *call, res= FALSE; } /* - exit_cond() will call mysql_mutex_unlock(LOCK_thd_data_ptr) for us: + exit_cond() will call mysql_mutex_unlock(LOCK_thd_kill_ptr) for us: */ caller_thd->EXIT_COND(&old_stage); @@ -186,7 +186,7 @@ bool Apc_target::make_apc_call(THD *caller_thd, Apc_call *call, } else { - mysql_mutex_unlock(LOCK_thd_data_ptr); + mysql_mutex_unlock(LOCK_thd_kill_ptr); } return res; } @@ -203,11 +203,11 @@ void Apc_target::process_apc_requests() { Call_request *request; - mysql_mutex_lock(LOCK_thd_data_ptr); + mysql_mutex_lock(LOCK_thd_kill_ptr); if (!(request= get_first_in_queue())) { /* No requests in the queue */ - mysql_mutex_unlock(LOCK_thd_data_ptr); + mysql_mutex_unlock(LOCK_thd_kill_ptr); break; } @@ -226,7 +226,7 @@ void Apc_target::process_apc_requests() n_calls_processed++; #endif mysql_cond_signal(&request->COND_request); - mysql_mutex_unlock(LOCK_thd_data_ptr); + mysql_mutex_unlock(LOCK_thd_kill_ptr); } } diff --git a/sql/my_apc.h b/sql/my_apc.h index 46c6fbd549d..a04e09257b9 100644 --- a/sql/my_apc.h +++ b/sql/my_apc.h @@ -44,7 +44,7 @@ class THD; */ class Apc_target { - mysql_mutex_t *LOCK_thd_data_ptr; + mysql_mutex_t *LOCK_thd_kill_ptr; public: Apc_target() : enabled(0), apc_calls(NULL) {} ~Apc_target() { DBUG_ASSERT(!enabled && !apc_calls);} @@ -66,9 +66,9 @@ public: void disable() { DBUG_ASSERT(enabled); - mysql_mutex_lock(LOCK_thd_data_ptr); + mysql_mutex_lock(LOCK_thd_kill_ptr); bool process= !--enabled && have_apc_requests(); - mysql_mutex_unlock(LOCK_thd_data_ptr); + mysql_mutex_unlock(LOCK_thd_kill_ptr); if (unlikely(process)) process_apc_requests(); } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index fe39aa6d688..f49365c9e9b 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1707,7 +1707,7 @@ static void close_connections(void) #endif tmp->set_killed(KILL_SERVER_HARD); MYSQL_CALLBACK(thread_scheduler, post_kill_notification, (tmp)); - mysql_mutex_lock(&tmp->LOCK_thd_data); + mysql_mutex_lock(&tmp->LOCK_thd_kill); if (tmp->mysys_var) { tmp->mysys_var->abort=1; @@ -1730,7 +1730,7 @@ static void close_connections(void) } mysql_mutex_unlock(&tmp->mysys_var->mutex); } - mysql_mutex_unlock(&tmp->LOCK_thd_data); + mysql_mutex_unlock(&tmp->LOCK_thd_kill); } mysql_mutex_unlock(&LOCK_thread_count); // For unlink from list diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 516d009a69e..0c42204fbb6 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -7750,6 +7750,9 @@ ER_NET_OK_PACKET_TOO_LARGE ER_GEOJSON_EMPTY_COORDINATES eng "Incorrect GeoJSON format - empty 'coordinates' array." +ER_MYROCKS_CANT_NOPAD_COLLATION + eng "MyRocks doesn't currently support collations with \"No pad\" attribute." + ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION eng "Illegal parameter data types %s and %s for operation '%s'" ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION diff --git a/sql/slave.cc b/sql/slave.cc index 1ee745ced6a..a57312998f1 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -516,9 +516,7 @@ handle_slave_background(void *arg __attribute__((unused))) THD *to_kill= p->to_kill; kill_list= p->next; - mysql_mutex_lock(&to_kill->LOCK_thd_data); to_kill->awake(KILL_CONNECTION); - mysql_mutex_unlock(&to_kill->LOCK_thd_data); mysql_mutex_lock(&to_kill->LOCK_wakeup_ready); to_kill->rgi_slave->killed_for_retry= rpl_group_info::RETRY_KILL_KILLED; @@ -1162,7 +1160,7 @@ terminate_slave_thread(THD *thd, int error __attribute__((unused)); DBUG_PRINT("loop", ("killing slave thread")); - mysql_mutex_lock(&thd->LOCK_thd_data); + mysql_mutex_lock(&thd->LOCK_thd_kill); #ifndef DONT_USE_THR_ALARM /* Error codes from pthread_kill are: @@ -1172,9 +1170,9 @@ terminate_slave_thread(THD *thd, int err __attribute__((unused))= pthread_kill(thd->real_id, thr_client_alarm); DBUG_ASSERT(err != EINVAL); #endif - thd->awake(NOT_KILLED); + thd->awake_no_mutex(NOT_KILLED); - mysql_mutex_unlock(&thd->LOCK_thd_data); + mysql_mutex_unlock(&thd->LOCK_thd_kill); /* There is a small chance that slave thread might miss the first diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 628671802a0..9d30ad65be4 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -555,8 +555,6 @@ char *thd_get_error_context_description(THD *thd, char *buffer, char header[256]; int len; - mysql_mutex_lock(&LOCK_thread_count); - /* The pointers thd->query and thd->proc_info might change since they are being modified concurrently. This is acceptable for proc_info since its @@ -612,7 +610,6 @@ char *thd_get_error_context_description(THD *thd, char *buffer, } mysql_mutex_unlock(&thd->LOCK_thd_data); } - mysql_mutex_unlock(&LOCK_thread_count); if (str.c_ptr_safe() == buffer) return buffer; @@ -704,10 +701,8 @@ handle_condition(THD *thd, extern "C" void thd_kill_timeout(THD* thd) { thd->status_var.max_statement_time_exceeded++; - mysql_mutex_lock(&thd->LOCK_thd_data); /* Kill queries that can't cause data corruptions */ thd->awake(KILL_TIMEOUT); - mysql_mutex_unlock(&thd->LOCK_thd_data); } @@ -1363,7 +1358,7 @@ void THD::init(void) session_tracker.enable(this); #endif //EMBEDDED_LIBRARY - apc_target.init(&LOCK_thd_data); + apc_target.init(&LOCK_thd_kill); DBUG_VOID_RETURN; } @@ -1627,9 +1622,13 @@ THD::~THD() if (!status_in_global) add_status_to_global(); - /* Ensure that no one is using THD */ - mysql_mutex_lock(&LOCK_thd_data); - mysql_mutex_unlock(&LOCK_thd_data); + /* + Other threads may have a lock on LOCK_thd_kill to ensure that this + THD is not deleted while they access it. The following mutex_lock + ensures that no one else is using this THD and it's now safe to delete + */ + mysql_mutex_lock(&LOCK_thd_kill); + mysql_mutex_unlock(&LOCK_thd_kill); #ifdef WITH_WSREP mysql_mutex_lock(&LOCK_wsrep_thd); @@ -1811,17 +1810,17 @@ void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var, This is normally called from another thread's THD object. - @note Do always call this while holding LOCK_thd_data. + @note Do always call this while holding LOCK_thd_kill. NOT_KILLED is used to awake a thread for a slave */ -void THD::awake(killed_state state_to_set) +void THD::awake_no_mutex(killed_state state_to_set) { DBUG_ENTER("THD::awake"); DBUG_PRINT("enter", ("this: %p current_thd: %p state: %d", this, current_thd, (int) state_to_set)); THD_CHECK_SENTRY(this); - mysql_mutex_assert_owner(&LOCK_thd_data); + mysql_mutex_assert_owner(&LOCK_thd_kill); print_aborted_warning(3, "KILLED"); @@ -1832,8 +1831,6 @@ void THD::awake(killed_state state_to_set) if (killed >= KILL_CONNECTION) state_to_set= killed; - /* Set the 'killed' flag of 'this', which is the target THD object. */ - mysql_mutex_lock(&LOCK_thd_kill); set_killed_no_mutex(state_to_set); if (state_to_set >= KILL_CONNECTION || state_to_set == NOT_KILLED) @@ -1920,7 +1917,6 @@ void THD::awake(killed_state state_to_set) } mysql_mutex_unlock(&mysys_var->mutex); } - mysql_mutex_unlock(&LOCK_thd_kill); DBUG_VOID_RETURN; } @@ -1936,10 +1932,10 @@ void THD::disconnect() { Vio *vio= NULL; - mysql_mutex_lock(&LOCK_thd_data); - set_killed(KILL_CONNECTION); + mysql_mutex_lock(&LOCK_thd_data); + #ifdef SIGNAL_WITH_VIO_CLOSE /* Since a active vio might might have not been set yet, in @@ -1972,9 +1968,9 @@ bool THD::notify_shared_lock(MDL_context_owner *ctx_in_use, { /* This code is similar to kill_delayed_threads() */ DBUG_PRINT("info", ("kill delayed thread")); - mysql_mutex_lock(&in_use->LOCK_thd_data); + mysql_mutex_lock(&in_use->LOCK_thd_kill); if (in_use->killed < KILL_CONNECTION) - in_use->set_killed(KILL_CONNECTION); + in_use->set_killed_no_mutex(KILL_CONNECTION); if (in_use->mysys_var) { mysql_mutex_lock(&in_use->mysys_var->mutex); @@ -1985,7 +1981,7 @@ bool THD::notify_shared_lock(MDL_context_owner *ctx_in_use, in_use->mysys_var->abort= 1; mysql_mutex_unlock(&in_use->mysys_var->mutex); } - mysql_mutex_unlock(&in_use->LOCK_thd_data); + mysql_mutex_unlock(&in_use->LOCK_thd_kill); signalled= TRUE; } @@ -2110,7 +2106,7 @@ bool THD::store_globals() return 1; /* mysys_var is concurrently readable by a killer thread. - It is protected by LOCK_thd_data, it is not needed to lock while the + It is protected by LOCK_thd_kill, it is not needed to lock while the pointer is changing from NULL not non-NULL. If the kill thread reads NULL it doesn't refer to anything, but if it is non-NULL we need to ensure that the thread doesn't proceed to assign another thread to @@ -2161,9 +2157,9 @@ bool THD::store_globals() void THD::reset_globals() { - mysql_mutex_lock(&LOCK_thd_data); + mysql_mutex_lock(&LOCK_thd_kill); mysys_var= 0; - mysql_mutex_unlock(&LOCK_thd_data); + mysql_mutex_unlock(&LOCK_thd_kill); /* Undocking the thread specific data. */ set_current_thd(0); @@ -5500,9 +5496,9 @@ void THD::set_query_and_id(char *query_arg, uint32 query_length_arg, /** Assign a new value to thd->mysys_var. */ void THD::set_mysys_var(struct st_my_thread_var *new_mysys_var) { - mysql_mutex_lock(&LOCK_thd_data); + mysql_mutex_lock(&LOCK_thd_kill); mysys_var= new_mysys_var; - mysql_mutex_unlock(&LOCK_thd_data); + mysql_mutex_unlock(&LOCK_thd_kill); } /** @@ -5635,7 +5631,7 @@ public: MY_MEMORY_ORDER_RELAXED)) { old&= ACQUIRED | RECOVERED; - (void) LF_BACKOFF; + (void) LF_BACKOFF(); } } bool acquire_recovered() @@ -5648,7 +5644,7 @@ public: if (!(old & RECOVERED) || (old & ACQUIRED)) return false; old= RECOVERED; - (void) LF_BACKOFF; + (void) LF_BACKOFF(); } return true; } diff --git a/sql/sql_class.h b/sql/sql_class.h index 038e1648596..20318d55da1 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2154,11 +2154,15 @@ public: - thd->query and thd->query_length (used by SHOW ENGINE INNODB STATUS and SHOW PROCESSLIST - thd->db and thd->db_length (used in SHOW PROCESSLIST) - - thd->mysys_var (used by KILL statement and shutdown). Is locked when THD is deleted. */ mysql_mutex_t LOCK_thd_data; - /* Protect kill information */ + /* + Protects: + - kill information + - mysys_var (used by KILL statement and shutdown). + - Also ensures that THD is not deleted while mutex is hold + */ mysql_mutex_t LOCK_thd_kill; /* all prepared statements and cursors of this connection */ @@ -3177,7 +3181,13 @@ public: } void close_active_vio(); #endif - void awake(killed_state state_to_set); + void awake_no_mutex(killed_state state_to_set); + void awake(killed_state state_to_set) + { + mysql_mutex_lock(&LOCK_thd_kill); + awake_no_mutex(state_to_set); + mysql_mutex_unlock(&LOCK_thd_kill); + } /** Disconnect the associated communication endpoint. */ void disconnect(); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 627e349c50b..51c6c80fd66 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -2701,9 +2701,9 @@ void kill_delayed_threads(void) Delayed_insert *di; while ((di= it++)) { - mysql_mutex_lock(&di->thd.LOCK_thd_data); + mysql_mutex_lock(&di->thd.LOCK_thd_kill); if (di->thd.killed < KILL_CONNECTION) - di->thd.set_killed(KILL_CONNECTION); + di->thd.set_killed_no_mutex(KILL_CONNECTION); if (di->thd.mysys_var) { mysql_mutex_lock(&di->thd.mysys_var->mutex); @@ -2721,7 +2721,7 @@ void kill_delayed_threads(void) } mysql_mutex_unlock(&di->thd.mysys_var->mutex); } - mysql_mutex_unlock(&di->thd.LOCK_thd_data); + mysql_mutex_unlock(&di->thd.LOCK_thd_kill); } mysql_mutex_unlock(&LOCK_delayed_insert); // For unlink from list DBUG_VOID_RETURN; @@ -3075,9 +3075,9 @@ pthread_handler_t handle_delayed_insert(void *arg) this. */ mysql_mutex_lock(&thd->LOCK_thd_data); - thd->set_killed(KILL_CONNECTION_HARD); // If error thd->mdl_context.set_needs_thr_lock_abort(0); mysql_mutex_unlock(&thd->LOCK_thd_data); + thd->set_killed(KILL_CONNECTION_HARD); // If error close_thread_tables(thd); // Free the table thd->mdl_context.release_transactional_locks(); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 346d1c0f18f..7a4c7ca4c56 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -5781,14 +5781,19 @@ end_with_restore_list: thd->print_aborted_warning(3, "RELEASE"); } #ifdef WITH_WSREP - if (WSREP(thd) && (thd->wsrep_conflict_state != NO_CONFLICT && - thd->wsrep_conflict_state != REPLAYING)) - { - DBUG_ASSERT(thd->is_error()); // the error is already issued + if (WSREP(thd)) { + + if (thd->wsrep_conflict_state == NO_CONFLICT || + thd->wsrep_conflict_state == REPLAYING) + { + my_ok(thd); + } + } else { +#endif /* WITH_WSREP */ + my_ok(thd); +#ifdef WITH_WSREP } - else #endif /* WITH_WSREP */ - my_ok(thd); break; } case SQLCOM_ROLLBACK: @@ -5825,13 +5830,16 @@ end_with_restore_list: if (tx_release) thd->set_killed(KILL_CONNECTION); #ifdef WITH_WSREP - if (WSREP(thd) && thd->wsrep_conflict_state != NO_CONFLICT) - { - DBUG_ASSERT(thd->is_error()); // the error is already issued + if (WSREP(thd)) { + if (thd->wsrep_conflict_state == NO_CONFLICT) { + my_ok(thd); + } + } else { +#endif /* WITH_WSREP */ + my_ok(thd); +#ifdef WITH_WSREP } - else #endif /* WITH_WSREP */ - my_ok(thd); break; } case SQLCOM_RELEASE_SAVEPOINT: @@ -6288,8 +6296,9 @@ finish: trans_rollback_stmt(thd); } #ifdef WITH_WSREP - else if (thd->spcont && + if (thd->spcont && (thd->wsrep_conflict_state == MUST_ABORT || + thd->wsrep_conflict_state == ABORTED || thd->wsrep_conflict_state == CERT_FAILURE)) { /* @@ -8773,13 +8782,13 @@ void add_join_natural(TABLE_LIST *a, TABLE_LIST *b, List<String> *using_fields, /** - Find a thread by id and return it, locking it LOCK_thd_data + Find a thread by id and return it, locking it LOCK_thd_kill @param id Identifier of the thread we're looking for @param query_id If true, search by query_id instead of thread_id @return NULL - not found - pointer - thread found, and its LOCK_thd_data is locked. + pointer - thread found, and its LOCK_thd_kill is locked. */ THD *find_thread_by_id(longlong id, bool query_id) @@ -8793,7 +8802,7 @@ THD *find_thread_by_id(longlong id, bool query_id) continue; if (id == (query_id ? tmp->query_id : (longlong) tmp->thread_id)) { - mysql_mutex_lock(&tmp->LOCK_thd_data); // Lock from delete + mysql_mutex_lock(&tmp->LOCK_thd_kill); // Lock from delete break; } } @@ -8849,13 +8858,13 @@ kill_one_thread(THD *thd, longlong id, killed_state kill_signal, killed_type typ thd->security_ctx->user_matches(tmp->security_ctx)) && !wsrep_thd_is_BF(tmp, true)) { - tmp->awake(kill_signal); + tmp->awake_no_mutex(kill_signal); error=0; } else error= (type == KILL_TYPE_QUERY ? ER_KILL_QUERY_DENIED_ERROR : ER_KILL_DENIED_ERROR); - mysql_mutex_unlock(&tmp->LOCK_thd_data); + mysql_mutex_unlock(&tmp->LOCK_thd_kill); } DBUG_PRINT("exit", ("%d", error)); DBUG_RETURN(error); @@ -8913,7 +8922,7 @@ static uint kill_threads_for_user(THD *thd, LEX_USER *user, DBUG_RETURN(ER_KILL_DENIED_ERROR); } if (!threads_to_kill.push_back(tmp, thd->mem_root)) - mysql_mutex_lock(&tmp->LOCK_thd_data); // Lock from delete + mysql_mutex_lock(&tmp->LOCK_thd_kill); // Lock from delete } } mysql_mutex_unlock(&LOCK_thread_count); @@ -8924,17 +8933,17 @@ static uint kill_threads_for_user(THD *thd, LEX_USER *user, THD *ptr= it2++; do { - ptr->awake(kill_signal); + ptr->awake_no_mutex(kill_signal); /* Careful here: The list nodes are allocated on the memroots of the THDs to be awakened. But those THDs may be terminated and deleted as soon as we release - LOCK_thd_data, which will make the list nodes invalid. + LOCK_thd_kill, which will make the list nodes invalid. Since the operation "it++" dereferences the "next" pointer of the - previous list node, we need to do this while holding LOCK_thd_data. + previous list node, we need to do this while holding LOCK_thd_kill. */ next_ptr= it2++; - mysql_mutex_unlock(&ptr->LOCK_thd_data); + mysql_mutex_unlock(&ptr->LOCK_thd_kill); (*rows)++; } while ((ptr= next_ptr)); } diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index d978a2d58ee..08e9dcf3fe6 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -3344,7 +3344,7 @@ void kill_zombie_dump_threads(uint32 slave_server_id) if (tmp->get_command() == COM_BINLOG_DUMP && tmp->variables.server_id == slave_server_id) { - mysql_mutex_lock(&tmp->LOCK_thd_data); // Lock from delete + mysql_mutex_lock(&tmp->LOCK_thd_kill); // Lock from delete break; } } @@ -3356,8 +3356,8 @@ void kill_zombie_dump_threads(uint32 slave_server_id) it will be slow because it will iterate through the list again. We just to do kill the thread ourselves. */ - tmp->awake(KILL_SLAVE_SAME_ID); - mysql_mutex_unlock(&tmp->LOCK_thd_data); + tmp->awake_no_mutex(KILL_SLAVE_SAME_ID); + mysql_mutex_unlock(&tmp->LOCK_thd_kill); } } diff --git a/sql/sql_show.cc b/sql/sql_show.cc index c88991f7795..befffb55e2e 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -137,6 +137,29 @@ static const LEX_CSTRING *view_algorithm(TABLE_LIST *table); bool get_lookup_field_values(THD *, COND *, TABLE_LIST *, LOOKUP_FIELD_VALUES *); +/** + Try to lock a mutex, but give up after a short while to not cause deadlocks + + The loop is short, as the mutex we are trying to lock are mutex the should + never be locked a long time, just over a few instructions. + + @return 0 ok + @return 1 error +*/ + +static bool trylock_short(mysql_mutex_t *mutex) +{ + uint i; + for (i= 0 ; i < 100 ; i++) + { + if (!mysql_mutex_trylock(mutex)) + return 0; + LF_BACKOFF(); + } + return 1; +} + + /*************************************************************************** ** List all table types supported ***************************************************************************/ @@ -790,6 +813,57 @@ static void dispose_db_dir(void *ptr) } +/* + Append an element into @@ignore_db_dirs + + This is a function to be called after regular option processing has been + finalized. +*/ + +void ignore_db_dirs_append(const char *dirname_arg) +{ + char *new_entry_buf; + LEX_STRING *new_entry; + size_t len= strlen(dirname_arg); + + if (!my_multi_malloc(0, + &new_entry, sizeof(LEX_STRING), + &new_entry_buf, len + 1, + NullS)) + return; + + memcpy(new_entry_buf, dirname_arg, len+1); + new_entry->str = new_entry_buf; + new_entry->length= len; + + if (my_hash_insert(&ignore_db_dirs_hash, (uchar *)new_entry)) + { + // Either the name is already there or out-of-memory. + my_free(new_entry); + return; + } + + // Append the name to the option string. + size_t curlen= strlen(opt_ignore_db_dirs); + // Add one for comma and one for \0. + size_t newlen= curlen + len + 1 + 1; + char *new_db_dirs; + if (!(new_db_dirs= (char*)my_malloc(newlen ,MYF(0)))) + { + // This is not a critical condition + return; + } + + memcpy(new_db_dirs, opt_ignore_db_dirs, curlen); + if (curlen != 0) + new_db_dirs[curlen]=','; + memcpy(new_db_dirs + (curlen + ((curlen!=0)?1:0)), dirname_arg, len+1); + + if (opt_ignore_db_dirs) + my_free(opt_ignore_db_dirs); + opt_ignore_db_dirs= new_db_dirs; +} + bool ignore_db_dirs_process_additions() { @@ -2566,23 +2640,28 @@ static const char *thread_state_info(THD *tmp) { if (tmp->net.reading_or_writing == 2) return "Writing to net"; - else if (tmp->get_command() == COM_SLEEP) + if (tmp->get_command() == COM_SLEEP) return ""; - else - return "Reading from net"; + return "Reading from net"; } - else #endif + + if (tmp->proc_info) + return tmp->proc_info; + + /* Check if we are waiting on a condition */ + if (!trylock_short(&tmp->LOCK_thd_kill)) { - if (tmp->proc_info) - return tmp->proc_info; - else if (tmp->mysys_var && tmp->mysys_var->current_cond) + /* mysys_var is protected by above mutex */ + bool cond= tmp->mysys_var && tmp->mysys_var->current_cond; + mysql_mutex_unlock(&tmp->LOCK_thd_kill); + if (cond) return "Waiting on cond"; - else - return NULL; } + return NULL; } + void mysqld_list_processes(THD *thd,const char *user, bool verbose) { Item *field; @@ -2645,7 +2724,7 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose) while ((tmp=it++)) { Security_context *tmp_sctx= tmp->security_ctx; - struct st_my_thread_var *mysys_var; + bool got_thd_data; if ((tmp->vio_ok() || tmp->system_thread) && (!user || (!tmp->system_thread && tmp_sctx->user && !strcmp(tmp_sctx->user, user)))) @@ -2669,48 +2748,59 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose) tmp_sctx->host_or_ip : tmp_sctx->host ? tmp_sctx->host : ""); thd_info->command=(int) tmp->get_command(); - mysql_mutex_lock(&tmp->LOCK_thd_data); - if ((thd_info->db= tmp->db)) // Safe test - thd_info->db= thd->strdup(thd_info->db); - if ((mysys_var= tmp->mysys_var)) - mysql_mutex_lock(&mysys_var->mutex); - thd_info->proc_info= (char*) (tmp->killed >= KILL_QUERY ? - "Killed" : 0); - thd_info->state_info= thread_state_info(tmp); - if (mysys_var) - mysql_mutex_unlock(&mysys_var->mutex); - /* Lock THD mutex that protects its data when looking at it. */ - if (tmp->query()) + if ((got_thd_data= !trylock_short(&tmp->LOCK_thd_data))) { - uint length= MY_MIN(max_query_length, tmp->query_length()); - char *q= thd->strmake(tmp->query(),length); - /* Safety: in case strmake failed, we set length to 0. */ - thd_info->query_string= - CSET_STRING(q, q ? length : 0, tmp->query_charset()); - } + /* This is an approximation */ + thd_info->proc_info= (char*) (tmp->killed >= KILL_QUERY ? + "Killed" : 0); + /* + The following variables are only safe to access under a lock + */ - /* - Progress report. We need to do this under a lock to ensure that all - is from the same stage. - */ - if (tmp->progress.max_counter) - { - uint max_stage= MY_MAX(tmp->progress.max_stage, 1); - thd_info->progress= (((tmp->progress.stage / (double) max_stage) + - ((tmp->progress.counter / - (double) tmp->progress.max_counter) / - (double) max_stage)) * - 100.0); - set_if_smaller(thd_info->progress, 100); + if ((thd_info->db= tmp->db)) // Safe test + thd_info->db= thd->strdup(thd_info->db); + + if (tmp->query()) + { + uint length= MY_MIN(max_query_length, tmp->query_length()); + char *q= thd->strmake(tmp->query(),length); + /* Safety: in case strmake failed, we set length to 0. */ + thd_info->query_string= + CSET_STRING(q, q ? length : 0, tmp->query_charset()); + } + + /* + Progress report. We need to do this under a lock to ensure that all + is from the same stage. + */ + if (tmp->progress.max_counter) + { + uint max_stage= MY_MAX(tmp->progress.max_stage, 1); + thd_info->progress= (((tmp->progress.stage / (double) max_stage) + + ((tmp->progress.counter / + (double) tmp->progress.max_counter) / + (double) max_stage)) * + 100.0); + set_if_smaller(thd_info->progress, 100); + } + else + thd_info->progress= 0.0; } else + { + thd_info->proc_info= "Busy"; thd_info->progress= 0.0; + } + + thd_info->state_info= thread_state_info(tmp); thd_info->start_time= tmp->start_utime; ulonglong utime_after_query_snapshot= tmp->utime_after_query; if (thd_info->start_time < utime_after_query_snapshot) thd_info->start_time= utime_after_query_snapshot; // COM_SLEEP - mysql_mutex_unlock(&tmp->LOCK_thd_data); + + if (got_thd_data) + mysql_mutex_unlock(&tmp->LOCK_thd_data); thread_infos.append(thd_info); } } @@ -2921,13 +3011,13 @@ int fill_show_explain(THD *thd, TABLE_LIST *table, COND *cond) tmp_sctx->user))) { my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "PROCESS"); - mysql_mutex_unlock(&tmp->LOCK_thd_data); + mysql_mutex_unlock(&tmp->LOCK_thd_kill); DBUG_RETURN(1); } if (tmp == thd) { - mysql_mutex_unlock(&tmp->LOCK_thd_data); + mysql_mutex_unlock(&tmp->LOCK_thd_kill); my_error(ER_TARGET_NOT_EXPLAINABLE, MYF(0)); DBUG_RETURN(1); } @@ -2935,7 +3025,7 @@ int fill_show_explain(THD *thd, TABLE_LIST *table, COND *cond) bool bres; /* Ok we've found the thread of interest and it won't go away because - we're holding its LOCK_thd data. Post it a SHOW EXPLAIN request. + we're holding its LOCK_thd_kill. Post it a SHOW EXPLAIN request. */ bool timed_out; int timeout_sec= 30; @@ -2949,7 +3039,7 @@ int fill_show_explain(THD *thd, TABLE_LIST *table, COND *cond) explain_req.request_thd= thd; explain_req.failed_to_produce= FALSE; - /* Ok, we have a lock on target->LOCK_thd_data, can call: */ + /* Ok, we have a lock on target->LOCK_thd_kill, can call: */ bres= tmp->apc_target.make_apc_call(thd, &explain_req, timeout_sec, &timed_out); if (bres || explain_req.failed_to_produce) @@ -3028,9 +3118,9 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond) while ((tmp= it++)) { Security_context *tmp_sctx= tmp->security_ctx; - struct st_my_thread_var *mysys_var; const char *val, *db; ulonglong max_counter; + bool got_thd_data; if ((!tmp->vio_ok() && !tmp->system_thread) || (user && (tmp->system_thread || !tmp_sctx->user || @@ -3056,23 +3146,26 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond) else table->field[2]->store(tmp_sctx->host_or_ip, strlen(tmp_sctx->host_or_ip), cs); - /* DB */ - mysql_mutex_lock(&tmp->LOCK_thd_data); - if ((db= tmp->db)) + + if ((got_thd_data= !trylock_short(&tmp->LOCK_thd_data))) { - table->field[3]->store(db, strlen(db), cs); - table->field[3]->set_notnull(); + /* DB */ + if ((db= tmp->db)) + { + table->field[3]->store(db, strlen(db), cs); + table->field[3]->set_notnull(); + } } - if ((mysys_var= tmp->mysys_var)) - mysql_mutex_lock(&mysys_var->mutex); /* COMMAND */ - if ((val= (char *) ((tmp->killed >= KILL_QUERY ? + if ((val= (char *) (!got_thd_data ? "Busy" : + (tmp->killed >= KILL_QUERY ? "Killed" : 0)))) table->field[4]->store(val, strlen(val), cs); else table->field[4]->store(command_name[tmp->get_command()].str, command_name[tmp->get_command()].length, cs); + /* MYSQL_TIME */ ulonglong utime= tmp->start_utime; ulonglong utime_after_query_snapshot= tmp->utime_after_query; @@ -3081,6 +3174,38 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond) utime= utime && utime < unow ? unow - utime : 0; table->field[5]->store(utime / HRTIME_RESOLUTION, TRUE); + + if (got_thd_data) + { + if (tmp->query()) + { + table->field[7]->store(tmp->query(), + MY_MIN(PROCESS_LIST_INFO_WIDTH, + tmp->query_length()), cs); + table->field[7]->set_notnull(); + + /* INFO_BINARY */ + table->field[16]->store(tmp->query(), + MY_MIN(PROCESS_LIST_INFO_WIDTH, + tmp->query_length()), + &my_charset_bin); + table->field[16]->set_notnull(); + } + + /* + Progress report. We need to do this under a lock to ensure that all + is from the same stage. + */ + if ((max_counter= tmp->progress.max_counter)) + { + table->field[9]->store((longlong) tmp->progress.stage + 1, 1); + table->field[10]->store((longlong) tmp->progress.max_stage, 1); + table->field[11]->store((double) tmp->progress.counter / + (double) max_counter*100.0); + } + mysql_mutex_unlock(&tmp->LOCK_thd_data); + } + /* STATE */ if ((val= thread_state_info(tmp))) { @@ -3088,46 +3213,9 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond) table->field[6]->set_notnull(); } - if (mysys_var) - mysql_mutex_unlock(&mysys_var->mutex); - mysql_mutex_unlock(&tmp->LOCK_thd_data); - /* TIME_MS */ table->field[8]->store((double)(utime / (HRTIME_RESOLUTION / 1000.0))); - /* INFO */ - /* Lock THD mutex that protects its data when looking at it. */ - mysql_mutex_lock(&tmp->LOCK_thd_data); - if (tmp->query()) - { - table->field[7]->store(tmp->query(), - MY_MIN(PROCESS_LIST_INFO_WIDTH, - tmp->query_length()), cs); - table->field[7]->set_notnull(); - } - - /* INFO_BINARY */ - if (tmp->query()) - { - table->field[16]->store(tmp->query(), - MY_MIN(PROCESS_LIST_INFO_WIDTH, - tmp->query_length()), &my_charset_bin); - table->field[16]->set_notnull(); - } - - /* - Progress report. We need to do this under a lock to ensure that all - is from the same stage. - */ - if ((max_counter= tmp->progress.max_counter)) - { - table->field[9]->store((longlong) tmp->progress.stage + 1, 1); - table->field[10]->store((longlong) tmp->progress.max_stage, 1); - table->field[11]->store((double) tmp->progress.counter / - (double) max_counter*100.0); - } - mysql_mutex_unlock(&tmp->LOCK_thd_data); - /* This may become negative if we free a memory allocated by another thread in this thread. However it's better that we notice it eventually diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index c67be1dbaf8..82f8359fefc 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -5163,7 +5163,8 @@ static Sys_var_mybool Sys_wsrep_on ( "wsrep_on", "To enable wsrep replication ", SESSION_VAR(wsrep_on), CMD_LINE(OPT_ARG), DEFAULT(FALSE), - NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), + NO_MUTEX_GUARD, NOT_IN_BINLOG, + ON_CHECK(wsrep_on_check), ON_UPDATE(wsrep_on_update)); static Sys_var_charptr Sys_wsrep_start_position ( diff --git a/sql/threadpool_common.cc b/sql/threadpool_common.cc index 486a829c645..fb9e61f9a05 100644 --- a/sql/threadpool_common.cc +++ b/sql/threadpool_common.cc @@ -250,7 +250,7 @@ static THD* threadpool_add_connection(CONNECT *connect, void *scheduler_data) } delete connect; add_to_active_threads(thd); - thd->mysys_var= mysys_var; + thd->set_mysys_var(mysys_var); thd->event_scheduler.data= scheduler_data; /* Create new PSI thread for use with the THD. */ @@ -477,11 +477,11 @@ void tp_timeout_handler(TP_connection *c) if (c->state != TP_STATE_IDLE) return; THD *thd=c->thd; - mysql_mutex_lock(&thd->LOCK_thd_data); + mysql_mutex_lock(&thd->LOCK_thd_kill); thd->set_killed(KILL_WAIT_TIMEOUT); c->priority= TP_PRIORITY_HIGH; post_kill_notification(thd); - mysql_mutex_unlock(&thd->LOCK_thd_data); + mysql_mutex_unlock(&thd->LOCK_thd_kill); } diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index 2f41e939ee4..da92aa9bedb 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -2492,9 +2492,7 @@ extern "C" void wsrep_thd_awake(THD *thd, my_bool signal) { if (signal) { - mysql_mutex_lock(&thd->LOCK_thd_data); thd->awake(KILL_QUERY); - mysql_mutex_unlock(&thd->LOCK_thd_data); } else { diff --git a/sql/wsrep_var.cc b/sql/wsrep_var.cc index 188fa3e292b..34c5865548c 100644 --- a/sql/wsrep_var.cc +++ b/sql/wsrep_var.cc @@ -42,12 +42,28 @@ int wsrep_init_vars() return 0; } +extern ulong innodb_lock_schedule_algorithm; + bool wsrep_on_update (sys_var *self, THD* thd, enum_var_type var_type) { if (var_type == OPT_GLOBAL) { // FIXME: this variable probably should be changed only per session thd->variables.wsrep_on = global_system_variables.wsrep_on; } + + return false; +} + +bool wsrep_on_check(sys_var *self, THD* thd, set_var* var) +{ + bool new_wsrep_on= (bool)var->save_result.ulonglong_value; + + if (new_wsrep_on && innodb_lock_schedule_algorithm != 0) { + my_message(ER_WRONG_ARGUMENTS, " WSREP (galera) can't be enabled " + "if innodb_lock_schedule_algorithm=VATS. Please configure" + " innodb_lock_schedule_algorithm=FCFS and restart.", MYF(0)); + return true; + } return false; } diff --git a/sql/wsrep_var.h b/sql/wsrep_var.h index dde59d1503f..b9051b29843 100644 --- a/sql/wsrep_var.h +++ b/sql/wsrep_var.h @@ -41,7 +41,8 @@ int wsrep_init_vars(); #define DEFAULT_ARGS (THD* thd, enum_var_type var_type) #define INIT_ARGS (const char* opt) -extern bool wsrep_causal_reads_update UPDATE_ARGS; +extern bool wsrep_causal_reads_update UPDATE_ARGS; +extern bool wsrep_on_check CHECK_ARGS; extern bool wsrep_on_update UPDATE_ARGS; extern bool wsrep_sync_wait_update UPDATE_ARGS; extern bool wsrep_start_position_check CHECK_ARGS; diff --git a/storage/innobase/btr/btr0defragment.cc b/storage/innobase/btr/btr0defragment.cc index cdbe47d48f8..86df5a077a8 100644 --- a/storage/innobase/btr/btr0defragment.cc +++ b/storage/innobase/btr/btr0defragment.cc @@ -831,6 +831,7 @@ DECLARE_THREAD(btr_defragment_thread)(void*) mtr_commit(&mtr); /* Reaching the end of the index. */ dict_stats_empty_defrag_stats(index); + trx->error_state = DB_SUCCESS; ut_d(trx->persistent_stats = true); ++trx->will_lock; dberr_t err = dict_stats_save_defrag_stats(index, trx); diff --git a/storage/innobase/dict/dict0defrag_bg.cc b/storage/innobase/dict/dict0defrag_bg.cc index 8f2c3231e1c..34120f0bdc9 100644 --- a/storage/innobase/dict/dict0defrag_bg.cc +++ b/storage/innobase/dict/dict0defrag_bg.cc @@ -213,6 +213,7 @@ dict_stats_process_entry_from_defrag_pool(trx_t* trx) index_id_t index_id; ut_ad(!srv_read_only_mode); + ut_ad(trx->persistent_stats); /* pop the first index from the auto defrag pool */ if (!dict_stats_defrag_pool_get(&table_id, &index_id)) { @@ -242,6 +243,7 @@ dict_stats_process_entry_from_defrag_pool(trx_t* trx) } mutex_exit(&dict_sys->mutex); + trx->error_state = DB_SUCCESS; ++trx->will_lock; dberr_t err = dict_stats_save_defrag_stats(index, trx); @@ -275,6 +277,8 @@ dict_defrag_process_entries_from_defrag_pool(trx_t* trx) dberr_t dict_stats_save_defrag_summary(dict_index_t* index, trx_t* trx) { + ut_ad(trx->persistent_stats); + if (dict_index_is_ibuf(index)) { return DB_SUCCESS; } @@ -294,6 +298,9 @@ dict_stats_save_defrag_summary(dict_index_t* index, trx_t* trx) dberr_t dict_stats_save_defrag_stats(dict_index_t* index, trx_t* trx) { + ut_ad(trx->error_state == DB_SUCCESS); + ut_ad(trx->persistent_stats); + if (dict_index_is_ibuf(index)) { return DB_SUCCESS; } @@ -318,7 +325,7 @@ dict_stats_save_defrag_stats(dict_index_t* index, trx_t* trx) return DB_SUCCESS; } - lint now = ut_time(); + ib_time_t now = ut_time(); dberr_t err = dict_stats_save_index_stat( index, now, "n_page_split", index->stat_defrag_n_page_split, diff --git a/storage/innobase/dict/dict0load.cc b/storage/innobase/dict/dict0load.cc index 0e55e353837..ac1087f1c65 100644 --- a/storage/innobase/dict/dict0load.cc +++ b/storage/innobase/dict/dict0load.cc @@ -377,8 +377,7 @@ dict_getnext_system( /********************************************************************//** This function processes one SYS_TABLES record and populate the dict_table_t -struct for the table. Extracted out of dict_print() to be used by -both monitor table output and information schema innodb_sys_tables output. +struct for the table. @return error message, or NULL on success */ const char* dict_process_sys_tables_rec_and_mtr_commit( diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc index 5fa049f6b2b..13dbd67997d 100644 --- a/storage/innobase/dict/dict0stats.cc +++ b/storage/innobase/dict/dict0stats.cc @@ -2264,7 +2264,7 @@ storage. dberr_t dict_stats_save_index_stat( dict_index_t* index, - lint last_update, + ib_time_t last_update, const char* stat_name, ib_uint64_t stat_value, ib_uint64_t* sample_size, @@ -2286,7 +2286,7 @@ dict_stats_save_index_stat( pars_info_add_str_literal(pinfo, "table_name", table_utf8); pars_info_add_str_literal(pinfo, "index_name", index->name); UNIV_MEM_ASSERT_RW_ABORT(&last_update, 4); - pars_info_add_int4_literal(pinfo, "last_update", last_update); + pars_info_add_int4_literal(pinfo, "last_update", (lint)last_update); UNIV_MEM_ASSERT_RW_ABORT(stat_name, strlen(stat_name)); pars_info_add_str_literal(pinfo, "stat_name", stat_name); UNIV_MEM_ASSERT_RW_ABORT(&stat_value, 8); @@ -2397,7 +2397,7 @@ dict_stats_save( const index_id_t* only_for_index = NULL) { pars_info_t* pinfo; - lint now; + ib_time_t now; dberr_t ret; dict_table_t* table; char db_utf8[MAX_DB_UTF8_LEN]; @@ -2415,16 +2415,14 @@ dict_stats_save( dict_fs2utf8(table->name.m_name, db_utf8, sizeof(db_utf8), table_utf8, sizeof(table_utf8)); - /* MySQL's timestamp is 4 byte, so we use - pars_info_add_int4_literal() which takes a lint arg, so "now" is - lint */ - now = (lint) ut_time(); + + now = ut_time(); pinfo = pars_info_create(); pars_info_add_str_literal(pinfo, "database_name", db_utf8); pars_info_add_str_literal(pinfo, "table_name", table_utf8); - pars_info_add_int4_literal(pinfo, "last_update", now); + pars_info_add_int4_literal(pinfo, "last_update", (lint)now); pars_info_add_ull_literal(pinfo, "n_rows", table->stat_n_rows); pars_info_add_ull_literal(pinfo, "clustered_index_size", table->stat_clustered_index_size); @@ -3669,8 +3667,8 @@ dict_stats_rename_table( new_db_utf8, new_table_utf8, trx); mutex_exit(&dict_sys->mutex); /* fall through */ - case DB_DEADLOCK: case DB_LOCK_WAIT_TIMEOUT: + trx->error_state = DB_SUCCESS; os_thread_sleep(200000 /* 0.2 sec */); continue; case DB_STATS_DO_NOT_EXIST: @@ -3711,8 +3709,8 @@ dict_stats_rename_table( new_db_utf8, new_table_utf8, trx); mutex_exit(&dict_sys->mutex); /* fall through */ - case DB_DEADLOCK: case DB_LOCK_WAIT_TIMEOUT: + trx->error_state = DB_SUCCESS; os_thread_sleep(200000 /* 0.2 sec */); continue; case DB_STATS_DO_NOT_EXIST: diff --git a/storage/innobase/dict/dict0stats_bg.cc b/storage/innobase/dict/dict0stats_bg.cc index 0f76c73bc96..3f5419a0751 100644 --- a/storage/innobase/dict/dict0stats_bg.cc +++ b/storage/innobase/dict/dict0stats_bg.cc @@ -378,6 +378,7 @@ dict_stats_process_entry_from_recalc_pool(trx_t* trx) dict_stats_recalc_pool_add(table); } else { + trx->error_state = DB_SUCCESS; ++trx->will_lock; dict_stats_update(table, DICT_STATS_RECALC_PERSISTENT, trx); if (trx->state != TRX_STATE_NOT_STARTED) { diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index 3b496e3959f..24bdaf2c263 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -6160,51 +6160,6 @@ fil_delete_file( } } -/** -Iterate over all the spaces in the space list and fetch the -tablespace names. It will return a copy of the name that must be -freed by the caller using: delete[]. -@return DB_SUCCESS if all OK. */ -dberr_t -fil_get_space_names( -/*================*/ - space_name_list_t& space_name_list) - /*!< in/out: List to append to */ -{ - fil_space_t* space; - dberr_t err = DB_SUCCESS; - - mutex_enter(&fil_system->mutex); - - for (space = UT_LIST_GET_FIRST(fil_system->space_list); - space != NULL; - space = UT_LIST_GET_NEXT(space_list, space)) { - - if (space->purpose == FIL_TYPE_TABLESPACE) { - ulint len; - char* name; - - len = ::strlen(space->name); - name = UT_NEW_ARRAY_NOKEY(char, len + 1); - - if (name == 0) { - /* Caller to free elements allocated so far. */ - err = DB_OUT_OF_MEMORY; - break; - } - - memcpy(name, space->name, len); - name[len] = 0; - - space_name_list.push_back(name); - } - } - - mutex_exit(&fil_system->mutex); - - return(err); -} - /** Generate redo log for swapping two .ibd files @param[in] old_table old table @param[in] new_table new table diff --git a/storage/innobase/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc index 80303314d9f..2531a9fb5aa 100644 --- a/storage/innobase/fsp/fsp0fsp.cc +++ b/storage/innobase/fsp/fsp0fsp.cc @@ -2446,8 +2446,6 @@ fseg_alloc_free_page_low( ut_ad(mach_read_from_4(seg_inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE); ut_ad(!((page_offset(seg_inode) - FSEG_ARR_OFFSET) % FSEG_INODE_SIZE)); - ut_ad(space->purpose == FIL_TYPE_TEMPORARY - || space->purpose == FIL_TYPE_TABLESPACE); seg_id = mach_read_from_8(seg_inode + FSEG_ID); ut_ad(seg_id); diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index 32cd56e78eb..403f1d57b9d 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -7002,15 +7002,6 @@ fts_drop_orphaned_tables(void) que_t* graph; ib_vector_t* tables; ib_alloc_t* heap_alloc; - space_name_list_t space_name_list; - dberr_t error = DB_SUCCESS; - - /* Note: We have to free the memory after we are done with the list. */ - error = fil_get_space_names(space_name_list); - - if (error == DB_OUT_OF_MEMORY) { - ib::fatal() << "Out of memory"; - } heap = mem_heap_create(1024); heap_alloc = ib_heap_allocator_create(heap); @@ -7023,35 +7014,32 @@ fts_drop_orphaned_tables(void) users can't map them back to table names and this will create unnecessary clutter. */ - for (space_name_list_t::iterator it = space_name_list.begin(); - it != space_name_list.end(); - ++it) { - - fts_aux_table_t* fts_aux_table; + mutex_enter(&fil_system->mutex); - fts_aux_table = static_cast<fts_aux_table_t*>( - ib_vector_push(tables, NULL)); + for (fil_space_t* space = UT_LIST_GET_FIRST(fil_system->space_list); + space != NULL; + space = UT_LIST_GET_NEXT(space_list, space)) { - memset(fts_aux_table, 0x0, sizeof(*fts_aux_table)); - - if (!fts_is_aux_table_name(fts_aux_table, *it, strlen(*it))) { - ib_vector_pop(tables); - } else { - ulint len = strlen(*it); - - fts_aux_table->id = fil_space_get_id_by_name(*it); + if (space->purpose != FIL_TYPE_TABLESPACE) { + continue; + } - /* We got this list from fil0fil.cc. The tablespace - with this name must exist. */ - ut_a(fts_aux_table->id != ULINT_UNDEFINED); + fts_aux_table_t fts_aux_table; + memset(&fts_aux_table, 0x0, sizeof fts_aux_table); - fts_aux_table->name = static_cast<char*>( - mem_heap_dup(heap, *it, len + 1)); + size_t len = strlen(space->name); - fts_aux_table->name[len] = 0; + if (!fts_is_aux_table_name(&fts_aux_table, space->name, len)) { + continue; } + + fts_aux_table.id = space->id; + fts_aux_table.name = mem_heap_strdupl(heap, space->name, len); + ib_vector_push(tables, &fts_aux_table); } + mutex_exit(&fil_system->mutex); + trx = trx_allocate_for_background(); trx->op_info = "dropping orphaned FTS tables"; row_mysql_lock_data_dictionary(trx); @@ -7079,7 +7067,7 @@ fts_drop_orphaned_tables(void) "CLOSE c;"); for (;;) { - error = fts_eval_sql(trx, graph); + dberr_t error = fts_eval_sql(trx, graph); if (error == DB_SUCCESS) { fts_check_and_drop_orphaned_tables(trx, tables); @@ -7112,14 +7100,6 @@ fts_drop_orphaned_tables(void) if (heap != NULL) { mem_heap_free(heap); } - - /** Free the memory allocated to store the .ibd names. */ - for (space_name_list_t::iterator it = space_name_list.begin(); - it != space_name_list.end(); - ++it) { - - UT_DELETE_ARRAY(*it); - } } /**********************************************************************//** diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 1765e2957f8..49f3e1f055c 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -3742,6 +3742,16 @@ innobase_init( goto error; } +#ifdef WITH_WSREP + /* Currently, Galera does not support VATS lock schedule algorithm. */ + if (innodb_lock_schedule_algorithm == INNODB_LOCK_SCHEDULE_ALGORITHM_VATS + && global_system_variables.wsrep_on) { + ib::info() << "In Galera environment Variance-Aware-Transaction-Sheduling Algorithm" + " is not supported. Falling back to First-Come-First-Served order. "; + innodb_lock_schedule_algorithm = INNODB_LOCK_SCHEDULE_ALGORITHM_FCFS; + } +#endif /* WITH_WSREP */ + #ifndef HAVE_LZ4 if (innodb_compression_algorithm == PAGE_LZ4_ALGORITHM) { sql_print_error("InnoDB: innodb_compression_algorithm = %lu unsupported.\n" @@ -5133,7 +5143,7 @@ innobase_kill_query( wsrep_thd_is_BF(current_thd, FALSE)); } - if (!wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { + if (!wsrep_thd_is_BF(trx->mysql_thd, FALSE) && trx->abort_type != TRX_WSREP_ABORT) { lock_mutex_enter(); lock_mutex_taken = true; } @@ -6252,6 +6262,7 @@ no_such_table: } ut_ad(!trx->persistent_stats); ut_d(trx->persistent_stats = true); + trx->error_state = DB_SUCCESS; ++trx->will_lock; dict_stats_init(ib_table, trx); innobase_commit_low(trx); @@ -12983,6 +12994,7 @@ create_table_info_t::create_table_update_dict() innobase_copy_frm_flags_from_create_info(innobase_table, m_create_info); ++m_trx->will_lock; + m_trx->error_state = DB_SUCCESS; dict_stats_update(innobase_table, DICT_STATS_EMPTY_TABLE, m_trx); innobase_commit_low(m_trx); @@ -13742,6 +13754,7 @@ ha_innobase::rename_table( normalize_table_name(norm_from, from); normalize_table_name(norm_to, to); + trx->error_state = DB_SUCCESS; ++trx->will_lock; ret = dict_stats_rename_table(norm_from, norm_to, errstr, sizeof errstr, trx); @@ -20233,7 +20246,7 @@ static MYSQL_SYSVAR_ULONG(doublewrite_batch_size, srv_doublewrite_batch_size, #endif /* defined UNIV_DEBUG || defined UNIV_PERF_DEBUG */ static MYSQL_SYSVAR_ENUM(lock_schedule_algorithm, innodb_lock_schedule_algorithm, - PLUGIN_VAR_RQCMDARG, + PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, "The algorithm Innodb uses for deciding which locks to grant next when" " a lock is released. Possible values are" " FCFS" diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 0d9f906429f..7d4b15fc40e 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -9675,6 +9675,7 @@ foreign_fail: } row_mysql_unlock_data_dictionary(trx); + trx->error_state = DB_SUCCESS; ++trx->will_lock; /* TODO: The following code could be executed diff --git a/storage/innobase/include/dict0load.h b/storage/innobase/include/dict0load.h index 22fd27c2484..9ba42007568 100644 --- a/storage/innobase/include/dict0load.h +++ b/storage/innobase/include/dict0load.h @@ -193,8 +193,7 @@ dict_getnext_system( mtr_t* mtr); /*!< in: the mini-transaction */ /********************************************************************//** This function processes one SYS_TABLES record and populate the dict_table_t -struct for the table. Extracted out of dict_print() to be used by -both monitor table output and information schema innodb_sys_tables output. +struct for the table. @return error message, or NULL on success */ const char* dict_process_sys_tables_rec_and_mtr_commit( diff --git a/storage/innobase/include/dict0stats.h b/storage/innobase/include/dict0stats.h index 4a34b90195a..357d26b5557 100644 --- a/storage/innobase/include/dict0stats.h +++ b/storage/innobase/include/dict0stats.h @@ -212,7 +212,7 @@ storage. dberr_t dict_stats_save_index_stat( dict_index_t* index, - lint last_update, + ib_time_t last_update, const char* stat_name, ib_uint64_t stat_value, ib_uint64_t* sample_size, diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index 695c490ea94..72d00f97d75 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -35,16 +35,11 @@ Created 10/25/1995 Heikki Tuuri #include "page0size.h" #include "ibuf0types.h" -#include <list> -#include <vector> - // Forward declaration struct trx_t; class page_id_t; class truncate_t; -typedef std::list<char*, ut_allocator<char*> > space_name_list_t; - /** Structure containing encryption specification */ struct fil_space_crypt_t; @@ -1503,18 +1498,6 @@ ulint fil_space_get_id_by_name( const char* tablespace); -/** -Iterate over all the spaces in the space list and fetch the -tablespace names. It will return a copy of the name that must be -freed by the caller using: delete[]. -@return DB_SUCCESS if all OK. */ -dberr_t -fil_get_space_names( -/*================*/ - space_name_list_t& space_name_list) - /*!< in/out: Vector for collecting the names. */ - MY_ATTRIBUTE((warn_unused_result)); - /** Generate redo log for swapping two .ibd files @param[in] old_table old table @param[in] new_table new table diff --git a/storage/innobase/include/lock0priv.h b/storage/innobase/include/lock0priv.h index 6bb75817ad6..185779e476f 100644 --- a/storage/innobase/include/lock0priv.h +++ b/storage/innobase/include/lock0priv.h @@ -721,7 +721,7 @@ public: as a victim, and we got the lock immediately: no need to wait then */ dberr_t add_to_waitq( - const lock_t* wait_for, + lock_t* wait_for, const lock_prdt_t* prdt = NULL); @@ -731,21 +731,22 @@ public: @param[in] owns_trx_mutex true if caller owns the trx_t::mutex @param[in] add_to_hash add the lock to hash table @param[in] prdt Predicate lock (optional) + @param[in,out] c_lock Conflicting lock request or NULL + in Galera conflicting lock is selected + as deadlock victim if requester + is BF transaction. @return new lock instance */ lock_t* create( trx_t* trx, bool owns_trx_mutex, bool add_to_hash, const lock_prdt_t* - prdt = NULL); + prdt = NULL +#ifdef WITH_WSREP + ,lock_t* c_lock = NULL +#endif /* WITH_WSREP */ + ); - lock_t* create( - lock_t* const c_lock, - trx_t* trx, - bool owns_trx_mutex, - bool add_to_hash, - const lock_prdt_t* - prdt = NULL); /** Check of the lock is on m_rec_id. @param[in] lock Lock to compare with diff --git a/storage/innobase/include/os0once.h b/storage/innobase/include/os0once.h index 05a45a69f33..551e78d24ba 100644 --- a/storage/innobase/include/os0once.h +++ b/storage/innobase/include/os0once.h @@ -30,6 +30,7 @@ Created Feb 20, 2014 Vasil Dimov #include "univ.i" #include "ut0ut.h" +#include "my_cpu.h" /** Execute a given function exactly once in a multi-threaded environment or wait for the function to be executed by another thread. @@ -110,7 +111,7 @@ public: ut_error; } - UT_RELAX_CPU(); + MY_RELAX_CPU(); } } } diff --git a/storage/innobase/include/row0vers.h b/storage/innobase/include/row0vers.h index b28533578e1..576b53358f8 100644 --- a/storage/innobase/include/row0vers.h +++ b/storage/innobase/include/row0vers.h @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2017, 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 @@ -38,19 +39,18 @@ Created 2/6/1997 Heikki Tuuri // Forward declaration class ReadView; -/*****************************************************************//** -Finds out if an active transaction has inserted or modified a secondary +/** Determine if an active transaction has inserted or modified a secondary index record. -@return 0 if committed, else the active transaction id; -NOTE that this function can return false positives but never false -negatives. The caller must confirm all positive results by calling -trx_is_active() while holding lock_sys->mutex. */ +@param[in] rec secondary index record +@param[in] index secondary index +@param[in] offsets rec_get_offsets(rec, index) +@return the active transaction; trx_release_reference() must be invoked +@retval NULL if the record was committed */ trx_t* row_vers_impl_x_locked( -/*===================*/ - const rec_t* rec, /*!< in: record in a secondary index */ - dict_index_t* index, /*!< in: the secondary index */ - const ulint* offsets);/*!< in: rec_get_offsets(rec, index) */ + const rec_t* rec, + dict_index_t* index, + const ulint* offsets); /*****************************************************************//** Finds out if we must preserve a delete marked earlier version of a clustered diff --git a/storage/innobase/include/ut0ut.h b/storage/innobase/include/ut0ut.h index 7cca4fe875b..1614d3ead6d 100644 --- a/storage/innobase/include/ut0ut.h +++ b/storage/innobase/include/ut0ut.h @@ -53,39 +53,6 @@ Created 1/20/1994 Heikki Tuuri /** Time stamp */ typedef time_t ib_time_t; -#ifdef HAVE_PAUSE_INSTRUCTION - /* According to the gcc info page, asm volatile means that the - instruction has important side-effects and must not be removed. - Also asm volatile may trigger a memory barrier (spilling all registers - to memory). */ -# ifdef __SUNPRO_CC -# define UT_RELAX_CPU() asm ("pause" ) -# else -# define UT_RELAX_CPU() __asm__ __volatile__ ("pause") -# endif /* __SUNPRO_CC */ - -#elif defined(HAVE_FAKE_PAUSE_INSTRUCTION) -# define UT_RELAX_CPU() __asm__ __volatile__ ("rep; nop") -#elif defined _WIN32 - /* In the Win32 API, the x86 PAUSE instruction is executed by calling - the YieldProcessor macro defined in WinNT.h. It is a CPU architecture- - independent way by using YieldProcessor. */ -# define UT_RELAX_CPU() YieldProcessor() -#elif defined(__powerpc__) && defined __GLIBC__ -# include <sys/platform/ppc.h> -# define UT_RELAX_CPU() __ppc_get_timebase() -#else -static inline void UT_RELAX_CPU(void) -{ - volatile int32 var; - int32 oldval = 0; - my_atomic_cas32_strong_explicit( - &var, &oldval, 1, - MY_MEMORY_ORDER_RELAXED, - MY_MEMORY_ORDER_RELAXED); -} -#endif - #if defined (__GNUC__) # define UT_COMPILER_BARRIER() __asm__ __volatile__ ("":::"memory") #elif defined (_MSC_VER) diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index fe943f8e5c6..97bacebaf24 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -818,13 +818,18 @@ lock_reset_lock_and_trx_wait( } ib::error() << - "Trx id " << lock->trx->id - << " is waiting a lock in statement " - << (stmt ? stmt : "NULL") - << " for this trx id " << trx_id - << " and statement " - << (stmt2 ? stmt2 : "NULL") - << "wait_lock " << lock->trx->lock.wait_lock; + "Trx id " << ib::hex(lock->trx->id) + << " is waiting a lock " + << " for this trx id " << ib::hex(trx_id) + << " wait_lock " << lock->trx->lock.wait_lock; + if (stmt) { + ib::info() << " SQL1: " << stmt; + } + + if (stmt2) { + ib::info() << " SQL2: " << stmt2; + } + ut_ad(0); } @@ -1323,7 +1328,7 @@ lock_rec_has_expl( Checks if some other transaction has a lock request in the queue. @return lock or NULL */ static -const lock_t* +lock_t* lock_rec_other_has_expl_req( /*========================*/ lock_mode mode, /*!< in: LOCK_S or LOCK_X */ @@ -1346,10 +1351,10 @@ lock_rec_other_has_expl_req( return(NULL); } - for (const lock_t* lock = lock_rec_get_first(lock_sys->rec_hash, + for (lock_t* lock = lock_rec_get_first(lock_sys->rec_hash, block, heap_no); lock != NULL; - lock = lock_rec_get_next_const(heap_no, lock)) { + lock = lock_rec_get_next(heap_no, lock)) { if (lock->trx != trx && !lock_rec_get_gap(lock) @@ -1438,7 +1443,7 @@ Checks if some other transaction has a conflicting explicit lock request in the queue, so that we have to wait. @return lock or NULL */ static -const lock_t* +lock_t* lock_rec_other_has_conflicting( /*===========================*/ ulint mode, /*!< in: LOCK_S or LOCK_X, @@ -1450,7 +1455,7 @@ lock_rec_other_has_conflicting( ulint heap_no,/*!< in: heap number of the record */ const trx_t* trx) /*!< in: our transaction */ { - const lock_t* lock; + lock_t* lock; ut_ad(lock_mutex_own()); @@ -1458,13 +1463,16 @@ lock_rec_other_has_conflicting( for (lock = lock_rec_get_first(lock_sys->rec_hash, block, heap_no); lock != NULL; - lock = lock_rec_get_next_const(heap_no, lock)) { + lock = lock_rec_get_next(heap_no, lock)) { if (lock_rec_has_to_wait(true, trx, mode, lock, is_supremum)) { #ifdef WITH_WSREP if (wsrep_on_trx(trx)) { trx_mutex_enter(lock->trx); - wsrep_kill_victim((trx_t *)trx, (lock_t *)lock); + /* Below function will roll back either trx + or lock->trx depending on priority of the + transaction. */ + wsrep_kill_victim(const_cast<trx_t*>(trx), lock); trx_mutex_exit(lock->trx); } #endif /* WITH_WSREP */ @@ -1957,19 +1965,21 @@ Create a new lock. @param[in] owns_trx_mutex true if caller owns the trx_t::mutex @param[in] add_to_hash add the lock to hash table @param[in] prdt Predicate lock (optional) +@param[in,out] c_lock Conflicting lock request or NULL + in Galera conflicting lock is selected + as deadlock victim if requester + is BF transaction. @return a new lock instance */ lock_t* -RecLock::create(trx_t* trx, bool owns_trx_mutex, bool add_to_hash, const lock_prdt_t* prdt) -{ - return create(NULL, trx, owns_trx_mutex, add_to_hash, prdt); -} -lock_t* RecLock::create( - lock_t* const c_lock, trx_t* trx, bool owns_trx_mutex, bool add_to_hash, - const lock_prdt_t* prdt) + const lock_prdt_t* prdt +#ifdef WITH_WSREP + ,lock_t* c_lock +#endif /* WITH_WSREP */ +) { ut_ad(lock_mutex_own()); ut_ad(owns_trx_mutex == trx_mutex_own(trx)); @@ -2055,7 +2065,7 @@ RecLock::create( trx_mutex_exit(c_lock->trx); if (wsrep_debug) { - ib::info() << "WSREP: c_lock canceled " << c_lock->trx->id; + ib::info() << "WSREP: c_lock canceled " << ib::hex(c_lock->trx->id); ib::info() << " SQL1: " << wsrep_thd_query(c_lock->trx->mysql_thd); ib::info() << " SQL2: " @@ -2192,8 +2202,8 @@ RecLock::mark_trx_for_rollback(trx_t* trx) if (thd != NULL) { char buffer[1024]; - ib::info() << "Blocking transaction: ID: " << trx->id << " - " - << " Blocked transaction ID: "<< m_trx->id << " - " + ib::info() << "Blocking transaction: ID: " << ib::hex(trx->id) << " - " + << " Blocked transaction ID: "<< ib::hex(m_trx->id) << " - " << thd_get_error_context_description(thd, buffer, sizeof(buffer), 512); } @@ -2234,7 +2244,7 @@ queue is itself waiting roll it back, also do a deadlock check and resolve. as a victim, and we got the lock immediately: no need to wait then; DB_LOCK_WAIT_TIMEOUT means no need to wait */ dberr_t -RecLock::add_to_waitq(const lock_t* wait_for, const lock_prdt_t* prdt) +RecLock::add_to_waitq(lock_t* wait_for, const lock_prdt_t* prdt) { ut_ad(lock_mutex_own()); ut_ad(m_trx == thr_get_trx(m_thr)); @@ -2274,7 +2284,12 @@ RecLock::add_to_waitq(const lock_t* wait_for, const lock_prdt_t* prdt) bool high_priority = trx_is_high_priority(m_trx); /* Don't queue the lock to hash table, if high priority transaction. */ - lock_t* lock = create(m_trx, true, !high_priority, prdt); + lock_t* lock = create( + m_trx, true, !high_priority, prdt +#ifdef WITH_WSREP + ,wait_for +#endif /* WITH_WSREP */ + ); /* Attempt to jump over the low priority waiting locks. */ if (high_priority && jump_queue(lock, wait_for)) { @@ -2283,10 +2298,18 @@ RecLock::add_to_waitq(const lock_t* wait_for, const lock_prdt_t* prdt) return(DB_SUCCESS); } +#ifdef WITH_WSREP + if (!lock_get_wait(lock) && wsrep_thd_is_BF(m_trx->mysql_thd, FALSE)) { + if (wsrep_debug) { + ib::info() << "WSREP: BF thread got lock granted early, ID " << ib::hex(lock->trx->id) + << " query: " << wsrep_thd_query(m_trx->mysql_thd); + } + return(DB_SUCCESS); + } +#endif /* WITH_WSREP */ ut_ad(lock_get_wait(lock)); - dberr_t err = deadlock_check(lock); - + dberr_t err = deadlock_check(lock); ut_ad(trx_mutex_own(m_trx)); // Move it only when it does not cause a deadlock. @@ -2568,8 +2591,7 @@ lock_rec_lock_slow( err = DB_SUCCESS; } else { - - const lock_t* wait_for = lock_rec_other_has_conflicting( + lock_t* wait_for = lock_rec_other_has_conflicting( mode, block, heap_no, trx); if (wait_for != NULL) { @@ -2699,6 +2721,14 @@ lock_rec_has_to_wait_in_queue( #ifdef WITH_WSREP if (wsrep_thd_is_BF(wait_lock->trx->mysql_thd, FALSE) && wsrep_thd_is_BF(lock->trx->mysql_thd, TRUE)) { + if (wsrep_debug) { + ib::info() << "WSREP: waiting BF trx: " << ib::hex(wait_lock->trx->id) + << " query: " << wsrep_thd_query(wait_lock->trx->mysql_thd); + lock_rec_print(stderr, wait_lock); + ib::info() << "WSREP: do not wait another BF trx: " << ib::hex(lock->trx->id) + << " query: " << wsrep_thd_query(lock->trx->mysql_thd); + lock_rec_print(stderr, lock); + } /* don't wait for another BF lock */ continue; } @@ -2801,8 +2831,8 @@ RecLock::jump_queue( DBUG_LOG("trx", "Granting High Priority Transaction " - << lock->trx->id << " a lock jumping over" - << " waiting Transaction " << conflict_lock->trx->id); + << ib::hex(lock->trx->id) << " a lock jumping over" + << " waiting Transaction " << ib::hex(conflict_lock->trx->id)); lock_reset_lock_and_trx_wait(lock); return(true); @@ -2973,9 +3003,9 @@ RecLock::make_trx_hit_list( ut_ad(trx->lock.wait_lock != next); DBUG_LOG("trx", "High Priority Transaction " - << lock->trx->id + << ib::hex(lock->trx->id) << " waking up blocking transaction " - << trx->id); + << ib::hex(trx->id)); trx->lock.was_chosen_as_deadlock_victim = true; lock_cancel_waiting_and_release(trx->lock.wait_lock); @@ -3065,22 +3095,21 @@ lock_grant_and_move_on_page( && lock_get_wait(lock) && !lock_rec_has_to_wait_in_queue(lock)) { - bool exit_trx_mutex = false; - + if (lock->trx->abort_type != TRX_SERVER_ABORT) { ut_ad(trx_mutex_own(lock->trx)); trx_mutex_exit(lock->trx); exit_trx_mutex = true; } - + lock_grant(lock, false); - + if (exit_trx_mutex) { ut_ad(!trx_mutex_own(lock->trx)); trx_mutex_enter(lock->trx); } - + if (previous != NULL) { /* Move the lock to the head of the list. */ HASH_GET_NEXT(hash, previous) = HASH_GET_NEXT(hash, lock); @@ -3176,9 +3205,9 @@ lock_rec_dequeue_from_page( } } } - } else { - lock_grant_and_move_on_page(lock_hash, space, page_no); - } + } else { + lock_grant_and_move_on_page(lock_hash, space, page_no); + } } /*************************************************************//** @@ -4428,7 +4457,7 @@ lock_table_create( ut_list_insert(table->locks, c_lock, lock, TableLockGetNode()); if (wsrep_debug) { ib::info() << "table lock BF conflict for " << - c_lock->trx->id; + ib::hex(c_lock->trx->id); ib::info() << " SQL: " << wsrep_thd_query(c_lock->trx->mysql_thd); } @@ -4464,7 +4493,7 @@ lock_table_create( } if (wsrep_debug) { - ib::info() << "WSREP: c_lock canceled " << c_lock->trx->id; + ib::info() << "WSREP: c_lock canceled " << ib::hex(c_lock->trx->id); ib::info() << " SQL: " << wsrep_thd_query(c_lock->trx->mysql_thd); } @@ -4736,7 +4765,7 @@ Checks if other transactions have an incompatible mode lock request in the lock queue. @return lock or NULL */ UNIV_INLINE -const lock_t* +lock_t* lock_table_other_has_incompatible( /*==============================*/ const trx_t* trx, /*!< in: transaction, or NULL if all @@ -4747,7 +4776,7 @@ lock_table_other_has_incompatible( const dict_table_t* table, /*!< in: table */ lock_mode mode) /*!< in: lock mode */ { - const lock_t* lock; + lock_t* lock; ut_ad(lock_mutex_own()); @@ -4796,7 +4825,7 @@ lock_table( { trx_t* trx; dberr_t err; - const lock_t* wait_for; + lock_t* wait_for; ut_ad(table && thr); @@ -4852,9 +4881,9 @@ lock_table( mode: this trx may have to wait */ if (wait_for != NULL) { - err = lock_table_enqueue_waiting((lock_t*)wait_for, mode | flags, table, thr); + err = lock_table_enqueue_waiting(wait_for, mode | flags, table, thr); } else { - lock_table_create(table, mode | flags, trx); + lock_table_create(wait_for, table, mode | flags, trx); ut_a(!flags || mode == LOCK_S || mode == LOCK_X); @@ -6789,7 +6818,7 @@ lock_rec_insert_check_and_lock( const ulint type_mode = LOCK_X | LOCK_GAP | LOCK_INSERT_INTENTION; - const lock_t* wait_for = lock_rec_other_has_conflicting( + lock_t* wait_for = lock_rec_other_has_conflicting( type_mode, block, heap_no, trx); if (wait_for != NULL) { @@ -8543,16 +8572,7 @@ DeadlockChecker::check_and_resolve(const lock_t* lock, trx_t* trx) ut_ad(trx == checker.m_start); ut_ad(trx == victim_trx); -#ifdef WITH_WSREP - if (!wsrep_thd_is_BF(victim_trx->mysql_thd, TRUE)) - { -#endif /* WITH_WSREP */ - rollback_print(victim_trx, lock); -#ifdef WITH_WSREP - } else { - /* BF processor */; - } -#endif /* WITH_WSREP */ + rollback_print(victim_trx, lock); MONITOR_INC(MONITOR_DEADLOCK); diff --git a/storage/innobase/lock/lock0prdt.cc b/storage/innobase/lock/lock0prdt.cc index 88573b8a71a..dc2c6e2d15e 100644 --- a/storage/innobase/lock/lock0prdt.cc +++ b/storage/innobase/lock/lock0prdt.cc @@ -290,7 +290,7 @@ Checks if some other transaction has a conflicting predicate lock request in the queue, so that we have to wait. @return lock or NULL */ static -const lock_t* +lock_t* lock_prdt_other_has_conflicting( /*============================*/ ulint mode, /*!< in: LOCK_S or LOCK_X, @@ -305,10 +305,10 @@ lock_prdt_other_has_conflicting( { ut_ad(lock_mutex_own()); - for (const lock_t* lock = lock_rec_get_first( + for (lock_t* lock = lock_rec_get_first( lock_hash_get(mode), block, PRDT_HEAPNO); lock != NULL; - lock = lock_rec_get_next_const(PRDT_HEAPNO, lock)) { + lock = lock_rec_get_next(PRDT_HEAPNO, lock)) { if (lock->trx == trx) { continue; @@ -565,7 +565,7 @@ lock_prdt_insert_check_and_lock( const ulint mode = LOCK_X | LOCK_PREDICATE | LOCK_INSERT_INTENTION; - const lock_t* wait_for = lock_prdt_other_has_conflicting( + lock_t* wait_for = lock_prdt_other_has_conflicting( mode, block, prdt, trx); if (wait_for != NULL) { @@ -854,7 +854,7 @@ lock_prdt_lock( if (lock == NULL) { - const lock_t* wait_for; + lock_t* wait_for; wait_for = lock_prdt_other_has_conflicting( prdt_mode, block, prdt, trx); diff --git a/storage/innobase/lock/lock0wait.cc b/storage/innobase/lock/lock0wait.cc index 0ed55558dc4..c41821412af 100644 --- a/storage/innobase/lock/lock0wait.cc +++ b/storage/innobase/lock/lock0wait.cc @@ -183,20 +183,38 @@ lock_wait_table_reserve_slot( /*********************************************************************//** check if lock timeout was for priority thread, as a side effect trigger lock monitor +@param[in] trx transaction owning the lock +@param[in] locked true if trx and lock_sys_mutex is ownd @return false for regular lock timeout */ -static ibool +static +bool wsrep_is_BF_lock_timeout( -/*====================*/ - trx_t* trx) /* in: trx to check for lock priority */ + const trx_t* trx, + bool locked = true) { - if (wsrep_on_trx(trx) && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { - fprintf(stderr, "WSREP: BF lock wait long\n"); + if (wsrep_on_trx(trx) + && wsrep_thd_is_BF(trx->mysql_thd, FALSE) + && trx->error_state != DB_DEADLOCK) { + ib::info() << "WSREP: BF lock wait long for trx:" << ib::hex(trx->id) + << " query: " << wsrep_thd_query(trx->mysql_thd); + if (!locked) { + lock_mutex_enter(); + } + + ut_ad(lock_mutex_own()); + + wsrep_trx_print_locking(stderr, trx, 3000); + + if (!locked) { + lock_mutex_exit(); + } + srv_print_innodb_monitor = TRUE; srv_print_innodb_lock_monitor = TRUE; os_event_set(srv_monitor_event); - return TRUE; + return true; } - return FALSE; + return false; } #endif /* WITH_WSREP */ @@ -399,7 +417,7 @@ lock_wait_suspend_thread( && wait_time > (double) lock_wait_timeout #ifdef WITH_WSREP && (!wsrep_on_trx(trx) || - (!wsrep_is_BF_lock_timeout(trx) && trx->error_state != DB_DEADLOCK)) + (!wsrep_is_BF_lock_timeout(trx, false) && trx->error_state != DB_DEADLOCK)) #endif /* WITH_WSREP */ && !trx_is_high_priority(trx)) { diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index e3c63d8923a..119d909dd8d 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -93,27 +93,6 @@ static ib_mutex_t row_drop_list_mutex; /** Flag: has row_mysql_drop_list been initialized? */ static ibool row_mysql_drop_list_inited = FALSE; -/** Magic table names for invoking various monitor threads */ -/* @{ */ -static const char S_innodb_monitor[] = "innodb_monitor"; -static const char S_innodb_lock_monitor[] = "innodb_lock_monitor"; -static const char S_innodb_tablespace_monitor[] = "innodb_tablespace_monitor"; -static const char S_innodb_table_monitor[] = "innodb_table_monitor"; -#ifdef UNIV_MEM_DEBUG -static const char S_innodb_mem_validate[] = "innodb_mem_validate"; -#endif /* UNIV_MEM_DEBUG */ -/* @} */ - -/** Evaluates to true if str1 equals str2_onstack, used for comparing -the magic table names. -@param str1 in: string to compare -@param str1_len in: length of str1, in bytes, including terminating NUL -@param str2_onstack in: char[] array containing a NUL terminated string -@return TRUE if str1 equals str2_onstack */ -#define STR_EQ(str1, str1_len, str2_onstack) \ - ((str1_len) == sizeof(str2_onstack) \ - && memcmp(str1, str2_onstack, sizeof(str2_onstack)) == 0) - /*******************************************************************//** Determine if the given name is a name reserved for MySQL system tables. @return TRUE if name is a MySQL system table name */ @@ -5140,31 +5119,6 @@ not_ok: goto loop; } -/*********************************************************************//** -Determines if a table is a magic monitor table. -@return true if monitor table */ -UNIV_INTERN -bool -row_is_magic_monitor_table( -/*=======================*/ - const char* table_name) /*!< in: name of the table, in the - form database/table_name */ -{ - const char* name; /* table_name without database/ */ - ulint len; - - name = dict_remove_db_name(table_name); - len = strlen(name) + 1; - - return(STR_EQ(name, len, S_innodb_monitor) - || STR_EQ(name, len, S_innodb_lock_monitor) - || STR_EQ(name, len, S_innodb_tablespace_monitor) - || STR_EQ(name, len, S_innodb_table_monitor) -#ifdef UNIV_MEM_DEBUG - || STR_EQ(name, len, S_innodb_mem_validate) -#endif /* UNIV_MEM_DEBUG */ - ); -} /*********************************************************************//** Initialize this module */ diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc index 11823087f1f..db76a354f03 100644 --- a/storage/innobase/row/row0sel.cc +++ b/storage/innobase/row/row0sel.cc @@ -4952,9 +4952,44 @@ wrong_offs: ulint lock_type; + if (srv_locks_unsafe_for_binlog + || trx->isolation_level <= TRX_ISO_READ_COMMITTED) { + /* At READ COMMITTED or READ UNCOMMITTED + isolation levels, do not lock committed + delete-marked records. */ + if (!rec_get_deleted_flag(rec, comp)) { + goto no_gap_lock; + } + if (index == clust_index) { + trx_id_t trx_id = row_get_rec_trx_id( + rec, index, offsets); + /* In delete-marked records, DB_TRX_ID must + always refer to an existing undo log record. */ + ut_ad(trx_id); + if (!trx_rw_is_active(trx_id, NULL, false)) { + /* The clustered index record + was delete-marked in a committed + transaction. Ignore the record. */ + goto locks_ok_del_marked; + } + } else if (trx_t* trx = row_vers_impl_x_locked( + rec, index, offsets)) { + /* The record belongs to an active + transaction. We must acquire a lock. */ + trx_release_reference(trx); + } else { + /* The secondary index record does not + point to a delete-marked clustered index + record that belongs to an active transaction. + Ignore the secondary index record, because + it is not locked. */ + goto next_rec; + } + + goto no_gap_lock; + } + if (!set_also_gap_locks - || srv_locks_unsafe_for_binlog - || trx->isolation_level <= TRX_ISO_READ_COMMITTED || (unique_search && !rec_get_deleted_flag(rec, comp)) || dict_index_is_spatial(index)) { @@ -5159,6 +5194,7 @@ locks_ok: page_rec_is_comp() cannot be used! */ if (rec_get_deleted_flag(rec, comp)) { +locks_ok_del_marked: /* In delete-marked records, DB_TRX_ID must always refer to an existing undo log record. */ ut_ad(index != clust_index @@ -5166,17 +5202,6 @@ locks_ok: /* The record is delete-marked: we can skip it */ - if ((srv_locks_unsafe_for_binlog - || trx->isolation_level <= TRX_ISO_READ_COMMITTED) - && prebuilt->select_lock_type != LOCK_NONE - && !did_semi_consistent_read) { - - /* No need to keep a lock on a delete-marked record - if we do not want to use next-key locking. */ - - row_unlock_for_mysql(prebuilt, TRUE); - } - /* This is an optimization to skip setting the next key lock on the record that follows this delete-marked record. This optimization works because of the unique search criteria diff --git a/storage/innobase/row/row0vers.cc b/storage/innobase/row/row0vers.cc index 8c9919511ad..712c46cba35 100644 --- a/storage/innobase/row/row0vers.cc +++ b/storage/innobase/row/row0vers.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, MariaDB Corporation +Copyright (c) 2017, 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 @@ -63,23 +63,25 @@ row_vers_non_vc_match( const dtuple_t* ientry, mem_heap_t* heap, ulint* n_non_v_col); -/*****************************************************************//** -Finds out if an active transaction has inserted or modified a secondary +/** Determine if an active transaction has inserted or modified a secondary index record. -@return 0 if committed, else the active transaction id; -NOTE that this function can return false positives but never false -negatives. The caller must confirm all positive results by calling -trx_is_active() while holding lock_sys->mutex. */ +@param[in] clust_rec clustered index record +@param[in] clust_index clustered index +@param[in] rec secondary index record +@param[in] index secondary index +@param[in] offsets rec_get_offsets(rec, index) +@param[in,out] mtr mini-transaction +@return the active transaction; trx_release_reference() must be invoked +@retval NULL if the record was committed */ UNIV_INLINE trx_t* row_vers_impl_x_locked_low( -/*=======================*/ - const rec_t* clust_rec, /*!< in: clustered index record */ - dict_index_t* clust_index, /*!< in: the clustered index */ - const rec_t* rec, /*!< in: secondary index record */ - dict_index_t* index, /*!< in: the secondary index */ - const ulint* offsets, /*!< in: rec_get_offsets(rec, index) */ - mtr_t* mtr) /*!< in/out: mini-transaction */ + const rec_t* clust_rec, + dict_index_t* clust_index, + const rec_t* rec, + dict_index_t* index, + const ulint* offsets, + mtr_t* mtr) { trx_id_t trx_id; ibool corrupt; @@ -338,19 +340,18 @@ result_check: DBUG_RETURN(trx); } -/*****************************************************************//** -Finds out if an active transaction has inserted or modified a secondary +/** Determine if an active transaction has inserted or modified a secondary index record. -@return 0 if committed, else the active transaction id; -NOTE that this function can return false positives but never false -negatives. The caller must confirm all positive results by calling -trx_is_active() while holding lock_sys->mutex. */ +@param[in] rec secondary index record +@param[in] index secondary index +@param[in] offsets rec_get_offsets(rec, index) +@return the active transaction; trx_release_reference() must be invoked +@retval NULL if the record was committed */ trx_t* row_vers_impl_x_locked( -/*===================*/ - const rec_t* rec, /*!< in: record in a secondary index */ - dict_index_t* index, /*!< in: the secondary index */ - const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */ + const rec_t* rec, + dict_index_t* index, + const ulint* offsets) { mtr_t mtr; trx_t* trx; diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc index 5d43563dffb..c2a56a808e9 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -437,8 +437,6 @@ stderr on startup/shutdown. Not enabled on the embedded server. */ ibool srv_print_verbose_log; my_bool srv_print_innodb_monitor; my_bool srv_print_innodb_lock_monitor; -my_bool srv_print_innodb_tablespace_monitor; -my_bool srv_print_innodb_table_monitor; /** innodb_force_primary_key; whether to disallow CREATE TABLE without PRIMARY KEY */ my_bool srv_force_primary_key; @@ -1691,8 +1689,6 @@ DECLARE_THREAD(srv_monitor_thread)(void*) double time_elapsed; time_t current_time; time_t last_monitor_time; - time_t last_table_monitor_time; - time_t last_tablespace_monitor_time; ulint mutex_skipped; ibool last_srv_print_monitor; @@ -1708,8 +1704,6 @@ DECLARE_THREAD(srv_monitor_thread)(void*) #endif /* UNIV_PFS_THREAD */ srv_last_monitor_time = ut_time(); - last_table_monitor_time = ut_time(); - last_tablespace_monitor_time = ut_time(); last_monitor_time = ut_time(); mutex_skipped = 0; last_srv_print_monitor = srv_print_innodb_monitor; @@ -1769,60 +1763,6 @@ loop: os_file_set_eof(srv_monitor_file); mutex_exit(&srv_monitor_file_mutex); } - - if (srv_print_innodb_tablespace_monitor - && difftime(current_time, - last_tablespace_monitor_time) > 60) { - last_tablespace_monitor_time = ut_time(); - - fputs("========================" - "========================\n", - stderr); - - ut_print_timestamp(stderr); - - fputs(" INNODB TABLESPACE MONITOR OUTPUT\n" - "========================" - "========================\n", - stderr); - - // JAN: TODO: MySQL 5.7 - //fsp_print(0); - //fputs("Validating tablespace\n", stderr); - //fsp_validate(0); - fputs("Validation ok\n" - "---------------------------------------\n" - "END OF INNODB TABLESPACE MONITOR OUTPUT\n" - "=======================================\n", - stderr); - } - - if (srv_print_innodb_table_monitor - && difftime(current_time, last_table_monitor_time) > 60) { - - last_table_monitor_time = ut_time(); - - // fprintf(stderr, "Warning: %s\n", - // DEPRECATED_MSG_INNODB_TABLE_MONITOR); - - fputs("===========================================\n", - stderr); - - ut_print_timestamp(stderr); - - fputs(" INNODB TABLE MONITOR OUTPUT\n" - "===========================================\n", - stderr); - // dict_print(); - - fputs("-----------------------------------\n" - "END OF INNODB TABLE MONITOR OUTPUT\n" - "==================================\n", - stderr); - - //fprintf(stderr, "Warning: %s\n", - // DEPRECATED_MSG_INNODB_TABLE_MONITOR); - } } if (srv_shutdown_state != SRV_SHUTDOWN_NONE) { @@ -1830,9 +1770,7 @@ loop: } if (srv_print_innodb_monitor - || srv_print_innodb_lock_monitor - || srv_print_innodb_tablespace_monitor - || srv_print_innodb_table_monitor) { + || srv_print_innodb_lock_monitor) { goto loop; } diff --git a/storage/innobase/ut/ut0ut.cc b/storage/innobase/ut/ut0ut.cc index 91c1934f065..25705cb0e2c 100644 --- a/storage/innobase/ut/ut0ut.cc +++ b/storage/innobase/ut/ut0ut.cc @@ -294,7 +294,7 @@ ut_delay( HMT_low(); for (i = 0; i < delay * 50; i++) { - UT_RELAX_CPU(); + MY_RELAX_CPU(); UT_COMPILER_BARRIER(); } diff --git a/storage/maria/lockman.c b/storage/maria/lockman.c index efdf7e1c4b8..fa0a3289106 100644 --- a/storage/maria/lockman.c +++ b/storage/maria/lockman.c @@ -268,7 +268,7 @@ retry: do { cursor->curr= PTR(*cursor->prev); lf_pin(pins, 1, cursor->curr); - } while(*cursor->prev != (intptr)cursor->curr && LF_BACKOFF); + } while(*cursor->prev != (intptr)cursor->curr && LF_BACKOFF()); for (;;) { if (!cursor->curr) @@ -277,7 +277,7 @@ retry: cur_link= cursor->curr->link; cursor->next= PTR(cur_link); lf_pin(pins, 0, cursor->next); - } while (cur_link != cursor->curr->link && LF_BACKOFF); + } while (cur_link != cursor->curr->link && LF_BACKOFF()); cur_hashnr= cursor->curr->hashnr; cur_resource= cursor->curr->resource; cur_lock= cursor->curr->lock; @@ -285,7 +285,7 @@ retry: cur_flags= cursor->curr->flags; if (*cursor->prev != (intptr)cursor->curr) { - (void)LF_BACKOFF; + (void)LF_BACKOFF(); goto retry; } if (!DELETED(cur_link)) @@ -362,7 +362,7 @@ retry: lf_alloc_free(pins, cursor->curr); else { - (void)LF_BACKOFF; + (void)LF_BACKOFF(); goto retry; } } diff --git a/storage/rocksdb/ha_rocksdb.cc b/storage/rocksdb/ha_rocksdb.cc index 44f234f371a..a9462c6e863 100644 --- a/storage/rocksdb/ha_rocksdb.cc +++ b/storage/rocksdb/ha_rocksdb.cc @@ -111,6 +111,10 @@ bool thd_binlog_filter_ok(const MYSQL_THD thd); MYSQL_PLUGIN_IMPORT bool my_disable_leak_check; +// Needed in rocksdb_init_func +void ignore_db_dirs_append(const char *dirname_arg); + + namespace myrocks { static st_global_stats global_stats; @@ -1446,7 +1450,7 @@ static MYSQL_SYSVAR_UINT( static MYSQL_SYSVAR_STR(datadir, rocksdb_datadir, PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY, "RocksDB data directory", nullptr, nullptr, - "./.rocksdb"); + "./#rocksdb"); static MYSQL_SYSVAR_STR(supported_compression_types, compression_types_val, @@ -3934,6 +3938,7 @@ static rocksdb::Status check_rocksdb_options_compatibility( return status; } + /* Storage Engine initialization function, invoked when plugin is loaded. */ @@ -3962,6 +3967,11 @@ static int rocksdb_init_func(void *const p) { mysql_mutex_init(rdb_mem_cmp_space_mutex_key, &rdb_mem_cmp_space_mutex, MY_MUTEX_INIT_FAST); + const char* initial_rocksdb_datadir_for_ignore_dirs= rocksdb_datadir; + if (!strncmp(rocksdb_datadir, "./", 2)) + initial_rocksdb_datadir_for_ignore_dirs += 2; + ignore_db_dirs_append(initial_rocksdb_datadir_for_ignore_dirs); + #if defined(HAVE_PSI_INTERFACE) rdb_collation_exceptions = new Regex_list_handler(key_rwlock_collation_exception_list); @@ -5954,6 +5964,19 @@ rdb_is_index_collation_supported(const my_core::Field *const field) { return true; } + +static bool +rdb_field_uses_nopad_collation(const my_core::Field *const field) { + const my_core::enum_field_types type = field->real_type(); + /* Handle [VAR](CHAR|BINARY) or TEXT|BLOB */ + if (type == MYSQL_TYPE_VARCHAR || type == MYSQL_TYPE_STRING || + type == MYSQL_TYPE_BLOB) { + return (field->charset()->state & MY_CS_NOPAD); + } + return false; +} + + /* Create structures needed for storing data in rocksdb. This is called when the table is created. The structures will be shared by all TABLE* objects. @@ -6062,8 +6085,7 @@ int ha_rocksdb::create_cfs( for (uint i = 0; i < tbl_def_arg->m_key_count; i++) { rocksdb::ColumnFamilyHandle *cf_handle; - if (rocksdb_strict_collation_check && - !is_hidden_pk(i, table_arg, tbl_def_arg) && + if (!is_hidden_pk(i, table_arg, tbl_def_arg) && tbl_def_arg->base_tablename().find(tmp_file_prefix) != 0) { if (!tsys_set) { @@ -6075,7 +6097,16 @@ int ha_rocksdb::create_cfs( for (uint part = 0; part < table_arg->key_info[i].ext_key_parts; part++) { - if (!rdb_is_index_collation_supported( + /* MariaDB: disallow NOPAD collations */ + if (rdb_field_uses_nopad_collation( + table_arg->key_info[i].key_part[part].field)) + { + my_error(ER_MYROCKS_CANT_NOPAD_COLLATION, MYF(0)); + DBUG_RETURN(HA_EXIT_FAILURE); + } + + if (rocksdb_strict_collation_check && + !rdb_is_index_collation_supported( table_arg->key_info[i].key_part[part].field) && !rdb_collation_exceptions->matches(tablename_sys)) { std::string collation_err; diff --git a/storage/rocksdb/mysql-test/rocksdb/r/2pc_group_commit.result b/storage/rocksdb/mysql-test/rocksdb/r/2pc_group_commit.result index a9e80f1562e..ac546a284fc 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/2pc_group_commit.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/2pc_group_commit.result @@ -14,16 +14,16 @@ SET GLOBAL rocksdb_flush_log_at_trx_commit=1; select variable_value into @b1 from information_schema.global_status where variable_name='Binlog_commits'; select variable_value into @b2 from information_schema.global_status where variable_name='Binlog_group_commits'; select variable_value into @b3 from information_schema.global_status where variable_name='Rocksdb_wal_synced'; -select IF(variable_value - @b1 = 1000, 'OK', 'FAIL') as Binlog_commits +select IF(variable_value - @b1 = 1000, 'OK', variable_value - @b1 = 1000) as Binlog_commits from information_schema.global_status where variable_name='Binlog_commits'; Binlog_commits OK -select IF(variable_value - @b2 = 1000, 'OK', 'FAIL') as Binlog_group_commits +select IF(variable_value - @b2 = 1000, 'OK', variable_value - @b2 = 1000) as Binlog_group_commits from information_schema.global_status where variable_name='Binlog_group_commits'; Binlog_group_commits OK # Prepare operations sync, commits don't. We expect slightly more than 1K syncs: -select IF(variable_value - @b3 between 1000 and 1500, 'OK', 'FAIL') as Rocksdb_wal_synced +select IF(variable_value - @b3 between 1000 and 1500, 'OK', variable_value - @b3 between 1000 and 1500) as Rocksdb_wal_synced from information_schema.global_status where variable_name='Rocksdb_wal_synced'; Rocksdb_wal_synced OK @@ -33,17 +33,17 @@ OK select variable_value into @b1 from information_schema.global_status where variable_name='Binlog_commits'; select variable_value into @b2 from information_schema.global_status where variable_name='Binlog_group_commits'; select variable_value into @b3 from information_schema.global_status where variable_name='Rocksdb_wal_synced'; -select IF(variable_value - @b1 = 10000, 'OK', 'FAIL') as Binlog_commits +select IF(variable_value - @b1 = 10000, 'OK', variable_value - @b1 = 10000) as Binlog_commits from information_schema.global_status where variable_name='Binlog_commits'; Binlog_commits OK -select IF(variable_value - @b2 between 100 and 5000, 'OK', 'FAIL') as Binlog_group_commits +select IF(variable_value - @b2 between 100 and 5000, 'OK', variable_value - @b2 between 100 and 5000) as Binlog_group_commits from information_schema.global_status where variable_name='Binlog_group_commits'; Binlog_group_commits OK -select IF(variable_value - @b3 between 1 and 9000, 'OK', 'FAIL') +select IF(variable_value - @b3 between 1 and 9000, 'OK', variable_value - @b3 between 1 and 9000) from information_schema.global_status where variable_name='Rocksdb_wal_synced'; -IF(variable_value - @b3 between 1 and 9000, 'OK', 'FAIL') +IF(variable_value - @b3 between 1 and 9000, 'OK', variable_value - @b3 between 1 and 9000) OK ## # 2PC enabled, MyRocks durability disabled, single thread @@ -53,17 +53,17 @@ SET GLOBAL rocksdb_flush_log_at_trx_commit=0; select variable_value into @b1 from information_schema.global_status where variable_name='Binlog_commits'; select variable_value into @b2 from information_schema.global_status where variable_name='Binlog_group_commits'; select variable_value into @b3 from information_schema.global_status where variable_name='Rocksdb_wal_synced'; -select IF(variable_value - @b1 = 1000, 'OK', 'FAIL') as Binlog_commits +select IF(variable_value - @b1 = 1000, 'OK', variable_value - @b1 = 1000) as Binlog_commits from information_schema.global_status where variable_name='Binlog_commits'; Binlog_commits OK -select IF(variable_value - @b2 = 1000, 'OK', 'FAIL') as Binlog_group_commits +select IF(variable_value - @b2 = 1000, 'OK', variable_value - @b2 = 1000) as Binlog_group_commits from information_schema.global_status where variable_name='Binlog_group_commits'; Binlog_group_commits OK -select IF(variable_value - @b3 < 10, 'OK', 'FAIL') +select IF(variable_value - @b3 < 10, 'OK', variable_value - @b3 < 10) from information_schema.global_status where variable_name='Rocksdb_wal_synced'; -IF(variable_value - @b3 < 10, 'OK', 'FAIL') +IF(variable_value - @b3 < 10, 'OK', variable_value - @b3 < 10) OK ## # 2PC enabled, MyRocks durability disabled, concurrent workload @@ -71,17 +71,17 @@ OK select variable_value into @b1 from information_schema.global_status where variable_name='Binlog_commits'; select variable_value into @b2 from information_schema.global_status where variable_name='Binlog_group_commits'; select variable_value into @b3 from information_schema.global_status where variable_name='Rocksdb_wal_synced'; -select IF(variable_value - @b1 = 10000, 'OK', 'FAIL') as Binlog_commits +select IF(variable_value - @b1 = 10000, 'OK', variable_value - @b1 = 10000) as Binlog_commits from information_schema.global_status where variable_name='Binlog_commits'; Binlog_commits OK -select IF(variable_value - @b2 < 8000, 'OK', 'FAIL') as Binlog_group_commits +select IF(variable_value - @b2 < 8000, 'OK', variable_value - @b2 < 8000) as Binlog_group_commits from information_schema.global_status where variable_name='Binlog_group_commits'; Binlog_group_commits OK -select IF(variable_value - @b3 < 10, 'OK', 'FAIL') +select IF(variable_value - @b3 < 10, 'OK', variable_value - @b3 < 10) from information_schema.global_status where variable_name='Rocksdb_wal_synced'; -IF(variable_value - @b3 < 10, 'OK', 'FAIL') +IF(variable_value - @b3 < 10, 'OK', variable_value - @b3 < 10) OK SET GLOBAL rocksdb_enable_2pc= @save_rocksdb_enable_2pc; SET GLOBAL rocksdb_flush_log_at_trx_commit= @save_rocksdb_flush_log_at_trx_commit; diff --git a/storage/rocksdb/mysql-test/rocksdb/r/mariadb_ignore_dirs.result b/storage/rocksdb/mysql-test/rocksdb/r/mariadb_ignore_dirs.result new file mode 100644 index 00000000000..9b91cdb5551 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb/r/mariadb_ignore_dirs.result @@ -0,0 +1,9 @@ +# +# RocksDB plugin adds #rocksdb to ignore_db_dirs +# +select @@ignore_db_dirs; +@@ignore_db_dirs +#rocksdb +select @@ignore_db_dirs; +@@ignore_db_dirs +aa,bbb,#rocksdb diff --git a/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result b/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result index 686b5637f7d..f590fd22dff 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result @@ -55,3 +55,12 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 range a a 32 NULL # Using where drop table t1,t2; set global rocksdb_strict_collation_check=@tmp_rscc; +# +# MDEV-14389: MyRocks and NOPAD collations +# +create table t1 (pk varchar(10) collate latin1_nopad_bin, primary key(pk)) engine=rocksdb; +ERROR HY000: MyRocks doesn't currently support collations with "No pad" attribute. +set global rocksdb_strict_collation_check=off; +create table t1 (pk varchar(10) collate latin1_nopad_bin, primary key(pk)) engine=rocksdb; +ERROR HY000: MyRocks doesn't currently support collations with "No pad" attribute. +set global rocksdb_strict_collation_check=@tmp_rscc; diff --git a/storage/rocksdb/mysql-test/rocksdb/r/rocksdb.result b/storage/rocksdb/mysql-test/rocksdb/r/rocksdb.result index ed0688c96ad..d791cf98bb0 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/rocksdb.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/rocksdb.result @@ -898,7 +898,7 @@ rocksdb_concurrent_prepare ON rocksdb_create_checkpoint rocksdb_create_if_missing ON rocksdb_create_missing_column_families OFF -rocksdb_datadir ./.rocksdb +rocksdb_datadir ./#rocksdb rocksdb_db_write_buffer_size 0 rocksdb_deadlock_detect OFF rocksdb_deadlock_detect_depth 50 diff --git a/storage/rocksdb/mysql-test/rocksdb/suite.opt b/storage/rocksdb/mysql-test/rocksdb/suite.opt index 47efa90a739..e12c09953a5 100644 --- a/storage/rocksdb/mysql-test/rocksdb/suite.opt +++ b/storage/rocksdb/mysql-test/rocksdb/suite.opt @@ -1 +1,2 @@ ---ignore-db-dirs=.rocksdb --plugin-load=$HA_ROCKSDB_SO --default-storage-engine=rocksdb --plugin-maturity=unknown +--plugin-load=$HA_ROCKSDB_SO --default-storage-engine=rocksdb +--plugin-maturity=unknown diff --git a/storage/rocksdb/mysql-test/rocksdb/t/2pc_group_commit.test b/storage/rocksdb/mysql-test/rocksdb/t/2pc_group_commit.test index 1a77424de39..d91d54a3543 100644 --- a/storage/rocksdb/mysql-test/rocksdb/t/2pc_group_commit.test +++ b/storage/rocksdb/mysql-test/rocksdb/t/2pc_group_commit.test @@ -31,12 +31,12 @@ select variable_value into @b1 from information_schema.global_status where varia select variable_value into @b2 from information_schema.global_status where variable_name='Binlog_group_commits'; select variable_value into @b3 from information_schema.global_status where variable_name='Rocksdb_wal_synced'; --exec $MYSQL_SLAP --silent --concurrency=1 --number-of-queries=1000 --query="INSERT INTO t1 (id, value) VALUES(NULL, 1)" -select IF(variable_value - @b1 = 1000, 'OK', 'FAIL') as Binlog_commits +select IF(variable_value - @b1 = 1000, 'OK', variable_value - @b1 = 1000) as Binlog_commits from information_schema.global_status where variable_name='Binlog_commits'; -select IF(variable_value - @b2 = 1000, 'OK', 'FAIL') as Binlog_group_commits +select IF(variable_value - @b2 = 1000, 'OK', variable_value - @b2 = 1000) as Binlog_group_commits from information_schema.global_status where variable_name='Binlog_group_commits'; --echo # Prepare operations sync, commits don't. We expect slightly more than 1K syncs: -select IF(variable_value - @b3 between 1000 and 1500, 'OK', 'FAIL') as Rocksdb_wal_synced +select IF(variable_value - @b3 between 1000 and 1500, 'OK', variable_value - @b3 between 1000 and 1500) as Rocksdb_wal_synced from information_schema.global_status where variable_name='Rocksdb_wal_synced'; --echo ## @@ -48,11 +48,11 @@ select variable_value into @b3 from information_schema.global_status where varia --exec $MYSQL_SLAP --silent --concurrency=50 --number-of-queries=10000 --query="INSERT INTO t1 (id, value) VALUES(NULL, 1)" -select IF(variable_value - @b1 = 10000, 'OK', 'FAIL') as Binlog_commits +select IF(variable_value - @b1 = 10000, 'OK', variable_value - @b1 = 10000) as Binlog_commits from information_schema.global_status where variable_name='Binlog_commits'; -select IF(variable_value - @b2 between 100 and 5000, 'OK', 'FAIL') as Binlog_group_commits +select IF(variable_value - @b2 between 100 and 5000, 'OK', variable_value - @b2 between 100 and 5000) as Binlog_group_commits from information_schema.global_status where variable_name='Binlog_group_commits'; -select IF(variable_value - @b3 between 1 and 9000, 'OK', 'FAIL') +select IF(variable_value - @b3 between 1 and 9000, 'OK', variable_value - @b3 between 1 and 9000) from information_schema.global_status where variable_name='Rocksdb_wal_synced'; --echo ## @@ -66,11 +66,11 @@ select variable_value into @b2 from information_schema.global_status where varia select variable_value into @b3 from information_schema.global_status where variable_name='Rocksdb_wal_synced'; --exec $MYSQL_SLAP --silent --concurrency=1 --number-of-queries=1000 --query="INSERT INTO t1 (id, value) VALUES(NULL, 1)" -select IF(variable_value - @b1 = 1000, 'OK', 'FAIL') as Binlog_commits +select IF(variable_value - @b1 = 1000, 'OK', variable_value - @b1 = 1000) as Binlog_commits from information_schema.global_status where variable_name='Binlog_commits'; -select IF(variable_value - @b2 = 1000, 'OK', 'FAIL') as Binlog_group_commits +select IF(variable_value - @b2 = 1000, 'OK', variable_value - @b2 = 1000) as Binlog_group_commits from information_schema.global_status where variable_name='Binlog_group_commits'; -select IF(variable_value - @b3 < 10, 'OK', 'FAIL') +select IF(variable_value - @b3 < 10, 'OK', variable_value - @b3 < 10) from information_schema.global_status where variable_name='Rocksdb_wal_synced'; --echo ## @@ -83,11 +83,11 @@ select variable_value into @b3 from information_schema.global_status where varia --exec $MYSQL_SLAP --silent --concurrency=50 --number-of-queries=10000 --query="INSERT INTO t1 (id, value) VALUES(NULL, 1)" -select IF(variable_value - @b1 = 10000, 'OK', 'FAIL') as Binlog_commits +select IF(variable_value - @b1 = 10000, 'OK', variable_value - @b1 = 10000) as Binlog_commits from information_schema.global_status where variable_name='Binlog_commits'; -select IF(variable_value - @b2 < 8000, 'OK', 'FAIL') as Binlog_group_commits +select IF(variable_value - @b2 < 8000, 'OK', variable_value - @b2 < 8000) as Binlog_group_commits from information_schema.global_status where variable_name='Binlog_group_commits'; -select IF(variable_value - @b3 < 10, 'OK', 'FAIL') +select IF(variable_value - @b3 < 10, 'OK', variable_value - @b3 < 10) from information_schema.global_status where variable_name='Rocksdb_wal_synced'; ## diff --git a/storage/rocksdb/mysql-test/rocksdb/t/bulk_load.inc b/storage/rocksdb/mysql-test/rocksdb/t/bulk_load.inc index 42cab5ad8c1..87cb1f70f32 100644 --- a/storage/rocksdb/mysql-test/rocksdb/t/bulk_load.inc +++ b/storage/rocksdb/mysql-test/rocksdb/t/bulk_load.inc @@ -134,7 +134,7 @@ select count(b) from t3; # the server starts --let $tmpext = .bulk_load.tmp --let $MYSQLD_DATADIR= `SELECT @@datadir` ---let $datadir = $MYSQLD_DATADIR/.rocksdb +--let $datadir = $MYSQLD_DATADIR/#rocksdb --write_file $datadir/test$tmpext dummy data EOF diff --git a/storage/rocksdb/mysql-test/rocksdb/t/compact_deletes_test.inc b/storage/rocksdb/mysql-test/rocksdb/t/compact_deletes_test.inc index 19a16fbe3a7..0a0d670505f 100644 --- a/storage/rocksdb/mysql-test/rocksdb/t/compact_deletes_test.inc +++ b/storage/rocksdb/mysql-test/rocksdb/t/compact_deletes_test.inc @@ -44,7 +44,7 @@ perl; print "wait_for_delete: $ENV{no_more_deletes}\n"; while ($retry++ < $num_retries) { $total_d=$total_e=0; - for $f (<$ENV{MYSQLTEST_VARDIR}/mysqld.1/data/.rocksdb/*.sst>) { + for $f (<$ENV{MYSQLTEST_VARDIR}/mysqld.1/data/#rocksdb/*.sst>) { # excluding system cf $filename= "$ENV{MARIAROCKS_SST_DUMP} --command=scan --output_hex --file=$f"; open(D, '-|', $filename) || die("Can't open file $filename: $!"); diff --git a/storage/rocksdb/mysql-test/rocksdb/t/drop_table2.test b/storage/rocksdb/mysql-test/rocksdb/t/drop_table2.test index 14d856cc0c5..a9012aea80a 100644 --- a/storage/rocksdb/mysql-test/rocksdb/t/drop_table2.test +++ b/storage/rocksdb/mysql-test/rocksdb/t/drop_table2.test @@ -97,7 +97,7 @@ set @@global.rocksdb_compact_cf = 'rev:cf2'; set @@global.rocksdb_compact_cf = 'default'; perl; -$size+=-s $_ for (<$ENV{MYSQLTEST_VARDIR}/mysqld.1/data/.rocksdb/*.sst>); +$size+=-s $_ for (<$ENV{MYSQLTEST_VARDIR}/mysqld.1/data/\#rocksdb/*.sst>); $filename= "$ENV{MYSQLTEST_VARDIR}/tmp/size_output"; open(F, '>', $filename) || die("Can't open file $filename: $!"); print F $size; @@ -121,7 +121,7 @@ let $wait_condition = select count(*) = 0 # Check that space is reclaimed perl; -$size+=-s $_ for (<$ENV{MYSQLTEST_VARDIR}/mysqld.1/data/.rocksdb/*.sst>); +$size+=-s $_ for (<$ENV{MYSQLTEST_VARDIR}/mysqld.1/data/\#rocksdb/*.sst>); $filename= "$ENV{MYSQLTEST_VARDIR}/tmp/size_output"; open(F, '<', $filename) || die("Can't open file $filename: $!"); $old=<F>; diff --git a/storage/rocksdb/mysql-test/rocksdb/t/mariadb_ignore_dirs.test b/storage/rocksdb/mysql-test/rocksdb/t/mariadb_ignore_dirs.test new file mode 100644 index 00000000000..49591dd612a --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb/t/mariadb_ignore_dirs.test @@ -0,0 +1,17 @@ +--source include/have_rocksdb.inc + + +--echo # +--echo # RocksDB plugin adds #rocksdb to ignore_db_dirs +--echo # + +select @@ignore_db_dirs; + +--let $_mysqld_option=--ignore-db-dirs=aa --ignore-db-dirs=bbb +--source include/restart_mysqld_with_option.inc + +select @@ignore_db_dirs; + +--let $_mysqld_option=--ignore-db-dirs=#rocksdb +--source include/restart_mysqld_with_option.inc + diff --git a/storage/rocksdb/mysql-test/rocksdb/t/mariadb_port_fixes.test b/storage/rocksdb/mysql-test/rocksdb/t/mariadb_port_fixes.test index f003aaf2032..70a4f5b05cb 100644 --- a/storage/rocksdb/mysql-test/rocksdb/t/mariadb_port_fixes.test +++ b/storage/rocksdb/mysql-test/rocksdb/t/mariadb_port_fixes.test @@ -54,3 +54,16 @@ explain select a from t2 where a <'zzz'; drop table t1,t2; set global rocksdb_strict_collation_check=@tmp_rscc; + +--echo # +--echo # MDEV-14389: MyRocks and NOPAD collations +--echo # + +--error ER_MYROCKS_CANT_NOPAD_COLLATION +create table t1 (pk varchar(10) collate latin1_nopad_bin, primary key(pk)) engine=rocksdb; + +set global rocksdb_strict_collation_check=off; +--error ER_MYROCKS_CANT_NOPAD_COLLATION +create table t1 (pk varchar(10) collate latin1_nopad_bin, primary key(pk)) engine=rocksdb; + +set global rocksdb_strict_collation_check=@tmp_rscc; diff --git a/storage/rocksdb/mysql-test/rocksdb/t/optimize_table.inc b/storage/rocksdb/mysql-test/rocksdb/t/optimize_table.inc index 9d03aae5c0c..5f66937cef1 100644 --- a/storage/rocksdb/mysql-test/rocksdb/t/optimize_table.inc +++ b/storage/rocksdb/mysql-test/rocksdb/t/optimize_table.inc @@ -1,7 +1,7 @@ # run a check script to verify sst files reduced enough during each optimize table perl; -$size += -s $_ for (<$ENV{datadir}/.rocksdb/*.sst>); +$size += -s $_ for (<$ENV{datadir}/#rocksdb/*.sst>); $file= "$ENV{MYSQL_TMP_DIR}/sst_size.dat"; if (-f $file) { diff --git a/storage/rocksdb/mysql-test/rocksdb_hotbackup/include/stream_run.sh b/storage/rocksdb/mysql-test/rocksdb_hotbackup/include/stream_run.sh index ecf8a851267..b6735abb0a9 100755 --- a/storage/rocksdb/mysql-test/rocksdb_hotbackup/include/stream_run.sh +++ b/storage/rocksdb/mysql-test/rocksdb_hotbackup/include/stream_run.sh @@ -77,7 +77,7 @@ MOVEBACK_LOG="${MYSQL_TMP_DIR}/myrocks_hotbackup_moveback_log" echo "myrocks_hotbackup move-back phase" $MYSQL_MYROCKS_HOTBACKUP --move_back --datadir=$dest_data_dir \ - --rocksdb_datadir=$dest_data_dir/.rocksdb \ - --rocksdb_waldir=$dest_data_dir/.rocksdb \ + --rocksdb_datadir=$dest_data_dir/\#rocksdb \ + --rocksdb_waldir=$dest_data_dir/\#rocksdb \ --backup_dir=$backup_dir > $MOVEBACK_LOG 2>&1 diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_wal_corrupt.inc b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_wal_corrupt.inc index a52bfc9186d..5e5961f3aef 100644 --- a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_wal_corrupt.inc +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_wal_corrupt.inc @@ -40,7 +40,7 @@ select * from mysql.slave_gtid_info; --write_file $MYSQL_TMP_DIR/truncate_tail_wal.sh #!/bin/bash -F=`ls -t $slave_data_dir/.rocksdb/*.log | head -n 1` +F=`ls -t $slave_data_dir/\#rocksdb/*.log | head -n 1` SIZE=`stat -c %s $F` NEW_SIZE=`expr $SIZE - 10` truncate -s $NEW_SIZE $F @@ -116,7 +116,7 @@ connection slave; #!/bin/bash # expected to be around 950 bytes -F=`ls -t $slave_data_dir/.rocksdb/*.log | head -n 1` +F=`ls -t $slave_data_dir/\#rocksdb/*.log | head -n 1` SIZE=`stat -c %s $F` OFFSET=$(( $SIZE-500 )) dd bs=1 if=/dev/zero of=$F count=100 seek=$OFFSET conv=notrunc diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_datadir_basic.result b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_datadir_basic.result index a3f9eff6c1f..3215624bad8 100644 --- a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_datadir_basic.result +++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_datadir_basic.result @@ -1,7 +1,7 @@ SET @start_global_value = @@global.ROCKSDB_DATADIR; SELECT @start_global_value; @start_global_value -./.rocksdb +./#rocksdb "Trying to set variable @@global.ROCKSDB_DATADIR to 444. It should fail because it is readonly." SET @@global.ROCKSDB_DATADIR = 444; ERROR HY000: Variable 'rocksdb_datadir' is a read only variable diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/suite.opt b/storage/rocksdb/mysql-test/rocksdb_sys_vars/suite.opt index 5ce5cf3e713..0effe1dadf7 100644 --- a/storage/rocksdb/mysql-test/rocksdb_sys_vars/suite.opt +++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/suite.opt @@ -1 +1,2 @@ ---ignore-db-dirs=.rocksdb --plugin-load=$HA_ROCKSDB_SO --plugin-maturity=unknown +--ignore-db-dirs=#rocksdb --plugin-load=$HA_ROCKSDB_SO +--plugin-maturity=unknown diff --git a/storage/rocksdb/mysql-test/storage_engine/cleanup_engine.inc b/storage/rocksdb/mysql-test/storage_engine/cleanup_engine.inc index 4f6c586172d..e6fe915ed38 100644 --- a/storage/rocksdb/mysql-test/storage_engine/cleanup_engine.inc +++ b/storage/rocksdb/mysql-test/storage_engine/cleanup_engine.inc @@ -12,14 +12,14 @@ --let $datadir= `SELECT @@datadir` --error 0,1 ---file_exists $datadir/.rocksdb/* +--file_exists $datadir/\#rocksdb/* if (!$mysql_errno) { --enable_reconnect --exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --shutdown_server --source include/wait_until_disconnected.inc - --rmdir $datadir/.rocksdb + --rmdir $datadir/\#rocksdb --exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --source include/wait_until_connected_again.inc } diff --git a/storage/rocksdb/mysql-test/storage_engine/parts/suite.opt b/storage/rocksdb/mysql-test/storage_engine/parts/suite.opt index 1e464761753..d77a822766f 100644 --- a/storage/rocksdb/mysql-test/storage_engine/parts/suite.opt +++ b/storage/rocksdb/mysql-test/storage_engine/parts/suite.opt @@ -1 +1 @@ ---ignore-db-dirs=.rocksdb --plugin-load=$HA_ROCKSDB_SO --binlog_format=ROW --loose-rocksdb_flush_log_at_trx_commit=0 +--ignore-db-dirs=#rocksdb --plugin-load=$HA_ROCKSDB_SO --binlog_format=ROW --loose-rocksdb_flush_log_at_trx_commit=0 diff --git a/storage/rocksdb/mysql-test/storage_engine/suite.opt b/storage/rocksdb/mysql-test/storage_engine/suite.opt index 5095f18b098..6ec1095bd9d 100644 --- a/storage/rocksdb/mysql-test/storage_engine/suite.opt +++ b/storage/rocksdb/mysql-test/storage_engine/suite.opt @@ -1 +1,2 @@ ---ignore-db-dirs=.rocksdb --plugin-load=$HA_ROCKSDB_SO --binlog_format=ROW --collation-server=latin1_bin --loose-rocksdb_flush_log_at_trx_commit=0 --plugin-maturity=unknown +--ignore-db-dirs=#rocksdb --plugin-load=$HA_ROCKSDB_SO --binlog_format=ROW --collation-server=latin1_bin --loose-rocksdb_flush_log_at_trx_commit=0 +--plugin-maturity=unknown diff --git a/storage/rocksdb/mysql-test/storage_engine/trx/suite.opt b/storage/rocksdb/mysql-test/storage_engine/trx/suite.opt index 1e464761753..d77a822766f 100644 --- a/storage/rocksdb/mysql-test/storage_engine/trx/suite.opt +++ b/storage/rocksdb/mysql-test/storage_engine/trx/suite.opt @@ -1 +1 @@ ---ignore-db-dirs=.rocksdb --plugin-load=$HA_ROCKSDB_SO --binlog_format=ROW --loose-rocksdb_flush_log_at_trx_commit=0 +--ignore-db-dirs=#rocksdb --plugin-load=$HA_ROCKSDB_SO --binlog_format=ROW --loose-rocksdb_flush_log_at_trx_commit=0 diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c index 9e476c23202..bfd533e6f98 100644 --- a/strings/ctype-mb.c +++ b/strings/ctype-mb.c @@ -799,9 +799,9 @@ fill_max_and_min: 'a\0\0... is the smallest possible string when we have space expand a\ff\ff... is the biggest possible string */ - *min_length= ((cs->state & MY_CS_BINSORT) ? (size_t) (min_str - min_org) : - res_length); - *max_length= res_length; + *min_length= (cs->state & (MY_CS_BINSORT | MY_CS_NOPAD)) ? + (size_t) (min_str - min_org) : + res_length; /* Create min key */ do { @@ -1002,9 +1002,9 @@ my_like_range_generic(CHARSET_INFO *cs, a\min\min... is the smallest possible string a\max\max... is the biggest possible string */ - *min_length= ((cs->state & MY_CS_BINSORT) ? + *min_length= (cs->state & (MY_CS_BINSORT | MY_CS_NOPAD)) ? (size_t) (min_str - min_org) : - res_length); + res_length; *max_length= res_length; goto pad_min_max; } diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c index cf73f117f0f..fc5218caba1 100644 --- a/strings/ctype-simple.c +++ b/strings/ctype-simple.c @@ -1059,9 +1059,9 @@ my_bool my_like_range_simple(CHARSET_INFO *cs, if (*ptr == w_many) /* '%' in SQL */ { /* Calculate length of keys */ - *min_length= ((cs->state & MY_CS_BINSORT) ? + *min_length= (cs->state & (MY_CS_BINSORT | MY_CS_NOPAD)) ? (size_t) (min_str - min_org) : - res_length); + res_length; *max_length= res_length; do { |