From c0e10f375ad619d825ef7c21232cf5946bdf5be7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 10 Nov 2017 09:07:45 +0200 Subject: Fix a -Wimplicit-fallthrough warning --- storage/maria/ma_loghandler.c | 1 - 1 file changed, 1 deletion(-) diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c index 556e7a93ef1..ef99307b441 100644 --- a/storage/maria/ma_loghandler.c +++ b/storage/maria/ma_loghandler.c @@ -6367,7 +6367,6 @@ my_bool translog_write_record(LSN *lsn, short_trid, &parts, trn, hook_arg); break; case LOGRECTYPE_NOT_ALLOWED: - DBUG_ASSERT(0); default: DBUG_ASSERT(0); rc= 1; -- cgit v1.2.1 From 2913f615f050f356f7be178e5d91650b86b33e4e Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Mon, 13 Nov 2017 16:30:02 +0100 Subject: MDEV-8949: COLUMN_CREATE unicode name breakage Use utf-mb4 if it is possible. --- include/ma_dyncol.h | 6 ++++++ mysql-test/r/ctype_utf8mb4.result | 27 +++++++++++++++++++++++++++ mysql-test/t/ctype_utf8mb4.test | 20 ++++++++++++++++++++ mysys/ma_dyncol.c | 3 +-- sql/item_cmpfunc.cc | 6 +++--- sql/item_strfunc.cc | 17 +++++++++-------- sql/item_strfunc.h | 7 ++++--- 7 files changed, 70 insertions(+), 16 deletions(-) diff --git a/include/ma_dyncol.h b/include/ma_dyncol.h index cb03ccb5382..300474e061e 100644 --- a/include/ma_dyncol.h +++ b/include/ma_dyncol.h @@ -63,6 +63,12 @@ typedef struct st_mysql_lex_string LEX_STRING; /* NO and OK is the same used just to show semantics */ #define ER_DYNCOL_NO ER_DYNCOL_OK +#ifdef HAVE_CHARSET_utf8mb4 +#define DYNCOL_UTF (&my_charset_utf8mb4_general_ci) +#else +#define DYNCOL_UTF (&my_charset_utf8_general_ci) +#endif + enum enum_dyncol_func_result { ER_DYNCOL_OK= 0, diff --git a/mysql-test/r/ctype_utf8mb4.result b/mysql-test/r/ctype_utf8mb4.result index 50382b5d5ca..ff9c155e445 100644 --- a/mysql-test/r/ctype_utf8mb4.result +++ b/mysql-test/r/ctype_utf8mb4.result @@ -3379,5 +3379,32 @@ F09F988E78 78F09F988E78 DROP TABLE t1; # +# MDEV-8949: COLUMN_CREATE unicode name breakage +# +SET NAMES utf8mb4; +SELECT COLUMN_JSON(COLUMN_CREATE(_utf8mb4 0xF09F988E, 1)); +COLUMN_JSON(COLUMN_CREATE(_utf8mb4 0xF09F988E, 1)) +{"😎":1} +SELECT COLUMN_LIST(COLUMN_CREATE(_utf8mb4 0xF09F988E, 1)); +COLUMN_LIST(COLUMN_CREATE(_utf8mb4 0xF09F988E, 1)) +`😎` +SELECT COLUMN_GET(COLUMN_CREATE(_utf8mb4 0xF09F988E, 1), _utf8mb4 0xF09F988E +as int); +COLUMN_GET(COLUMN_CREATE(_utf8mb4 0xF09F988E, 1), _utf8mb4 0xF09F988E +as int) +1 +CREATE TABLE t1 AS SELECT +COLUMN_LIST(COLUMN_CREATE('a',1)), +COLUMN_JSON(COLUMN_CREATE('b',1)); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `COLUMN_LIST(COLUMN_CREATE('a',1))` longtext CHARACTER SET utf8mb4, + `COLUMN_JSON(COLUMN_CREATE('b',1))` longtext CHARACTER SET utf8mb4 +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; +SET NAMES default; +# End of 10.0 tests +# # End of tests # diff --git a/mysql-test/t/ctype_utf8mb4.test b/mysql-test/t/ctype_utf8mb4.test index cf1c103137e..10786183ad0 100644 --- a/mysql-test/t/ctype_utf8mb4.test +++ b/mysql-test/t/ctype_utf8mb4.test @@ -1876,6 +1876,26 @@ LOAD DATA INFILE '../../std_data/loaddata/mdev-11343.txt' INTO TABLE t1 CHARACTE SELECT HEX(a) FROM t1; DROP TABLE t1; +--echo # +--echo # MDEV-8949: COLUMN_CREATE unicode name breakage +--echo # + +SET NAMES utf8mb4; +SELECT COLUMN_JSON(COLUMN_CREATE(_utf8mb4 0xF09F988E, 1)); +SELECT COLUMN_LIST(COLUMN_CREATE(_utf8mb4 0xF09F988E, 1)); +SELECT COLUMN_GET(COLUMN_CREATE(_utf8mb4 0xF09F988E, 1), _utf8mb4 0xF09F988E +as int); + +CREATE TABLE t1 AS SELECT + COLUMN_LIST(COLUMN_CREATE('a',1)), + COLUMN_JSON(COLUMN_CREATE('b',1)); +SHOW CREATE TABLE t1; +DROP TABLE t1; + +SET NAMES default; + +--echo # End of 10.0 tests + --echo # --echo # End of tests --echo # diff --git a/mysys/ma_dyncol.c b/mysys/ma_dyncol.c index d0d6254d11c..9f6df107316 100644 --- a/mysys/ma_dyncol.c +++ b/mysys/ma_dyncol.c @@ -4184,8 +4184,7 @@ mariadb_dyncol_json_internal(DYNAMIC_COLUMN *str, DYNAMIC_STRING *json, } else { - if ((rc= mariadb_dyncol_val_str(json, &val, - &my_charset_utf8_general_ci, '"')) < 0) + if ((rc= mariadb_dyncol_val_str(json, &val, DYNCOL_UTF, '"')) < 0) goto err; } } diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index b086b084f97..807ce828131 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -6642,7 +6642,7 @@ longlong Item_func_dyncol_exists::val_int() null_value= 1; return 1; } - if (my_charset_same(nm->charset(), &my_charset_utf8_general_ci)) + if (my_charset_same(nm->charset(), DYNCOL_UTF)) { buf.str= (char *) nm->ptr(); buf.length= nm->length(); @@ -6652,11 +6652,11 @@ longlong Item_func_dyncol_exists::val_int() uint strlen; uint dummy_errors; buf.str= (char *)sql_alloc((strlen= nm->length() * - my_charset_utf8_general_ci.mbmaxlen + 1)); + DYNCOL_UTF->mbmaxlen + 1)); if (buf.str) { buf.length= - copy_and_convert(buf.str, strlen, &my_charset_utf8_general_ci, + copy_and_convert(buf.str, strlen, DYNCOL_UTF, nm->ptr(), nm->length(), nm->charset(), &dummy_errors); } diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index c3043adac47..c1bca3e12eb 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -4444,7 +4444,7 @@ bool Item_func_dyncol_create::prepare_arguments(bool force_names_arg) if (res) { // guaranty UTF-8 string for names - if (my_charset_same(res->charset(), &my_charset_utf8_general_ci)) + if (my_charset_same(res->charset(), DYNCOL_UTF)) { keys_str[i].length= res->length(); keys_str[i].str= sql_strmake(res->ptr(), res->length()); @@ -4455,11 +4455,11 @@ bool Item_func_dyncol_create::prepare_arguments(bool force_names_arg) uint dummy_errors; char *str= (char *)sql_alloc((strlen= res->length() * - my_charset_utf8_general_ci.mbmaxlen + 1)); + DYNCOL_UTF->mbmaxlen + 1)); if (str) { keys_str[i].length= - copy_and_convert(str, strlen, &my_charset_utf8_general_ci, + copy_and_convert(str, strlen, DYNCOL_UTF, res->ptr(), res->length(), res->charset(), &dummy_errors); keys_str[i].str= str; @@ -4680,9 +4680,10 @@ String *Item_func_dyncol_json::val_str(String *str) size_t length, alloc_length; dynstr_reassociate(&json, &ptr, &length, &alloc_length); str->reassociate(ptr, (uint32) length, (uint32) alloc_length, - &my_charset_utf8_general_ci); + DYNCOL_UTF); null_value= FALSE; } + str->set_charset(DYNCOL_UTF); return str; null: @@ -4781,7 +4782,7 @@ bool Item_dyncol_get::get_dyn_value(DYNAMIC_COLUMN_VALUE *val, String *tmp) return 1; } - if (my_charset_same(nm->charset(), &my_charset_utf8_general_ci)) + if (my_charset_same(nm->charset(), DYNCOL_UTF)) { buf.str= (char *) nm->ptr(); buf.length= nm->length(); @@ -4791,11 +4792,11 @@ bool Item_dyncol_get::get_dyn_value(DYNAMIC_COLUMN_VALUE *val, String *tmp) uint strlen; uint dummy_errors; buf.str= (char *)sql_alloc((strlen= nm->length() * - my_charset_utf8_general_ci.mbmaxlen + 1)); + DYNCOL_UTF->mbmaxlen + 1)); if (buf.str) { buf.length= - copy_and_convert(buf.str, strlen, &my_charset_utf8_general_ci, + copy_and_convert(buf.str, strlen, DYNCOL_UTF, nm->ptr(), nm->length(), nm->charset(), &dummy_errors); } @@ -5229,7 +5230,6 @@ String *Item_func_dyncol_list::val_str(String *str) goto null; str->length(0); - str->set_charset(&my_charset_utf8_general_ci); for (i= 0; i < count; i++) { append_identifier(current_thd, str, names[i].str, names[i].length); @@ -5239,6 +5239,7 @@ String *Item_func_dyncol_list::val_str(String *str) null_value= FALSE; if (names) my_free(names); + str->set_charset(DYNCOL_UTF); return str; null: diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 1b133d1d885..6520591145b 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -1177,14 +1177,14 @@ public: class Item_func_dyncol_json: public Item_str_func { public: - Item_func_dyncol_json(Item *str) :Item_str_func(str) {} + Item_func_dyncol_json(Item *str) :Item_str_func(str) + {collation.set(DYNCOL_UTF);} const char *func_name() const{ return "column_json"; } String *val_str(String *); void fix_length_and_dec() { max_length= MAX_BLOB_WIDTH; maybe_null= 1; - collation.set(&my_charset_bin); decimals= 0; } }; @@ -1218,7 +1218,8 @@ public: class Item_func_dyncol_list: public Item_str_func { public: - Item_func_dyncol_list(Item *str) :Item_str_func(str) {}; + Item_func_dyncol_list(Item *str) :Item_str_func(str) + {collation.set(DYNCOL_UTF);}; void fix_length_and_dec() { maybe_null= 1; max_length= MAX_BLOB_WIDTH; }; const char *func_name() const{ return "column_list"; } String *val_str(String *); -- cgit v1.2.1 From ea1739f90d07c9f252b63a19cd9425b05abaf33a Mon Sep 17 00:00:00 2001 From: Eugene Kosov Date: Tue, 14 Nov 2017 11:29:52 +0300 Subject: removed garbase struct member --- storage/innobase/include/que0que.h | 3 --- storage/xtradb/include/que0que.h | 3 --- 2 files changed, 6 deletions(-) diff --git a/storage/innobase/include/que0que.h b/storage/innobase/include/que0que.h index ba8828623af..f37581cbf8f 100644 --- a/storage/innobase/include/que0que.h +++ b/storage/innobase/include/que0que.h @@ -383,9 +383,6 @@ struct que_thr_t{ UT_LIST_NODE_T(que_thr_t) thrs; /*!< list of thread nodes of the fork node */ - UT_LIST_NODE_T(que_thr_t) - trx_thrs; /*!< lists of threads in wait list of - the trx */ UT_LIST_NODE_T(que_thr_t) queue; /*!< list of runnable thread nodes in the server task queue */ diff --git a/storage/xtradb/include/que0que.h b/storage/xtradb/include/que0que.h index e5b2a1ba3fc..005f28d2af1 100644 --- a/storage/xtradb/include/que0que.h +++ b/storage/xtradb/include/que0que.h @@ -384,9 +384,6 @@ struct que_thr_t{ UT_LIST_NODE_T(que_thr_t) thrs; /*!< list of thread nodes of the fork node */ - UT_LIST_NODE_T(que_thr_t) - trx_thrs; /*!< lists of threads in wait list of - the trx */ UT_LIST_NODE_T(que_thr_t) queue; /*!< list of runnable thread nodes in the server task queue */ -- cgit v1.2.1 From 02e35ef5f237b03c3e735fa7afe21dd92086cbc5 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Wed, 15 Nov 2017 15:52:03 +0400 Subject: MDEV-12681 Wrong VIEW results for CHAR(0xDF USING latin1) --- mysql-test/r/ctype_utf8.result | 15 +++++++++++++++ mysql-test/r/func_str.result | 21 +++++++++++++++++++++ mysql-test/t/ctype_utf8.test | 12 ++++++++++++ mysql-test/t/func_str.test | 12 ++++++++++++ sql/item_strfunc.cc | 14 ++++++++++++++ sql/item_strfunc.h | 1 + 6 files changed, 75 insertions(+) diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index e292b64cfa6..7a3ff3732c3 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -10113,5 +10113,20 @@ DROP FUNCTION iswellformed; DROP TABLE allbytes; # End of ctype_backslash.inc # +# MDEV-12681 Wrong VIEW results for CHAR(0xDF USING latin1) +# +SET NAMES utf8; +SELECT CHAR(0xDF USING latin1); +CHAR(0xDF USING latin1) +ß +CREATE OR REPLACE VIEW v1 AS SELECT CHAR(0xDF USING latin1) AS c; +SHOW CREATE VIEW v1; +View Create View character_set_client collation_connection +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select char(0xdf using latin1) AS `c` utf8 utf8_general_ci +SELECT * FROM v1; +c +ß +DROP VIEW v1; +# # End of 10.0 tests # diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index 8f08d7acd25..9a9b9f0d73d 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -4530,3 +4530,24 @@ latin2_general_ci # # End of 5.6 tests # +# +# Start of 10.0 tests +# +# +# MDEV-12681 Wrong VIEW results for CHAR(0xDF USING latin1) +# +EXPLAIN EXTENDED SELECT CHAR(0xDF USING latin1); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Warnings: +Note 1003 select char(0xdf using latin1) AS `CHAR(0xDF USING latin1)` +EXPLAIN EXTENDED SELECT CHAR(0xDF USING `binary`); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Warnings: +Note 1003 select char(0xdf) AS `CHAR(0xDF USING ``binary``)` +EXPLAIN EXTENDED SELECT CHAR(0xDF); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Warnings: +Note 1003 select char(0xdf) AS `CHAR(0xDF)` diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index 4b181182c46..2524daffa9e 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -1868,6 +1868,18 @@ SELECT _utf8 0x7E, _utf8 X'7E', _utf8 B'01111110'; let $ctype_unescape_combinations=selected; --source include/ctype_unescape.inc +--echo # +--echo # MDEV-12681 Wrong VIEW results for CHAR(0xDF USING latin1) +--echo # + +SET NAMES utf8; +SELECT CHAR(0xDF USING latin1); +CREATE OR REPLACE VIEW v1 AS SELECT CHAR(0xDF USING latin1) AS c; +SHOW CREATE VIEW v1; +SELECT * FROM v1; +DROP VIEW v1; + + --echo # --echo # End of 10.0 tests --echo # diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index 6369609bea3..bdeca8d0d86 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -1742,3 +1742,15 @@ EXECUTE stmt; --echo # --echo # End of 5.6 tests --echo # + +--echo # +--echo # Start of 10.0 tests +--echo # + +--echo # +--echo # MDEV-12681 Wrong VIEW results for CHAR(0xDF USING latin1) +--echo # + +EXPLAIN EXTENDED SELECT CHAR(0xDF USING latin1); +EXPLAIN EXTENDED SELECT CHAR(0xDF USING `binary`); +EXPLAIN EXTENDED SELECT CHAR(0xDF); diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index c1bca3e12eb..3ee8a0e4970 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2905,6 +2905,20 @@ String *Item_func_make_set::val_str(String *str) } +void Item_func_char::print(String *str, enum_query_type query_type) +{ + str->append(Item_func_char::func_name()); + str->append('('); + print_args(str, 0, query_type); + if (collation.collation != &my_charset_bin) + { + str->append(C_STRING_WITH_LEN(" using ")); + str->append(collation.collation->csname); + } + str->append(')'); +} + + String *Item_func_char::val_str(String *str) { DBUG_ASSERT(fixed == 1); diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 6520591145b..aa3486d4e73 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -702,6 +702,7 @@ public: max_length= arg_count * 4; } const char *func_name() const { return "char"; } + void print(String *str, enum_query_type query_type); }; -- cgit v1.2.1 From 923ea5dbf6644fab088e35122523b2b8ef03b7ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Thu, 16 Nov 2017 13:18:22 +0200 Subject: MDEV-9663: InnoDB assertion failure: *cursor->index->name == TEMP_INDEX_PREFIX Imported missing test case from MySQL 5.7 for commit 25781c154396dbbc21023786aa3be070057d6999 Author: Annamalai Gurusami Date: Mon Feb 24 14:00:03 2014 +0530 Bug #17604730 ASSERTION: *CURSOR->INDEX->NAME == TEMP_INDEX_PREFIX --- mysql-test/suite/innodb/r/innodb-replace-debug.result | 9 +++++++++ mysql-test/suite/innodb/t/innodb-replace-debug.test | 13 +++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 mysql-test/suite/innodb/r/innodb-replace-debug.result create mode 100644 mysql-test/suite/innodb/t/innodb-replace-debug.test diff --git a/mysql-test/suite/innodb/r/innodb-replace-debug.result b/mysql-test/suite/innodb/r/innodb-replace-debug.result new file mode 100644 index 00000000000..0de351efded --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb-replace-debug.result @@ -0,0 +1,9 @@ +# +# Bug#17604730 ASSERTION: *CURSOR->INDEX->NAME == TEMP_INDEX_PREFIX +# +create table t1 (f1 int primary key, f2 int, f3 int, unique key k1(f2), +key k2(f3)) engine=innodb; +insert into t1 values (14, 24, 34); +set debug = '+d,row_ins_sec_index_entry_timeout'; +replace into t1 values (14, 25, 34); +drop table t1; diff --git a/mysql-test/suite/innodb/t/innodb-replace-debug.test b/mysql-test/suite/innodb/t/innodb-replace-debug.test new file mode 100644 index 00000000000..250c90ba5b1 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-replace-debug.test @@ -0,0 +1,13 @@ +--source include/have_innodb.inc +--source include/have_debug.inc + +--echo # +--echo # Bug#17604730 ASSERTION: *CURSOR->INDEX->NAME == TEMP_INDEX_PREFIX +--echo # + +create table t1 (f1 int primary key, f2 int, f3 int, unique key k1(f2), + key k2(f3)) engine=innodb; +insert into t1 values (14, 24, 34); +set debug = '+d,row_ins_sec_index_entry_timeout'; +replace into t1 values (14, 25, 34); +drop table t1; -- cgit v1.2.1 From 93326ef051350787a3b289f68137365224a5e77a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Thu, 16 Nov 2017 13:21:07 +0200 Subject: MDEV-9663: InnoDB assertion failure: *cursor->index->name == TEMP_INDEX_PREFIX MariaDB adjustments to test case innodb-replace-debug. MariaDB 10.0 does not seem to be affected. --- mysql-test/suite/innodb/r/innodb-replace-debug.result | 6 +++++- mysql-test/suite/innodb/t/innodb-replace-debug.test | 4 +++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/innodb/r/innodb-replace-debug.result b/mysql-test/suite/innodb/r/innodb-replace-debug.result index 0de351efded..84bc9dc9769 100644 --- a/mysql-test/suite/innodb/r/innodb-replace-debug.result +++ b/mysql-test/suite/innodb/r/innodb-replace-debug.result @@ -4,6 +4,10 @@ create table t1 (f1 int primary key, f2 int, f3 int, unique key k1(f2), key k2(f3)) engine=innodb; insert into t1 values (14, 24, 34); -set debug = '+d,row_ins_sec_index_entry_timeout'; +set @@debug_dbug = '+d,row_ins_sec_index_entry_timeout'; replace into t1 values (14, 25, 34); +select * from t1; +f1 f2 f3 +14 25 34 drop table t1; +set @@debug_dbug = '-d,row_ins_sec_index_entry_timeout'; diff --git a/mysql-test/suite/innodb/t/innodb-replace-debug.test b/mysql-test/suite/innodb/t/innodb-replace-debug.test index 250c90ba5b1..5cec9e1febf 100644 --- a/mysql-test/suite/innodb/t/innodb-replace-debug.test +++ b/mysql-test/suite/innodb/t/innodb-replace-debug.test @@ -8,6 +8,8 @@ create table t1 (f1 int primary key, f2 int, f3 int, unique key k1(f2), key k2(f3)) engine=innodb; insert into t1 values (14, 24, 34); -set debug = '+d,row_ins_sec_index_entry_timeout'; +set @@debug_dbug = '+d,row_ins_sec_index_entry_timeout'; replace into t1 values (14, 25, 34); +select * from t1; drop table t1; +set @@debug_dbug = '-d,row_ins_sec_index_entry_timeout'; -- cgit v1.2.1 From d8ccc61f76d56b761e52564701814739abc190d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Thu, 16 Nov 2017 14:03:02 +0200 Subject: MDEV-9663: InnoDB assertion failure: *cursor->index->name == TEMP_INDEX_PREFIX Add missing instrumentation to row0ins.cc. --- storage/innobase/row/row0ins.cc | 4 ++++ storage/xtradb/row/row0ins.cc | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index 47f09ac764b..2c1b784109d 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -2918,6 +2918,10 @@ row_ins_sec_index_entry( mem_heap_t* offsets_heap; mem_heap_t* heap; + DBUG_EXECUTE_IF("row_ins_sec_index_entry_timeout", { + DBUG_SET("-d,row_ins_sec_index_entry_timeout"); + return(DB_LOCK_WAIT);}); + if (!index->table->foreign_set.empty()) { err = row_ins_check_foreign_constraints(index->table, index, entry, thr); diff --git a/storage/xtradb/row/row0ins.cc b/storage/xtradb/row/row0ins.cc index 6dcb11c8bb5..c9cdee9e6be 100644 --- a/storage/xtradb/row/row0ins.cc +++ b/storage/xtradb/row/row0ins.cc @@ -2991,6 +2991,10 @@ row_ins_sec_index_entry( mem_heap_t* offsets_heap; mem_heap_t* heap; + DBUG_EXECUTE_IF("row_ins_sec_index_entry_timeout", { + DBUG_SET("-d,row_ins_sec_index_entry_timeout"); + return(DB_LOCK_WAIT);}); + if (!index->table->foreign_set.empty()) { err = row_ins_check_foreign_constraints(index->table, index, entry, thr); -- cgit v1.2.1 From 622466644dda1e3c72f5fe276e3a8127b20c1182 Mon Sep 17 00:00:00 2001 From: Ian Gilfillan Date: Mon, 20 Nov 2017 11:00:44 +0200 Subject: mysql_uprade --help and man page fixes --- client/mysql_upgrade.c | 4 ++-- man/mysql_upgrade.1 | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index e131aabd8b6..cecf212ad92 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -164,8 +164,8 @@ static struct my_option my_long_options[]= "server with which it was built/distributed.", &opt_version_check, &opt_version_check, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, - {"write-binlog", OPT_WRITE_BINLOG, "All commands including those, " - "issued by mysqlcheck, are written to the binary log.", + {"write-binlog", OPT_WRITE_BINLOG, "All commands including those " + "issued by mysqlcheck are written to the binary log.", &opt_write_binlog, &opt_write_binlog, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} diff --git a/man/mysql_upgrade.1 b/man/mysql_upgrade.1 index 3948a670436..200037de41a 100644 --- a/man/mysql_upgrade.1 +++ b/man/mysql_upgrade.1 @@ -691,8 +691,7 @@ it was built/distributed. Defaults to on; use \fB\-\-skip\-version\-check\fR to .sp Cause binary logging to be enabled while \fBmysql_upgrade\fR -runs\&. This is the default behavior; to disable binary logging during the upgrade, use the inverse of this option (that is, start the program with -\fB\-\-skip\-write\-binlog\fR)\&. +runs\&. .RE .SH "COPYRIGHT" .br -- cgit v1.2.1 From 1374f958c120ee0fdf3f4b017f1289aba87dae07 Mon Sep 17 00:00:00 2001 From: Monty Date: Thu, 7 Dec 2017 17:22:24 +0200 Subject: Fixed failing tokudb tests This was caused by my earlier fix for rpl.rpl_row_log_innodb :( --- storage/tokudb/mysql-test/rpl/r/rpl_tokudb_row_log.result | 2 -- storage/tokudb/mysql-test/rpl/r/rpl_tokudb_stm_log.result | 2 -- 2 files changed, 4 deletions(-) diff --git a/storage/tokudb/mysql-test/rpl/r/rpl_tokudb_row_log.result b/storage/tokudb/mysql-test/rpl/r/rpl_tokudb_row_log.result index 8cbbda48c1f..f283b3adf80 100644 --- a/storage/tokudb/mysql-test/rpl/r/rpl_tokudb_row_log.result +++ b/storage/tokudb/mysql-test/rpl/r/rpl_tokudb_row_log.result @@ -215,7 +215,6 @@ master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Rotate # # master-bin.000002;pos=POS include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000002 # Binlog_checkpoint # # master-bin.000002 master-bin.000002 # Gtid # # GTID #-#-# master-bin.000002 # Query # # use `test`; create table t3 (a int)ENGINE=TokuDB master-bin.000002 # Gtid # # GTID #-#-# @@ -253,7 +252,6 @@ slave-bin.000001 # Query # # use `test`; create table t3 (a int)ENGINE=TokuDB slave-bin.000001 # Rotate # # slave-bin.000002;pos=POS include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info -slave-bin.000002 # Binlog_checkpoint # # slave-bin.000002 slave-bin.000002 # Gtid # # GTID #-#-# slave-bin.000002 # Query # # use `test`; create table t2 (n int)ENGINE=TokuDB slave-bin.000002 # Gtid # # BEGIN GTID #-#-# diff --git a/storage/tokudb/mysql-test/rpl/r/rpl_tokudb_stm_log.result b/storage/tokudb/mysql-test/rpl/r/rpl_tokudb_stm_log.result index 42defbe07b5..0334000f12e 100644 --- a/storage/tokudb/mysql-test/rpl/r/rpl_tokudb_stm_log.result +++ b/storage/tokudb/mysql-test/rpl/r/rpl_tokudb_stm_log.result @@ -215,7 +215,6 @@ master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Rotate # # master-bin.000002;pos=POS include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000002 # Binlog_checkpoint # # master-bin.000002 master-bin.000002 # Gtid # # GTID #-#-# master-bin.000002 # Query # # use `test`; create table t3 (a int)ENGINE=TokuDB master-bin.000002 # Gtid # # GTID #-#-# @@ -252,7 +251,6 @@ slave-bin.000001 # Query # # use `test`; create table t3 (a int)ENGINE=TokuDB slave-bin.000001 # Rotate # # slave-bin.000002;pos=POS include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info -slave-bin.000002 # Binlog_checkpoint # # slave-bin.000002 slave-bin.000002 # Gtid # # GTID #-#-# slave-bin.000002 # Query # # use `test`; create table t2 (n int)ENGINE=TokuDB slave-bin.000002 # Gtid # # BEGIN GTID #-#-# -- cgit v1.2.1 From e66bb5726716b7852c880e02b0acf0f5b9a1e8ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Sat, 9 Dec 2017 11:20:46 +0200 Subject: MDEV-12837: WSREP: BF lock wait long This is 10.1 version where no merge error exists. wsrep_on_check New check function. Galera can't be enabled if innodb-lock-schedule-algorithm=VATS. innobase_kill_query In Galera async kill we could own lock mutex. innobase_init If Variance-Aware-Transaction-Sheduling Algorithm (VATS) is used on Galera we refuse to start InnoDB. Changed innodb-lock-schedule-algorithm as read-only parameter as it was designed to be. lock_rec_other_has_expl_req, lock_rec_other_has_conflicting, lock_rec_lock_slow lock_table_other_has_incompatible lock_rec_insert_check_and_lock Change pointer to conflicting lock to normal pointer as this pointer contents could be changed later. --- mysql-test/suite/sys_vars/r/sysvars_innodb.result | 2 +- mysql-test/suite/sys_vars/t/wsrep_on_basic.opt | 1 + sql/sys_vars.cc | 3 +- sql/wsrep_var.cc | 16 ++++ sql/wsrep_var.h | 3 +- storage/innobase/handler/ha_innodb.cc | 17 +++- storage/innobase/lock/lock0lock.cc | 94 +++++++++++++++-------- storage/innobase/lock/lock0wait.cc | 39 +++++----- storage/xtradb/handler/ha_innodb.cc | 17 +++- storage/xtradb/lock/lock0lock.cc | 91 ++++++++++++++-------- storage/xtradb/lock/lock0wait.cc | 39 +++++----- 11 files changed, 215 insertions(+), 107 deletions(-) create mode 100644 mysql-test/suite/sys_vars/t/wsrep_on_basic.opt diff --git a/mysql-test/suite/sys_vars/r/sysvars_innodb.result b/mysql-test/suite/sys_vars/r/sysvars_innodb.result index acdbd007e6e..161f740dbfb 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_innodb.result +++ b/mysql-test/suite/sys_vars/r/sysvars_innodb.result @@ -1347,7 +1347,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/sql/sys_vars.cc b/sql/sys_vars.cc index 8eb3d35a96e..303633939c3 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -4895,7 +4895,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/wsrep_var.cc b/sql/wsrep_var.cc index b21041eb0f8..ad1f4ec0eac 100644 --- a/sql/wsrep_var.cc +++ b/sql/wsrep_var.cc @@ -52,12 +52,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 7530fd98870..55eb2fbc501 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/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 9a7258bc924..2d319439fad 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -3478,6 +3478,17 @@ 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) { + /* Do not allow InnoDB startup with VATS and Galera */ + sql_print_error("In Galera environment Variance-Aware-Transaction-Sheduling Algorithm" + " is not supported."); + goto error; + } +#endif /* WITH_WSREP */ + #ifndef HAVE_LZ4 if (innodb_compression_algorithm == PAGE_LZ4_ALGORITHM) { sql_print_error("InnoDB: innodb_compression_algorithm = %lu unsupported.\n" @@ -4882,8 +4893,8 @@ innobase_kill_query( wsrep_thd_is_BF(current_thd, FALSE), lock_get_info(trx->lock.wait_lock).c_str()); - if (!wsrep_thd_is_BF(trx->mysql_thd, FALSE) && - trx->abort_type == TRX_SERVER_ABORT) { + if (!wsrep_thd_is_BF(trx->mysql_thd, FALSE) + && trx->abort_type == TRX_SERVER_ABORT) { ut_ad(!lock_mutex_own()); lock_mutex_enter(); } @@ -19234,7 +19245,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/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index 6b2c309e432..61385891b76 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -925,15 +925,21 @@ lock_reset_lock_and_trx_wait( ib_logf(IB_LOG_LEVEL_INFO, "Trx id " TRX_ID_FMT - " is waiting a lock in statement %s" + " is waiting a lock " " for this trx id " TRX_ID_FMT - " and statement %s wait_lock %p", + " wait_lock %p", lock->trx->id, - stmt ? stmt : "NULL", trx_id, - stmt2 ? stmt2 : "NULL", lock->trx->lock.wait_lock); + if (stmt) { + ib_logf(IB_LOG_LEVEL_INFO, " SQL1: %s\n", stmt); + } + + if (stmt2) { + ib_logf(IB_LOG_LEVEL_INFO, " SQL2: %s\n", stmt2); + } + ut_ad(lock->trx->lock.wait_lock == lock); } @@ -1151,7 +1157,7 @@ lock_rec_has_to_wait( type_mode, lock_is_on_supremum); fprintf(stderr, "conflicts states: my %d locked %d\n", - wsrep_thd_conflict_state(trx->mysql_thd, FALSE), + wsrep_thd_conflict_state(trx->mysql_thd, FALSE), wsrep_thd_conflict_state(lock2->trx->mysql_thd, FALSE) ); lock_rec_print(stderr, lock2); if (for_locking) return FALSE; @@ -1687,7 +1693,7 @@ lock_rec_discard(lock_t* in_lock); 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( /*========================*/ enum lock_mode mode, /*!< in: LOCK_S or LOCK_X */ @@ -1704,7 +1710,7 @@ lock_rec_other_has_expl_req( requests by all transactions are taken into account */ { - const lock_t* lock; + lock_t* lock; ut_ad(lock_mutex_own()); ut_ad(mode == LOCK_X || mode == LOCK_S); @@ -1713,7 +1719,7 @@ lock_rec_other_has_expl_req( for (lock = lock_rec_get_first(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 && (gap @@ -1800,7 +1806,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( /*===========================*/ enum lock_mode mode, /*!< in: LOCK_S or LOCK_X, @@ -1812,7 +1818,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; ibool is_supremum; ut_ad(lock_mutex_own()); @@ -1821,13 +1827,16 @@ lock_rec_other_has_conflicting( for (lock = lock_rec_get_first(block, heap_no); lock != NULL; - lock = lock_rec_get_next_const(heap_no, lock)) { + lock = lock_rec_get_next(heap_no, lock)) { #ifdef WITH_WSREP if (lock_rec_has_to_wait(TRUE, trx, mode, lock, is_supremum)) { if (wsrep_on_trx(trx)) { trx_mutex_enter(lock->trx); - wsrep_kill_victim(trx, lock); + /* Below function will roll back either trx + or lock->trx depending on priority of the + transaction. */ + wsrep_kill_victim(const_cast(trx), lock); trx_mutex_exit(lock->trx); } #else @@ -2023,15 +2032,17 @@ wsrep_print_wait_locks( { if (wsrep_debug && c_lock->trx->lock.wait_lock != c_lock) { fprintf(stderr, "WSREP: c_lock != wait lock\n"); - if (lock_get_type_low(c_lock) & LOCK_TABLE) + if (lock_get_type_low(c_lock) & LOCK_TABLE) { lock_table_print(stderr, c_lock); - else + } else { lock_rec_print(stderr, c_lock); + } - if (lock_get_type_low(c_lock->trx->lock.wait_lock) & LOCK_TABLE) + if (lock_get_type_low(c_lock->trx->lock.wait_lock) & LOCK_TABLE) { lock_table_print(stderr, c_lock->trx->lock.wait_lock); - else + } else { lock_rec_print(stderr, c_lock->trx->lock.wait_lock); + } } } #endif /* WITH_WSREP */ @@ -2217,8 +2228,8 @@ lock_rec_create( if (wsrep_debug) { fprintf( stderr, - "WSREP: c_lock canceled %llu\n", - (ulonglong) c_lock->trx->id); + "WSREP: c_lock canceled " TRX_ID_FMT "\n", + c_lock->trx->id); } /* have to bail out here to avoid lock_set_lock... */ @@ -2519,6 +2530,16 @@ lock_rec_enqueue_waiting( err = DB_LOCK_WAIT; } +#ifdef WITH_WSREP + if (!lock_get_wait(lock) && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { + if (wsrep_debug) { + fprintf(stderr, "WSREP: BF thread got lock granted early, ID " TRX_ID_FMT + "\n", + lock->trx->id); + } + return(DB_SUCCESS); + } +#endif /* WITH_WSREP */ // Move it only when it does not cause a deadlock. if (err != DB_DEADLOCK && innodb_lock_schedule_algorithm @@ -2814,7 +2835,7 @@ lock_rec_lock_slow( /* The trx already has a strong enough lock on rec: do nothing */ #ifdef WITH_WSREP - } else if ((c_lock = (ib_lock_t*)lock_rec_other_has_conflicting( + } else if ((c_lock = lock_rec_other_has_conflicting( static_cast(mode), block, heap_no, trx))) { #else @@ -2946,6 +2967,15 @@ 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) { + fprintf(stderr, + "BF-BF lock conflict " TRX_ID_FMT + " : " TRX_ID_FMT "\n", + wait_lock->trx->id, + lock->trx->id); + lock_rec_print(stderr, wait_lock); + lock_rec_print(stderr, lock); + } /* don't wait for another BF lock */ continue; } @@ -3104,7 +3134,7 @@ lock_grant_and_move_on_page( && !lock_rec_has_to_wait_in_queue(lock)) { lock_grant(lock, false); - + if (previous != NULL) { /* Move the lock to the head of the list. */ HASH_GET_NEXT(hash, previous) = HASH_GET_NEXT(hash, lock); @@ -4978,8 +5008,8 @@ lock_table_create( } if (wsrep_debug) { - fprintf(stderr, "WSREP: c_lock canceled %llu\n", - (ulonglong) c_lock->trx->id); + fprintf(stderr, "WSREP: c_lock canceled " TRX_ID_FMT "\n", + c_lock->trx->id); } } if (c_lock) { @@ -5251,7 +5281,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 @@ -5262,7 +5292,7 @@ lock_table_other_has_incompatible( const dict_table_t* table, /*!< in: table */ enum lock_mode mode) /*!< in: lock mode */ { - const lock_t* lock; + lock_t* lock; ut_ad(lock_mutex_own()); @@ -5315,7 +5345,7 @@ lock_table( #endif trx_t* trx; dberr_t err; - const lock_t* wait_for; + lock_t* wait_for; ut_ad(table != NULL); ut_ad(thr != NULL); @@ -5362,13 +5392,13 @@ lock_table( if (wait_for != NULL) { #ifdef WITH_WSREP - err = lock_table_enqueue_waiting((ib_lock_t*)wait_for, mode | flags, table, thr); + err = lock_table_enqueue_waiting(wait_for, mode | flags, table, thr); #else err = lock_table_enqueue_waiting(mode | flags, table, thr); #endif } else { #ifdef WITH_WSREP - lock_table_create(c_lock, table, mode | flags, trx); + lock_table_create(c_lock, table, mode | flags, trx); #else lock_table_create(table, mode | flags, trx); #endif @@ -7036,10 +7066,10 @@ lock_rec_insert_check_and_lock( on the successor, which produced an unnecessary deadlock. */ #ifdef WITH_WSREP - if ((c_lock = (ib_lock_t*)lock_rec_other_has_conflicting( - static_cast( - LOCK_X | LOCK_GAP | LOCK_INSERT_INTENTION), - block, next_rec_heap_no, trx))) { + if ((c_lock = lock_rec_other_has_conflicting( + static_cast( + LOCK_X | LOCK_GAP | LOCK_INSERT_INTENTION), + block, next_rec_heap_no, trx))) { #else if (lock_rec_other_has_conflicting( static_cast( @@ -7052,7 +7082,7 @@ lock_rec_insert_check_and_lock( #ifdef WITH_WSREP err = lock_rec_enqueue_waiting(c_lock, - LOCK_X | LOCK_GAP | LOCK_INSERT_INTENTION, + LOCK_X | LOCK_GAP | LOCK_INSERT_INTENTION, block, next_rec_heap_no, index, thr); #else err = lock_rec_enqueue_waiting( diff --git a/storage/innobase/lock/lock0wait.cc b/storage/innobase/lock/lock0wait.cc index ca9d05a4829..a0f557e18e5 100644 --- a/storage/innobase/lock/lock0wait.cc +++ b/storage/innobase/lock/lock0wait.cc @@ -191,22 +191,25 @@ 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"); - srv_print_innodb_monitor = TRUE; - srv_print_innodb_lock_monitor = TRUE; - os_event_set(srv_monitor_event); - return TRUE; - } - return FALSE; - } + if (wsrep_on_trx(trx) + && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { + fprintf(stderr, "WSREP: BF lock wait long for trx " TRX_ID_FMT "\n", trx->id); + srv_print_innodb_monitor = TRUE; + srv_print_innodb_lock_monitor = TRUE; + os_event_set(srv_monitor_event); + return true; + } + return false; +} #endif /* WITH_WSREP */ /***************************************************************//** @@ -402,15 +405,15 @@ lock_wait_suspend_thread( if (lock_wait_timeout < 100000000 && wait_time > (double) lock_wait_timeout) { #ifdef WITH_WSREP - if (!wsrep_on_trx(trx) || - (!wsrep_is_BF_lock_timeout(trx) && - trx->error_state != DB_DEADLOCK)) { + if (!wsrep_on_trx(trx) || + (!wsrep_is_BF_lock_timeout(trx) && + trx->error_state != DB_DEADLOCK)) { #endif /* WITH_WSREP */ - trx->error_state = DB_LOCK_WAIT_TIMEOUT; + trx->error_state = DB_LOCK_WAIT_TIMEOUT; #ifdef WITH_WSREP - } + } #endif /* WITH_WSREP */ MONITOR_INC(MONITOR_TIMEOUT); } diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 28e3b23b667..8487c5b2510 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -3934,6 +3934,17 @@ innobase_init( } } +#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) { + /* Do not allow InnoDB startup with VATS and Galera */ + sql_print_error("In Galera environment Variance-Aware-Transaction-Sheduling Algorithm" + " is not supported."); + goto error; + } +#endif /* WITH_WSREP */ + #ifndef HAVE_LZ4 if (innodb_compression_algorithm == PAGE_LZ4_ALGORITHM) { sql_print_error("InnoDB: innodb_compression_algorithm = %lu unsupported.\n" @@ -5485,8 +5496,8 @@ innobase_kill_connection( wsrep_thd_is_BF(current_thd, FALSE), lock_get_info(trx->lock.wait_lock).c_str()); - if (!wsrep_thd_is_BF(trx->mysql_thd, FALSE) && - trx->abort_type == TRX_SERVER_ABORT) { + if (!wsrep_thd_is_BF(trx->mysql_thd, FALSE) + && trx->abort_type == TRX_SERVER_ABORT) { ut_ad(!lock_mutex_own()); lock_mutex_enter(); } @@ -20500,7 +20511,7 @@ static MYSQL_SYSVAR_ENUM(empty_free_list_algorithm, &innodb_empty_free_list_algorithm_typelib); 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/xtradb/lock/lock0lock.cc b/storage/xtradb/lock/lock0lock.cc index ddaeff69f10..20e3f5adeb7 100644 --- a/storage/xtradb/lock/lock0lock.cc +++ b/storage/xtradb/lock/lock0lock.cc @@ -937,14 +937,21 @@ lock_reset_lock_and_trx_wait( ib_logf(IB_LOG_LEVEL_INFO, "Trx id " TRX_ID_FMT - " is waiting a lock in statement %s" + " is waiting a lock " " for this trx id " TRX_ID_FMT - " and statement %s wait_lock %p", + " wait_lock %p", lock->trx->id, - stmt ? stmt : "NULL", trx_id, - stmt2 ? stmt2 : "NULL", lock->trx->lock.wait_lock); + + if (stmt) { + ib_logf(IB_LOG_LEVEL_INFO, " SQL1: %s\n", stmt); + } + + if (stmt2) { + ib_logf(IB_LOG_LEVEL_INFO, " SQL2: %s\n", stmt2); + } + ut_ad(lock->trx->lock.wait_lock == lock); } @@ -1162,7 +1169,7 @@ lock_rec_has_to_wait( type_mode, lock_is_on_supremum); fprintf(stderr, "conflicts states: my %d locked %d\n", - wsrep_thd_conflict_state(trx->mysql_thd, FALSE), + wsrep_thd_conflict_state(trx->mysql_thd, FALSE), wsrep_thd_conflict_state(lock2->trx->mysql_thd, FALSE) ); lock_rec_print(stderr, lock2); if (for_locking) return FALSE; @@ -1714,7 +1721,7 @@ lock_rec_other_has_expl_req( ulint heap_no,/*!< in: heap number of the record */ trx_id_t trx_id) /*!< in: transaction */ { - const lock_t* lock; + lock_t* lock; ut_ad(lock_mutex_own()); ut_ad(mode == LOCK_X || mode == LOCK_S); @@ -1723,7 +1730,7 @@ lock_rec_other_has_expl_req( for (lock = lock_rec_get_first(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->id != trx_id && (gap @@ -1810,7 +1817,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( /*===========================*/ enum lock_mode mode, /*!< in: LOCK_S or LOCK_X, @@ -1822,7 +1829,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; ibool is_supremum; ut_ad(lock_mutex_own()); @@ -1831,13 +1838,16 @@ lock_rec_other_has_conflicting( for (lock = lock_rec_get_first(block, heap_no); lock != NULL; - lock = lock_rec_get_next_const(heap_no, lock)) { + lock = lock_rec_get_next(heap_no, lock)) { #ifdef WITH_WSREP if (lock_rec_has_to_wait(TRUE, trx, mode, lock, is_supremum)) { if (wsrep_on_trx(trx)) { trx_mutex_enter(lock->trx); - wsrep_kill_victim(trx, lock); + /* Below function will roll back either trx + or lock->trx depending on priority of the + transaction. */ + wsrep_kill_victim(const_cast(trx), lock); trx_mutex_exit(lock->trx); } #else @@ -2045,15 +2055,17 @@ wsrep_print_wait_locks( { if (wsrep_debug && c_lock->trx->lock.wait_lock != c_lock) { fprintf(stderr, "WSREP: c_lock != wait lock\n"); - if (lock_get_type_low(c_lock) & LOCK_TABLE) + if (lock_get_type_low(c_lock) & LOCK_TABLE) { lock_table_print(stderr, c_lock); - else + } else { lock_rec_print(stderr, c_lock); + } - if (lock_get_type_low(c_lock->trx->lock.wait_lock) & LOCK_TABLE) + if (lock_get_type_low(c_lock->trx->lock.wait_lock) & LOCK_TABLE) { lock_table_print(stderr, c_lock->trx->lock.wait_lock); - else + } else { lock_rec_print(stderr, c_lock->trx->lock.wait_lock); + } } } #endif /* WITH_WSREP */ @@ -2358,8 +2370,8 @@ lock_rec_create( if (wsrep_debug) { fprintf( stderr, - "WSREP: c_lock canceled %llu\n", - (ulonglong) c_lock->trx->id); + "WSREP: c_lock canceled " TRX_ID_FMT "\n", + c_lock->trx->id); } /* have to bail out here to avoid lock_set_lock... */ @@ -2551,6 +2563,16 @@ lock_rec_enqueue_waiting( err = DB_LOCK_WAIT; } +#ifdef WITH_WSREP + if (!lock_get_wait(lock) && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { + if (wsrep_debug) { + fprintf(stderr, "WSREP: BF thread got lock granted early, ID " TRX_ID_FMT + "\n", + lock->trx->id); + } + return(DB_SUCCESS); + } +#endif /* WITH_WSREP */ // Move it only when it does not cause a deadlock. if (err != DB_DEADLOCK && innodb_lock_schedule_algorithm @@ -2981,6 +3003,15 @@ 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) { + fprintf(stderr, + "BF-BF lock conflict " TRX_ID_FMT + " : " TRX_ID_FMT "\n", + wait_lock->trx->id, + lock->trx->id); + lock_rec_print(stderr, wait_lock); + lock_rec_print(stderr, lock); + } /* don't wait for another BF lock */ continue; } @@ -3139,7 +3170,7 @@ lock_grant_and_move_on_page( && !lock_rec_has_to_wait_in_queue(lock)) { lock_grant(lock, false); - + if (previous != NULL) { /* Move the lock to the head of the list. */ HASH_GET_NEXT(hash, previous) = HASH_GET_NEXT(hash, lock); @@ -5017,8 +5048,8 @@ lock_table_create( } if (wsrep_debug) { - fprintf(stderr, "WSREP: c_lock canceled %llu\n", - (ulonglong) c_lock->trx->id); + fprintf(stderr, "WSREP: c_lock canceled " TRX_ID_FMT "\n", + c_lock->trx->id); } } if (c_lock) { @@ -5297,7 +5328,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 @@ -5308,7 +5339,7 @@ lock_table_other_has_incompatible( const dict_table_t* table, /*!< in: table */ enum lock_mode mode) /*!< in: lock mode */ { - const lock_t* lock; + lock_t* lock; ut_ad(lock_mutex_own()); @@ -5361,7 +5392,7 @@ lock_table( #endif trx_t* trx; dberr_t err; - const lock_t* wait_for; + lock_t* wait_for; ut_ad(table != NULL); ut_ad(thr != NULL); @@ -5412,13 +5443,13 @@ lock_table( if (wait_for != NULL) { #ifdef WITH_WSREP - err = lock_table_enqueue_waiting((ib_lock_t*)wait_for, mode | flags, table, thr); + err = lock_table_enqueue_waiting(wait_for, mode | flags, table, thr); #else err = lock_table_enqueue_waiting(mode | flags, table, thr); #endif } else { #ifdef WITH_WSREP - lock_table_create(c_lock, table, mode | flags, trx); + lock_table_create(c_lock, table, mode | flags, trx); #else lock_table_create(table, mode | flags, trx); #endif @@ -7101,10 +7132,10 @@ lock_rec_insert_check_and_lock( on the successor, which produced an unnecessary deadlock. */ #ifdef WITH_WSREP - if ((c_lock = (ib_lock_t*)lock_rec_other_has_conflicting( - static_cast( - LOCK_X | LOCK_GAP | LOCK_INSERT_INTENTION), - block, next_rec_heap_no, trx))) { + if ((c_lock = lock_rec_other_has_conflicting( + static_cast( + LOCK_X | LOCK_GAP | LOCK_INSERT_INTENTION), + block, next_rec_heap_no, trx))) { #else if (lock_rec_other_has_conflicting( static_cast( @@ -7117,7 +7148,7 @@ lock_rec_insert_check_and_lock( #ifdef WITH_WSREP err = lock_rec_enqueue_waiting(c_lock, - LOCK_X | LOCK_GAP | LOCK_INSERT_INTENTION, + LOCK_X | LOCK_GAP | LOCK_INSERT_INTENTION, block, next_rec_heap_no, index, thr); #else err = lock_rec_enqueue_waiting( diff --git a/storage/xtradb/lock/lock0wait.cc b/storage/xtradb/lock/lock0wait.cc index ca9d05a4829..a0f557e18e5 100644 --- a/storage/xtradb/lock/lock0wait.cc +++ b/storage/xtradb/lock/lock0wait.cc @@ -191,22 +191,25 @@ 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"); - srv_print_innodb_monitor = TRUE; - srv_print_innodb_lock_monitor = TRUE; - os_event_set(srv_monitor_event); - return TRUE; - } - return FALSE; - } + if (wsrep_on_trx(trx) + && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { + fprintf(stderr, "WSREP: BF lock wait long for trx " TRX_ID_FMT "\n", trx->id); + srv_print_innodb_monitor = TRUE; + srv_print_innodb_lock_monitor = TRUE; + os_event_set(srv_monitor_event); + return true; + } + return false; +} #endif /* WITH_WSREP */ /***************************************************************//** @@ -402,15 +405,15 @@ lock_wait_suspend_thread( if (lock_wait_timeout < 100000000 && wait_time > (double) lock_wait_timeout) { #ifdef WITH_WSREP - if (!wsrep_on_trx(trx) || - (!wsrep_is_BF_lock_timeout(trx) && - trx->error_state != DB_DEADLOCK)) { + if (!wsrep_on_trx(trx) || + (!wsrep_is_BF_lock_timeout(trx) && + trx->error_state != DB_DEADLOCK)) { #endif /* WITH_WSREP */ - trx->error_state = DB_LOCK_WAIT_TIMEOUT; + trx->error_state = DB_LOCK_WAIT_TIMEOUT; #ifdef WITH_WSREP - } + } #endif /* WITH_WSREP */ MONITOR_INC(MONITOR_TIMEOUT); } -- cgit v1.2.1 From feb8296ee61cbd349a8bc13cac4e126306039fb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Sat, 9 Dec 2017 11:21:23 +0200 Subject: MDEV-14401: Stored procedure that declares a handler that catches ER_LOCK_DEADLOCK error causes thd->is_error() assertion This was missing bug fix from MySQL wsrep i.e. Galera. Problem was that if stored procedure declares a handler that catches deadlock error, then the error may have been cleared in method sp_rcontext::handle_sql_condition(). Use wsrep_conflict_state correctly to determine is the error already sent to client. Add test case for both this bug and MDEV-12837: WSREP: BF lock wait long. Test requires both fixes to pass. --- .../suite/galera/r/galera_bf_lock_wait.result | 18 ++++++++ mysql-test/suite/galera/t/galera_bf_lock_wait.test | 52 ++++++++++++++++++++++ sql/sql_parse.cc | 33 +++++++++----- 3 files changed, 91 insertions(+), 12 deletions(-) create mode 100644 mysql-test/suite/galera/r/galera_bf_lock_wait.result create mode 100644 mysql-test/suite/galera/t/galera_bf_lock_wait.test 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..4e6019ec8ad --- /dev/null +++ b/mysql-test/suite/galera/r/galera_bf_lock_wait.result @@ -0,0 +1,18 @@ +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| +call p1; +call p1; +call p1; +call p1; +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/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/sql/sql_parse.cc b/sql/sql_parse.cc index 7337a8aeb21..5cea264e4a8 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -5041,14 +5041,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: @@ -5085,13 +5090,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: @@ -5720,8 +5728,9 @@ finish: if (thd->is_error() || (thd->variables.option_bits & OPTION_MASTER_SQL_ERROR)) 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)) { /* -- cgit v1.2.1 From de76cbdcb0728b80c0f7b453b24b0b81f653e450 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Sat, 9 Dec 2017 11:21:56 +0200 Subject: Add Galera test cases that fail to disabled. --- mysql-test/suite/galera/disabled.def | 5 +++++ mysql-test/suite/galera/r/MW-388.result | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index cd19fccd483..b67dea0f2f4 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -54,3 +54,8 @@ galera_pc_ignore_sb : MDEV-13549 Galera test failures 10.1 galera_lock_table : MDEV-13549 Galera test failures 10.1 MW-284 : MDEV-13549 Galera test failures 10.1 galera_as_slave : MDEV-13549 Galera test failures 10.1 +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 \ No newline at end of file diff --git a/mysql-test/suite/galera/r/MW-388.result b/mysql-test/suite/galera/r/MW-388.result index 17d347a11fb..59d4d4a2bf3 100644 --- a/mysql-test/suite/galera/r/MW-388.result +++ b/mysql-test/suite/galera/r/MW-388.result @@ -25,7 +25,7 @@ SET DEBUG_SYNC = "now SIGNAL wsrep_after_replication_continue"; SET DEBUG_SYNC = "now SIGNAL signal.wsrep_apply_cb"; SELECT @errno = 1213; @errno = 1213 -1 +0 SELECT * FROM t1; f1 f2 1 node 2 -- cgit v1.2.1 From 1e6ac94451ff11c0a96843c26b55fecb9e30a57d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 11 Dec 2017 12:37:19 +0200 Subject: Correct the comment of row_vers_impl_x_locked() --- storage/innobase/include/row0vers.h | 20 +++++++-------- storage/innobase/row/row0vers.cc | 49 +++++++++++++++++++------------------ 2 files changed, 35 insertions(+), 34 deletions(-) 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/row/row0vers.cc b/storage/innobase/row/row0vers.cc index c5d08e1ece6..23ba751ea67 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; @@ -325,19 +327,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; -- cgit v1.2.1 From 434c9e6f0e6c6aa09953f2367ab4db42a1f26f53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 11 Dec 2017 13:55:05 +0200 Subject: MDEV-14614 InnoDB: Failing assertion in dict_stats_rename_table() dict_stats_rename_table(): After DB_LOCK_WAIT_TIMEOUT or DB_DUPLICATE_KEY, reset the trx->error_state before retrying. Also, properly treat DB_DEADLOCK as a hard error. --- storage/innobase/dict/dict0stats.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc index e4aca96da4b..662ea959b9e 100644 --- a/storage/innobase/dict/dict0stats.cc +++ b/storage/innobase/dict/dict0stats.cc @@ -3659,8 +3659,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: @@ -3701,8 +3701,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: -- cgit v1.2.1 From 13b9ec651a807be59139fc295431d7ad14d3c8db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 11 Dec 2017 14:39:53 +0200 Subject: MDEV-14589 InnoDB should not lock a delete-marked record When the transaction isolation level is SERIALIZABLE, or when a locking read is performed in the REPEATABLE READ isolation level, InnoDB must lock delete-marked records in order to prevent another transaction from inserting something. However, at READ UNCOMMITTED or READ COMMITTED isolation level or when the parameter innodb_locks_unsafe_for_binlog is set, the repeatability of the reads does not matter, and there is no need to lock any records. row_search_mvcc(): Skip locks on delete-marked committed records upfront, instead of invoking row_unlock_for_mysql() afterwards. The unlocking never worked for secondary index records. --- mysql-test/suite/innodb/r/lock_deleted.result | 57 +++++++++++++++++++++ mysql-test/suite/innodb/t/lock_deleted.test | 72 +++++++++++++++++++++++++++ storage/innobase/row/row0sel.cc | 51 ++++++++++++++----- 3 files changed, 167 insertions(+), 13 deletions(-) create mode 100644 mysql-test/suite/innodb/r/lock_deleted.result create mode 100644 mysql-test/suite/innodb/t/lock_deleted.test 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/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/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc index 9bf71592f54..9cad3ab7de6 100644 --- a/storage/innobase/row/row0sel.cc +++ b/storage/innobase/row/row0sel.cc @@ -4890,9 +4890,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)) { @@ -5096,6 +5131,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 @@ -5103,17 +5139,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 -- cgit v1.2.1 From e12f77a7e3c29a1c1418e2b87194d0f06e2711e2 Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Tue, 12 Dec 2017 01:33:03 +0300 Subject: MDEV-14389: MyRocks and NOPAD collations Disallow use of NOPAD collations in indexed columns. --- sql/share/errmsg-utf8.txt | 4 ++++ storage/rocksdb/ha_rocksdb.cc | 27 +++++++++++++++++++--- .../mysql-test/rocksdb/r/mariadb_port_fixes.result | 9 ++++++++ .../mysql-test/rocksdb/t/mariadb_port_fixes.test | 13 +++++++++++ 4 files changed, 50 insertions(+), 3 deletions(-) diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 32f1a25e126..528dc7107e6 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -7749,3 +7749,7 @@ 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." + diff --git a/storage/rocksdb/ha_rocksdb.cc b/storage/rocksdb/ha_rocksdb.cc index e08329ab61e..564832993ce 100644 --- a/storage/rocksdb/ha_rocksdb.cc +++ b/storage/rocksdb/ha_rocksdb.cc @@ -5964,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. @@ -6072,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) { @@ -6085,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/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/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; -- cgit v1.2.1 From 86c69263a441dd6fb2de180dba846eb4fc53a5f0 Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Tue, 12 Dec 2017 13:31:41 +0300 Subject: MDEV-14389: MyRocks and NOPAD collations Part #2: Take into accont the fact that three binary collations that we handle are technically NOPAD collations --- storage/rocksdb/ha_rocksdb.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/storage/rocksdb/ha_rocksdb.cc b/storage/rocksdb/ha_rocksdb.cc index 564832993ce..a9d37c1def2 100644 --- a/storage/rocksdb/ha_rocksdb.cc +++ b/storage/rocksdb/ha_rocksdb.cc @@ -5971,6 +5971,15 @@ rdb_field_uses_nopad_collation(const my_core::Field *const field) { /* Handle [VAR](CHAR|BINARY) or TEXT|BLOB */ if (type == MYSQL_TYPE_VARCHAR || type == MYSQL_TYPE_STRING || type == MYSQL_TYPE_BLOB) { + + /* + This is technically a NOPAD collation but it's a binary collation + that we can handle. + */ + if (RDB_INDEX_COLLATIONS.find(field->charset()->number) != + RDB_INDEX_COLLATIONS.end()) + return false; + return (field->charset()->state & MY_CS_NOPAD); } return false; -- cgit v1.2.1 From a3476a5de2ee87e0881742eda7ebe0310d1c3f61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 12 Dec 2017 20:00:28 +0200 Subject: =?UTF-8?q?Skip=20btr=5Fsearch=5Flatches[]=C2=A0in=20SHOW=20ENGINE?= =?UTF-8?q?=20INNODB=20STATUS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ha_print_info(): Remove. srv_printf_innodb_monitor(): Do not acquire btr_search_latches[] Add the equivalent functionality that was part of the non-debug version of ha_print_info(). --- storage/innobase/ha/ha0ha.cc | 58 ---------------------------------------- storage/innobase/include/ha0ha.h | 7 ----- storage/innobase/srv/srv0srv.cc | 25 ++++++++++++++--- 3 files changed, 22 insertions(+), 68 deletions(-) diff --git a/storage/innobase/ha/ha0ha.cc b/storage/innobase/ha/ha0ha.cc index f620db6f62e..da542d4f742 100644 --- a/storage/innobase/ha/ha0ha.cc +++ b/storage/innobase/ha/ha0ha.cc @@ -489,62 +489,4 @@ ha_validate( return(ok); } #endif /* defined UNIV_AHI_DEBUG || defined UNIV_DEBUG */ - -/*************************************************************//** -Prints info of a hash table. */ -void -ha_print_info( -/*==========*/ - FILE* file, /*!< in: file where to print */ - hash_table_t* table) /*!< in: hash table */ -{ -#ifdef UNIV_DEBUG -/* Some of the code here is disabled for performance reasons in production -builds, see http://bugs.mysql.com/36941 */ -#define PRINT_USED_CELLS -#endif /* UNIV_DEBUG */ - -#ifdef PRINT_USED_CELLS - hash_cell_t* cell; - ulint cells = 0; - ulint i; -#endif /* PRINT_USED_CELLS */ - ulint n_bufs; - - ut_ad(table); - ut_ad(table->magic_n == HASH_TABLE_MAGIC_N); -#ifdef PRINT_USED_CELLS - for (i = 0; i < hash_get_n_cells(table); i++) { - - cell = hash_get_nth_cell(table, i); - - if (cell->node) { - - cells++; - } - } -#endif /* PRINT_USED_CELLS */ - - fprintf(file, "Hash table size %lu", - (ulong) hash_get_n_cells(table)); - -#ifdef PRINT_USED_CELLS - fprintf(file, ", used cells %lu", (ulong) cells); -#endif /* PRINT_USED_CELLS */ - - if (table->heaps == NULL && table->heap != NULL) { - - /* This calculation is intended for the adaptive hash - index: how many buffer frames we have reserved? */ - - n_bufs = UT_LIST_GET_LEN(table->heap->base) - 1; - - if (table->heap->free_block) { - n_bufs++; - } - - fprintf(file, ", node heap has %lu buffer(s)\n", - (ulong) n_bufs); - } -} #endif /* BTR_CUR_HASH_ADAPT */ diff --git a/storage/innobase/include/ha0ha.h b/storage/innobase/include/ha0ha.h index db53b6c6580..ca4cb0a5f8f 100644 --- a/storage/innobase/include/ha0ha.h +++ b/storage/innobase/include/ha0ha.h @@ -198,13 +198,6 @@ ha_validate( ulint start_index, /*!< in: start index */ ulint end_index); /*!< in: end index */ #endif /* defined UNIV_AHI_DEBUG || defined UNIV_DEBUG */ -/*************************************************************//** -Prints info of a hash table. */ -void -ha_print_info( -/*==========*/ - FILE* file, /*!< in: file where to print */ - hash_table_t* table); /*!< in: hash table */ /** The hash table external chain node */ struct ha_node_t { diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc index b6d9fbe635d..d9eeaa82117 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -1323,9 +1323,28 @@ srv_printf_innodb_monitor( #ifdef BTR_CUR_HASH_ADAPT for (ulint i = 0; i < btr_ahi_parts; ++i) { - rw_lock_s_lock(btr_search_latches[i]); - ha_print_info(file, btr_search_sys->hash_tables[i]); - rw_lock_s_unlock(btr_search_latches[i]); + const hash_table_t* table = btr_search_sys->hash_tables[i]; + + ut_ad(table->magic_n == HASH_TABLE_MAGIC_N); + /* this is only used for buf_pool->page_hash */ + ut_ad(!table->heaps); + /* this is used for the adaptive hash index */ + ut_ad(table->heap); + + const mem_heap_t* heap = table->heap; + /* The heap may change during the following call, + so the data displayed may be garbage. We intentionally + avoid acquiring btr_search_latches[] so that the + diagnostic output will not stop here even in case another + thread hangs while holding btr_search_latches[]. + + This should be safe from crashes, because + table->heap will be pointing to the same object + for the full lifetime of the server. Even during + btr_search_disable() the heap will stay valid. */ + fprintf(file, "Hash table size " ULINTPF + ", node heap has " ULINTPF " buffer(s)\n", + table->n_cells, heap->base.count - !heap->free_block); } fprintf(file, -- cgit v1.2.1 From 0e69d0b094365c36d01180d10fcc6534143a25b5 Mon Sep 17 00:00:00 2001 From: Elena Stepanova Date: Wed, 13 Dec 2017 00:29:44 +0200 Subject: MDEV-14607 storage_engine-rocksdb.type_bit_indexes fails after latest pushes --- .../suite/storage_engine/type_bit_indexes.result | 4 ++-- .../rocksdb/mysql-test/storage_engine/disabled.def | 1 + .../mysql-test/storage_engine/type_bit_indexes.rdiff | 20 ++++++++++++++++++++ .../storage_engine/type_enum_indexes.rdiff | 11 +++++++++++ .../mysql-test/storage_engine/type_set_indexes.rdiff | 20 ++++++++++++++++++++ 5 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 storage/rocksdb/mysql-test/storage_engine/type_bit_indexes.rdiff create mode 100644 storage/rocksdb/mysql-test/storage_engine/type_enum_indexes.rdiff create mode 100644 storage/rocksdb/mysql-test/storage_engine/type_set_indexes.rdiff diff --git a/mysql-test/suite/storage_engine/type_bit_indexes.result b/mysql-test/suite/storage_engine/type_bit_indexes.result index e7c0cf656c5..af8ddf7d6c9 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 -# # # # # NULL # # # # +# # # # # b_c # # # # 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 -# # # # # NULL # # # # +# # # # # a # # # # SELECT DISTINCT a+0 FROM t1 ORDER BY a; a+0 0 diff --git a/storage/rocksdb/mysql-test/storage_engine/disabled.def b/storage/rocksdb/mysql-test/storage_engine/disabled.def index 0643b2052e2..930e1d82b87 100644 --- a/storage/rocksdb/mysql-test/storage_engine/disabled.def +++ b/storage/rocksdb/mysql-test/storage_engine/disabled.def @@ -14,6 +14,7 @@ lock_concurrent : MDEV-13148 - LOCK TABLE on RocksDB table fails with a bog optimize_table : MDEV-13148 - LOCK TABLE on RocksDB table fails with a bogus error message repair_table : MDEV-13148 - LOCK TABLE on RocksDB table fails with a bogus error message select_high_prio : Not supported +show_engine : SHOW ENGINE produces different number of lines depending on previous tests show_table_status : MDEV-13152 - Indeterministic row number in SHOW TABLE STATUS on RocksDB table tbl_opt_data_dir : Not supported tbl_opt_index_dir : Not supported diff --git a/storage/rocksdb/mysql-test/storage_engine/type_bit_indexes.rdiff b/storage/rocksdb/mysql-test/storage_engine/type_bit_indexes.rdiff new file mode 100644 index 00000000000..e53a33b4fba --- /dev/null +++ b/storage/rocksdb/mysql-test/storage_engine/type_bit_indexes.rdiff @@ -0,0 +1,20 @@ +--- suite/storage_engine/type_bit_indexes.result 2017-12-12 20:34:34.000000000 +0200 ++++ suite/storage_engine/type_bit_indexes.reject 2017-12-12 20:35:24.539330056 +0200 +@@ -69,7 +69,7 @@ + (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 @@ + (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/storage/rocksdb/mysql-test/storage_engine/type_enum_indexes.rdiff b/storage/rocksdb/mysql-test/storage_engine/type_enum_indexes.rdiff new file mode 100644 index 00000000000..be83fb6e212 --- /dev/null +++ b/storage/rocksdb/mysql-test/storage_engine/type_enum_indexes.rdiff @@ -0,0 +1,11 @@ +--- suite/storage_engine/type_enum_indexes.result 2017-03-12 04:38:50.000000000 +0200 ++++ suite/storage_engine/type_enum_indexes.reject 2017-12-12 20:36:47.455331726 +0200 +@@ -30,7 +30,7 @@ + t1 0 a_b 2 b # # NULL NULL # # + EXPLAIN SELECT a FROM t1 WHERE b > 'test2' ORDER BY a; + id select_type table type possible_keys key key_len ref rows Extra +-# # # # # a_b # # # # ++# # # # # NULL # # # # + SELECT a FROM t1 WHERE b > 'test2' ORDER BY a; + a + Africa diff --git a/storage/rocksdb/mysql-test/storage_engine/type_set_indexes.rdiff b/storage/rocksdb/mysql-test/storage_engine/type_set_indexes.rdiff new file mode 100644 index 00000000000..2703e81b745 --- /dev/null +++ b/storage/rocksdb/mysql-test/storage_engine/type_set_indexes.rdiff @@ -0,0 +1,20 @@ +--- suite/storage_engine/type_set_indexes.result 2017-03-12 04:38:50.000000000 +0200 ++++ suite/storage_engine/type_set_indexes.reject 2017-12-12 20:37:16.187332305 +0200 +@@ -97,7 +97,7 @@ + Warning 1265 Data truncated for column 'b' at row 7 + EXPLAIN SELECT a FROM t1 WHERE FIND_IN_SET('Europe',a) > 0; + id select_type table type possible_keys key key_len ref rows Extra +-# # # # # a # # # # ++# # # # # NULL # # # # + SELECT a FROM t1 WHERE FIND_IN_SET('Europe',a) > 0; + a + Africa,Europe,Asia +@@ -124,7 +124,7 @@ + Warning 1265 Data truncated for column 'b' at row 7 + EXPLAIN SELECT DISTINCT a, b FROM t1 ORDER BY b DESC, a; + id select_type table type possible_keys key key_len ref rows Extra +-# # # # # b_a # # # # ++# # # # # NULL # # # # + SELECT DISTINCT a, b FROM t1 ORDER BY b DESC, a; + a b + test1,test3 -- cgit v1.2.1 From b93a87f18682f9b0b5fed8e7bc4d3241cfe13074 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 13 Dec 2017 12:52:28 +0200 Subject: Try to prevent sporadic test failures On Windows, sometimes more files stay open: [Warning] InnoDB: innodb_open_files=13 is exceeded (15 files stay open) --- mysql-test/suite/innodb/t/table_definition_cache_debug.opt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/suite/innodb/t/table_definition_cache_debug.opt b/mysql-test/suite/innodb/t/table_definition_cache_debug.opt index 6195e055dc8..6d341857397 100644 --- a/mysql-test/suite/innodb/t/table_definition_cache_debug.opt +++ b/mysql-test/suite/innodb/t/table_definition_cache_debug.opt @@ -1 +1 @@ ---innodb-open-files=13 +--innodb-open-files=20 -- cgit v1.2.1 From 58eb4e5db9e333768cc927d5d5a63d68fbd74548 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 13 Dec 2017 14:16:15 +0200 Subject: MDEV-14422 Assertion failure in trx_purge_run() on shutdown row_quiesce_table_start(), row_quiesce_table_complete(): Use the more appropriate predicate srv_undo_sources for skipping purge control. (This change alone is insufficient; it is possible that this predicate will change during the call to trx_purge_stop() or trx_purge_run().) trx_purge_stop(), trx_purge_run(): Tolerate PURGE_STATE_EXIT. It is very well possible to initiate shutdown soon after the statement FLUSH TABLES FOR EXPORT has been submitted to execution. srv_purge_coordinator_thread(): Ensure that the wait for purge_sys->event in trx_purge_stop() will terminate when the coordinator thread exits. --- storage/innobase/row/row0quiesce.cc | 4 +-- storage/innobase/srv/srv0srv.cc | 3 ++ storage/innobase/trx/trx0purge.cc | 70 ++++++++++++++++++------------------- 3 files changed, 40 insertions(+), 37 deletions(-) diff --git a/storage/innobase/row/row0quiesce.cc b/storage/innobase/row/row0quiesce.cc index dd6289c91e6..21cc67620f6 100644 --- a/storage/innobase/row/row0quiesce.cc +++ b/storage/innobase/row/row0quiesce.cc @@ -520,7 +520,7 @@ row_quiesce_table_start( ut_ad(fil_space_get(table->space) != NULL); ib::info() << "Sync to disk of " << table->name << " started."; - if (trx_purge_state() != PURGE_STATE_DISABLED) { + if (srv_undo_sources) { trx_purge_stop(); } @@ -603,7 +603,7 @@ row_quiesce_table_complete( ib::info() << "Deleting the meta-data file '" << cfg_name << "'"; } - if (trx_purge_state() != PURGE_STATE_DISABLED) { + if (srv_undo_sources) { trx_purge_run(); } diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc index d9eeaa82117..19be088912a 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -2872,6 +2872,9 @@ DECLARE_THREAD(srv_purge_coordinator_thread)( purge_sys->running = false; + /* Ensure that the wait in trx_purge_stop() will terminate. */ + os_event_set(purge_sys->event); + rw_lock_x_unlock(&purge_sys->latch); #ifdef UNIV_DEBUG_THREAD_CREATION diff --git a/storage/innobase/trx/trx0purge.cc b/storage/innobase/trx/trx0purge.cc index 61c36637a4e..4fd9333c0ba 100644 --- a/storage/innobase/trx/trx0purge.cc +++ b/storage/innobase/trx/trx0purge.cc @@ -1770,52 +1770,48 @@ void trx_purge_stop(void) /*================*/ { - ut_a(srv_n_purge_threads > 0); - rw_lock_x_lock(&purge_sys->latch); - const int64_t sig_count = os_event_reset(purge_sys->event); - const purge_state_t state = purge_sys->state; - - ut_a(state == PURGE_STATE_RUN || state == PURGE_STATE_STOP); - - ++purge_sys->n_stop; - - if (state == PURGE_STATE_RUN) { + switch (purge_sys->state) { + case PURGE_STATE_INIT: + case PURGE_STATE_DISABLED: + ut_error; + case PURGE_STATE_EXIT: + /* Shutdown must have been initiated during + FLUSH TABLES FOR EXPORT. */ + ut_ad(!srv_undo_sources); +unlock: + rw_lock_x_unlock(&purge_sys->latch); + break; + case PURGE_STATE_STOP: + ut_ad(srv_n_purge_threads > 0); + ++purge_sys->n_stop; + purge_sys->state = PURGE_STATE_STOP; + if (!purge_sys->running) { + goto unlock; + } + ib::info() << "Waiting for purge to stop"; + do { + rw_lock_x_unlock(&purge_sys->latch); + os_thread_sleep(10000); + rw_lock_x_lock(&purge_sys->latch); + } while (purge_sys->running); + goto unlock; + case PURGE_STATE_RUN: + ut_ad(srv_n_purge_threads > 0); + ++purge_sys->n_stop; ib::info() << "Stopping purge"; /* We need to wakeup the purge thread in case it is suspended, so that it can acknowledge the state change. */ + const int64_t sig_count = os_event_reset(purge_sys->event); + purge_sys->state = PURGE_STATE_STOP; srv_purge_wakeup(); - } - - purge_sys->state = PURGE_STATE_STOP; - - if (state != PURGE_STATE_STOP) { rw_lock_x_unlock(&purge_sys->latch); /* Wait for purge coordinator to signal that it is suspended. */ os_event_wait_low(purge_sys->event, sig_count); - } else { - bool once = true; - - /* Wait for purge to signal that it has actually stopped. */ - while (purge_sys->running) { - - if (once) { - ib::info() << "Waiting for purge to stop"; - once = false; - } - - rw_lock_x_unlock(&purge_sys->latch); - - os_thread_sleep(10000); - - rw_lock_x_lock(&purge_sys->latch); - } - - rw_lock_x_unlock(&purge_sys->latch); } MONITOR_INC_VALUE(MONITOR_PURGE_STOP_COUNT, 1); @@ -1830,8 +1826,12 @@ trx_purge_run(void) rw_lock_x_lock(&purge_sys->latch); switch (purge_sys->state) { - case PURGE_STATE_INIT: case PURGE_STATE_EXIT: + /* Shutdown must have been initiated during + FLUSH TABLES FOR EXPORT. */ + ut_ad(!srv_undo_sources); + break; + case PURGE_STATE_INIT: case PURGE_STATE_DISABLED: ut_error; -- cgit v1.2.1 From 6559ba71a564aecad487dee1fbb52fc42c768c8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 13 Dec 2017 16:18:08 +0200 Subject: MDEV-13797 InnoDB may hang if shutdown is initiated soon after startup while rolling back recovered incomplete transactions trx_rollback_resurrected(): If shutdown was initiated, fake all remaining active transactions to XA PREPARE state, so that shutdown can proceed. Also, make the parameter "all" an output that will be assigned to FALSE in this case. trx_rollback_or_clean_recovered(): Remove the shutdown check (it was moved to trx_rollback_resurrected()). trx_undo_free_prepared(): Relax assertions. --- mysql-test/suite/innodb/r/recovery_shutdown.result | 51 ++++++++++++++++++++++ mysql-test/suite/innodb/t/recovery_shutdown.test | 51 ++++++++++++++++++++++ storage/innobase/trx/trx0roll.cc | 37 ++++++++-------- storage/innobase/trx/trx0undo.cc | 16 +++++-- storage/xtradb/trx/trx0roll.cc | 37 ++++++++-------- storage/xtradb/trx/trx0undo.cc | 16 +++++-- 6 files changed, 166 insertions(+), 42 deletions(-) create mode 100644 mysql-test/suite/innodb/r/recovery_shutdown.result create mode 100644 mysql-test/suite/innodb/t/recovery_shutdown.test diff --git a/mysql-test/suite/innodb/r/recovery_shutdown.result b/mysql-test/suite/innodb/r/recovery_shutdown.result new file mode 100644 index 00000000000..028a0bd6239 --- /dev/null +++ b/mysql-test/suite/innodb/r/recovery_shutdown.result @@ -0,0 +1,51 @@ +# +# MDEV-13797 InnoDB may hang if shutdown is initiated soon after startup +# while rolling back recovered incomplete transactions +# +CREATE TABLE t (a INT) ENGINE=InnoDB; +BEGIN; +COMMIT; +CREATE TABLE t8 (a SERIAL, b INT UNIQUE, c INT UNIQUE) ENGINE=InnoDB; +BEGIN; +INSERT INTO t8 (a) SELECT NULL FROM t; +UPDATE t8 SET a=a+100, b=a; +DELETE FROM t8; +CREATE TABLE t7 (a SERIAL, b INT UNIQUE, c INT UNIQUE) ENGINE=InnoDB; +BEGIN; +INSERT INTO t7 (a) SELECT NULL FROM t; +UPDATE t7 SET a=a+100, b=a; +DELETE FROM t7; +CREATE TABLE t6 (a SERIAL, b INT UNIQUE, c INT UNIQUE) ENGINE=InnoDB; +BEGIN; +INSERT INTO t6 (a) SELECT NULL FROM t; +UPDATE t6 SET a=a+100, b=a; +DELETE FROM t6; +CREATE TABLE t5 (a SERIAL, b INT UNIQUE, c INT UNIQUE) ENGINE=InnoDB; +BEGIN; +INSERT INTO t5 (a) SELECT NULL FROM t; +UPDATE t5 SET a=a+100, b=a; +DELETE FROM t5; +CREATE TABLE t4 (a SERIAL, b INT UNIQUE, c INT UNIQUE) ENGINE=InnoDB; +BEGIN; +INSERT INTO t4 (a) SELECT NULL FROM t; +UPDATE t4 SET a=a+100, b=a; +DELETE FROM t4; +CREATE TABLE t3 (a SERIAL, b INT UNIQUE, c INT UNIQUE) ENGINE=InnoDB; +BEGIN; +INSERT INTO t3 (a) SELECT NULL FROM t; +UPDATE t3 SET a=a+100, b=a; +DELETE FROM t3; +CREATE TABLE t2 (a SERIAL, b INT UNIQUE, c INT UNIQUE) ENGINE=InnoDB; +BEGIN; +INSERT INTO t2 (a) SELECT NULL FROM t; +UPDATE t2 SET a=a+100, b=a; +DELETE FROM t2; +CREATE TABLE t1 (a SERIAL, b INT UNIQUE, c INT UNIQUE) ENGINE=InnoDB; +BEGIN; +INSERT INTO t1 (a) SELECT NULL FROM t; +UPDATE t1 SET a=a+100, b=a; +DELETE FROM t1; +SET GLOBAL innodb_flush_log_at_trx_commit=1; +CREATE TABLE u(a SERIAL) ENGINE=INNODB; +# Kill and restart +DROP TABLE t,u; diff --git a/mysql-test/suite/innodb/t/recovery_shutdown.test b/mysql-test/suite/innodb/t/recovery_shutdown.test new file mode 100644 index 00000000000..ea38bd19a9f --- /dev/null +++ b/mysql-test/suite/innodb/t/recovery_shutdown.test @@ -0,0 +1,51 @@ +--source include/have_innodb.inc +--source include/not_embedded.inc + +--echo # +--echo # MDEV-13797 InnoDB may hang if shutdown is initiated soon after startup +--echo # while rolling back recovered incomplete transactions +--echo # + +CREATE TABLE t (a INT) ENGINE=InnoDB; +let $size = 100; +let $trx = 8; +let $c = $size; +BEGIN; +--disable_query_log +while ($c) { +INSERT INTO t VALUES(); +dec $c; +} +--enable_query_log +COMMIT; + +let $c = $trx; +while ($c) +{ +connect (con$c,localhost,root,,); +eval CREATE TABLE t$c (a SERIAL, b INT UNIQUE, c INT UNIQUE) ENGINE=InnoDB; +BEGIN; +eval INSERT INTO t$c (a) SELECT NULL FROM t; +eval UPDATE t$c SET a=a+$size, b=a; +eval DELETE FROM t$c; +dec $c; +} + +--connection default +SET GLOBAL innodb_flush_log_at_trx_commit=1; +CREATE TABLE u(a SERIAL) ENGINE=INNODB; + +--source include/kill_and_restart_mysqld.inc +--source include/restart_mysqld.inc + +--disable_query_log +let $c = $trx; +while ($c) +{ +disconnect con$c; +eval DROP TABLE t$c; +dec $c; +} +--enable_query_log + +DROP TABLE t,u; diff --git a/storage/innobase/trx/trx0roll.cc b/storage/innobase/trx/trx0roll.cc index ae5e792a4bb..dbb902258c6 100644 --- a/storage/innobase/trx/trx0roll.cc +++ b/storage/innobase/trx/trx0roll.cc @@ -672,7 +672,7 @@ ibool trx_rollback_resurrected( /*=====================*/ trx_t* trx, /*!< in: transaction to rollback or clean */ - ibool all) /*!< in: FALSE=roll back dictionary transactions; + ibool* all) /*!< in/out: FALSE=roll back dictionary transactions; TRUE=roll back all non-PREPARED transactions */ { ut_ad(mutex_own(&trx_sys->mutex)); @@ -683,16 +683,15 @@ trx_rollback_resurrected( to accidentally clean up a non-recovered transaction here. */ trx_mutex_enter(trx); - bool is_recovered = trx->is_recovered; - trx_state_t state = trx->state; - trx_mutex_exit(trx); - - if (!is_recovered) { + if (!trx->is_recovered) { +func_exit: + trx_mutex_exit(trx); return(FALSE); } - switch (state) { + switch (trx->state) { case TRX_STATE_COMMITTED_IN_MEMORY: + trx_mutex_exit(trx); mutex_exit(&trx_sys->mutex); fprintf(stderr, "InnoDB: Cleaning up trx with id " TRX_ID_FMT "\n", @@ -701,7 +700,17 @@ trx_rollback_resurrected( trx_free_for_background(trx); return(TRUE); case TRX_STATE_ACTIVE: - if (all || trx_get_dict_operation(trx) != TRX_DICT_OP_NONE) { + if (srv_shutdown_state != SRV_SHUTDOWN_NONE + && srv_fast_shutdown) { + trx->state = TRX_STATE_PREPARED; + trx_sys->n_prepared_trx++; + trx_sys->n_prepared_recovered_trx++; + *all = FALSE; + goto func_exit; + } + trx_mutex_exit(trx); + + if (*all || trx_get_dict_operation(trx) != TRX_DICT_OP_NONE) { mutex_exit(&trx_sys->mutex); trx_rollback_active(trx); trx_free_for_background(trx); @@ -709,13 +718,13 @@ trx_rollback_resurrected( } return(FALSE); case TRX_STATE_PREPARED: - return(FALSE); + goto func_exit; case TRX_STATE_NOT_STARTED: break; } ut_error; - return(FALSE); + goto func_exit; } /*******************************************************************//** @@ -762,17 +771,11 @@ trx_rollback_or_clean_recovered( assert_trx_in_rw_list(trx); - if (srv_shutdown_state != SRV_SHUTDOWN_NONE - && srv_fast_shutdown != 0) { - all = FALSE; - break; - } - /* If this function does a cleanup or rollback then it will release the trx_sys->mutex, therefore we need to reacquire it before retrying the loop. */ - if (trx_rollback_resurrected(trx, all)) { + if (trx_rollback_resurrected(trx, &all)) { mutex_enter(&trx_sys->mutex); diff --git a/storage/innobase/trx/trx0undo.cc b/storage/innobase/trx/trx0undo.cc index 1836d282cd4..5638ccd17a6 100644 --- a/storage/innobase/trx/trx0undo.cc +++ b/storage/innobase/trx/trx0undo.cc @@ -2023,9 +2023,13 @@ trx_undo_free_prepared( /* fall through */ case TRX_UNDO_ACTIVE: /* lock_trx_release_locks() assigns - trx->is_recovered=false */ + trx->is_recovered=false and + trx->state = TRX_STATE_COMMITTED_IN_MEMORY, + also for transactions that we faked + to TRX_STATE_PREPARED in trx_rollback_resurrected(). */ ut_a(srv_read_only_mode - || srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO); + || srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO + || srv_fast_shutdown); break; default: ut_error; @@ -2047,9 +2051,13 @@ trx_undo_free_prepared( /* fall through */ case TRX_UNDO_ACTIVE: /* lock_trx_release_locks() assigns - trx->is_recovered=false */ + trx->is_recovered=false and + trx->state = TRX_STATE_COMMITTED_IN_MEMORY, + also for transactions that we faked + to TRX_STATE_PREPARED in trx_rollback_resurrected(). */ ut_a(srv_read_only_mode - || srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO); + || srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO + || srv_fast_shutdown); break; default: ut_error; diff --git a/storage/xtradb/trx/trx0roll.cc b/storage/xtradb/trx/trx0roll.cc index ae5e792a4bb..dbb902258c6 100644 --- a/storage/xtradb/trx/trx0roll.cc +++ b/storage/xtradb/trx/trx0roll.cc @@ -672,7 +672,7 @@ ibool trx_rollback_resurrected( /*=====================*/ trx_t* trx, /*!< in: transaction to rollback or clean */ - ibool all) /*!< in: FALSE=roll back dictionary transactions; + ibool* all) /*!< in/out: FALSE=roll back dictionary transactions; TRUE=roll back all non-PREPARED transactions */ { ut_ad(mutex_own(&trx_sys->mutex)); @@ -683,16 +683,15 @@ trx_rollback_resurrected( to accidentally clean up a non-recovered transaction here. */ trx_mutex_enter(trx); - bool is_recovered = trx->is_recovered; - trx_state_t state = trx->state; - trx_mutex_exit(trx); - - if (!is_recovered) { + if (!trx->is_recovered) { +func_exit: + trx_mutex_exit(trx); return(FALSE); } - switch (state) { + switch (trx->state) { case TRX_STATE_COMMITTED_IN_MEMORY: + trx_mutex_exit(trx); mutex_exit(&trx_sys->mutex); fprintf(stderr, "InnoDB: Cleaning up trx with id " TRX_ID_FMT "\n", @@ -701,7 +700,17 @@ trx_rollback_resurrected( trx_free_for_background(trx); return(TRUE); case TRX_STATE_ACTIVE: - if (all || trx_get_dict_operation(trx) != TRX_DICT_OP_NONE) { + if (srv_shutdown_state != SRV_SHUTDOWN_NONE + && srv_fast_shutdown) { + trx->state = TRX_STATE_PREPARED; + trx_sys->n_prepared_trx++; + trx_sys->n_prepared_recovered_trx++; + *all = FALSE; + goto func_exit; + } + trx_mutex_exit(trx); + + if (*all || trx_get_dict_operation(trx) != TRX_DICT_OP_NONE) { mutex_exit(&trx_sys->mutex); trx_rollback_active(trx); trx_free_for_background(trx); @@ -709,13 +718,13 @@ trx_rollback_resurrected( } return(FALSE); case TRX_STATE_PREPARED: - return(FALSE); + goto func_exit; case TRX_STATE_NOT_STARTED: break; } ut_error; - return(FALSE); + goto func_exit; } /*******************************************************************//** @@ -762,17 +771,11 @@ trx_rollback_or_clean_recovered( assert_trx_in_rw_list(trx); - if (srv_shutdown_state != SRV_SHUTDOWN_NONE - && srv_fast_shutdown != 0) { - all = FALSE; - break; - } - /* If this function does a cleanup or rollback then it will release the trx_sys->mutex, therefore we need to reacquire it before retrying the loop. */ - if (trx_rollback_resurrected(trx, all)) { + if (trx_rollback_resurrected(trx, &all)) { mutex_enter(&trx_sys->mutex); diff --git a/storage/xtradb/trx/trx0undo.cc b/storage/xtradb/trx/trx0undo.cc index 1836d282cd4..5638ccd17a6 100644 --- a/storage/xtradb/trx/trx0undo.cc +++ b/storage/xtradb/trx/trx0undo.cc @@ -2023,9 +2023,13 @@ trx_undo_free_prepared( /* fall through */ case TRX_UNDO_ACTIVE: /* lock_trx_release_locks() assigns - trx->is_recovered=false */ + trx->is_recovered=false and + trx->state = TRX_STATE_COMMITTED_IN_MEMORY, + also for transactions that we faked + to TRX_STATE_PREPARED in trx_rollback_resurrected(). */ ut_a(srv_read_only_mode - || srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO); + || srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO + || srv_fast_shutdown); break; default: ut_error; @@ -2047,9 +2051,13 @@ trx_undo_free_prepared( /* fall through */ case TRX_UNDO_ACTIVE: /* lock_trx_release_locks() assigns - trx->is_recovered=false */ + trx->is_recovered=false and + trx->state = TRX_STATE_COMMITTED_IN_MEMORY, + also for transactions that we faked + to TRX_STATE_PREPARED in trx_rollback_resurrected(). */ ut_a(srv_read_only_mode - || srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO); + || srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO + || srv_fast_shutdown); break; default: ut_error; -- cgit v1.2.1 From b46fa627caaa00d32ca30b9bd09b5cb2dd99629b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 13 Dec 2017 18:02:09 +0200 Subject: MDEV-12352 InnoDB shutdown should not be blocked by a large transaction rollback row_undo_step(), trx_rollback_active(): Abort the rollback of a recovered ordinary transaction if fast shutdown has been initiated. trx_rollback_resurrected(): Convert an aborted-rollback transaction into a fake XA PREPARE transaction, so that fast shutdown can proceed. --- mysql-test/suite/innodb/r/recovery_shutdown.result | 5 ++++ mysql-test/suite/innodb/t/recovery_shutdown.test | 6 +++++ storage/innobase/include/trx0roll.h | 4 ++- storage/innobase/row/row0undo.cc | 10 ++++++++ storage/innobase/trx/trx0roll.cc | 29 +++++++++++++++++----- storage/xtradb/include/trx0roll.h | 4 ++- storage/xtradb/row/row0undo.cc | 10 ++++++++ storage/xtradb/trx/trx0roll.cc | 29 +++++++++++++++++----- 8 files changed, 83 insertions(+), 14 deletions(-) diff --git a/mysql-test/suite/innodb/r/recovery_shutdown.result b/mysql-test/suite/innodb/r/recovery_shutdown.result index 028a0bd6239..861461dd072 100644 --- a/mysql-test/suite/innodb/r/recovery_shutdown.result +++ b/mysql-test/suite/innodb/r/recovery_shutdown.result @@ -45,6 +45,11 @@ BEGIN; INSERT INTO t1 (a) SELECT NULL FROM t; UPDATE t1 SET a=a+100, b=a; DELETE FROM t1; +INSERT INTO t1(a) SELECT NULL FROM t; +INSERT INTO t1(a) SELECT NULL FROM t1; +INSERT INTO t1(a) SELECT NULL FROM t1; +INSERT INTO t1(a) SELECT NULL FROM t1; +INSERT INTO t1(a) SELECT NULL FROM t1; SET GLOBAL innodb_flush_log_at_trx_commit=1; CREATE TABLE u(a SERIAL) ENGINE=INNODB; # Kill and restart diff --git a/mysql-test/suite/innodb/t/recovery_shutdown.test b/mysql-test/suite/innodb/t/recovery_shutdown.test index ea38bd19a9f..28b80cd3818 100644 --- a/mysql-test/suite/innodb/t/recovery_shutdown.test +++ b/mysql-test/suite/innodb/t/recovery_shutdown.test @@ -31,6 +31,12 @@ eval DELETE FROM t$c; dec $c; } +INSERT INTO t1(a) SELECT NULL FROM t; +INSERT INTO t1(a) SELECT NULL FROM t1; +INSERT INTO t1(a) SELECT NULL FROM t1; +INSERT INTO t1(a) SELECT NULL FROM t1; +INSERT INTO t1(a) SELECT NULL FROM t1; + --connection default SET GLOBAL innodb_flush_log_at_trx_commit=1; CREATE TABLE u(a SERIAL) ENGINE=INNODB; diff --git a/storage/innobase/include/trx0roll.h b/storage/innobase/include/trx0roll.h index 98a667b2ec1..e9e3f3a77c8 100644 --- a/storage/innobase/include/trx0roll.h +++ b/storage/innobase/include/trx0roll.h @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 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 @@ -32,7 +33,8 @@ Created 3/26/1996 Heikki Tuuri #include "mtr0mtr.h" #include "trx0sys.h" -extern bool trx_rollback_or_clean_is_active; +extern bool trx_rollback_or_clean_is_active; +extern const trx_t* trx_roll_crash_recv_trx; /*******************************************************************//** Determines if this transaction is rolling back an incomplete transaction diff --git a/storage/innobase/row/row0undo.cc b/storage/innobase/row/row0undo.cc index 149dc671930..95b88f6ce42 100644 --- a/storage/innobase/row/row0undo.cc +++ b/storage/innobase/row/row0undo.cc @@ -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 @@ -44,6 +45,7 @@ Created 1/8/1997 Heikki Tuuri #include "row0upd.h" #include "row0mysql.h" #include "srv0srv.h" +#include "srv0start.h" /* How to undo row operations? (1) For an insert, we have stored a prefix of the clustered index record @@ -348,6 +350,14 @@ row_undo_step( ut_ad(que_node_get_type(node) == QUE_NODE_UNDO); + if (UNIV_UNLIKELY(trx == trx_roll_crash_recv_trx) + && trx_get_dict_operation(trx) == TRX_DICT_OP_NONE + && !srv_undo_sources && srv_fast_shutdown) { + /* Shutdown has been initiated. */ + trx->error_state = DB_INTERRUPTED; + return(NULL); + } + err = row_undo(node, thr); trx->error_state = err; diff --git a/storage/innobase/trx/trx0roll.cc b/storage/innobase/trx/trx0roll.cc index dbb902258c6..a0bc85e0433 100644 --- a/storage/innobase/trx/trx0roll.cc +++ b/storage/innobase/trx/trx0roll.cc @@ -55,7 +55,7 @@ rollback */ bool trx_rollback_or_clean_is_active; /** In crash recovery, the current trx to be rolled back; NULL otherwise */ -static const trx_t* trx_roll_crash_recv_trx = NULL; +const trx_t* trx_roll_crash_recv_trx; /** In crash recovery we set this to the undo n:o of the current trx to be rolled back. Then we can print how many % the rollback has progressed. */ @@ -605,6 +605,14 @@ trx_rollback_active( que_run_threads(roll_node->undo_thr); + if (trx->error_state != DB_SUCCESS) { + ut_ad(trx->error_state == DB_INTERRUPTED); + ut_ad(!srv_undo_sources); + ut_ad(srv_fast_shutdown); + ut_ad(!dictionary_locked); + goto func_exit; + } + trx_rollback_finish(thr_get_trx(roll_node->undo_thr)); /* Free the memory reserved by the undo graph */ @@ -649,13 +657,14 @@ trx_rollback_active( } } + ib_logf(IB_LOG_LEVEL_INFO, + "Rollback of trx with id " TRX_ID_FMT " completed", trx->id); + +func_exit: if (dictionary_locked) { row_mysql_unlock_data_dictionary(trx); } - ib_logf(IB_LOG_LEVEL_INFO, - "Rollback of trx with id " TRX_ID_FMT " completed", trx->id); - mem_heap_free(heap); trx_roll_crash_recv_trx = NULL; @@ -700,8 +709,8 @@ func_exit: trx_free_for_background(trx); return(TRUE); case TRX_STATE_ACTIVE: - if (srv_shutdown_state != SRV_SHUTDOWN_NONE - && srv_fast_shutdown) { + if (!srv_undo_sources && srv_fast_shutdown) { +fake_prepared: trx->state = TRX_STATE_PREPARED; trx_sys->n_prepared_trx++; trx_sys->n_prepared_recovered_trx++; @@ -713,6 +722,14 @@ func_exit: if (*all || trx_get_dict_operation(trx) != TRX_DICT_OP_NONE) { mutex_exit(&trx_sys->mutex); trx_rollback_active(trx); + if (trx->error_state != DB_SUCCESS) { + ut_ad(trx->error_state == DB_INTERRUPTED); + ut_ad(!srv_undo_sources); + ut_ad(srv_fast_shutdown); + mutex_enter(&trx_sys->mutex); + trx_mutex_enter(trx); + goto fake_prepared; + } trx_free_for_background(trx); return(TRUE); } diff --git a/storage/xtradb/include/trx0roll.h b/storage/xtradb/include/trx0roll.h index b2e9d8a077f..399b29610ff 100644 --- a/storage/xtradb/include/trx0roll.h +++ b/storage/xtradb/include/trx0roll.h @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 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 @@ -33,7 +34,8 @@ Created 3/26/1996 Heikki Tuuri #include "mtr0mtr.h" #include "trx0sys.h" -extern bool trx_rollback_or_clean_is_active; +extern bool trx_rollback_or_clean_is_active; +extern const trx_t* trx_roll_crash_recv_trx; /*******************************************************************//** Determines if this transaction is rolling back an incomplete transaction diff --git a/storage/xtradb/row/row0undo.cc b/storage/xtradb/row/row0undo.cc index 149dc671930..95b88f6ce42 100644 --- a/storage/xtradb/row/row0undo.cc +++ b/storage/xtradb/row/row0undo.cc @@ -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 @@ -44,6 +45,7 @@ Created 1/8/1997 Heikki Tuuri #include "row0upd.h" #include "row0mysql.h" #include "srv0srv.h" +#include "srv0start.h" /* How to undo row operations? (1) For an insert, we have stored a prefix of the clustered index record @@ -348,6 +350,14 @@ row_undo_step( ut_ad(que_node_get_type(node) == QUE_NODE_UNDO); + if (UNIV_UNLIKELY(trx == trx_roll_crash_recv_trx) + && trx_get_dict_operation(trx) == TRX_DICT_OP_NONE + && !srv_undo_sources && srv_fast_shutdown) { + /* Shutdown has been initiated. */ + trx->error_state = DB_INTERRUPTED; + return(NULL); + } + err = row_undo(node, thr); trx->error_state = err; diff --git a/storage/xtradb/trx/trx0roll.cc b/storage/xtradb/trx/trx0roll.cc index dbb902258c6..a0bc85e0433 100644 --- a/storage/xtradb/trx/trx0roll.cc +++ b/storage/xtradb/trx/trx0roll.cc @@ -55,7 +55,7 @@ rollback */ bool trx_rollback_or_clean_is_active; /** In crash recovery, the current trx to be rolled back; NULL otherwise */ -static const trx_t* trx_roll_crash_recv_trx = NULL; +const trx_t* trx_roll_crash_recv_trx; /** In crash recovery we set this to the undo n:o of the current trx to be rolled back. Then we can print how many % the rollback has progressed. */ @@ -605,6 +605,14 @@ trx_rollback_active( que_run_threads(roll_node->undo_thr); + if (trx->error_state != DB_SUCCESS) { + ut_ad(trx->error_state == DB_INTERRUPTED); + ut_ad(!srv_undo_sources); + ut_ad(srv_fast_shutdown); + ut_ad(!dictionary_locked); + goto func_exit; + } + trx_rollback_finish(thr_get_trx(roll_node->undo_thr)); /* Free the memory reserved by the undo graph */ @@ -649,13 +657,14 @@ trx_rollback_active( } } + ib_logf(IB_LOG_LEVEL_INFO, + "Rollback of trx with id " TRX_ID_FMT " completed", trx->id); + +func_exit: if (dictionary_locked) { row_mysql_unlock_data_dictionary(trx); } - ib_logf(IB_LOG_LEVEL_INFO, - "Rollback of trx with id " TRX_ID_FMT " completed", trx->id); - mem_heap_free(heap); trx_roll_crash_recv_trx = NULL; @@ -700,8 +709,8 @@ func_exit: trx_free_for_background(trx); return(TRUE); case TRX_STATE_ACTIVE: - if (srv_shutdown_state != SRV_SHUTDOWN_NONE - && srv_fast_shutdown) { + if (!srv_undo_sources && srv_fast_shutdown) { +fake_prepared: trx->state = TRX_STATE_PREPARED; trx_sys->n_prepared_trx++; trx_sys->n_prepared_recovered_trx++; @@ -713,6 +722,14 @@ func_exit: if (*all || trx_get_dict_operation(trx) != TRX_DICT_OP_NONE) { mutex_exit(&trx_sys->mutex); trx_rollback_active(trx); + if (trx->error_state != DB_SUCCESS) { + ut_ad(trx->error_state == DB_INTERRUPTED); + ut_ad(!srv_undo_sources); + ut_ad(srv_fast_shutdown); + mutex_enter(&trx_sys->mutex); + trx_mutex_enter(trx); + goto fake_prepared; + } trx_free_for_background(trx); return(TRUE); } -- cgit v1.2.1 From 08d0ea1fcf4b7d9b56f1bdc32c5ea079261457da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 13 Dec 2017 18:53:46 +0200 Subject: Follow-up to MDEV-11027: Use recv_sys_t::report() --- storage/innobase/log/log0recv.cc | 11 +++++------ storage/xtradb/log/log0recv.cc | 11 +++++------ 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index b99bd582b9a..9741d6768f4 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -1770,12 +1770,11 @@ recv_recover_page_func( recv_addr->state = RECV_PROCESSED; ut_a(recv_sys->n_addrs > 0); - if (--recv_sys->n_addrs && recv_sys->progress_time - time >= 15) { - recv_sys->progress_time = time; - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: To recover: " ULINTPF " pages from log\n", - recv_sys->n_addrs); + if (ulint n = --recv_sys->n_addrs) { + if (recv_sys->report(time)) { + ib_logf(IB_LOG_LEVEL_INFO, + "To recover: " ULINTPF " pages from log", n); + } } mutex_exit(&recv_sys->mutex); diff --git a/storage/xtradb/log/log0recv.cc b/storage/xtradb/log/log0recv.cc index 2316c35be71..3a378244f0b 100644 --- a/storage/xtradb/log/log0recv.cc +++ b/storage/xtradb/log/log0recv.cc @@ -1860,12 +1860,11 @@ recv_recover_page_func( recv_addr->state = RECV_PROCESSED; ut_a(recv_sys->n_addrs > 0); - if (--recv_sys->n_addrs && recv_sys->progress_time - time >= 15) { - recv_sys->progress_time = time; - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: To recover: " ULINTPF " pages from log\n", - recv_sys->n_addrs); + if (ulint n = --recv_sys->n_addrs) { + if (recv_sys->report(time)) { + ib_logf(IB_LOG_LEVEL_INFO, + "To recover: " ULINTPF " pages from log", n); + } } mutex_exit(&recv_sys->mutex); -- cgit v1.2.1 From b1977a39ded64ffc8080a32dff99551dd1997c7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 13 Dec 2017 18:56:22 +0200 Subject: MDEV-12323 Rollback progress log messages during crash recovery are intermixed with unrelated log messages trx_roll_must_shutdown(): During the rollback of recovered transactions, report progress and check if the rollback should be interrupted because of a pending shutdown. trx_roll_max_undo_no, trx_roll_progress_printed_pct: Remove, along with the messages that were interleaved with other messages. --- storage/innobase/include/trx0roll.h | 5 ++ storage/innobase/row/row0undo.cc | 4 +- storage/innobase/trx/trx0roll.cc | 95 ++++++++++++++++--------------------- storage/xtradb/include/trx0roll.h | 5 ++ storage/xtradb/row/row0undo.cc | 4 +- storage/xtradb/trx/trx0roll.cc | 95 ++++++++++++++++--------------------- 6 files changed, 96 insertions(+), 112 deletions(-) diff --git a/storage/innobase/include/trx0roll.h b/storage/innobase/include/trx0roll.h index e9e3f3a77c8..274a3b038ba 100644 --- a/storage/innobase/include/trx0roll.h +++ b/storage/innobase/include/trx0roll.h @@ -105,6 +105,11 @@ trx_undo_rec_release( /*=================*/ trx_t* trx, /*!< in/out: transaction */ undo_no_t undo_no);/*!< in: undo number */ +/** Report progress when rolling back a row of a recovered transaction. +@return whether the rollback should be aborted due to pending shutdown */ +UNIV_INTERN +bool +trx_roll_must_shutdown(); /*******************************************************************//** Rollback or clean up any incomplete transactions which were encountered in crash recovery. If the transaction already was diff --git a/storage/innobase/row/row0undo.cc b/storage/innobase/row/row0undo.cc index 95b88f6ce42..eb28b7c3221 100644 --- a/storage/innobase/row/row0undo.cc +++ b/storage/innobase/row/row0undo.cc @@ -45,7 +45,6 @@ Created 1/8/1997 Heikki Tuuri #include "row0upd.h" #include "row0mysql.h" #include "srv0srv.h" -#include "srv0start.h" /* How to undo row operations? (1) For an insert, we have stored a prefix of the clustered index record @@ -351,8 +350,7 @@ row_undo_step( ut_ad(que_node_get_type(node) == QUE_NODE_UNDO); if (UNIV_UNLIKELY(trx == trx_roll_crash_recv_trx) - && trx_get_dict_operation(trx) == TRX_DICT_OP_NONE - && !srv_undo_sources && srv_fast_shutdown) { + && trx_roll_must_shutdown()) { /* Shutdown has been initiated. */ trx->error_state = DB_INTERRUPTED; return(NULL); diff --git a/storage/innobase/trx/trx0roll.cc b/storage/innobase/trx/trx0roll.cc index a0bc85e0433..de4f48a1506 100644 --- a/storage/innobase/trx/trx0roll.cc +++ b/storage/innobase/trx/trx0roll.cc @@ -57,13 +57,6 @@ bool trx_rollback_or_clean_is_active; /** In crash recovery, the current trx to be rolled back; NULL otherwise */ const trx_t* trx_roll_crash_recv_trx; -/** In crash recovery we set this to the undo n:o of the current trx to be -rolled back. Then we can print how many % the rollback has progressed. */ -static undo_no_t trx_roll_max_undo_no; - -/** Auxiliary variable which tells the previous progress % we printed */ -static ulint trx_roll_progress_printed_pct; - /****************************************************************//** Finishes a transaction rollback. */ static @@ -551,8 +544,6 @@ trx_rollback_active( que_thr_t* thr; roll_node_t* roll_node; dict_table_t* table; - ib_int64_t rows_to_undo; - const char* unit = ""; ibool dictionary_locked = FALSE; heap = mem_heap_create(512); @@ -571,30 +562,8 @@ trx_rollback_active( ut_a(thr == que_fork_start_command(fork)); - mutex_enter(&trx_sys->mutex); - trx_roll_crash_recv_trx = trx; - trx_roll_max_undo_no = trx->undo_no; - - trx_roll_progress_printed_pct = 0; - - rows_to_undo = trx_roll_max_undo_no; - - mutex_exit(&trx_sys->mutex); - - if (rows_to_undo > 1000000000) { - rows_to_undo = rows_to_undo / 1000000; - unit = "M"; - } - - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: Rolling back trx with id " TRX_ID_FMT ", %lu%s" - " rows to undo\n", - trx->id, - (ulong) rows_to_undo, unit); - if (trx_get_dict_operation(trx) != TRX_DICT_OP_NONE) { row_mysql_lock_data_dictionary(trx); dictionary_locked = TRUE; @@ -744,6 +713,48 @@ fake_prepared: goto func_exit; } +/** Report progress when rolling back a row of a recovered transaction. +@return whether the rollback should be aborted due to pending shutdown */ +UNIV_INTERN +bool +trx_roll_must_shutdown() +{ + const trx_t* trx = trx_roll_crash_recv_trx; + ut_ad(trx); + ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE)); + + if (trx_get_dict_operation(trx) == TRX_DICT_OP_NONE + && !srv_undo_sources && srv_fast_shutdown) { + return true; + } + + ib_time_t time = ut_time(); + mutex_enter(&trx_sys->mutex); + mutex_enter(&recv_sys->mutex); + + if (recv_sys->report(time)) { + ulint n_trx = 0, n_rows = 0; + for (const trx_t* t = UT_LIST_GET_FIRST(trx_sys->rw_trx_list); + t != NULL; + t = UT_LIST_GET_NEXT(trx_list, t)) { + + assert_trx_in_rw_list(t); + if (t->is_recovered + && trx_state_eq(t, TRX_STATE_ACTIVE)) { + n_trx++; + n_rows += t->undo_no; + } + } + ib_logf(IB_LOG_LEVEL_INFO, + "To roll back: " ULINTPF " transactions, " + ULINTPF " rows", n_trx, n_rows); + } + + mutex_exit(&recv_sys->mutex); + mutex_exit(&trx_sys->mutex); + return false; +} + /*******************************************************************//** Rollback or clean up any incomplete transactions which were encountered in crash recovery. If the transaction already was @@ -1119,7 +1130,6 @@ trx_roll_pop_top_rec_of_trx( undo_no_t undo_no; ibool is_insert; trx_rseg_t* rseg; - ulint progress_pct; mtr_t mtr; rseg = trx->rseg; @@ -1177,27 +1187,6 @@ try_again: ut_ad(undo_no + 1 == trx->undo_no); - /* We print rollback progress info if we are in a crash recovery - and the transaction has at least 1000 row operations to undo. */ - - if (trx == trx_roll_crash_recv_trx && trx_roll_max_undo_no > 1000) { - - progress_pct = 100 - (ulint) - ((undo_no * 100) / trx_roll_max_undo_no); - if (progress_pct != trx_roll_progress_printed_pct) { - if (trx_roll_progress_printed_pct == 0) { - fprintf(stderr, - "\nInnoDB: Progress in percents:" - " %lu", (ulong) progress_pct); - } else { - fprintf(stderr, - " %lu", (ulong) progress_pct); - } - fflush(stderr); - trx_roll_progress_printed_pct = progress_pct; - } - } - trx->undo_no = undo_no; if (!trx_undo_arr_store_info(trx, undo_no)) { diff --git a/storage/xtradb/include/trx0roll.h b/storage/xtradb/include/trx0roll.h index 399b29610ff..565079b17b4 100644 --- a/storage/xtradb/include/trx0roll.h +++ b/storage/xtradb/include/trx0roll.h @@ -106,6 +106,11 @@ trx_undo_rec_release( /*=================*/ trx_t* trx, /*!< in/out: transaction */ undo_no_t undo_no);/*!< in: undo number */ +/** Report progress when rolling back a row of a recovered transaction. +@return whether the rollback should be aborted due to pending shutdown */ +UNIV_INTERN +bool +trx_roll_must_shutdown(); /*******************************************************************//** Rollback or clean up any incomplete transactions which were encountered in crash recovery. If the transaction already was diff --git a/storage/xtradb/row/row0undo.cc b/storage/xtradb/row/row0undo.cc index 95b88f6ce42..eb28b7c3221 100644 --- a/storage/xtradb/row/row0undo.cc +++ b/storage/xtradb/row/row0undo.cc @@ -45,7 +45,6 @@ Created 1/8/1997 Heikki Tuuri #include "row0upd.h" #include "row0mysql.h" #include "srv0srv.h" -#include "srv0start.h" /* How to undo row operations? (1) For an insert, we have stored a prefix of the clustered index record @@ -351,8 +350,7 @@ row_undo_step( ut_ad(que_node_get_type(node) == QUE_NODE_UNDO); if (UNIV_UNLIKELY(trx == trx_roll_crash_recv_trx) - && trx_get_dict_operation(trx) == TRX_DICT_OP_NONE - && !srv_undo_sources && srv_fast_shutdown) { + && trx_roll_must_shutdown()) { /* Shutdown has been initiated. */ trx->error_state = DB_INTERRUPTED; return(NULL); diff --git a/storage/xtradb/trx/trx0roll.cc b/storage/xtradb/trx/trx0roll.cc index a0bc85e0433..de4f48a1506 100644 --- a/storage/xtradb/trx/trx0roll.cc +++ b/storage/xtradb/trx/trx0roll.cc @@ -57,13 +57,6 @@ bool trx_rollback_or_clean_is_active; /** In crash recovery, the current trx to be rolled back; NULL otherwise */ const trx_t* trx_roll_crash_recv_trx; -/** In crash recovery we set this to the undo n:o of the current trx to be -rolled back. Then we can print how many % the rollback has progressed. */ -static undo_no_t trx_roll_max_undo_no; - -/** Auxiliary variable which tells the previous progress % we printed */ -static ulint trx_roll_progress_printed_pct; - /****************************************************************//** Finishes a transaction rollback. */ static @@ -551,8 +544,6 @@ trx_rollback_active( que_thr_t* thr; roll_node_t* roll_node; dict_table_t* table; - ib_int64_t rows_to_undo; - const char* unit = ""; ibool dictionary_locked = FALSE; heap = mem_heap_create(512); @@ -571,30 +562,8 @@ trx_rollback_active( ut_a(thr == que_fork_start_command(fork)); - mutex_enter(&trx_sys->mutex); - trx_roll_crash_recv_trx = trx; - trx_roll_max_undo_no = trx->undo_no; - - trx_roll_progress_printed_pct = 0; - - rows_to_undo = trx_roll_max_undo_no; - - mutex_exit(&trx_sys->mutex); - - if (rows_to_undo > 1000000000) { - rows_to_undo = rows_to_undo / 1000000; - unit = "M"; - } - - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: Rolling back trx with id " TRX_ID_FMT ", %lu%s" - " rows to undo\n", - trx->id, - (ulong) rows_to_undo, unit); - if (trx_get_dict_operation(trx) != TRX_DICT_OP_NONE) { row_mysql_lock_data_dictionary(trx); dictionary_locked = TRUE; @@ -744,6 +713,48 @@ fake_prepared: goto func_exit; } +/** Report progress when rolling back a row of a recovered transaction. +@return whether the rollback should be aborted due to pending shutdown */ +UNIV_INTERN +bool +trx_roll_must_shutdown() +{ + const trx_t* trx = trx_roll_crash_recv_trx; + ut_ad(trx); + ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE)); + + if (trx_get_dict_operation(trx) == TRX_DICT_OP_NONE + && !srv_undo_sources && srv_fast_shutdown) { + return true; + } + + ib_time_t time = ut_time(); + mutex_enter(&trx_sys->mutex); + mutex_enter(&recv_sys->mutex); + + if (recv_sys->report(time)) { + ulint n_trx = 0, n_rows = 0; + for (const trx_t* t = UT_LIST_GET_FIRST(trx_sys->rw_trx_list); + t != NULL; + t = UT_LIST_GET_NEXT(trx_list, t)) { + + assert_trx_in_rw_list(t); + if (t->is_recovered + && trx_state_eq(t, TRX_STATE_ACTIVE)) { + n_trx++; + n_rows += t->undo_no; + } + } + ib_logf(IB_LOG_LEVEL_INFO, + "To roll back: " ULINTPF " transactions, " + ULINTPF " rows", n_trx, n_rows); + } + + mutex_exit(&recv_sys->mutex); + mutex_exit(&trx_sys->mutex); + return false; +} + /*******************************************************************//** Rollback or clean up any incomplete transactions which were encountered in crash recovery. If the transaction already was @@ -1119,7 +1130,6 @@ trx_roll_pop_top_rec_of_trx( undo_no_t undo_no; ibool is_insert; trx_rseg_t* rseg; - ulint progress_pct; mtr_t mtr; rseg = trx->rseg; @@ -1177,27 +1187,6 @@ try_again: ut_ad(undo_no + 1 == trx->undo_no); - /* We print rollback progress info if we are in a crash recovery - and the transaction has at least 1000 row operations to undo. */ - - if (trx == trx_roll_crash_recv_trx && trx_roll_max_undo_no > 1000) { - - progress_pct = 100 - (ulint) - ((undo_no * 100) / trx_roll_max_undo_no); - if (progress_pct != trx_roll_progress_printed_pct) { - if (trx_roll_progress_printed_pct == 0) { - fprintf(stderr, - "\nInnoDB: Progress in percents:" - " %lu", (ulong) progress_pct); - } else { - fprintf(stderr, - " %lu", (ulong) progress_pct); - } - fflush(stderr); - trx_roll_progress_printed_pct = progress_pct; - } - } - trx->undo_no = undo_no; if (!trx_undo_arr_store_info(trx, undo_no)) { -- cgit v1.2.1 From 2fe990df9f25ead34d9d7a39e19f939fbbfea127 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 13 Dec 2017 20:41:32 +0200 Subject: Fix the grammar of an error message --- storage/innobase/handler/ha_innodb.cc | 2 +- storage/xtradb/handler/ha_innodb.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 2d319439fad..6e98bab66af 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -3483,7 +3483,7 @@ innobase_init( if (innodb_lock_schedule_algorithm == INNODB_LOCK_SCHEDULE_ALGORITHM_VATS && global_system_variables.wsrep_on) { /* Do not allow InnoDB startup with VATS and Galera */ - sql_print_error("In Galera environment Variance-Aware-Transaction-Sheduling Algorithm" + sql_print_error("In Galera, innodb_lock_schedule_algorithm=vats" " is not supported."); goto error; } diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 8487c5b2510..dd7c5b8324a 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -3939,7 +3939,7 @@ innobase_init( if (innodb_lock_schedule_algorithm == INNODB_LOCK_SCHEDULE_ALGORITHM_VATS && global_system_variables.wsrep_on) { /* Do not allow InnoDB startup with VATS and Galera */ - sql_print_error("In Galera environment Variance-Aware-Transaction-Sheduling Algorithm" + sql_print_error("In Galera, innodb_lock_schedule_algorithm=vats" " is not supported."); goto error; } -- cgit v1.2.1 From e9cc486c97d030e27e9c0ad8770b3d8a25afc27d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 13 Dec 2017 20:42:53 +0200 Subject: Fix a typo: schedule, scheduling --- mysys/thr_alarm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysys/thr_alarm.c b/mysys/thr_alarm.c index 9d917d3dd59..61ef3657161 100644 --- a/mysys/thr_alarm.c +++ b/mysys/thr_alarm.c @@ -273,7 +273,7 @@ void thr_end_alarm(thr_alarm_t *alarmed) /* Come here when some alarm in queue is due. Mark all alarms with are finnished in list. - Shedule alarms to be sent again after 1-10 sec (many alarms at once) + Schedule alarms to be sent again after 1-10 sec (many alarms at once) If alarm_aborted is set then all alarms are given and resent every second. */ @@ -425,7 +425,7 @@ void end_thr_alarm(my_bool free_structures) if (alarm_aborted != 1) /* If memory not freed */ { mysql_mutex_lock(&LOCK_alarm); - DBUG_PRINT("info",("Resheduling %d waiting alarms",alarm_queue.elements)); + DBUG_PRINT("info",("Rescheduling %d waiting alarms",alarm_queue.elements)); alarm_aborted= -1; /* mark aborted */ if (alarm_queue.elements || (alarm_thread_running && free_structures)) { -- cgit v1.2.1 From 9d76b2749835a4fdbd009433c5a762da2769c4dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 13 Dec 2017 22:30:13 +0200 Subject: Follow-up fix for MDEV-12352: Plug a memory leak trx_rollback_active(): When aborting the rollback, free the query graph. --- storage/innobase/trx/trx0roll.cc | 2 ++ storage/xtradb/trx/trx0roll.cc | 2 ++ 2 files changed, 4 insertions(+) diff --git a/storage/innobase/trx/trx0roll.cc b/storage/innobase/trx/trx0roll.cc index de4f48a1506..ab488b06121 100644 --- a/storage/innobase/trx/trx0roll.cc +++ b/storage/innobase/trx/trx0roll.cc @@ -579,6 +579,8 @@ trx_rollback_active( ut_ad(!srv_undo_sources); ut_ad(srv_fast_shutdown); ut_ad(!dictionary_locked); + que_graph_free(static_cast( + roll_node->undo_thr->common.parent)); goto func_exit; } diff --git a/storage/xtradb/trx/trx0roll.cc b/storage/xtradb/trx/trx0roll.cc index de4f48a1506..ab488b06121 100644 --- a/storage/xtradb/trx/trx0roll.cc +++ b/storage/xtradb/trx/trx0roll.cc @@ -579,6 +579,8 @@ trx_rollback_active( ut_ad(!srv_undo_sources); ut_ad(srv_fast_shutdown); ut_ad(!dictionary_locked); + que_graph_free(static_cast( + roll_node->undo_thr->common.parent)); goto func_exit; } -- cgit v1.2.1 From 806380494353bb1389507def0256b3308e5cedbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 13 Dec 2017 23:14:54 +0200 Subject: Re-remove the file kill_and_restart_mysqld.inc --- mysql-test/include/kill_and_restart_mysqld.inc | 15 -------- mysql-test/suite/innodb/r/update_time.result | 1 - mysql-test/suite/innodb/t/update_time.test | 3 +- mysql-test/suite/innodb_gis/r/kill_server.result | 1 - .../suite/innodb_gis/r/rtree_compress2.result | 1 - mysql-test/suite/innodb_gis/r/rtree_crash.result | 41 ---------------------- .../suite/innodb_gis/r/rtree_recovery.result | 2 -- mysql-test/suite/innodb_gis/r/types.result | 1 - mysql-test/suite/innodb_gis/t/kill_server.test | 3 +- mysql-test/suite/innodb_gis/t/rtree_compress2.test | 3 +- mysql-test/suite/innodb_gis/t/rtree_recovery.test | 5 +-- mysql-test/suite/innodb_gis/t/types.test | 3 +- 12 files changed, 11 insertions(+), 68 deletions(-) delete mode 100644 mysql-test/include/kill_and_restart_mysqld.inc delete mode 100644 mysql-test/suite/innodb_gis/r/rtree_crash.result diff --git a/mysql-test/include/kill_and_restart_mysqld.inc b/mysql-test/include/kill_and_restart_mysqld.inc deleted file mode 100644 index b67fb7350b4..00000000000 --- a/mysql-test/include/kill_and_restart_mysqld.inc +++ /dev/null @@ -1,15 +0,0 @@ -if (!$restart_parameters) -{ - let $restart_parameters = restart; -} - ---let $_server_id= `SELECT @@server_id` ---let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.$_server_id.expect - ---echo # Kill and $restart_parameters ---exec echo "$restart_parameters" > $_expect_file_name ---shutdown_server 0 ---source include/wait_until_disconnected.inc ---enable_reconnect ---source include/wait_until_connected_again.inc ---disable_reconnect diff --git a/mysql-test/suite/innodb/r/update_time.result b/mysql-test/suite/innodb/r/update_time.result index ab3eeb08dc7..d8b9069b1ae 100644 --- a/mysql-test/suite/innodb/r/update_time.result +++ b/mysql-test/suite/innodb/r/update_time.result @@ -43,7 +43,6 @@ XA PREPARE 'xatrx'; CONNECT con1,localhost,root,,; call mtr.add_suppression("Found 1 prepared XA transactions"); FLUSH TABLES; -# Kill and restart SELECT update_time FROM information_schema.tables WHERE table_name = 't'; update_time NULL diff --git a/mysql-test/suite/innodb/t/update_time.test b/mysql-test/suite/innodb/t/update_time.test index e2213c5d9b7..1a00e3b9f73 100644 --- a/mysql-test/suite/innodb/t/update_time.test +++ b/mysql-test/suite/innodb/t/update_time.test @@ -67,7 +67,8 @@ CONNECT (con1,localhost,root,,); call mtr.add_suppression("Found 1 prepared XA transactions"); FLUSH TABLES; ---source include/kill_and_restart_mysqld.inc +--let $shutdown_timeout=0 +--source include/restart_mysqld.inc SELECT update_time FROM information_schema.tables WHERE table_name = 't'; diff --git a/mysql-test/suite/innodb_gis/r/kill_server.result b/mysql-test/suite/innodb_gis/r/kill_server.result index 579317872b4..eac4feb442f 100644 --- a/mysql-test/suite/innodb_gis/r/kill_server.result +++ b/mysql-test/suite/innodb_gis/r/kill_server.result @@ -36,6 +36,5 @@ call mtr.add_suppression("InnoDB: A copy of page \[page id: space=[0-9]+, page n START TRANSACTION; CALL insert_t1(5000); COMMIT; -# Kill and restart drop procedure insert_t1; drop table t1; diff --git a/mysql-test/suite/innodb_gis/r/rtree_compress2.result b/mysql-test/suite/innodb_gis/r/rtree_compress2.result index 3522a1097aa..04940f2b3b1 100644 --- a/mysql-test/suite/innodb_gis/r/rtree_compress2.result +++ b/mysql-test/suite/innodb_gis/r/rtree_compress2.result @@ -20,6 +20,5 @@ call mtr.add_suppression("InnoDB: A copy of page \[page id: space=[0-9]+, page n START TRANSACTION; CALL insert_t1(5000); COMMIT; -# Kill and restart drop procedure insert_t1; drop table t1; diff --git a/mysql-test/suite/innodb_gis/r/rtree_crash.result b/mysql-test/suite/innodb_gis/r/rtree_crash.result deleted file mode 100644 index 12ca15a420d..00000000000 --- a/mysql-test/suite/innodb_gis/r/rtree_crash.result +++ /dev/null @@ -1,41 +0,0 @@ -create table t1 (c1 int, c2 geometry not null, spatial index (c2))engine=innodb; -create procedure insert_t1(IN total int) -begin -declare i int default 1; -while (i <= total) DO -insert into t1 values (i, Point(i, i)); -set i = i + 1; -end while; -end| -CALL insert_t1(5000); -select count(*) from t1; -count(*) -5000 -check table t1; -Table Op Msg_type Msg_text -test.t1 check status OK -truncate table t1; -CALL insert_t1(10000); -select count(*) from t1; -count(*) -10000 -drop index c2 on t1; -create spatial index idx on t1(c2); -show create table t1; -Table Create Table -t1 CREATE TABLE `t1` ( - `c1` int(11) DEFAULT NULL, - `c2` geometry NOT NULL, - SPATIAL KEY `idx` (`c2`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1 -check table t1; -Table Op Msg_type Msg_text -test.t1 check status OK -truncate table t1; -call mtr.add_suppression("InnoDB: page [0-9]+ in the doublewrite buffer is not within space bounds.*"); -START TRANSACTION; -CALL insert_t1(5000); -COMMIT; -# Kill and restart -drop procedure insert_t1; -drop table t1; diff --git a/mysql-test/suite/innodb_gis/r/rtree_recovery.result b/mysql-test/suite/innodb_gis/r/rtree_recovery.result index d2f4409f38c..3572e3e0bed 100644 --- a/mysql-test/suite/innodb_gis/r/rtree_recovery.result +++ b/mysql-test/suite/innodb_gis/r/rtree_recovery.result @@ -18,7 +18,6 @@ end while; end| CALL insert_t1(367); COMMIT; -# Kill and restart check table t1; Table Op Msg_type Msg_text test.t1 check status OK @@ -29,7 +28,6 @@ CALL update_t1(367); SET @poly1 = ST_GeomFromText('POLYGON((10000 10000, 10000 10350, 10350 10350, 10350 10000, 10000 10000))'); delete from t1 where ST_Contains(@poly1, c2); COMMIT; -# Kill and restart check table t1; Table Op Msg_type Msg_text test.t1 check status OK diff --git a/mysql-test/suite/innodb_gis/r/types.result b/mysql-test/suite/innodb_gis/r/types.result index ac1802085d6..7d823927df1 100644 --- a/mysql-test/suite/innodb_gis/r/types.result +++ b/mysql-test/suite/innodb_gis/r/types.result @@ -53,7 +53,6 @@ COMMIT; INSERT INTO t_wl6455 VALUES(11, POINT(11,11)); BEGIN; INSERT INTO t_wl6455 VALUES(1, POINT(1,1)); -# Kill and restart CHECK TABLE t_wl6455; Table Op Msg_type Msg_text test.t_wl6455 check status OK diff --git a/mysql-test/suite/innodb_gis/t/kill_server.test b/mysql-test/suite/innodb_gis/t/kill_server.test index 9b6469606ca..028bbbdd40d 100644 --- a/mysql-test/suite/innodb_gis/t/kill_server.test +++ b/mysql-test/suite/innodb_gis/t/kill_server.test @@ -58,7 +58,8 @@ CALL insert_t1(5000); COMMIT; ---source include/kill_and_restart_mysqld.inc +--let $shutdown_timeout=0 +--source include/restart_mysqld.inc # Clean up. drop procedure insert_t1; diff --git a/mysql-test/suite/innodb_gis/t/rtree_compress2.test b/mysql-test/suite/innodb_gis/t/rtree_compress2.test index 5956fc9a774..86ef1171833 100644 --- a/mysql-test/suite/innodb_gis/t/rtree_compress2.test +++ b/mysql-test/suite/innodb_gis/t/rtree_compress2.test @@ -51,7 +51,8 @@ CALL insert_t1(5000); COMMIT; ---source include/kill_and_restart_mysqld.inc +--let $shutdown_timeout=0 +--source include/restart_mysqld.inc # Clean up. drop procedure insert_t1; diff --git a/mysql-test/suite/innodb_gis/t/rtree_recovery.test b/mysql-test/suite/innodb_gis/t/rtree_recovery.test index 9e332c089f2..d995048ceac 100644 --- a/mysql-test/suite/innodb_gis/t/rtree_recovery.test +++ b/mysql-test/suite/innodb_gis/t/rtree_recovery.test @@ -44,7 +44,8 @@ delimiter ;| CALL insert_t1(367); COMMIT; ---source include/kill_and_restart_mysqld.inc +--let $shutdown_timeout=0 +--source include/restart_mysqld.inc # Check table. check table t1; @@ -63,7 +64,7 @@ SET @poly1 = ST_GeomFromText('POLYGON((10000 10000, 10000 10350, 10350 10350, 10 delete from t1 where ST_Contains(@poly1, c2); COMMIT; ---source include/kill_and_restart_mysqld.inc +--source include/restart_mysqld.inc # Check table. check table t1; diff --git a/mysql-test/suite/innodb_gis/t/types.test b/mysql-test/suite/innodb_gis/t/types.test index bd03e7b1dbe..65f65e5ae1f 100644 --- a/mysql-test/suite/innodb_gis/t/types.test +++ b/mysql-test/suite/innodb_gis/t/types.test @@ -73,7 +73,8 @@ INSERT INTO t_wl6455 VALUES(11, POINT(11,11)); BEGIN; INSERT INTO t_wl6455 VALUES(1, POINT(1,1)); ---source include/kill_and_restart_mysqld.inc +--let $shutdown_timeout=0 +--source include/restart_mysqld.inc CHECK TABLE t_wl6455; SELECT ST_AsText(g) FROM t_wl6455; -- cgit v1.2.1 From a9a4089175a8fd5a9b973f99f87cd0fe181f8f47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 14 Dec 2017 13:47:38 +0200 Subject: Plug a small memory leak in mariabackup --backup --- extra/mariabackup/xtrabackup.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index 90a0c829773..f145a94c923 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -3626,7 +3626,6 @@ fail: /* Reset the system variables in the recovery module. */ recv_sys_var_init(); trx_pool_init(); - row_mysql_init(); ut_crc32_init(); crc_init(); -- cgit v1.2.1 From ef9e78c9d41a5ac644f08068e3dabad948b0e30a Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Wed, 13 Dec 2017 11:52:53 +0100 Subject: MDEV-14524 TokuDB is unable to be built on Linux tokudb needs either F_NOCACHE or O_DIRECT, not both --- storage/tokudb/CMakeLists.txt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/storage/tokudb/CMakeLists.txt b/storage/tokudb/CMakeLists.txt index 4e0291545ec..f01c4aed449 100644 --- a/storage/tokudb/CMakeLists.txt +++ b/storage/tokudb/CMakeLists.txt @@ -4,13 +4,17 @@ IF(CMAKE_VERSION VERSION_LESS "2.8.9") MESSAGE(STATUS "CMake 2.8.9 or higher is required by TokuDB") ELSEIF(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "amd64") -# tokudb requires F_NOCACHE, O_DIRECT, and designated initializers +# tokudb requires F_NOCACHE or O_DIRECT, and designated initializers CHECK_CXX_SOURCE_COMPILES( " #include struct a {int b; int c; }; struct a d = { .b=1, .c=2 }; -int main() { return F_NOCACHE + O_DIRECT; } +#if defined(O_DIRECT) || defined(F_NOCACHE) +int main() { return 0; } +#else +#error +#endif " TOKUDB_OK) ENDIF() -- cgit v1.2.1 From 64b11e61b5055cbdcdb97911d426b4f13f14fbd1 Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Fri, 15 Dec 2017 17:59:33 +0300 Subject: MDEV-14293: MyRocks lacks basic functionality The error "Unsupported collation on string indexed column %s Use binary collation (latin1_bin, binary, utf8_bin)." is misleading. Change it: - It is now a warning - It is printed only for collations that do not support index-only access (reversible collations that use unpack_info are ok) - The new warning text is: Indexed column %s.%s uses a collation that does not allow index-only access in secondary key and has reduced disk space efficiency in primary key. --- sql/share/errmsg-utf8.txt | 3 +++ storage/rocksdb/ha_rocksdb.cc | 22 ++++++++-------------- .../mysql-test/rocksdb/r/add_index_inplace.result | 9 ++++++++- .../mysql-test/rocksdb/t/add_index_inplace.test | 9 ++++++++- storage/rocksdb/rdb_datadic.cc | 2 +- storage/rocksdb/rdb_datadic.h | 2 ++ 6 files changed, 30 insertions(+), 17 deletions(-) diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 528dc7107e6..50ccc6eadd1 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -7753,3 +7753,6 @@ ER_GEOJSON_EMPTY_COORDINATES ER_MYROCKS_CANT_NOPAD_COLLATION eng "MyRocks doesn't currently support collations with \"No pad\" attribute." +ER_MYROCKS_COLLATION_IS_LIMITED + eng "Indexed column %s.%s uses a collation that does not allow index-only access in secondary key and has reduced disk space efficiency in primary key." + diff --git a/storage/rocksdb/ha_rocksdb.cc b/storage/rocksdb/ha_rocksdb.cc index a9d37c1def2..6afba00b3f8 100644 --- a/storage/rocksdb/ha_rocksdb.cc +++ b/storage/rocksdb/ha_rocksdb.cc @@ -5957,9 +5957,11 @@ rdb_is_index_collation_supported(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 RDB_INDEX_COLLATIONS.find(field->charset()->number) != - RDB_INDEX_COLLATIONS.end(); + type == MYSQL_TYPE_BLOB) { + + return (RDB_INDEX_COLLATIONS.find(field->charset()->number) != + RDB_INDEX_COLLATIONS.end()) || + rdb_is_collation_supported(field->charset()); } return true; } @@ -6118,18 +6120,10 @@ int ha_rocksdb::create_cfs( !rdb_is_index_collation_supported( table_arg->key_info[i].key_part[part].field) && !rdb_collation_exceptions->matches(tablename_sys)) { - std::string collation_err; - for (const auto &coll : RDB_INDEX_COLLATIONS) { - if (collation_err != "") { - collation_err += ", "; - } - collation_err += get_charset_name(coll); - } - my_error(ER_UNSUPPORTED_COLLATION, MYF(0), + + my_error(ER_MYROCKS_COLLATION_IS_LIMITED, MYF(ME_JUST_WARNING), tbl_def_arg->full_tablename().c_str(), - table_arg->key_info[i].key_part[part].field->field_name, - collation_err.c_str()); - DBUG_RETURN(HA_EXIT_FAILURE); + table_arg->key_info[i].key_part[part].field->field_name); } } } diff --git a/storage/rocksdb/mysql-test/rocksdb/r/add_index_inplace.result b/storage/rocksdb/mysql-test/rocksdb/r/add_index_inplace.result index 01fa9f1d35b..ca770c2358a 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/add_index_inplace.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/add_index_inplace.result @@ -279,8 +279,15 @@ DROP TABLE t1; set @tmp_rocksdb_strict_collation_check= @@rocksdb_strict_collation_check; set global rocksdb_strict_collation_check=1; CREATE TABLE t1 (a INT, b TEXT); +# MariaDB no longer gives ER_UNSUPPORTED_COLLATION ALTER TABLE t1 ADD KEY kb(b(10)); -ERROR HY000: Unsupported collation on string indexed column test.t1.b Use binary collation (latin1_bin, binary, utf8_bin). +ALTER TABLE t1 ADD PRIMARY KEY(a); +DROP TABLE t1; +CREATE TABLE t1 (a INT, b TEXT collate utf8_general_ci); +# MariaDB no longer gives ER_UNSUPPORTED_COLLATION +ALTER TABLE t1 ADD KEY kb(b(10)); +Warnings: +Warning 4078 Indexed column test.t1.b uses a collation that does not allow index-only access in secondary key and has reduced disk space efficiency in primary key. ALTER TABLE t1 ADD PRIMARY KEY(a); DROP TABLE t1; set global rocksdb_strict_collation_check= @tmp_rocksdb_strict_collation_check; diff --git a/storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace.test b/storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace.test index c1a91c2a5a2..876ef2c9965 100644 --- a/storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace.test +++ b/storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace.test @@ -173,10 +173,17 @@ set @tmp_rocksdb_strict_collation_check= @@rocksdb_strict_collation_check; set global rocksdb_strict_collation_check=1; CREATE TABLE t1 (a INT, b TEXT); ---error ER_UNSUPPORTED_COLLATION +--echo # MariaDB no longer gives ER_UNSUPPORTED_COLLATION ALTER TABLE t1 ADD KEY kb(b(10)); ALTER TABLE t1 ADD PRIMARY KEY(a); DROP TABLE t1; + +CREATE TABLE t1 (a INT, b TEXT collate utf8_general_ci); +--echo # MariaDB no longer gives ER_UNSUPPORTED_COLLATION +ALTER TABLE t1 ADD KEY kb(b(10)); +ALTER TABLE t1 ADD PRIMARY KEY(a); +DROP TABLE t1; + set global rocksdb_strict_collation_check= @tmp_rocksdb_strict_collation_check; # make sure race condition between connection close and alter on another diff --git a/storage/rocksdb/rdb_datadic.cc b/storage/rocksdb/rdb_datadic.cc index 3efd3ae6433..df743ff0c48 100644 --- a/storage/rocksdb/rdb_datadic.cc +++ b/storage/rocksdb/rdb_datadic.cc @@ -2921,7 +2921,7 @@ std::array rdb_collation_data; mysql_mutex_t rdb_collation_data_mutex; -static bool rdb_is_collation_supported(const my_core::CHARSET_INFO *const cs) { +bool rdb_is_collation_supported(const my_core::CHARSET_INFO *const cs) { return cs->strxfrm_multiply==1 && cs->mbmaxlen == 1 && !(cs->state & (MY_CS_BINSORT | MY_CS_NOPAD)); } diff --git a/storage/rocksdb/rdb_datadic.h b/storage/rocksdb/rdb_datadic.h index b1ecef045d1..5796132de39 100644 --- a/storage/rocksdb/rdb_datadic.h +++ b/storage/rocksdb/rdb_datadic.h @@ -1358,4 +1358,6 @@ struct Rdb_index_info { uint64 m_ttl_duration = 0; }; +bool rdb_is_collation_supported(const my_core::CHARSET_INFO *const cs); + } // namespace myrocks -- cgit v1.2.1 From 7380376370dd9ec93fbcd684c80ab4e5bda70f24 Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Sat, 16 Dec 2017 16:44:33 +0300 Subject: MDEV-14293: MyRocks lacks basic functionality Adjust the fix according to the review input: don't introduce a special error caode, use ER_INTERNAL_ERROR catch-all. --- sql/share/errmsg-utf8.txt | 4 ---- storage/rocksdb/ha_rocksdb.cc | 12 +++++++++--- .../rocksdb/mysql-test/rocksdb/r/add_index_inplace.result | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 50ccc6eadd1..74ac7e9f557 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -7752,7 +7752,3 @@ ER_GEOJSON_EMPTY_COORDINATES ER_MYROCKS_CANT_NOPAD_COLLATION eng "MyRocks doesn't currently support collations with \"No pad\" attribute." - -ER_MYROCKS_COLLATION_IS_LIMITED - eng "Indexed column %s.%s uses a collation that does not allow index-only access in secondary key and has reduced disk space efficiency in primary key." - diff --git a/storage/rocksdb/ha_rocksdb.cc b/storage/rocksdb/ha_rocksdb.cc index 6afba00b3f8..766c8036fba 100644 --- a/storage/rocksdb/ha_rocksdb.cc +++ b/storage/rocksdb/ha_rocksdb.cc @@ -6121,9 +6121,15 @@ int ha_rocksdb::create_cfs( table_arg->key_info[i].key_part[part].field) && !rdb_collation_exceptions->matches(tablename_sys)) { - my_error(ER_MYROCKS_COLLATION_IS_LIMITED, MYF(ME_JUST_WARNING), - tbl_def_arg->full_tablename().c_str(), - table_arg->key_info[i].key_part[part].field->field_name); + char buf[1024]; + my_snprintf(buf, sizeof(buf), + "Indexed column %s.%s uses a collation that does not " + "allow index-only access in secondary key and has " + "reduced disk space efficiency in primary key.", + tbl_def_arg->full_tablename().c_str(), + table_arg->key_info[i].key_part[part].field->field_name); + + my_error(ER_INTERNAL_ERROR, MYF(ME_JUST_WARNING), buf); } } } diff --git a/storage/rocksdb/mysql-test/rocksdb/r/add_index_inplace.result b/storage/rocksdb/mysql-test/rocksdb/r/add_index_inplace.result index ca770c2358a..6325dc97cf5 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/add_index_inplace.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/add_index_inplace.result @@ -287,7 +287,7 @@ CREATE TABLE t1 (a INT, b TEXT collate utf8_general_ci); # MariaDB no longer gives ER_UNSUPPORTED_COLLATION ALTER TABLE t1 ADD KEY kb(b(10)); Warnings: -Warning 4078 Indexed column test.t1.b uses a collation that does not allow index-only access in secondary key and has reduced disk space efficiency in primary key. +Warning 1815 Internal error: Indexed column test.t1.b uses a collation that does not allow index-only access in secondary key and has reduced disk space efficiency in primary key. ALTER TABLE t1 ADD PRIMARY KEY(a); DROP TABLE t1; set global rocksdb_strict_collation_check= @tmp_rocksdb_strict_collation_check; -- cgit v1.2.1 From 4bd63bd55158566db8c8b46b29fee590e9596a5e Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Sat, 16 Dec 2017 17:45:55 +0300 Subject: MDEV-14679: RocksdB plugin fails to load with "Loading of unknown plugin ROCKSDB_CFSTATS Set maturity level of all "Sub-plugins" to be the same as the main maturity level. --- storage/rocksdb/ha_rocksdb.cc | 3 ++- storage/rocksdb/ha_rocksdb.h | 3 +++ .../mysql-test/rocksdb/r/mariadb_port_fixes.result | 17 +++++++++++++++++ .../mysql-test/rocksdb/t/mariadb_port_fixes.test | 6 ++++++ storage/rocksdb/rdb_i_s.cc | 22 +++++++++++----------- 5 files changed, 39 insertions(+), 12 deletions(-) diff --git a/storage/rocksdb/ha_rocksdb.cc b/storage/rocksdb/ha_rocksdb.cc index 766c8036fba..98a9785713a 100644 --- a/storage/rocksdb/ha_rocksdb.cc +++ b/storage/rocksdb/ha_rocksdb.cc @@ -12499,6 +12499,7 @@ void print_keydup_error(TABLE *table, KEY *key, myf errflag, its name generation. */ + struct st_mysql_storage_engine rocksdb_storage_engine = { MYSQL_HANDLERTON_INTERFACE_VERSION}; @@ -12515,7 +12516,7 @@ maria_declare_plugin(rocksdb_se){ myrocks::rocksdb_status_vars, /* status variables */ myrocks::rocksdb_system_variables, /* system variables */ "1.0", /* string version */ - MariaDB_PLUGIN_MATURITY_ALPHA /* maturity */ + myrocks::MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL }, myrocks::rdb_i_s_cfstats, myrocks::rdb_i_s_dbstats, myrocks::rdb_i_s_perf_context, myrocks::rdb_i_s_perf_context_global, diff --git a/storage/rocksdb/ha_rocksdb.h b/storage/rocksdb/ha_rocksdb.h index d064988d0f3..82819bbf7b2 100644 --- a/storage/rocksdb/ha_rocksdb.h +++ b/storage/rocksdb/ha_rocksdb.h @@ -1411,4 +1411,7 @@ private: Rdb_inplace_alter_ctx(const Rdb_inplace_alter_ctx &); Rdb_inplace_alter_ctx &operator=(const Rdb_inplace_alter_ctx &); }; + +const int MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL= MariaDB_PLUGIN_MATURITY_ALPHA; + } // namespace myrocks 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 f590fd22dff..9952314cd2c 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result @@ -64,3 +64,20 @@ 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; +# +# MDEV-14679: RocksdB plugin fails to load with "Loading of unknown plugin ROCKSDB_CFSTATS +# +select plugin_name, plugin_maturity from information_schema.plugins where plugin_name like '%rocksdb%'; +plugin_name plugin_maturity +ROCKSDB Alpha +ROCKSDB_CFSTATS Alpha +ROCKSDB_DBSTATS Alpha +ROCKSDB_PERF_CONTEXT Alpha +ROCKSDB_PERF_CONTEXT_GLOBAL Alpha +ROCKSDB_CF_OPTIONS Alpha +ROCKSDB_COMPACTION_STATS Alpha +ROCKSDB_GLOBAL_INFO Alpha +ROCKSDB_DDL Alpha +ROCKSDB_INDEX_FILE_MAP Alpha +ROCKSDB_LOCKS Alpha +ROCKSDB_TRX Alpha 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 70a4f5b05cb..980f2e302b2 100644 --- a/storage/rocksdb/mysql-test/rocksdb/t/mariadb_port_fixes.test +++ b/storage/rocksdb/mysql-test/rocksdb/t/mariadb_port_fixes.test @@ -67,3 +67,9 @@ set global rocksdb_strict_collation_check=off; create table t1 (pk varchar(10) collate latin1_nopad_bin, primary key(pk)) engine=rocksdb; set global rocksdb_strict_collation_check=@tmp_rscc; + +--echo # +--echo # MDEV-14679: RocksdB plugin fails to load with "Loading of unknown plugin ROCKSDB_CFSTATS +--echo # +select plugin_name, plugin_maturity from information_schema.plugins where plugin_name like '%rocksdb%'; + diff --git a/storage/rocksdb/rdb_i_s.cc b/storage/rocksdb/rdb_i_s.cc index 346a2994ec1..424a9e6c1f4 100644 --- a/storage/rocksdb/rdb_i_s.cc +++ b/storage/rocksdb/rdb_i_s.cc @@ -1484,7 +1484,7 @@ struct st_maria_plugin rdb_i_s_cfstats = { nullptr, /* status variables */ nullptr, /* system variables */ nullptr, /* config options */ - 0, /* flags */ + MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL }; struct st_maria_plugin rdb_i_s_dbstats = { @@ -1500,7 +1500,7 @@ struct st_maria_plugin rdb_i_s_dbstats = { nullptr, /* status variables */ nullptr, /* system variables */ nullptr, /* config options */ - 0, /* flags */ + MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL }; struct st_maria_plugin rdb_i_s_perf_context = { @@ -1516,7 +1516,7 @@ struct st_maria_plugin rdb_i_s_perf_context = { nullptr, /* status variables */ nullptr, /* system variables */ nullptr, /* config options */ - 0, /* flags */ + MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL }; struct st_maria_plugin rdb_i_s_perf_context_global = { @@ -1532,7 +1532,7 @@ struct st_maria_plugin rdb_i_s_perf_context_global = { nullptr, /* status variables */ nullptr, /* system variables */ nullptr, /* config options */ - 0, /* flags */ + MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL }; struct st_maria_plugin rdb_i_s_cfoptions = { @@ -1548,7 +1548,7 @@ struct st_maria_plugin rdb_i_s_cfoptions = { nullptr, /* status variables */ nullptr, /* system variables */ nullptr, /* config options */ - 0, /* flags */ + MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL }; struct st_maria_plugin rdb_i_s_global_info = { @@ -1564,7 +1564,7 @@ struct st_maria_plugin rdb_i_s_global_info = { nullptr, /* status variables */ nullptr, /* system variables */ nullptr, /* config options */ - 0, /* flags */ + MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL }; struct st_maria_plugin rdb_i_s_compact_stats = { @@ -1580,7 +1580,7 @@ struct st_maria_plugin rdb_i_s_compact_stats = { nullptr, /* status variables */ nullptr, /* system variables */ nullptr, /* config options */ - 0, /* flags */ + MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL }; struct st_maria_plugin rdb_i_s_ddl = { @@ -1596,7 +1596,7 @@ struct st_maria_plugin rdb_i_s_ddl = { nullptr, /* status variables */ nullptr, /* system variables */ nullptr, /* config options */ - 0, /* flags */ + MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL }; struct st_maria_plugin rdb_i_s_index_file_map = { @@ -1612,7 +1612,7 @@ struct st_maria_plugin rdb_i_s_index_file_map = { nullptr, /* status variables */ nullptr, /* system variables */ nullptr, /* config options */ - 0, /* flags */ + MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL }; struct st_maria_plugin rdb_i_s_lock_info = { @@ -1628,7 +1628,7 @@ struct st_maria_plugin rdb_i_s_lock_info = { nullptr, /* status variables */ nullptr, /* system variables */ nullptr, /* config options */ - 0, /* flags */ + MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL }; struct st_maria_plugin rdb_i_s_trx_info = { @@ -1644,6 +1644,6 @@ struct st_maria_plugin rdb_i_s_trx_info = { nullptr, /* status variables */ nullptr, /* system variables */ nullptr, /* config options */ - 0, /* flags */ + MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL }; } // namespace myrocks -- cgit v1.2.1 From 06f0b23a78ab15b6f3d4465e77ac1bdc747524d4 Mon Sep 17 00:00:00 2001 From: Monty Date: Sun, 17 Dec 2017 17:53:53 +0200 Subject: Fixed memory leak in my_rocks rocksdb_sys_vars.rocksdb_update_cf_options_basic.test failed with reports about not freed memory. --- storage/rocksdb/ha_rocksdb.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/storage/rocksdb/ha_rocksdb.cc b/storage/rocksdb/ha_rocksdb.cc index 98a9785713a..8857b2e8cba 100644 --- a/storage/rocksdb/ha_rocksdb.cc +++ b/storage/rocksdb/ha_rocksdb.cc @@ -12337,6 +12337,7 @@ void rocksdb_set_update_cf_options(THD *const /* unused */, // Basic sanity checking and parsing the options into a map. If this fails // then there's no point to proceed. if (!Rdb_cf_options::parse_cf_options(val, &option_map)) { + my_free(*reinterpret_cast(var_ptr)); *reinterpret_cast(var_ptr) = nullptr; // NO_LINT_DEBUG @@ -12405,6 +12406,7 @@ void rocksdb_set_update_cf_options(THD *const /* unused */, // the CF options. This will results in consistent behavior and avoids // dealing with cases when only a subset of CF-s was successfully updated. if (val) { + my_free(*reinterpret_cast(var_ptr)); *reinterpret_cast(var_ptr) = my_strdup(val, MYF(0)); } else { *reinterpret_cast(var_ptr) = nullptr; -- cgit v1.2.1 From c1e5fef05d87038fff8b55ba763d082a5bec5d78 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Mon, 18 Dec 2017 11:25:38 +0400 Subject: MDEV-14008 Assertion failing: `!is_set() || (m_status == DA_OK_BULK && is_bulk_op()) --- mysql-test/suite/innodb/r/innodb-autoinc.result | 12 ++++++++++++ mysql-test/suite/innodb/t/innodb-autoinc.test | 12 ++++++++++++ sql/field.cc | 4 ++-- sql/field.h | 8 +++++++- storage/innobase/handler/ha_innodb.cc | 4 ++-- storage/xtradb/handler/ha_innodb.cc | 4 ++-- 6 files changed, 37 insertions(+), 7 deletions(-) diff --git a/mysql-test/suite/innodb/r/innodb-autoinc.result b/mysql-test/suite/innodb/r/innodb-autoinc.result index 879f9dfa238..9aa819de22b 100644 --- a/mysql-test/suite/innodb/r/innodb-autoinc.result +++ b/mysql-test/suite/innodb/r/innodb-autoinc.result @@ -1348,3 +1348,15 @@ t CREATE TABLE `t` ( KEY `i` (`i`) ) ENGINE=InnoDB AUTO_INCREMENT=401 DEFAULT CHARSET=latin1 DROP TABLE t; +# +# MDEV-14008 Assertion failing: `!is_set() || (m_status == DA_OK_BULK && is_bulk_op()) +# +SET sql_mode=STRICT_ALL_TABLES; +CREATE TABLE t1 ( +c1 DOUBLE NOT NULL PRIMARY KEY AUTO_INCREMENT +) ENGINE=InnoDB AUTO_INCREMENT=10000000000000000000; +INSERT INTO t1 VALUES (); +SELECT * FROM t1; +c1 +1e19 +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/innodb-autoinc.test b/mysql-test/suite/innodb/t/innodb-autoinc.test index 362be2e055b..ebb6a5d24ff 100644 --- a/mysql-test/suite/innodb/t/innodb-autoinc.test +++ b/mysql-test/suite/innodb/t/innodb-autoinc.test @@ -680,3 +680,15 @@ INSERT INTO t VALUES (NULL); SELECT * FROM t; SHOW CREATE TABLE t; DROP TABLE t; + +--echo # +--echo # MDEV-14008 Assertion failing: `!is_set() || (m_status == DA_OK_BULK && is_bulk_op()) +--echo # + +SET sql_mode=STRICT_ALL_TABLES; +CREATE TABLE t1 ( + c1 DOUBLE NOT NULL PRIMARY KEY AUTO_INCREMENT +) ENGINE=InnoDB AUTO_INCREMENT=10000000000000000000; +INSERT INTO t1 VALUES (); +SELECT * FROM t1; +DROP TABLE t1; diff --git a/sql/field.cc b/sql/field.cc index 7074cc2cbc4..a3c20ec18f2 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4390,7 +4390,7 @@ double Field_double::val_real(void) return j; } -longlong Field_double::val_int(void) +longlong Field_double::val_int_from_real(bool want_unsigned_result) { ASSERT_COLUMN_MARKED_FOR_READ; double j; @@ -4398,7 +4398,7 @@ longlong Field_double::val_int(void) bool error; float8get(j,ptr); - res= double_to_longlong(j, 0, &error); + res= double_to_longlong(j, want_unsigned_result, &error); if (error) { ErrConvDouble err(j); diff --git a/sql/field.h b/sql/field.h index e7bd5532ae6..c99327bd068 100644 --- a/sql/field.h +++ b/sql/field.h @@ -420,6 +420,10 @@ public: enum_check_fields check_level); virtual double val_real(void)=0; virtual longlong val_int(void)=0; + virtual ulonglong val_uint(void) + { + return (ulonglong) val_int(); + } virtual my_decimal *val_decimal(my_decimal *); inline String *val_str(String *str) { return val_str(str, str); } /* @@ -1554,6 +1558,7 @@ private: class Field_double :public Field_real { + longlong val_int_from_real(bool want_unsigned_result); public: Field_double(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, uchar null_bit_arg, @@ -1580,7 +1585,8 @@ public: int store(longlong nr, bool unsigned_val); int reset(void) { bzero(ptr,sizeof(double)); return 0; } double val_real(void); - longlong val_int(void); + longlong val_int(void) { return val_int_from_real(false); } + ulonglong val_uint(void) { return (ulonglong) val_int_from_real(true); } String *val_str(String*,String *); bool send_binary(Protocol *protocol); int cmp(const uchar *,const uchar *); diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 4aab1b8d713..59a8aedd266 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -7274,7 +7274,7 @@ no_commit: table->next_number_field); /* Get the value that MySQL attempted to store in the table.*/ - auto_inc = table->next_number_field->val_int(); + auto_inc = table->next_number_field->val_uint(); switch (error) { case DB_DUPLICATE_KEY: @@ -7735,7 +7735,7 @@ ha_innobase::update_row( ulonglong auto_inc; ulonglong col_max_value; - auto_inc = table->next_number_field->val_int(); + auto_inc = table->next_number_field->val_uint(); /* We need the upper limit of the col type to check for whether we update the table autoinc counter or not. */ diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index f111a576d8f..88b59db9a46 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -7988,7 +7988,7 @@ no_commit: table->next_number_field); /* Get the value that MySQL attempted to store in the table.*/ - auto_inc = table->next_number_field->val_int(); + auto_inc = table->next_number_field->val_uint(); switch (error) { case DB_DUPLICATE_KEY: @@ -8468,7 +8468,7 @@ ha_innobase::update_row( ulonglong auto_inc; ulonglong col_max_value; - auto_inc = table->next_number_field->val_int(); + auto_inc = table->next_number_field->val_uint(); /* We need the upper limit of the col type to check for whether we update the table autoinc counter or not. */ -- cgit v1.2.1 From 6ee9cba74502e2da628ac72b21ce42570ff361b9 Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Mon, 18 Dec 2017 15:21:50 +0400 Subject: MDEV-10486 MariaDB 10.x does not update rows_examined in performance_schema tables. Save the rows_examined counter before it gets emptied. --- mysql-test/suite/perfschema/r/misc.result | 16 ++++++++++++++++ mysql-test/suite/perfschema/t/misc.test | 15 +++++++++++++++ sql/sql_parse.cc | 5 +++-- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/perfschema/r/misc.result b/mysql-test/suite/perfschema/r/misc.result index 2adf2cba851..7a097a27576 100644 --- a/mysql-test/suite/perfschema/r/misc.result +++ b/mysql-test/suite/perfschema/r/misc.result @@ -118,3 +118,19 @@ B select count(*) from events_statements_history where sql_text like "%..."; count(*) 2 +use test; +create table t1 (id int); +insert into t1 values (1), (2), (3); +truncate performance_schema.events_statements_history; +select * from t1; +id +1 +2 +3 +insert into t1 select RAND()*10000 from t1; +select sql_text, rows_examined from performance_schema.events_statements_history; +sql_text rows_examined +truncate performance_schema.events_statements_history 0 +select * from t1 3 +insert into t1 select RAND()*10000 from t1 6 +drop table t1; diff --git a/mysql-test/suite/perfschema/t/misc.test b/mysql-test/suite/perfschema/t/misc.test index bf3e8afffdc..c9f7dc6bfc0 100644 --- a/mysql-test/suite/perfschema/t/misc.test +++ b/mysql-test/suite/perfschema/t/misc.test @@ -207,3 +207,18 @@ select 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa select _utf8mb4 'васÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑ' as B; select count(*) from events_statements_history where sql_text like "%..."; + + +# +# MDEV-10486 MariaDB 10.x does not update rows_examined in performance_schema tables +# Verify that the rows_examined counter is set properly. + +use test; +create table t1 (id int); +insert into t1 values (1), (2), (3); +truncate performance_schema.events_statements_history; +select * from t1; +insert into t1 select RAND()*10000 from t1; +select sql_text, rows_examined from performance_schema.events_statements_history; +drop table t1; + diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 5cea264e4a8..3121ee99834 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1957,11 +1957,12 @@ bool dispatch_command(enum enum_server_command command, THD *thd, THD_STAGE_INFO(thd, stage_cleaning_up); thd->reset_query(); - thd->set_examined_row_count(0); // For processlist - thd->set_command(COM_SLEEP); /* Performance Schema Interface instrumentation, end */ MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da()); + thd->set_examined_row_count(0); // For processlist + thd->set_command(COM_SLEEP); + thd->m_statement_psi= NULL; thd->m_digest= NULL; -- cgit v1.2.1 From 03e91ce324465e465468021edd050c3b73d4cee3 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 15 Dec 2017 16:38:46 +0100 Subject: MDEV-14641 Incompatible key or row definition between the MariaDB .frm file and the information in the storage engine make sure that mysql_create_frm_image() and fast_alter_partition_table() use the same code to derive HA_OPTION_PACK_RECORD from create_info->row_type. --- mysql-test/suite/parts/r/partition_alter_myisam.result | 10 ++++++++++ mysql-test/suite/parts/t/partition_alter_myisam.test | 17 +++++++++++++++++ sql/handler.h | 7 +++++++ sql/sql_partition.cc | 5 +---- sql/sql_table.cc | 5 +---- 5 files changed, 36 insertions(+), 8 deletions(-) create mode 100644 mysql-test/suite/parts/r/partition_alter_myisam.result create mode 100644 mysql-test/suite/parts/t/partition_alter_myisam.test diff --git a/mysql-test/suite/parts/r/partition_alter_myisam.result b/mysql-test/suite/parts/r/partition_alter_myisam.result new file mode 100644 index 00000000000..514593fd4ef --- /dev/null +++ b/mysql-test/suite/parts/r/partition_alter_myisam.result @@ -0,0 +1,10 @@ +CREATE TABLE t1 (i INT) ENGINE=MYISAM +PARTITION BY LIST(i) ( +PARTITION p0 VALUES IN (1), +PARTITION p1 VALUES IN (2) +); +ALTER TABLE t1 ROW_FORMAT=COMPRESSED; +ALTER TABLE t1 DROP PARTITION p1; +SELECT * FROM t1; +i +DROP TABLE t1; diff --git a/mysql-test/suite/parts/t/partition_alter_myisam.test b/mysql-test/suite/parts/t/partition_alter_myisam.test new file mode 100644 index 00000000000..91ce8d21327 --- /dev/null +++ b/mysql-test/suite/parts/t/partition_alter_myisam.test @@ -0,0 +1,17 @@ +# +# MDEV-14641 Incompatible key or row definition between the MariaDB .frm file and the information in the storage engine +# + +--source include/have_partition.inc + +CREATE TABLE t1 (i INT) ENGINE=MYISAM +PARTITION BY LIST(i) ( + PARTITION p0 VALUES IN (1), + PARTITION p1 VALUES IN (2) +); +ALTER TABLE t1 ROW_FORMAT=COMPRESSED; +ALTER TABLE t1 DROP PARTITION p1; +SELECT * FROM t1; + +# Cleanup +DROP TABLE t1; diff --git a/sql/handler.h b/sql/handler.h index 772f2e68dab..c422094b4d5 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1666,6 +1666,13 @@ struct HA_CREATE_INFO used_fields|= (HA_CREATE_USED_CHARSET | HA_CREATE_USED_DEFAULT_CHARSET); return false; } + ulong table_options_with_row_type() + { + if (row_type == ROW_TYPE_DYNAMIC || row_type == ROW_TYPE_PAGE) + return table_options | HA_OPTION_PACK_RECORD; + else + return table_options; + } }; diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 02109b22898..a675d325a8b 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -6834,10 +6834,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table, lpt->part_info= part_info; lpt->alter_info= alter_info; lpt->create_info= create_info; - lpt->db_options= create_info->table_options; - if (create_info->row_type != ROW_TYPE_FIXED && - create_info->row_type != ROW_TYPE_DEFAULT) - lpt->db_options|= HA_OPTION_PACK_RECORD; + lpt->db_options= create_info->table_options_with_row_type(); lpt->table= table; lpt->key_info_buffer= 0; lpt->key_count= 0; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 9549884bc4e..7d37c559e20 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4405,10 +4405,7 @@ handler *mysql_create_frm_image(THD *thd, set_table_default_charset(thd, create_info, (char*) db); - db_options= create_info->table_options; - if (create_info->row_type == ROW_TYPE_DYNAMIC || - create_info->row_type == ROW_TYPE_PAGE) - db_options|= HA_OPTION_PACK_RECORD; + db_options= create_info->table_options_with_row_type(); if (!(file= get_new_handler((TABLE_SHARE*) 0, thd->mem_root, create_info->db_type))) -- cgit v1.2.1 From f32063c5137adc028a9b038b9e99f9384e583d0b Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Mon, 18 Dec 2017 15:37:06 +0000 Subject: MDEV-13620 - improve help message for 'plugin-dir' and 'plugin-load' options. --- extra/mariabackup/xtrabackup.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index 4d179961d1d..eb1cbf4748d 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -1103,11 +1103,13 @@ Disable with --skip-innodb-doublewrite.", (G_PTR*) &innobase_use_doublewrite, (G_PTR*) &defaults_group, (G_PTR*) &defaults_group, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"plugin-dir", OPT_PLUGIN_DIR, "Server plugin directory", + {"plugin-dir", OPT_PLUGIN_DIR, + "Server plugin directory. Used to load encryption plugin during 'prepare' phase." + "Has no effect in the 'backup' phase (plugin directory during backup is the same as server's)", &xb_plugin_dir, &xb_plugin_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, - { "plugin-load", OPT_PLUGIN_LOAD, "encrypton plugin to load", + { "plugin-load", OPT_PLUGIN_LOAD, "encrypton plugin to load during 'prepare' phase.", &xb_plugin_load, &xb_plugin_load, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, -- cgit v1.2.1 From 1c2f59f7fbacc0fa7c4037bf03630f849859ad45 Mon Sep 17 00:00:00 2001 From: Martynas Bendorius Date: Sun, 1 Oct 2017 15:45:51 +0200 Subject: MDEV-13969 sst mysqldump and xtrabackup-v2 handle WSREP_SST_OPT_CONF incorrectly wrep_sst_common: Setting "-c ''" for my_print_defaults just takes no values from config at all. $MY_PRINT_DEFAULTS is already set at the top of the script to have --defaults-file and --defaults-extra-file. If WSREP_SST_OPT_CONF if set to "--defaults-file=/etc/my.cnf --defaults-extra-file=/etc/my.extra.cnf", then "my_print_defaults -c "" --defaults-file=/etc/my.cnf" succeeds, but if WSREP_SST_OPT_CONF is empty - no default values are taken at all. wsrep_sst_xtrabackup-v2: innobackupex does not support --defaults-extra-file, so ${WSREP_SST_OPT_CONF} cannot be used as an argument, it has been changed to ${WSREP_SST_OPT_DEFAULT}. Removed --defaults-file= from INNOMOVE line, because WSREP_SST_OPT_CONF already includes it (INNOBACKUP was fine, INNOMOVE - not). --- scripts/wsrep_sst_common.sh | 4 ++-- scripts/wsrep_sst_xtrabackup-v2.sh | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh index 1ef4830661b..788e1a12f37 100644 --- a/scripts/wsrep_sst_common.sh +++ b/scripts/wsrep_sst_common.sh @@ -257,12 +257,12 @@ parse_cnf() # look in group+suffix if [ -n $WSREP_SST_OPT_CONF_SUFFIX ]; then - reval=$($MY_PRINT_DEFAULTS -c $WSREP_SST_OPT_CONF "${group}${WSREP_SST_OPT_CONF_SUFFIX}" | awk -F= '{if ($1 ~ /_/) { gsub(/_/,"-",$1); print $1"="$2 } else { print $0 }}' | grep -- "--$var=" | cut -d= -f2- | tail -1) + reval=$($MY_PRINT_DEFAULTS "${group}${WSREP_SST_OPT_CONF_SUFFIX}" | awk -F= '{if ($1 ~ /_/) { gsub(/_/,"-",$1); print $1"="$2 } else { print $0 }}' | grep -- "--$var=" | cut -d= -f2- | tail -1) fi # look in group if [ -z $reval ]; then - reval=$($MY_PRINT_DEFAULTS -c $WSREP_SST_OPT_CONF $group | awk -F= '{if ($1 ~ /_/) { gsub(/_/,"-",$1); print $1"="$2 } else { print $0 }}' | grep -- "--$var=" | cut -d= -f2- | tail -1) + reval=$($MY_PRINT_DEFAULTS $group | awk -F= '{if ($1 ~ /_/) { gsub(/_/,"-",$1); print $1"="$2 } else { print $0 }}' | grep -- "--$var=" | cut -d= -f2- | tail -1) fi # use default if we haven't found a value diff --git a/scripts/wsrep_sst_xtrabackup-v2.sh b/scripts/wsrep_sst_xtrabackup-v2.sh index faa7bc5e815..40e686d4d6b 100644 --- a/scripts/wsrep_sst_xtrabackup-v2.sh +++ b/scripts/wsrep_sst_xtrabackup-v2.sh @@ -492,7 +492,7 @@ read_cnf() ssystag+="-" if [[ $ssyslog -ne -1 ]];then - if $MY_PRINT_DEFAULTS -c $WSREP_SST_OPT_CONF mysqld_safe | tr '_' '-' | grep -q -- "--syslog";then + if $MY_PRINT_DEFAULTS mysqld_safe | tr '_' '-' | grep -q -- "--syslog";then ssyslog=1 fi fi @@ -669,7 +669,7 @@ check_extra() local use_socket=1 if [[ $uextra -eq 1 ]];then if $MY_PRINT_DEFAULTS --mysqld | tr '_' '-' | grep -- "--thread-handling=" | grep -q 'pool-of-threads';then - local eport=$($MY_PRINT_DEFAULTS -c $WSREP_SST_OPT_CONF mysqld | tr '_' '-' | grep -- "--extra-port=" | cut -d= -f2) + local eport=$($MY_PRINT_DEFAULTS mysqld | tr '_' '-' | grep -- "--extra-port=" | cut -d= -f2) if [[ -n $eport ]];then # Xtrabackup works only locally. # Hence, setting host to 127.0.0.1 unconditionally. @@ -865,14 +865,14 @@ if [[ $ssyslog -eq 1 ]];then } INNOAPPLY="${INNOBACKUPEX_BIN} $disver $iapts --apply-log \$rebuildcmd \${DATA} 2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-apply " - INNOMOVE="${INNOBACKUPEX_BIN} --defaults-file=${WSREP_SST_OPT_CONF} $disver $impts --datadir=${DATA} --move-back --force-non-empty-directories \${DATA} 2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-move " - INNOBACKUP="${INNOBACKUPEX_BIN} ${WSREP_SST_OPT_CONF} $disver $iopts \$tmpopts \$INNOEXTRA --galera-info --stream=\$sfmt \$itmpdir 2> >(logger -p daemon.err -t ${ssystag}innobackupex-backup)" + INNOMOVE="${INNOBACKUPEX_BIN} ${WSREP_SST_OPT_DEFAULT} $disver $impts --datadir=${DATA} --move-back --force-non-empty-directories \${DATA} 2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-move " + INNOBACKUP="${INNOBACKUPEX_BIN} ${WSREP_SST_OPT_DEFAULT} $disver $iopts \$tmpopts \$INNOEXTRA --galera-info --stream=\$sfmt \$itmpdir 2> >(logger -p daemon.err -t ${ssystag}innobackupex-backup)" fi else INNOAPPLY="${INNOBACKUPEX_BIN} $disver $iapts --apply-log \$rebuildcmd \${DATA} &>\${DATA}/innobackup.prepare.log" - INNOMOVE="${INNOBACKUPEX_BIN} --defaults-file=${WSREP_SST_OPT_CONF} --defaults-group=mysqld${WSREP_SST_OPT_CONF_SUFFIX} $disver $impts --datadir=${DATA} --move-back --force-non-empty-directories \${DATA} &>\${DATA}/innobackup.move.log" - INNOBACKUP="${INNOBACKUPEX_BIN} ${WSREP_SST_OPT_CONF} $disver $iopts \$tmpopts \$INNOEXTRA --galera-info --stream=\$sfmt \$itmpdir 2>\${DATA}/innobackup.backup.log" + INNOMOVE="${INNOBACKUPEX_BIN} ${WSREP_SST_OPT_DEFAULT} --defaults-group=mysqld${WSREP_SST_OPT_CONF_SUFFIX} $disver $impts --datadir=${DATA} --move-back --force-non-empty-directories \${DATA} &>\${DATA}/innobackup.move.log" + INNOBACKUP="${INNOBACKUPEX_BIN} ${WSREP_SST_OPT_DEFAULT} $disver $iopts \$tmpopts \$INNOEXTRA --galera-info --stream=\$sfmt \$itmpdir 2>\${DATA}/innobackup.backup.log" fi get_stream -- cgit v1.2.1 From beabe6b2167ee7e8c2659da9507e33ddd56a9c29 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 16 Oct 2017 19:33:06 +0200 Subject: MDEV-13969 sst mysqldump and xtrabackup-v2 handle WSREP_SST_OPT_CONF incorrectly $WSREP_SST_OPT_CONF already includes --defaults-extra-file= prefix. --- scripts/wsrep_sst_mysqldump.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/wsrep_sst_mysqldump.sh b/scripts/wsrep_sst_mysqldump.sh index 59d9a3c5c9c..f086d9873d0 100644 --- a/scripts/wsrep_sst_mysqldump.sh +++ b/scripts/wsrep_sst_mysqldump.sh @@ -117,7 +117,7 @@ GTID_BINLOG_STATE=$(echo "SHOW GLOBAL VARIABLES LIKE 'gtid_binlog_state'" |\ $MYSQL_CLIENT $AUTH -S$WSREP_SST_OPT_SOCKET --disable-reconnect --connect_timeout=10 |\ tail -1 | awk -F ' ' '{ print $2 }') -MYSQL="$MYSQL_CLIENT --defaults-extra-file=$WSREP_SST_OPT_CONF "\ +MYSQL="$MYSQL_CLIENT $WSREP_SST_OPT_CONF "\ "$AUTH -h${WSREP_SST_OPT_HOST_UNESCAPED:-$WSREP_SST_OPT_HOST} "\ "-P$WSREP_SST_OPT_PORT --disable-reconnect --connect_timeout=10" -- cgit v1.2.1 From 91daf8819cf84828b4c96be6f0b35caca97bb61c Mon Sep 17 00:00:00 2001 From: sjaakola Date: Tue, 12 Dec 2017 17:47:06 +0100 Subject: MW-416 Moved TOI replication to happen after ACL checking for commands: SQLCOM_CREATE_EVENT SQLCOM_ALTER_EVENT SQLCOM_DROP_EVENT SQLCOM_CREATE_VIEW SQLCOM_CREATE_TRIGGER SQLCOM_DROP_TRIGGER SQLCOM_INSTALL_PLUGIN SQLCOM_UNINSTALL_PLUGIN --- sql/events.cc | 18 ++++++++++++++++++ sql/sql_parse.cc | 7 ------- sql/sql_plugin.cc | 20 ++++++++++++++++---- sql/sql_trigger.cc | 5 +++++ sql/sql_view.cc | 5 +++++ 5 files changed, 44 insertions(+), 11 deletions(-) diff --git a/sql/events.cc b/sql/events.cc index 51f68ca4c03..cdc15f41716 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -335,6 +335,7 @@ Events::create_event(THD *thd, Event_parse_data *parse_data) if (check_access(thd, EVENT_ACL, parse_data->dbname.str, NULL, NULL, 0, 0)) DBUG_RETURN(TRUE); + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) if (lock_object_name(thd, MDL_key::EVENT, parse_data->dbname.str, parse_data->name.str)) @@ -417,6 +418,10 @@ Events::create_event(THD *thd, Event_parse_data *parse_data) thd->restore_stmt_binlog_format(save_binlog_format); DBUG_RETURN(ret); +#ifdef WITH_WSREP + error: + DBUG_RETURN(true); +#endif /* WITH_WSREP */ } @@ -457,6 +462,9 @@ Events::update_event(THD *thd, Event_parse_data *parse_data, if (check_access(thd, EVENT_ACL, parse_data->dbname.str, NULL, NULL, 0, 0)) DBUG_RETURN(TRUE); + + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) + if (lock_object_name(thd, MDL_key::EVENT, parse_data->dbname.str, parse_data->name.str)) DBUG_RETURN(TRUE); @@ -541,6 +549,10 @@ Events::update_event(THD *thd, Event_parse_data *parse_data, thd->restore_stmt_binlog_format(save_binlog_format); DBUG_RETURN(ret); +#ifdef WITH_WSREP +error: + DBUG_RETURN(TRUE); +#endif /* WITH_WSREP */ } @@ -581,6 +593,8 @@ Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists) if (check_access(thd, EVENT_ACL, dbname.str, NULL, NULL, 0, 0)) DBUG_RETURN(TRUE); + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) + /* Turn off row binlogging of this statement and use statement-based so that all supporting tables are updated for DROP EVENT command. @@ -602,6 +616,10 @@ Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists) thd->restore_stmt_binlog_format(save_binlog_format); DBUG_RETURN(ret); +#ifdef WITH_WSREP +error: + DBUG_RETURN(TRUE); +#endif } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 3121ee99834..6084c59a257 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4565,7 +4565,6 @@ end_with_restore_list: if (res) break; - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) switch (lex->sql_command) { case SQLCOM_CREATE_EVENT: { @@ -4599,7 +4598,6 @@ end_with_restore_list: lex->spname->m_name); break; case SQLCOM_DROP_EVENT: - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) if (!(res= Events::drop_event(thd, lex->spname->m_db, lex->spname->m_name, lex->if_exists()))) @@ -5505,7 +5503,6 @@ end_with_restore_list: Note: SQLCOM_CREATE_VIEW also handles 'ALTER VIEW' commands as specified through the thd->lex->create_view_mode flag. */ - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) res= mysql_create_view(thd, first_table, thd->lex->create_view_mode); break; } @@ -5521,7 +5518,6 @@ end_with_restore_list: case SQLCOM_CREATE_TRIGGER: { /* Conditionally writes to binlog. */ - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) res= mysql_create_or_drop_trigger(thd, all_tables, 1); break; @@ -5529,7 +5525,6 @@ end_with_restore_list: case SQLCOM_DROP_TRIGGER: { /* Conditionally writes to binlog. */ - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) res= mysql_create_or_drop_trigger(thd, all_tables, 0); break; } @@ -5594,13 +5589,11 @@ end_with_restore_list: my_ok(thd); break; case SQLCOM_INSTALL_PLUGIN: - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) if (! (res= mysql_install_plugin(thd, &thd->lex->comment, &thd->lex->ident))) my_ok(thd); break; case SQLCOM_UNINSTALL_PLUGIN: - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) if (! (res= mysql_uninstall_plugin(thd, &thd->lex->comment, &thd->lex->ident))) my_ok(thd); diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index f41d1e0fdbf..3a4097734ec 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -2108,12 +2108,16 @@ bool mysql_install_plugin(THD *thd, const LEX_STRING *name, bool error; int argc=orig_argc; char **argv=orig_argv; + unsigned long event_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE] = + { MYSQL_AUDIT_GENERAL_CLASSMASK }; DBUG_ENTER("mysql_install_plugin"); tables.init_one_table("mysql", 5, "plugin", 6, "plugin", TL_WRITE); if (!opt_noacl && check_table_access(thd, INSERT_ACL, &tables, FALSE, 1, FALSE)) DBUG_RETURN(TRUE); + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) + /* need to open before acquiring LOCK_plugin or it will deadlock */ if (! (table = open_ltable(thd, &tables, TL_WRITE, MYSQL_LOCK_IGNORE_TIMEOUT))) @@ -2146,8 +2150,6 @@ bool mysql_install_plugin(THD *thd, const LEX_STRING *name, See also mysql_uninstall_plugin() and initialize_audit_plugin() */ - unsigned long event_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE] = - { MYSQL_AUDIT_GENERAL_CLASSMASK }; mysql_audit_acquire_plugins(thd, event_class_mask); mysql_mutex_lock(&LOCK_plugin); @@ -2178,6 +2180,10 @@ err: if (argv) free_defaults(argv); DBUG_RETURN(error); +#ifdef WITH_WSREP +error: + DBUG_RETURN(TRUE); +#endif /* WITH_WSREP */ } @@ -2244,6 +2250,8 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name, TABLE_LIST tables; LEX_STRING dl= *dl_arg; bool error= false; + unsigned long event_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE] = + { MYSQL_AUDIT_GENERAL_CLASSMASK }; DBUG_ENTER("mysql_uninstall_plugin"); tables.init_one_table("mysql", 5, "plugin", 6, "plugin", TL_WRITE); @@ -2251,6 +2259,8 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name, if (!opt_noacl && check_table_access(thd, DELETE_ACL, &tables, FALSE, 1, FALSE)) DBUG_RETURN(TRUE); + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) + /* need to open before acquiring LOCK_plugin or it will deadlock */ if (! (table= open_ltable(thd, &tables, TL_WRITE, MYSQL_LOCK_IGNORE_TIMEOUT))) DBUG_RETURN(TRUE); @@ -2276,8 +2286,6 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name, See also mysql_install_plugin() and initialize_audit_plugin() */ - unsigned long event_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE] = - { MYSQL_AUDIT_GENERAL_CLASSMASK }; mysql_audit_acquire_plugins(thd, event_class_mask); mysql_mutex_lock(&LOCK_plugin); @@ -2307,6 +2315,10 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name, mysql_mutex_unlock(&LOCK_plugin); DBUG_RETURN(error); +#ifdef WITH_WSREP +error: + DBUG_RETURN(TRUE); +#endif /* WITH_WSREP */ } diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 28e59319a50..0b4978b2862 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -441,6 +441,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) my_error(ER_BINLOG_CREATE_ROUTINE_NEED_SUPER, MYF(0)); DBUG_RETURN(TRUE); } + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) if (!create) { @@ -606,6 +607,10 @@ end: my_ok(thd); DBUG_RETURN(result); +#ifdef WITH_WSREP + error: + DBUG_RETURN(true); +#endif /* WITH_WSREP */ } /** diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 90c94e6a503..629dd865b0e 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -425,6 +425,7 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, if ((res= create_view_precheck(thd, tables, view, mode))) goto err; + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) lex->link_first_table_back(view, link_to_local); view->open_type= OT_BASE_ONLY; @@ -695,6 +696,10 @@ err: lex->link_first_table_back(view, link_to_local); unit->cleanup(); DBUG_RETURN(res || thd->is_error()); +#ifdef WITH_WSREP + error: + DBUG_RETURN(true); +#endif /* WITH_WSREP */ } -- cgit v1.2.1 From 682c3bfd259b3184232e5329558094faa0bc8562 Mon Sep 17 00:00:00 2001 From: Nirbhay Choubey Date: Mon, 21 Nov 2016 16:20:10 -0500 Subject: MDEV-10442: "Address already in use" on restart SST processes should inherit mysqld's process group. --- sql/wsrep_utils.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/sql/wsrep_utils.cc b/sql/wsrep_utils.cc index 580c8bbd55c..8a72d754a43 100644 --- a/sql/wsrep_utils.cc +++ b/sql/wsrep_utils.cc @@ -264,7 +264,6 @@ process::process (const char* cmd, const char* type, char** env) err_ = posix_spawnattr_setflags (&attr, POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK | - /* start a new process group */ POSIX_SPAWN_SETPGROUP | POSIX_SPAWN_USEVFORK); if (err_) { -- cgit v1.2.1 From 40088bfc7e100294d622ab32a6e7cbcb79c12eab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 18 Dec 2017 19:46:23 +0200 Subject: MDEV-13407 innodb.drop_table_background failed in buildbot with "Tablespace for table exists" The InnoDB background DROP TABLE queue is something that we should really remove, but are unable to until we remove dict_operation_lock so that DDL and DML operations can be combined in a single transaction. Because the queue is not persistent, it is not crash-safe. In stable versions of MariaDB, we can only try harder to drop all enqueued tables before server shutdown. row_mysql_drop_t::table_id: Replaces table_name. row_drop_tables_for_mysql_in_background(): Do not remove the entry from the list as long as the table exists. In this way, the table should eventually be dropped. --- storage/innobase/row/row0mysql.cc | 136 +++++++++++--------------------------- storage/xtradb/row/row0mysql.cc | 136 +++++++++++--------------------------- 2 files changed, 74 insertions(+), 198 deletions(-) diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 74a17b9a1c3..4a39fc311b0 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -73,7 +73,7 @@ UNIV_INTERN ibool row_rollback_on_timeout = FALSE; /** Chain node of the list of tables to drop in the background. */ struct row_mysql_drop_t{ - char* table_name; /*!< table name */ + table_id_t table_id; /*!< table id */ UT_LIST_NODE_T(row_mysql_drop_t)row_mysql_drop_list; /*!< list chain node */ }; @@ -136,19 +136,6 @@ row_mysql_is_system_table( || 0 == strcmp(name + 6, "db")); } -/*********************************************************************//** -If a table is not yet in the drop list, adds the table to the list of tables -which the master thread drops in background. We need this on Unix because in -ALTER TABLE MySQL may call drop table even if the table has running queries on -it. Also, if there are running foreign key checks on the table, we drop the -table lazily. -@return TRUE if the table was not yet in the drop list, and was added there */ -static -ibool -row_add_table_to_background_drop_list( -/*==================================*/ - const char* name); /*!< in: table name */ - /*******************************************************************//** Delays an INSERT, DELETE or UPDATE operation if the purge is lagging. */ static @@ -2727,7 +2714,7 @@ loop: mutex_enter(&row_drop_list_mutex); ut_a(row_mysql_drop_list_inited); - +next: drop = UT_LIST_GET_FIRST(row_mysql_drop_list); n_tables = UT_LIST_GET_LEN(row_mysql_drop_list); @@ -2740,62 +2727,39 @@ loop: return(n_tables + n_tables_dropped); } - DBUG_EXECUTE_IF("row_drop_tables_in_background_sleep", - os_thread_sleep(5000000); - ); - - table = dict_table_open_on_name(drop->table_name, FALSE, FALSE, - DICT_ERR_IGNORE_NONE); - - if (table == NULL) { - /* If for some reason the table has already been dropped - through some other mechanism, do not try to drop it */ + table = dict_table_open_on_id(drop->table_id, FALSE, + DICT_TABLE_OP_NORMAL); - goto already_dropped; + if (!table) { + n_tables_dropped++; + mutex_enter(&row_drop_list_mutex); + UT_LIST_REMOVE(row_mysql_drop_list, row_mysql_drop_list, drop); + MONITOR_DEC(MONITOR_BACKGROUND_DROP_TABLE); + ut_free(drop); + goto next; } + ut_a(!table->can_be_evicted); + if (!table->to_be_dropped) { - /* There is a scenario: the old table is dropped - just after it's added into drop list, and new - table with the same name is created, then we try - to drop the new table in background. */ dict_table_close(table, FALSE, FALSE); - goto already_dropped; + mutex_enter(&row_drop_list_mutex); + UT_LIST_REMOVE(row_mysql_drop_list, row_mysql_drop_list, drop); + UT_LIST_ADD_LAST(row_mysql_drop_list, row_mysql_drop_list, + drop); + goto next; } - ut_a(!table->can_be_evicted); - dict_table_close(table, FALSE, FALSE); if (DB_SUCCESS != row_drop_table_for_mysql_in_background( - drop->table_name)) { + table->name)) { /* If the DROP fails for some table, we return, and let the main thread retry later */ - return(n_tables + n_tables_dropped); } - n_tables_dropped++; - -already_dropped: - mutex_enter(&row_drop_list_mutex); - - UT_LIST_REMOVE(row_mysql_drop_list, row_mysql_drop_list, drop); - - MONITOR_DEC(MONITOR_BACKGROUND_DROP_TABLE); - - ut_print_timestamp(stderr); - fputs(" InnoDB: Dropped table ", stderr); - ut_print_name(stderr, NULL, TRUE, drop->table_name); - fputs(" in background drop queue.\n", stderr); - - mem_free(drop->table_name); - - mem_free(drop); - - mutex_exit(&row_drop_list_mutex); - goto loop; } @@ -2827,14 +2791,13 @@ which the master thread drops in background. We need this on Unix because in ALTER TABLE MySQL may call drop table even if the table has running queries on it. Also, if there are running foreign key checks on the table, we drop the table lazily. -@return TRUE if the table was not yet in the drop list, and was added there */ +@return whether background DROP TABLE was scheduled for the first time */ static -ibool -row_add_table_to_background_drop_list( -/*==================================*/ - const char* name) /*!< in: table name */ +bool +row_add_table_to_background_drop_list(table_id_t table_id) { row_mysql_drop_t* drop; + bool added = true; mutex_enter(&row_drop_list_mutex); @@ -2845,31 +2808,21 @@ row_add_table_to_background_drop_list( drop != NULL; drop = UT_LIST_GET_NEXT(row_mysql_drop_list, drop)) { - if (strcmp(drop->table_name, name) == 0) { - /* Already in the list */ - - mutex_exit(&row_drop_list_mutex); - - return(FALSE); + if (drop->table_id == table_id) { + added = false; + goto func_exit; } } - drop = static_cast( - mem_alloc(sizeof(row_mysql_drop_t))); - - drop->table_name = mem_strdup(name); + drop = static_cast(ut_malloc(sizeof *drop)); + drop->table_id = table_id; UT_LIST_ADD_LAST(row_mysql_drop_list, row_mysql_drop_list, drop); MONITOR_INC(MONITOR_BACKGROUND_DROP_TABLE); - - /* fputs("InnoDB: Adding table ", stderr); - ut_print_name(stderr, trx, TRUE, drop->table_name); - fputs(" to background drop list\n", stderr); */ - +func_exit: mutex_exit(&row_drop_list_mutex); - - return(TRUE); + return added; } /*********************************************************************//** @@ -4043,7 +3996,7 @@ row_drop_table_for_mysql( DBUG_EXECUTE_IF("row_drop_table_add_to_background", - row_add_table_to_background_drop_list(table->name); + row_add_table_to_background_drop_list(table->id); err = DB_SUCCESS; goto funct_exit; ); @@ -4055,33 +4008,22 @@ row_drop_table_for_mysql( checks take an IS or IX lock on the table. */ if (table->n_foreign_key_checks_running > 0) { - - const char* save_tablename = table->name; - ibool added; - - added = row_add_table_to_background_drop_list(save_tablename); - - if (added) { + if (row_add_table_to_background_drop_list(table->id)) { ut_print_timestamp(stderr); fputs(" InnoDB: You are trying to drop table ", stderr); - ut_print_name(stderr, trx, TRUE, save_tablename); + ut_print_name(stderr, trx, TRUE, table->name); fputs("\n" "InnoDB: though there is a" " foreign key check running on it.\n" "InnoDB: Adding the table to" " the background drop queue.\n", stderr); - - /* We return DB_SUCCESS to MySQL though the drop will - happen lazily later */ - - err = DB_SUCCESS; - } else { - /* The table is already in the background drop list */ - err = DB_ERROR; } + /* We return DB_SUCCESS to MySQL though the drop will + happen lazily later */ + err = DB_SUCCESS; goto funct_exit; } @@ -4103,11 +4045,7 @@ row_drop_table_for_mysql( lock_remove_all_on_table(table, TRUE); ut_a(table->n_rec_locks == 0); } else if (table->n_ref_count > 0 || table->n_rec_locks > 0) { - ibool added; - - added = row_add_table_to_background_drop_list(table->name); - - if (added) { + if (row_add_table_to_background_drop_list(table->id)) { ut_print_timestamp(stderr); fputs(" InnoDB: Warning: MySQL is" " trying to drop table ", stderr); diff --git a/storage/xtradb/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc index ebdee381713..8a6e2728342 100644 --- a/storage/xtradb/row/row0mysql.cc +++ b/storage/xtradb/row/row0mysql.cc @@ -72,7 +72,7 @@ UNIV_INTERN ibool row_rollback_on_timeout = FALSE; /** Chain node of the list of tables to drop in the background. */ struct row_mysql_drop_t{ - char* table_name; /*!< table name */ + table_id_t table_id; /*!< table id */ UT_LIST_NODE_T(row_mysql_drop_t)row_mysql_drop_list; /*!< list chain node */ }; @@ -135,19 +135,6 @@ row_mysql_is_system_table( || 0 == strcmp(name + 6, "db")); } -/*********************************************************************//** -If a table is not yet in the drop list, adds the table to the list of tables -which the master thread drops in background. We need this on Unix because in -ALTER TABLE MySQL may call drop table even if the table has running queries on -it. Also, if there are running foreign key checks on the table, we drop the -table lazily. -@return TRUE if the table was not yet in the drop list, and was added there */ -static -ibool -row_add_table_to_background_drop_list( -/*==================================*/ - const char* name); /*!< in: table name */ - /*******************************************************************//** Delays an INSERT, DELETE or UPDATE operation if the purge is lagging. */ static @@ -2739,7 +2726,7 @@ loop: mutex_enter(&row_drop_list_mutex); ut_a(row_mysql_drop_list_inited); - +next: drop = UT_LIST_GET_FIRST(row_mysql_drop_list); n_tables = UT_LIST_GET_LEN(row_mysql_drop_list); @@ -2752,62 +2739,39 @@ loop: return(n_tables + n_tables_dropped); } - DBUG_EXECUTE_IF("row_drop_tables_in_background_sleep", - os_thread_sleep(5000000); - ); - - table = dict_table_open_on_name(drop->table_name, FALSE, FALSE, - DICT_ERR_IGNORE_NONE); - - if (table == NULL) { - /* If for some reason the table has already been dropped - through some other mechanism, do not try to drop it */ + table = dict_table_open_on_id(drop->table_id, FALSE, + DICT_TABLE_OP_NORMAL); - goto already_dropped; + if (!table) { + n_tables_dropped++; + mutex_enter(&row_drop_list_mutex); + UT_LIST_REMOVE(row_mysql_drop_list, row_mysql_drop_list, drop); + MONITOR_DEC(MONITOR_BACKGROUND_DROP_TABLE); + ut_free(drop); + goto next; } + ut_a(!table->can_be_evicted); + if (!table->to_be_dropped) { - /* There is a scenario: the old table is dropped - just after it's added into drop list, and new - table with the same name is created, then we try - to drop the new table in background. */ dict_table_close(table, FALSE, FALSE); - goto already_dropped; + mutex_enter(&row_drop_list_mutex); + UT_LIST_REMOVE(row_mysql_drop_list, row_mysql_drop_list, drop); + UT_LIST_ADD_LAST(row_mysql_drop_list, row_mysql_drop_list, + drop); + goto next; } - ut_a(!table->can_be_evicted); - dict_table_close(table, FALSE, FALSE); if (DB_SUCCESS != row_drop_table_for_mysql_in_background( - drop->table_name)) { + table->name)) { /* If the DROP fails for some table, we return, and let the main thread retry later */ - return(n_tables + n_tables_dropped); } - n_tables_dropped++; - -already_dropped: - mutex_enter(&row_drop_list_mutex); - - UT_LIST_REMOVE(row_mysql_drop_list, row_mysql_drop_list, drop); - - MONITOR_DEC(MONITOR_BACKGROUND_DROP_TABLE); - - ut_print_timestamp(stderr); - fputs(" InnoDB: Dropped table ", stderr); - ut_print_name(stderr, NULL, TRUE, drop->table_name); - fputs(" in background drop queue.\n", stderr); - - mem_free(drop->table_name); - - mem_free(drop); - - mutex_exit(&row_drop_list_mutex); - goto loop; } @@ -2839,14 +2803,13 @@ which the master thread drops in background. We need this on Unix because in ALTER TABLE MySQL may call drop table even if the table has running queries on it. Also, if there are running foreign key checks on the table, we drop the table lazily. -@return TRUE if the table was not yet in the drop list, and was added there */ +@return whether background DROP TABLE was scheduled for the first time */ static -ibool -row_add_table_to_background_drop_list( -/*==================================*/ - const char* name) /*!< in: table name */ +bool +row_add_table_to_background_drop_list(table_id_t table_id) { row_mysql_drop_t* drop; + bool added = true; mutex_enter(&row_drop_list_mutex); @@ -2857,31 +2820,21 @@ row_add_table_to_background_drop_list( drop != NULL; drop = UT_LIST_GET_NEXT(row_mysql_drop_list, drop)) { - if (strcmp(drop->table_name, name) == 0) { - /* Already in the list */ - - mutex_exit(&row_drop_list_mutex); - - return(FALSE); + if (drop->table_id == table_id) { + added = false; + goto func_exit; } } - drop = static_cast( - mem_alloc(sizeof(row_mysql_drop_t))); - - drop->table_name = mem_strdup(name); + drop = static_cast(ut_malloc(sizeof *drop)); + drop->table_id = table_id; UT_LIST_ADD_LAST(row_mysql_drop_list, row_mysql_drop_list, drop); MONITOR_INC(MONITOR_BACKGROUND_DROP_TABLE); - - /* fputs("InnoDB: Adding table ", stderr); - ut_print_name(stderr, trx, TRUE, drop->table_name); - fputs(" to background drop list\n", stderr); */ - +func_exit: mutex_exit(&row_drop_list_mutex); - - return(TRUE); + return added; } /*********************************************************************//** @@ -4057,7 +4010,7 @@ row_drop_table_for_mysql( DBUG_EXECUTE_IF("row_drop_table_add_to_background", - row_add_table_to_background_drop_list(table->name); + row_add_table_to_background_drop_list(table->id); err = DB_SUCCESS; goto funct_exit; ); @@ -4069,33 +4022,22 @@ row_drop_table_for_mysql( checks take an IS or IX lock on the table. */ if (table->n_foreign_key_checks_running > 0) { - - const char* save_tablename = table->name; - ibool added; - - added = row_add_table_to_background_drop_list(save_tablename); - - if (added) { + if (row_add_table_to_background_drop_list(table->id)) { ut_print_timestamp(stderr); fputs(" InnoDB: You are trying to drop table ", stderr); - ut_print_name(stderr, trx, TRUE, save_tablename); + ut_print_name(stderr, trx, TRUE, table->name); fputs("\n" "InnoDB: though there is a" " foreign key check running on it.\n" "InnoDB: Adding the table to" " the background drop queue.\n", stderr); - - /* We return DB_SUCCESS to MySQL though the drop will - happen lazily later */ - - err = DB_SUCCESS; - } else { - /* The table is already in the background drop list */ - err = DB_ERROR; } + /* We return DB_SUCCESS to MySQL though the drop will + happen lazily later */ + err = DB_SUCCESS; goto funct_exit; } @@ -4117,11 +4059,7 @@ row_drop_table_for_mysql( lock_remove_all_on_table(table, TRUE); ut_a(table->n_rec_locks == 0); } else if (table->n_ref_count > 0 || table->n_rec_locks > 0) { - ibool added; - - added = row_add_table_to_background_drop_list(table->name); - - if (added) { + if (row_add_table_to_background_drop_list(table->id)) { ut_print_timestamp(stderr); fputs(" InnoDB: Warning: MySQL is" " trying to drop table ", stderr); -- cgit v1.2.1 From 64f1fab068582a82ac54ce4793542655d5fc58ab Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Tue, 19 Dec 2017 10:24:50 +1100 Subject: MDEV-12128: systemd - add Documentation= directives --- support-files/mariadb.service.in | 4 +++- support-files/mariadb@.service.in | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/support-files/mariadb.service.in b/support-files/mariadb.service.in index 6a307b2c41f..2b02a1d0db9 100644 --- a/support-files/mariadb.service.in +++ b/support-files/mariadb.service.in @@ -13,7 +13,9 @@ # and probably others [Unit] -Description=MariaDB database server +Description=MariaDB @VERSION@ database server +Documentation=man:mysqld(8) +Documentation=https://mariadb.com/kb/en/library/systemd/ After=network.target After=syslog.target diff --git a/support-files/mariadb@.service.in b/support-files/mariadb@.service.in index 410e7433b2b..a4a6a0ffef6 100644 --- a/support-files/mariadb@.service.in +++ b/support-files/mariadb@.service.in @@ -18,7 +18,9 @@ # Inspired from https://gitweb.gentoo.org/repo/gentoo.git/tree/dev-db/mysql-init-scripts/files/mysqld_at.service [Unit] -Description=MariaDB database server +Description=MariaDB @VERSION@ database server (multi-instance) +Documentation=man:mysqld(8) +Documentation=https://mariadb.com/kb/en/library/systemd/ After=network.target After=syslog.target -- cgit v1.2.1 From ce4cdfa0f8691f47366d50acd6049b8cd7520e8a Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Tue, 19 Dec 2017 08:56:31 +1100 Subject: MDEV-13809: [service] should [Service] in systemd service files --- support-files/mariadb.service.in | 5 +++-- support-files/mariadb@.service.in | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/support-files/mariadb.service.in b/support-files/mariadb.service.in index 2b02a1d0db9..fe00f160d28 100644 --- a/support-files/mariadb.service.in +++ b/support-files/mariadb.service.in @@ -78,7 +78,7 @@ ExecStartPre=/bin/sh -c "[ ! -e @bindir@/galera_recovery ] && VAR= || \ # Start main service # MYSQLD_OPTS here is for users to set in /etc/systemd/system/mariadb.service.d/MY_SPECIAL.conf -# Use the [service] section and Environment="MYSQLD_OPTS=...". +# Use the [Service] section and Environment="MYSQLD_OPTS=...". # This isn't a replacement for my.cnf. # _WSREP_NEW_CLUSTER is for the exclusive use of the script galera_new_cluster ExecStart=@sbindir@/mysqld $MYSQLD_OPTS $_WSREP_NEW_CLUSTER $_WSREP_START_POSITION @@ -105,7 +105,8 @@ UMask=007 ## ## ## by creating a file in /etc/systemd/system/mariadb.service.d/MY_SPECIAL.conf -## and adding/setting the following will override this file's settings. +## and adding/setting the following under [Service] will override this file's +## settings. # Useful options not previously available in [mysqld_safe] diff --git a/support-files/mariadb@.service.in b/support-files/mariadb@.service.in index a4a6a0ffef6..000724d7fe2 100644 --- a/support-files/mariadb@.service.in +++ b/support-files/mariadb@.service.in @@ -91,7 +91,7 @@ ExecStartPre=/bin/sh -c "[ ! -e @bindir@/galera_recovery ] && VAR= || \ # Start main service # MYSQLD_OPTS here is for users to set in /etc/systemd/system/mariadb@.service.d/MY_SPECIAL.conf -# Use the [service] section and Environment="MYSQLD_OPTS=...". +# Use the [Service] section and Environment="MYSQLD_OPTS=...". # This isn't a replacement for my.cnf. # _WSREP_NEW_CLUSTER is for the exclusive use of the script galera_new_cluster @@ -126,7 +126,8 @@ UMask=007 ## ## ## by creating a file in /etc/systemd/system/mariadb.service.d/MY_SPECIAL.conf -## and adding/setting the following will override this file's settings. +## and adding/setting the following below [Service] will override this file's +## settings. # Useful options not previously available in [mysqld_safe] -- cgit v1.2.1 From 079c3599711b9cbd3ce323f32cf99693cc3d5e3b Mon Sep 17 00:00:00 2001 From: Galina Shalygina Date: Tue, 19 Dec 2017 11:49:40 +0200 Subject: MDEV-14629: failing assertion when a user-defined variable is defined by the recursive CTE During the user-defined variable defined by the recursive CTE handling procedure check_dependencies_in_with_clauses that checks dependencies between the tables that are defined in the CTE and find recursive definitions wasn't called. --- mysql-test/r/cte_recursive.result | 47 ++++++++++++++++++++++++++++++++++++ mysql-test/t/cte_recursive.test | 51 +++++++++++++++++++++++++++++++++++++++ sql/sql_parse.cc | 3 +++ 3 files changed, 101 insertions(+) diff --git a/mysql-test/r/cte_recursive.result b/mysql-test/r/cte_recursive.result index b744f24bb57..ece5421e279 100644 --- a/mysql-test/r/cte_recursive.result +++ b/mysql-test/r/cte_recursive.result @@ -2897,3 +2897,50 @@ n 1 2 3 +# +# mdev-14629: a user-defined variable is defined by the recursive CTE +# +set @var= +( +with recursive cte_tab(a) as ( +select 1 +union +select a+1 from cte_tab +where a<3) +select count(*) from cte_tab +); +select @var; +@var +3 +create table t1(a int, b int); +insert into t1 values (3,8),(1,5),(5,7),(7,4),(4,3); +set @var= +( +with recursive summ(a,s) as ( +select 1, 0 union +select t1.b, t1.b+summ.s from summ, t1 +where summ.a=t1.a) +select s from summ +order by a desc +limit 1 +); +select @var; +@var +27 +set @var= +( +with recursive +cte_1 as ( +select 1 +union +select * from cte_2), +cte_2 as ( +select * from cte_1 +union +select a from t1, cte_2 +where t1.a=cte_2.a) +select * from cte_2 +limit 1 +); +ERROR HY000: Unacceptable mutual recursion with anchored table 'cte_1' +drop table t1; diff --git a/mysql-test/t/cte_recursive.test b/mysql-test/t/cte_recursive.test index 36d948251c3..928f8a4334b 100644 --- a/mysql-test/t/cte_recursive.test +++ b/mysql-test/t/cte_recursive.test @@ -1947,3 +1947,54 @@ cte2 as ( ) SELECT * FROM cte1; + +--echo # +--echo # mdev-14629: a user-defined variable is defined by the recursive CTE +--echo # + +set @var= +( + with recursive cte_tab(a) as ( + select 1 + union + select a+1 from cte_tab + where a<3) + select count(*) from cte_tab +); + +select @var; + +create table t1(a int, b int); +insert into t1 values (3,8),(1,5),(5,7),(7,4),(4,3); + +set @var= +( + with recursive summ(a,s) as ( + select 1, 0 union + select t1.b, t1.b+summ.s from summ, t1 + where summ.a=t1.a) + select s from summ + order by a desc + limit 1 +); + +select @var; + +--ERROR ER_UNACCEPTABLE_MUTUAL_RECURSION +set @var= +( + with recursive + cte_1 as ( + select 1 + union + select * from cte_2), + cte_2 as ( + select * from cte_1 + union + select a from t1, cte_2 + where t1.a=cte_2.a) + select * from cte_2 + limit 1 +); + +drop table t1; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index d964831a098..7a4530082eb 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4818,6 +4818,9 @@ end_with_restore_list: { List *lex_var_list= &lex->var_list; + if (check_dependencies_in_with_clauses(thd->lex->with_clauses_list)) + goto error; + if ((check_table_access(thd, SELECT_ACL, all_tables, FALSE, UINT_MAX, FALSE) || open_and_lock_tables(thd, all_tables, TRUE, 0))) goto error; -- cgit v1.2.1 From 252e690c859b53c51c7eecf072f33dbaaa01bcdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Tue, 19 Dec 2017 16:13:35 +0200 Subject: Fix galera.view test case crash. WSREP_TO_ISOLATION_BEGIN() call must be after view name is back on tables list. --- sql/sql_view.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 629dd865b0e..0f08883639a 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -425,11 +425,12 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, if ((res= create_view_precheck(thd, tables, view, mode))) goto err; - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) lex->link_first_table_back(view, link_to_local); view->open_type= OT_BASE_ONLY; + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) + /* ignore lock specs for CREATE statement */ -- cgit v1.2.1 From eb1404238346405edc51b0b916a8e0650f061cf0 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Wed, 20 Dec 2017 16:52:02 +0100 Subject: MDEV-14613: Assertion `fixed == 0' failed in Item_func::fix_fields fix_fields calls fixed. --- mysql-test/r/func_misc.result | 15 +++++++++++++++ mysql-test/t/func_misc.test | 21 +++++++++++++++++++++ sql/item.cc | 6 ++++-- 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result index 0462a1dc48a..218b11a2fc2 100644 --- a/mysql-test/r/func_misc.result +++ b/mysql-test/r/func_misc.result @@ -1523,5 +1523,20 @@ str str1 b c ::10.0.5.9 ::10.0.5.9 1 0 DROP TABLE t1; # +# MDEV-14613: Assertion `fixed == 0' failed in Item_func::fix_fields +# +CREATE TABLE `t1` ( +`numgtfmt` char(10) COLLATE utf8_bin NOT NULL +) DEFAULT CHARSET=utf8 COLLATE=utf8_bin; +create view v1(numgtfmt) +as +select 'x' from t1 +union +select 'x' from t1 ; +SELECT * FROM v1 WHERE numgtfmt = NAME_CONST('wnumgtfmt',_utf8'QEDITIONS' COLLATE 'utf8_bin'); +numgtfmt +DROP VIEW v1; +DROP TABLE t1; +# # End of 10.2 tests # diff --git a/mysql-test/t/func_misc.test b/mysql-test/t/func_misc.test index 5d0dc52a6af..e2684ab4957 100644 --- a/mysql-test/t/func_misc.test +++ b/mysql-test/t/func_misc.test @@ -1152,6 +1152,27 @@ INSERT INTO t1 (str) VALUES ('::FFFF:192.168.0.1'),('::10.0.5.9'); SELECT str, str1, b,c FROM t1; DROP TABLE t1; +--echo # +--echo # MDEV-14613: Assertion `fixed == 0' failed in Item_func::fix_fields +--echo # + +CREATE TABLE `t1` ( + `numgtfmt` char(10) COLLATE utf8_bin NOT NULL +) DEFAULT CHARSET=utf8 COLLATE=utf8_bin; + +create view v1(numgtfmt) +as +select 'x' from t1 +union +select 'x' from t1 ; + +SELECT * FROM v1 WHERE numgtfmt = NAME_CONST('wnumgtfmt',_utf8'QEDITIONS' COLLATE 'utf8_bin'); + +# Cleanup +DROP VIEW v1; +DROP TABLE t1; + + --echo # --echo # End of 10.2 tests --echo # diff --git a/sql/item.cc b/sql/item.cc index 029f8216bf1..6dcb436baba 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1814,8 +1814,10 @@ bool Item_name_const::fix_fields(THD *thd, Item **ref) String s(buf, sizeof(buf), &my_charset_bin); s.length(0); - if (value_item->fix_fields(thd, &value_item) || - name_item->fix_fields(thd, &name_item) || + if ((!value_item->fixed && + value_item->fix_fields(thd, &value_item)) || + (!name_item->fixed && + name_item->fix_fields(thd, &name_item)) || !value_item->const_item() || !name_item->const_item() || !(item_name= name_item->val_str(&s))) // Can't have a NULL name -- cgit v1.2.1 From 21eed925a0e374c9f643d32544d3468954435ebc Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Wed, 20 Dec 2017 19:37:07 +0300 Subject: Cleanup out of date comments (no real changes). --- storage/rocksdb/mysql-test/rocksdb/t/disabled.def | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/storage/rocksdb/mysql-test/rocksdb/t/disabled.def b/storage/rocksdb/mysql-test/rocksdb/t/disabled.def index a0810fe63ec..1c4bdf1b082 100644 --- a/storage/rocksdb/mysql-test/rocksdb/t/disabled.def +++ b/storage/rocksdb/mysql-test/rocksdb/t/disabled.def @@ -68,19 +68,12 @@ lock_wait_timeout_stats: MDEV-13404 compact_deletes: MDEV-12663 : rocksdb.compact_deletes times out and causes other tests to fail blind_delete_without_tx_api: MDEV-12286: rocksdb.blind_delete_without_tx_api test fails -# Enabling these didn't seem to cause any trouble: -# autoinc_vars_thread : MDEV-12474 Regularly fails on buildbot -# unique_check : MDEV-12474 Regularly fails on buildbot -# bloomfilter : MDEV-12474 Regularly fails on buildbot -# unique_sec : Intermittent failures in BB - - ## ## Tests that fail for some other reason ## + information_schema : MariaRocks: requires GTIDs mysqlbinlog_gtid_skip_empty_trans_rocksdb : MariaRocks: requires GTIDs -#read_only_tx : MariaRocks: requires GTIDs rpl_row_triggers : MariaRocks: requires GTIDs -- cgit v1.2.1 From 73fa7aeb203299d8d358f8f6b4cdd58aa9f1d0ec Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Wed, 20 Dec 2017 19:49:56 +0300 Subject: MDEV-14165: not MyRocks -problem in ps-protocol, happens in upstream too Enable the test back, as the fix has been pushed. --- storage/rocksdb/mysql-test/rocksdb/t/disabled.def | 1 - 1 file changed, 1 deletion(-) diff --git a/storage/rocksdb/mysql-test/rocksdb/t/disabled.def b/storage/rocksdb/mysql-test/rocksdb/t/disabled.def index 1c4bdf1b082..91bbe7fe30e 100644 --- a/storage/rocksdb/mysql-test/rocksdb/t/disabled.def +++ b/storage/rocksdb/mysql-test/rocksdb/t/disabled.def @@ -41,7 +41,6 @@ rocksdb_deadlock_stress_rr: stress test ## persistent_cache: Upstream RocksDB bug https://github.com/facebook/mysql-5.6/issues/579 collation: Fails on gcc 4.8 and before, MDEV-12433 -col_opt_zerofill: MDEV-14165: not MyRocks -problem in ps-protocol, happens in upstream too ## -- cgit v1.2.1 From 85fad60dc77f4c5b85ec1b7e5d4c3bff456a0ada Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Thu, 21 Dec 2017 01:50:44 +0300 Subject: Disable back rocksdb.col_opt_zerofill due to MDEV-14729 --- storage/rocksdb/mysql-test/rocksdb/t/disabled.def | 1 + 1 file changed, 1 insertion(+) diff --git a/storage/rocksdb/mysql-test/rocksdb/t/disabled.def b/storage/rocksdb/mysql-test/rocksdb/t/disabled.def index 91bbe7fe30e..dc2e04b93d7 100644 --- a/storage/rocksdb/mysql-test/rocksdb/t/disabled.def +++ b/storage/rocksdb/mysql-test/rocksdb/t/disabled.def @@ -41,6 +41,7 @@ rocksdb_deadlock_stress_rr: stress test ## persistent_cache: Upstream RocksDB bug https://github.com/facebook/mysql-5.6/issues/579 collation: Fails on gcc 4.8 and before, MDEV-12433 +col_opt_zerofill: MDEV-14729 (also MDEV-14165 which was fixed): problem in the client ## -- cgit v1.2.1 From e27e7ec767e6c278c7e6a4db1c1ce0006f72a955 Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Thu, 21 Dec 2017 02:02:25 +0300 Subject: Better comments part #1 --- storage/rocksdb/mysql-test/rocksdb_rpl/t/disabled.def | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/disabled.def b/storage/rocksdb/mysql-test/rocksdb_rpl/t/disabled.def index 07a2738eee5..3232ff185bb 100644 --- a/storage/rocksdb/mysql-test/rocksdb_rpl/t/disabled.def +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/disabled.def @@ -1,5 +1,14 @@ +## +## Tests that require FB/MySQL specific features for which there are +## no plans to port them to MariaDB +## +rpl_no_unique_check_on_lag : unique_check_lag_threshold is not available in MariaDB +rpl_no_unique_check_on_lag_mts : unique_check_lag_threshold is not available in MariaDB -# rpl_rocksdb_2pc_crash_recover + +## +## Tests that are disabled for other reasons +## consistent_snapshot_mixed_engines : Didn't try with MariaDB, yet multiclient_2pc : Didn't try with MariaDB, yet @@ -8,8 +17,6 @@ rpl_ddl_high_priority : Didn't try with MariaDB, yet rpl_gtid_crash_safe : Didn't try with MariaDB, yet rpl_gtid_crash_safe_wal_corrupt : Didn't try with MariaDB, yet rpl_gtid_rocksdb_sys_header : Didn't try with MariaDB, yet -rpl_no_unique_check_on_lag : Didn't try with MariaDB, yet -rpl_no_unique_check_on_lag_mts : Didn't try with MariaDB, yet rpl_rocksdb_snapshot : Didn't try with MariaDB, yet rpl_rocksdb_snapshot_without_gtid : Didn't try with MariaDB, yet rpl_rocksdb_stress_crash : Didn't try with MariaDB, yet -- cgit v1.2.1 From 207976d6b9c42868d982a54a2bdd16b77a3c73da Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Thu, 21 Dec 2017 02:34:02 +0300 Subject: Better comments part #2 --- storage/rocksdb/mysql-test/rocksdb_rpl/t/disabled.def | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/disabled.def b/storage/rocksdb/mysql-test/rocksdb_rpl/t/disabled.def index 3232ff185bb..e46e89517a9 100644 --- a/storage/rocksdb/mysql-test/rocksdb_rpl/t/disabled.def +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/disabled.def @@ -4,13 +4,12 @@ ## rpl_no_unique_check_on_lag : unique_check_lag_threshold is not available in MariaDB rpl_no_unique_check_on_lag_mts : unique_check_lag_threshold is not available in MariaDB - +consistent_snapshot_mixed_engines : Tests START TRANSACTION WITH CONSISTENT $ENGINE_NAME SNAPSHOT ## ## Tests that are disabled for other reasons ## -consistent_snapshot_mixed_engines : Didn't try with MariaDB, yet multiclient_2pc : Didn't try with MariaDB, yet rpl_crash_safe_wal_corrupt : Didn't try with MariaDB, yet rpl_ddl_high_priority : Didn't try with MariaDB, yet -- cgit v1.2.1