From c8dc866fdeee551993ef91fb321135f9106ea00e Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Tue, 10 Sep 2019 23:51:42 +0300 Subject: MDEV-20371: Invalid reads at plan refinement stage: join->positions... best_access_path() is called from two optimization phases: 1. Plan choice phase, in choose_plan(). Here, the join prefix being considered is in join->positions[] 2. Plan refinement stage, in fix_semijoin_strategies_for_picked_join_order Here, the join prefix is in join->best_positions[] It used to access join->positions[] from stage #2. This didnt cause any valgrind or asan failures (as join->positions[] has been written-to before) but the effect was similar to that of reading the random data: The join prefix we've picked (in join->best_positions) could have nothing in common with the join prefix that was last to be considered (in join->positions). --- sql/opt_subselect.cc | 26 ++++++++++++++++---------- sql/opt_subselect.h | 8 ++++++-- sql/sql_select.cc | 38 +++++++++++++++++++++++--------------- sql/sql_select.h | 8 +++++++- 4 files changed, 52 insertions(+), 28 deletions(-) diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index 99fa1c7344f..1d3ebba4f4e 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -456,11 +456,6 @@ bool find_eq_ref_candidate(TABLE *table, table_map sj_inner_tables); static SJ_MATERIALIZATION_INFO * at_sjmat_pos(const JOIN *join, table_map remaining_tables, const JOIN_TAB *tab, uint idx, bool *loose_scan); -void best_access_path(JOIN *join, JOIN_TAB *s, - table_map remaining_tables, uint idx, - bool disable_jbuf, double record_count, - POSITION *pos, POSITION *loose_scan_pos); - static Item *create_subq_in_equalities(THD *thd, SJ_MATERIALIZATION_INFO *sjm, Item_in_subselect *subq_pred); static void remove_sj_conds(THD *thd, Item **tree); @@ -2756,6 +2751,13 @@ void advance_sj_state(JOIN *join, table_map remaining_tables, uint idx, NULL, }; +#ifdef HAVE_valgrind + new (&pos->firstmatch_picker) Firstmatch_picker; + new (&pos->loosescan_picker) LooseScan_picker; + new (&pos->sjmat_picker) Sj_materialization_picker; + new (&pos->dups_weedout_picker) Duplicate_weedout_picker; +#endif + if (join->emb_sjm_nest) { /* @@ -3045,7 +3047,8 @@ bool Sj_materialization_picker::check_qep(JOIN *join, bool disable_jbuf= (join->thd->variables.join_cache_level == 0); for (i= first_tab + mat_info->tables; i <= idx; i++) { - best_access_path(join, join->positions[i].table, rem_tables, i, + best_access_path(join, join->positions[i].table, rem_tables, + join->positions, i, disable_jbuf, prefix_rec_count, &curpos, &dummy); prefix_rec_count= COST_MULT(prefix_rec_count, curpos.records_read); prefix_cost= COST_ADD(prefix_cost, curpos.read_time); @@ -3661,7 +3664,8 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join) join->cur_sj_inner_tables= 0; for (i= first + sjm->tables; i <= tablenr; i++) { - best_access_path(join, join->best_positions[i].table, rem_tables, i, + best_access_path(join, join->best_positions[i].table, rem_tables, + join->best_positions, i, FALSE, prefix_rec_count, join->best_positions + i, &dummy); prefix_rec_count *= join->best_positions[i].records_read; @@ -3693,8 +3697,9 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join) { if (join->best_positions[idx].use_join_buffer) { - best_access_path(join, join->best_positions[idx].table, - rem_tables, idx, TRUE /* no jbuf */, + best_access_path(join, join->best_positions[idx].table, + rem_tables, join->best_positions, idx, + TRUE /* no jbuf */, record_count, join->best_positions + idx, &dummy); } record_count *= join->best_positions[idx].records_read; @@ -3724,7 +3729,8 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join) if (join->best_positions[idx].use_join_buffer || (idx == first)) { best_access_path(join, join->best_positions[idx].table, - rem_tables, idx, TRUE /* no jbuf */, + rem_tables, join->best_positions, idx, + TRUE /* no jbuf */, record_count, join->best_positions + idx, &loose_scan_pos); if (idx==first) diff --git a/sql/opt_subselect.h b/sql/opt_subselect.h index 1b4c8116135..7641a5d6196 100644 --- a/sql/opt_subselect.h +++ b/sql/opt_subselect.h @@ -88,6 +88,7 @@ class Loose_scan_opt KEYUSE *best_loose_scan_start_key; uint best_max_loose_keypart; + table_map best_ref_depend_map; public: Loose_scan_opt(): @@ -250,13 +251,14 @@ public: best_loose_scan_records= records; best_max_loose_keypart= max_loose_keypart; best_loose_scan_start_key= start_key; + best_ref_depend_map= 0; } } } } void check_ref_access_part2(uint key, KEYUSE *start_key, double records, - double read_time) + double read_time, table_map ref_depend_map_arg) { if (part1_conds_met && read_time < best_loose_scan_cost) { @@ -266,6 +268,7 @@ public: best_loose_scan_records= records; best_max_loose_keypart= max_loose_keypart; best_loose_scan_start_key= start_key; + best_ref_depend_map= ref_depend_map_arg; } } @@ -281,6 +284,7 @@ public: best_loose_scan_records= rows2double(quick->records); best_max_loose_keypart= quick_max_loose_keypart; best_loose_scan_start_key= NULL; + best_ref_depend_map= 0; } } @@ -296,7 +300,7 @@ public: pos->loosescan_picker.loosescan_parts= best_max_loose_keypart + 1; pos->use_join_buffer= FALSE; pos->table= tab; - // todo need ref_depend_map ? + pos->ref_depend_map= best_ref_depend_map; DBUG_PRINT("info", ("Produced a LooseScan plan, key %s, %s", tab->table->key_info[best_loose_scan_key].name, best_loose_scan_start_key? "(ref access)": diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 1b82b11fce6..24edac2dae1 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -97,10 +97,6 @@ static int sort_keyuse(KEYUSE *a,KEYUSE *b); static bool are_tables_local(JOIN_TAB *jtab, table_map used_tables); static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse, bool allow_full_scan, table_map used_tables); -void best_access_path(JOIN *join, JOIN_TAB *s, - table_map remaining_tables, uint idx, - bool disable_jbuf, double record_count, - POSITION *pos, POSITION *loose_scan_pos); static void optimize_straight_join(JOIN *join, table_map join_tables); static bool greedy_search(JOIN *join, table_map remaining_tables, uint depth, uint prune_level, @@ -4571,6 +4567,13 @@ make_join_statistics(JOIN *join, List &tables_list, { if (choose_plan(join, all_table_map & ~join->const_table_map)) goto error; + +#ifdef HAVE_valgrind + // JOIN::positions holds the current query plan. We've already + // made the plan choice, so we should only use JOIN::best_positions + for (uint k=join->const_tables; k < join->table_count; k++) + MEM_UNDEFINED(&join->positions[k], sizeof(join->positions[k])); +#endif } else { @@ -6285,6 +6288,7 @@ void best_access_path(JOIN *join, JOIN_TAB *s, table_map remaining_tables, + const POSITION *join_positions, uint idx, bool disable_jbuf, double record_count, @@ -6388,7 +6392,7 @@ best_access_path(JOIN *join, if (!(keyuse->used_tables & ~join->const_table_map)) const_part|= keyuse->keypart_map; - double tmp2= prev_record_reads(join->positions, idx, + double tmp2= prev_record_reads(join_positions, idx, (found_ref | keyuse->used_tables)); if (tmp2 < best_prev_record_reads) { @@ -6429,7 +6433,7 @@ best_access_path(JOIN *join, Really, there should be records=0.0 (yes!) but 1.0 would be probably safer */ - tmp= prev_record_reads(join->positions, idx, found_ref); + tmp= prev_record_reads(join_positions, idx, found_ref); records= 1.0; } else @@ -6445,7 +6449,7 @@ best_access_path(JOIN *join, if ((key_flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME || MY_TEST(key_flags & HA_EXT_NOSAME)) { - tmp = prev_record_reads(join->positions, idx, found_ref); + tmp = prev_record_reads(join_positions, idx, found_ref); records=1.0; } else @@ -6689,7 +6693,8 @@ best_access_path(JOIN *join, } tmp= COST_ADD(tmp, s->startup_cost); - loose_scan_opt.check_ref_access_part2(key, start_key, records, tmp); + loose_scan_opt.check_ref_access_part2(key, start_key, records, tmp, + found_ref); } /* not ft_key */ if (tmp + 0.0001 < best_time - records/(double) TIME_FOR_COMPARE) { @@ -7367,7 +7372,8 @@ optimize_straight_join(JOIN *join, table_map join_tables) for (JOIN_TAB **pos= join->best_ref + idx ; (s= *pos) ; pos++) { /* Find the best access method from 's' to the current partial plan */ - best_access_path(join, s, join_tables, idx, disable_jbuf, record_count, + best_access_path(join, s, join_tables, join->positions, idx, + disable_jbuf, record_count, join->positions + idx, &loose_scan_pos); /* compute the cost of the new plan extended with 's' */ @@ -8285,8 +8291,9 @@ best_extension_by_limited_search(JOIN *join, /* Find the best access method from 's' to the current partial plan */ POSITION loose_scan_pos; - best_access_path(join, s, remaining_tables, idx, disable_jbuf, - record_count, join->positions + idx, &loose_scan_pos); + best_access_path(join, s, remaining_tables, join->positions, idx, + disable_jbuf, record_count, join->positions + idx, + &loose_scan_pos); /* Compute the cost of extending the plan with 's' */ current_record_count= COST_MULT(record_count, position->records_read); @@ -8672,11 +8679,11 @@ cache_record_length(JOIN *join,uint idx) */ double -prev_record_reads(POSITION *positions, uint idx, table_map found_ref) +prev_record_reads(const POSITION *positions, uint idx, table_map found_ref) { double found=1.0; - POSITION *pos_end= positions - 1; - for (POSITION *pos= positions + idx - 1; pos != pos_end; pos--) + const POSITION *pos_end= positions - 1; + for (const POSITION *pos= positions + idx - 1; pos != pos_end; pos--) { if (pos->table->table->map & found_ref) { @@ -15400,7 +15407,8 @@ void optimize_wo_join_buffering(JOIN *join, uint first_tab, uint last_tab, if ((i == first_tab && first_alt) || join->positions[i].use_join_buffer) { /* Find the best access method that would not use join buffering */ - best_access_path(join, rs, reopt_remaining_tables, i, + best_access_path(join, rs, reopt_remaining_tables, + join->positions, i, TRUE, rec_count, &pos, &loose_scan_pos); } diff --git a/sql/sql_select.h b/sql/sql_select.h index 60c2ce55a16..fe44f448446 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -792,6 +792,7 @@ public: friend void best_access_path(JOIN *join, JOIN_TAB *s, table_map remaining_tables, + const struct st_position *join_positions, uint idx, bool disable_jbuf, double record_count, @@ -1960,6 +1961,11 @@ protected: } }; +void best_access_path(JOIN *join, JOIN_TAB *s, + table_map remaining_tables, + const POSITION *join_positions, uint idx, + bool disable_jbuf, double record_count, + POSITION *pos, POSITION *loose_scan_pos); bool cp_buffer_from_ref(THD *thd, TABLE *table, TABLE_REF *ref); bool error_if_full_join(JOIN *join); int report_error(TABLE *table, int error); @@ -2277,7 +2283,7 @@ bool instantiate_tmp_table(TABLE *table, KEY *keyinfo, ulonglong options); bool open_tmp_table(TABLE *table); void setup_tmp_table_column_bitmaps(TABLE *table, uchar *bitmaps); -double prev_record_reads(POSITION *positions, uint idx, table_map found_ref); +double prev_record_reads(const POSITION *positions, uint idx, table_map found_ref); void fix_list_after_tbl_changes(SELECT_LEX *new_parent, List *tlist); struct st_cond_statistic -- cgit v1.2.1 From be6beb73e9e6adf2ebd69354a2496817f03ae6ff Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Wed, 11 Sep 2019 23:05:12 +0300 Subject: MDEV-16560: [counter] rocksdb.ttl_secondary_read_filtering fail in buildbot It is not reproducible, but the issue seems to be the same as with MDEV-20490 and rocksdb.ttl_primary_read_filtering - a compaction caused by DROP TABLE gets behind and compacts away the expired rows for the next test. Fix this in the same way. --- .../rocksdb/mysql-test/rocksdb/r/ttl_secondary_read_filtering.result | 1 + storage/rocksdb/mysql-test/rocksdb/t/ttl_secondary_read_filtering.test | 3 +++ 2 files changed, 4 insertions(+) diff --git a/storage/rocksdb/mysql-test/rocksdb/r/ttl_secondary_read_filtering.result b/storage/rocksdb/mysql-test/rocksdb/r/ttl_secondary_read_filtering.result index 90de5447891..395c84edfe9 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/ttl_secondary_read_filtering.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/ttl_secondary_read_filtering.result @@ -101,6 +101,7 @@ a b SELECT * FROM t1 FORCE INDEX (kb); a b DROP TABLE t1; +set global rocksdb_compact_cf= 'default'; # Read filtering index scan tests (None of these queries should return any results) CREATE TABLE t1 ( a int, diff --git a/storage/rocksdb/mysql-test/rocksdb/t/ttl_secondary_read_filtering.test b/storage/rocksdb/mysql-test/rocksdb/t/ttl_secondary_read_filtering.test index d6be7d95f8d..f6042cc517e 100644 --- a/storage/rocksdb/mysql-test/rocksdb/t/ttl_secondary_read_filtering.test +++ b/storage/rocksdb/mysql-test/rocksdb/t/ttl_secondary_read_filtering.test @@ -121,6 +121,9 @@ SELECT * FROM t1 FORCE INDEX (kb); DROP TABLE t1; +# Compact away the dropped data +set global rocksdb_compact_cf= 'default'; + --echo # Read filtering index scan tests (None of these queries should return any results) CREATE TABLE t1 ( a int, -- cgit v1.2.1 From 99ecb33389dd675c5c79928c2ac705585b0c467d Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Thu, 12 Sep 2019 15:15:33 +0200 Subject: MDEV-20570 : Packaging fails "The specified timestamp server either could not be reached" On Windows, during packaging step, if signing fails, retry signtool again without timestamp parameter. Fixes sporadic (rare) failures on buildbot --- cmake/sign.cmake.in | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/cmake/sign.cmake.in b/cmake/sign.cmake.in index 61ae38d152d..50768a3dcc9 100644 --- a/cmake/sign.cmake.in +++ b/cmake/sign.cmake.in @@ -1,13 +1,31 @@ +# If timestamping is used, it can (rarely) fail, when public timestamping service has issues. +# +# To handle the error gracefully and tranparently, we'll retry the signtool command, +# second time without "/t URL" parameter +SET(SIGNTOOL_PARAMETERS_NO_TIMESTAMP "@SIGNTOOL_PARAMETERS@") +LIST(FIND SIGNTOOL_PARAMETERS_NO_TIMESTAMP /t idx) +IF(NOT(idx EQUAL -1)) + LIST(REMOVE_AT SIGNTOOL_PARAMETERS_NO_TIMESTAMP ${idx}) + #remove the URL following /t , as well + LIST(REMOVE_AT SIGNTOOL_PARAMETERS_NO_TIMESTAMP ${idx}) +ENDIF() + +GET_FILENAME_COMPONENT(SIGNTOOL_DIR "@SIGNTOOL_EXECUTABLE@" DIRECTORY) +GET_FILENAME_COMPONENT(SIGNTOOL_NAME "@SIGNTOOL_EXECUTABLE@" NAME) + FILE(GLOB_RECURSE files "@CMAKE_BINARY_DIR@/*.signme") MESSAGE(STATUS "signing files") + + FOREACH(f ${files}) STRING(REPLACE ".signme" "" exe_location "${f}") string (REPLACE ";" " " params "@SIGNTOOL_PARAMETERS@") - #MESSAGE("@SIGNTOOL_EXECUTABLE@" sign ${params} "${exe_location}") EXECUTE_PROCESS(COMMAND - "@SIGNTOOL_EXECUTABLE@" sign @SIGNTOOL_PARAMETERS@ "${exe_location}" + cmd /c "${SIGNTOOL_NAME}" sign @SIGNTOOL_PARAMETERS@ "${exe_location}" 2>NUL + || "${SIGNTOOL_NAME}" sign ${SIGNTOOL_PARAMETERS_NO_TIMESTAMP} "${exe_location}" + WORKING_DIRECTORY ${SIGNTOOL_DIR} RESULT_VARIABLE ERR) IF(NOT ${ERR} EQUAL 0) MESSAGE( "Error ${ERR} signing ${exe_location}") -- cgit v1.2.1 From 41290e91b7be29ed72b8a41c7b6698ec1d2b96ab Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Thu, 12 Sep 2019 17:06:06 +0200 Subject: Fix CMake warning in spider, in Windows ninja build --- storage/spider/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/storage/spider/CMakeLists.txt b/storage/spider/CMakeLists.txt index 62dfc968579..706b11ac141 100644 --- a/storage/spider/CMakeLists.txt +++ b/storage/spider/CMakeLists.txt @@ -55,6 +55,9 @@ ELSE() DESTINATION ${INSTALL_MYSQLSHAREDIR} COMPONENT Server ) MYSQL_ADD_PLUGIN(spider ${SPIDER_SOURCES} STORAGE_ENGINE MODULE_ONLY MODULE_OUTPUT_NAME "ha_spider") + IF(NOT TARGET spider) + RETURN() + ENDIF() ENDIF() IF(ORACLE_INCLUDE_DIR AND ORACLE_OCI_LIBRARY) -- cgit v1.2.1 From deb9121fdf2152752346c767321e6e01aa5d6c69 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Thu, 12 Sep 2019 23:00:49 -0700 Subject: MDEV-20576 A new assertion added to check validity of calculated selectivity values fails After having set the assertion that checks validity of selectivity values returned by the function table_cond_selectivity() a test case from order_by.tesst failed. The failure occurred because range optimizer could return as an estimate of the cardinality of the ranges built for an index a number exceeding the total number of records in the table. The second bug is more subtle. It may happen when there are several indexes with same prefix defined on the first joined table t accessed by a constant ref access. In this case the range optimizer estimates the number of accessed records of t for each usable index and these estimates can be different. Only the first of these estimates is taken into account when the selectivity of the ref access is calculated. However the optimizer later can choose a different index that provides a different estimate. The function table_condition_selectivity() could use this estimate to discount the selectivity of the ref access. This could lead to an selectivity value returned by this function that was greater that 1. --- mysql-test/r/innodb_icp.result | 4 +- mysql-test/r/range_vs_index_merge.result | 2 +- mysql-test/r/range_vs_index_merge_innodb.result | 2 +- mysql-test/r/selectivity.result | 85 +++++++++++++++++++++++++ mysql-test/r/selectivity_innodb.result | 85 +++++++++++++++++++++++++ mysql-test/t/selectivity.test | 81 +++++++++++++++++++++++ sql/opt_range.cc | 10 +++ sql/sql_select.cc | 15 +++++ 8 files changed, 280 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/innodb_icp.result b/mysql-test/r/innodb_icp.result index a5215bf9f0d..0c95f31ae95 100644 --- a/mysql-test/r/innodb_icp.result +++ b/mysql-test/r/innodb_icp.result @@ -679,7 +679,7 @@ EXPLAIN SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0 HAVING t1.c != 5 ORDER BY t1.c; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using where; Using filesort +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 1 Using where; Using filesort 1 SIMPLE t2 ref a a 515 test.t1.a 1 Using where SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0 HAVING t1.c != 5 ORDER BY t1.c; @@ -690,7 +690,7 @@ EXPLAIN SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0 HAVING t1.c != 5 ORDER BY t1.c; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using where; Using filesort +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 1 Using where; Using filesort 1 SIMPLE t2 ref a a 515 test.t1.a 1 Using where SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0 HAVING t1.c != 5 ORDER BY t1.c; diff --git a/mysql-test/r/range_vs_index_merge.result b/mysql-test/r/range_vs_index_merge.result index bc46a4fdd0b..4f3c36b7660 100644 --- a/mysql-test/r/range_vs_index_merge.result +++ b/mysql-test/r/range_vs_index_merge.result @@ -1795,7 +1795,7 @@ SELECT * FROM t1 FORCE KEY (state,capital) WHERE ( state = 'Alabama' OR state >= 'Colorado' ) AND id != 9 OR ( capital >= 'Topeka' OR state = 'Kansas' ) AND state != 'Texas'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range state,capital state 71 NULL 12 Using index condition; Using where +1 SIMPLE t1 range state,capital state 71 NULL 8 Using index condition; Using where SELECT * FROM t1 FORCE KEY (state,capital) WHERE ( state = 'Alabama' OR state >= 'Colorado' ) AND id != 9 OR ( capital >= 'Topeka' OR state = 'Kansas' ) AND state != 'Texas'; diff --git a/mysql-test/r/range_vs_index_merge_innodb.result b/mysql-test/r/range_vs_index_merge_innodb.result index a6ec200538d..08b7df66c67 100644 --- a/mysql-test/r/range_vs_index_merge_innodb.result +++ b/mysql-test/r/range_vs_index_merge_innodb.result @@ -1796,7 +1796,7 @@ SELECT * FROM t1 FORCE KEY (state,capital) WHERE ( state = 'Alabama' OR state >= 'Colorado' ) AND id != 9 OR ( capital >= 'Topeka' OR state = 'Kansas' ) AND state != 'Texas'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range state,capital state 71 NULL 10 Using index condition; Using where +1 SIMPLE t1 range state,capital state 71 NULL 8 Using index condition; Using where SELECT * FROM t1 FORCE KEY (state,capital) WHERE ( state = 'Alabama' OR state >= 'Colorado' ) AND id != 9 OR ( capital >= 'Topeka' OR state = 'Kansas' ) AND state != 'Texas'; diff --git a/mysql-test/r/selectivity.result b/mysql-test/r/selectivity.result index 3f5db42d341..d8b2d462952 100644 --- a/mysql-test/r/selectivity.result +++ b/mysql-test/r/selectivity.result @@ -1668,4 +1668,89 @@ Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` drop table t1; set use_stat_tables= @save_use_stat_tables; set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; +# +# MDEV-20576: failing assertion DBUG_ASSERT(0.0 < sel && sel <= 1) +# +set @@optimizer_use_condition_selectivity=2; +set names utf8; +CREATE DATABASE world; +use world; +CREATE TABLE Country ( +Code char(3) NOT NULL default '', +Name char(52) NOT NULL default '', +SurfaceArea float(10,2) NOT NULL default '0.00', +Population int(11) NOT NULL default '0', +Capital int(11) default NULL, +PRIMARY KEY (Code), +UNIQUE INDEX (Name) +); +CREATE TABLE City ( +ID int(11) NOT NULL auto_increment, +Name char(35) NOT NULL default '', +Country char(3) NOT NULL default '', +Population int(11) NOT NULL default '0', +PRIMARY KEY (ID), +INDEX (Population), +INDEX (Country) +); +CREATE TABLE CountryLanguage ( +Country char(3) NOT NULL default '', +Language char(30) NOT NULL default '', +Percentage float(3,1) NOT NULL default '0.0', +PRIMARY KEY (Country, Language), +INDEX (Percentage) +); +CREATE INDEX Name ON City(Name); +CREATE INDEX CountryPopulation ON City(Country,Population); +CREATE INDEX CountryName ON City(Country,Name); +set @@optimizer_use_condition_selectivity=2; +EXPLAIN +SELECT * FROM City WHERE Country='FIN'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City ref Country,CountryPopulation,CountryName CountryName 3 const 5 Using index condition +DROP DATABASE world; +use test; +CREATE TABLE t1 ( +a INT, +b INT NOT NULL, +c char(100), +KEY (b, c), +KEY (b, a, c) +) +DEFAULT CHARSET = utf8; +INSERT INTO t1 VALUES +(1, 1, 1), +(2, 2, 2), +(3, 3, 3), +(4, 4, 4), +(5, 5, 5), +(6, 6, 6), +(7, 7, 7), +(8, 8, 8), +(9, 9, 9); +INSERT INTO t1 SELECT a + 10, b, c FROM t1; +INSERT INTO t1 SELECT a + 20, b, c FROM t1; +INSERT INTO t1 SELECT a + 40, b, c FROM t1; +INSERT INTO t1 SELECT a + 80, b, c FROM t1; +INSERT INTO t1 SELECT a + 160, b, c FROM t1; +INSERT INTO t1 SELECT a + 320, b, c FROM t1; +INSERT INTO t1 SELECT a + 640, b, c FROM t1; +INSERT INTO t1 SELECT a + 1280, b, c FROM t1 LIMIT 80; +EXPLAIN +SELECT a FROM t1 WHERE b = 1 ORDER BY c DESC LIMIT 9; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range b,b_2 b 4 NULL 226 Using where +SELECT a FROM t1 WHERE b = 1 ORDER BY c DESC LIMIT 9; +a +2071 +2061 +2051 +2041 +2031 +2021 +2011 +2001 +1991 +set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; +DROP TABLE t1; # End of 10.1 tests diff --git a/mysql-test/r/selectivity_innodb.result b/mysql-test/r/selectivity_innodb.result index 1d73c2f5d50..56a79001b13 100644 --- a/mysql-test/r/selectivity_innodb.result +++ b/mysql-test/r/selectivity_innodb.result @@ -1678,6 +1678,91 @@ Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` drop table t1; set use_stat_tables= @save_use_stat_tables; set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; +# +# MDEV-20576: failing assertion DBUG_ASSERT(0.0 < sel && sel <= 1) +# +set @@optimizer_use_condition_selectivity=2; +set names utf8; +CREATE DATABASE world; +use world; +CREATE TABLE Country ( +Code char(3) NOT NULL default '', +Name char(52) NOT NULL default '', +SurfaceArea float(10,2) NOT NULL default '0.00', +Population int(11) NOT NULL default '0', +Capital int(11) default NULL, +PRIMARY KEY (Code), +UNIQUE INDEX (Name) +); +CREATE TABLE City ( +ID int(11) NOT NULL auto_increment, +Name char(35) NOT NULL default '', +Country char(3) NOT NULL default '', +Population int(11) NOT NULL default '0', +PRIMARY KEY (ID), +INDEX (Population), +INDEX (Country) +); +CREATE TABLE CountryLanguage ( +Country char(3) NOT NULL default '', +Language char(30) NOT NULL default '', +Percentage float(3,1) NOT NULL default '0.0', +PRIMARY KEY (Country, Language), +INDEX (Percentage) +); +CREATE INDEX Name ON City(Name); +CREATE INDEX CountryPopulation ON City(Country,Population); +CREATE INDEX CountryName ON City(Country,Name); +set @@optimizer_use_condition_selectivity=2; +EXPLAIN +SELECT * FROM City WHERE Country='FIN'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City ref Country,CountryPopulation,CountryName Country 3 const 7 Using index condition +DROP DATABASE world; +use test; +CREATE TABLE t1 ( +a INT, +b INT NOT NULL, +c char(100), +KEY (b, c), +KEY (b, a, c) +) +DEFAULT CHARSET = utf8; +INSERT INTO t1 VALUES +(1, 1, 1), +(2, 2, 2), +(3, 3, 3), +(4, 4, 4), +(5, 5, 5), +(6, 6, 6), +(7, 7, 7), +(8, 8, 8), +(9, 9, 9); +INSERT INTO t1 SELECT a + 10, b, c FROM t1; +INSERT INTO t1 SELECT a + 20, b, c FROM t1; +INSERT INTO t1 SELECT a + 40, b, c FROM t1; +INSERT INTO t1 SELECT a + 80, b, c FROM t1; +INSERT INTO t1 SELECT a + 160, b, c FROM t1; +INSERT INTO t1 SELECT a + 320, b, c FROM t1; +INSERT INTO t1 SELECT a + 640, b, c FROM t1; +INSERT INTO t1 SELECT a + 1280, b, c FROM t1 LIMIT 80; +EXPLAIN +SELECT a FROM t1 WHERE b = 1 ORDER BY c DESC LIMIT 9; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref b,b_2 b_2 4 const 207 Using where; Using index; Using filesort +SELECT a FROM t1 WHERE b = 1 ORDER BY c DESC LIMIT 9; +a +2071 +81 +71 +61 +51 +41 +31 +21 +11 +set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; +DROP TABLE t1; # End of 10.1 tests set optimizer_switch=@save_optimizer_switch_for_selectivity_test; set @tmp_ust= @@use_stat_tables; diff --git a/mysql-test/t/selectivity.test b/mysql-test/t/selectivity.test index f1c9d6b31b8..6e93e60fff6 100644 --- a/mysql-test/t/selectivity.test +++ b/mysql-test/t/selectivity.test @@ -1124,5 +1124,86 @@ drop table t1; set use_stat_tables= @save_use_stat_tables; set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; + +--echo # +--echo # MDEV-20576: failing assertion DBUG_ASSERT(0.0 < sel && sel <= 1) +--echo # + +set @@optimizer_use_condition_selectivity=2; + +set names utf8; + +CREATE DATABASE world; + +use world; + +--source include/world_schema.inc + +--disable_query_log +--disable_result_log +--disable_warnings +--source include/world.inc +--enable_warnings +--enable_result_log +--enable_query_log + +CREATE INDEX Name ON City(Name); +CREATE INDEX CountryPopulation ON City(Country,Population); +CREATE INDEX CountryName ON City(Country,Name); + +--disable_query_log +--disable_result_log +--disable_warnings +ANALYZE TABLE City; +--enable_warnings +--enable_result_log +--enable_query_log + +set @@optimizer_use_condition_selectivity=2; + +EXPLAIN +SELECT * FROM City WHERE Country='FIN'; + +DROP DATABASE world; + +use test; + +CREATE TABLE t1 ( + a INT, + b INT NOT NULL, + c char(100), + KEY (b, c), + KEY (b, a, c) +) +DEFAULT CHARSET = utf8; + +INSERT INTO t1 VALUES +(1, 1, 1), +(2, 2, 2), +(3, 3, 3), +(4, 4, 4), +(5, 5, 5), +(6, 6, 6), +(7, 7, 7), +(8, 8, 8), +(9, 9, 9); + +INSERT INTO t1 SELECT a + 10, b, c FROM t1; +INSERT INTO t1 SELECT a + 20, b, c FROM t1; +INSERT INTO t1 SELECT a + 40, b, c FROM t1; +INSERT INTO t1 SELECT a + 80, b, c FROM t1; +INSERT INTO t1 SELECT a + 160, b, c FROM t1; +INSERT INTO t1 SELECT a + 320, b, c FROM t1; +INSERT INTO t1 SELECT a + 640, b, c FROM t1; +INSERT INTO t1 SELECT a + 1280, b, c FROM t1 LIMIT 80; + +EXPLAIN +SELECT a FROM t1 WHERE b = 1 ORDER BY c DESC LIMIT 9; +SELECT a FROM t1 WHERE b = 1 ORDER BY c DESC LIMIT 9; + +set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; + +DROP TABLE t1; + --echo # End of 10.1 tests diff --git a/sql/opt_range.cc b/sql/opt_range.cc index e8421ad052a..45dad8882a1 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -10179,6 +10179,16 @@ ha_rows check_quick_select(PARAM *param, uint idx, bool index_only, bufsize, mrr_flags, cost); if (rows != HA_POS_ERROR) { + ha_rows table_records= param->table->stat_records(); + if (rows > table_records) + { + /* + For any index the total number of records within all ranges + cannot be be bigger than the number of records in the table + */ + rows= table_records; + set_if_bigger(rows, 1); + } param->quick_rows[keynr]= rows; param->possible_keys.set_bit(keynr); if (update_tbl_stats) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 5b96c15bff5..c6e70c2430c 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -7643,7 +7643,19 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s, } keyparts++; } + /* + Here we discount selectivity of the constant range CR. To calculate + this selectivity we use elements from the quick_rows[] array. + If we have indexes i1,...,ik with the same prefix compatible + with CR any of the estimate quick_rows[i1], ... quick_rows[ik] could + be used for this calculation but here we don't know which one was + actually used. So sel could be greater than 1 and we have to cap it. + However if sel becomes greater than 2 then with high probability + something went wrong. + */ sel /= (double)table->quick_rows[key] / (double) table->stat_records(); + DBUG_ASSERT(0 < sel && sel <= 2.0); + set_if_smaller(sel, 1.0); used_range_selectivity= true; } } @@ -7691,6 +7703,7 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s, if (table->field[fldno]->cond_selectivity > 0) { sel /= table->field[fldno]->cond_selectivity; + DBUG_ASSERT(0 < sel && sel <= 2.0); set_if_smaller(sel, 1.0); } /* @@ -7748,6 +7761,7 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s, if (field->cond_selectivity > 0) { sel/= field->cond_selectivity; + DBUG_ASSERT(0 < sel && sel <= 2.0); set_if_smaller(sel, 1.0); } break; @@ -7759,6 +7773,7 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s, sel*= table_multi_eq_cond_selectivity(join, idx, s, rem_tables, keyparts, ref_keyuse_steps); + DBUG_ASSERT(0.0 < sel && sel <= 1.0); return sel; } -- cgit v1.2.1 From 40beeb1402e1bf443eadb2986fd87cd3f0e9ff24 Mon Sep 17 00:00:00 2001 From: Teemu Ollakka Date: Fri, 13 Sep 2019 09:18:11 +0300 Subject: MDEV-20561 Galera node shutdown fails in non-Primary (#1386) Command COM_SHUTDOWN was rejected in non-Primary because server_command_flags[COM_SHUTDOWN] had value CF_NO_COM_MULTI instead of CF_SKIP_WSREP_CHECK. As a fix removed assignment server_command_flags[CF_NO_COM_MULTI]= CF_NO_COM_MULTI which overwrote server_command_flags[COM_SHUTDOWN]. --- .../suite/galera/r/galera_shutdown_nonprim.result | 9 ++++++ .../suite/galera/t/galera_shutdown_nonprim.test | 36 ++++++++++++++++++++++ sql/sql_parse.cc | 1 - 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 mysql-test/suite/galera/r/galera_shutdown_nonprim.result create mode 100644 mysql-test/suite/galera/t/galera_shutdown_nonprim.test diff --git a/mysql-test/suite/galera/r/galera_shutdown_nonprim.result b/mysql-test/suite/galera/r/galera_shutdown_nonprim.result new file mode 100644 index 00000000000..5353543e395 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_shutdown_nonprim.result @@ -0,0 +1,9 @@ +connection node_1; +connection node_2; +connection node_1; +SET GLOBAL wsrep_provider_options = 'pc.weight=2'; +connection node_2; +SET GLOBAL wsrep_provider_options = 'gmcast.isolate = 1'; +SET SESSION wsrep_sync_wait = 0; +connection node_1; +SET GLOBAL wsrep_provider_options = 'pc.weight = 1'; diff --git a/mysql-test/suite/galera/t/galera_shutdown_nonprim.test b/mysql-test/suite/galera/t/galera_shutdown_nonprim.test new file mode 100644 index 00000000000..cf7018cd751 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_shutdown_nonprim.test @@ -0,0 +1,36 @@ +# +# Check that server can be shut down in non-primary configuration. +# + +--source include/galera_cluster.inc +--source include/have_innodb.inc + +--let $node_1 = node_1 +--let $node_2 = node_2 +--source include/auto_increment_offset_save.inc + +--connection node_1 +# Set higher weight for node_1 to keep it in primary +# while node_2 is isolated. +SET GLOBAL wsrep_provider_options = 'pc.weight=2'; + +--connection node_2 +# Isolate node_2 from the group and wait until wsrep_ready becomes OFF. +SET GLOBAL wsrep_provider_options = 'gmcast.isolate = 1'; +SET SESSION wsrep_sync_wait = 0; +--let $wait_condition = SELECT VARIABLE_VALUE = 'OFF' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready' +--source include/wait_condition.inc + +# Verify that graceful shutdown succeeds. +--source include/shutdown_mysqld.inc +--source include/start_mysqld.inc + +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc + +--connection node_1 +--source include/wait_condition.inc + +# Restore original settings. +SET GLOBAL wsrep_provider_options = 'pc.weight = 1'; +--source include/auto_increment_offset_restore.inc diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 181041f4dd6..d6bbefc3be7 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -528,7 +528,6 @@ void init_update_queries(void) server_command_flags[COM_STMT_SEND_LONG_DATA]= CF_SKIP_WSREP_CHECK; server_command_flags[COM_REGISTER_SLAVE]= CF_SKIP_WSREP_CHECK; server_command_flags[COM_MULTI]= CF_SKIP_WSREP_CHECK | CF_NO_COM_MULTI; - server_command_flags[CF_NO_COM_MULTI]= CF_NO_COM_MULTI; /* Initialize the sql command flags array. */ memset(sql_command_flags, 0, sizeof(sql_command_flags)); -- cgit v1.2.1 From 3422c13ab748a9da688c00b1b1e522cbcd38d4a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Wed, 11 Sep 2019 14:15:17 +0300 Subject: Try to fix galera.MW-336 test case. --- mysql-test/suite/galera/r/MW-336.result | 8 +++----- mysql-test/suite/galera/t/MW-336.test | 13 ++++++------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/mysql-test/suite/galera/r/MW-336.result b/mysql-test/suite/galera/r/MW-336.result index ed2f0755f0d..b91e73aaada 100644 --- a/mysql-test/suite/galera/r/MW-336.result +++ b/mysql-test/suite/galera/r/MW-336.result @@ -6,10 +6,6 @@ SET GLOBAL wsrep_slave_threads = 1; connection node_2; INSERT INTO t1 VALUES (1); connection node_1; -SET SESSION wsrep_sync_wait=15; -SELECT COUNT(*) FROM t1; -COUNT(*) -1 SET GLOBAL wsrep_slave_threads = 10; # Set slave threads to 10 step 2 SET GLOBAL wsrep_slave_threads = 20; @@ -43,9 +39,11 @@ INSERT INTO t1 VALUES (17); INSERT INTO t1 VALUES (18); INSERT INTO t1 VALUES (19); INSERT INTO t1 VALUES (20); +INSERT INTO t1 VALUES (21); +INSERT INTO t1 VALUES (22); connection node_1; SELECT COUNT(*) FROM t1; COUNT(*) -21 +23 SET GLOBAL wsrep_slave_threads = 1; DROP TABLE t1; diff --git a/mysql-test/suite/galera/t/MW-336.test b/mysql-test/suite/galera/t/MW-336.test index b6df78ac7a6..4b606d58772 100644 --- a/mysql-test/suite/galera/t/MW-336.test +++ b/mysql-test/suite/galera/t/MW-336.test @@ -13,7 +13,7 @@ SET GLOBAL wsrep_slave_threads = 10; # ensure that the threads have actually started running --echo # Set slave threads to 10 step 1 ---let $wait_condition = SELECT COUNT(*) = 10 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE = 'wsrep applier idle'; +--let $wait_condition = SELECT VARIABLE_VALUE = 10 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_applier_thread_count'; --let $wait_condition_on_error_output = SELECT COUNT(*), 10 as EXPECTED_VALUE FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE = 'wsrep applier idle'; show processlist --source include/wait_condition_with_debug.inc @@ -23,20 +23,17 @@ SET GLOBAL wsrep_slave_threads = 1; INSERT INTO t1 VALUES (1); --connection node_1 -SET SESSION wsrep_sync_wait=15; -SELECT COUNT(*) FROM t1; - SET GLOBAL wsrep_slave_threads = 10; --echo # Set slave threads to 10 step 2 ---let $wait_condition = SELECT COUNT(*) = 10 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE = 'wsrep applier idle'; +--let $wait_condition = SELECT VARIABLE_VALUE = 10 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_applier_thread_count'; --let $wait_condition_on_error_output = SELECT COUNT(*), 10 as EXPECTED_VALUE FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE = 'wsrep applier idle'; show processlist --source include/wait_condition_with_debug.inc SET GLOBAL wsrep_slave_threads = 20; --echo # Set slave threads to 20 ---let $wait_condition = SELECT COUNT(*) = 20 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE = 'wsrep applier idle'; +--let $wait_condition = SELECT VARIABLE_VALUE = 20 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_applier_thread_count'; --let $wait_condition_on_error_output = SELECT COUNT(*), 20 as EXPECTED_VALUE FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE = 'wsrep applier idle'; show processlist --source include/wait_condition_with_debug.inc @@ -58,7 +55,7 @@ INSERT INTO t1 VALUES (10); SET GLOBAL wsrep_slave_threads = 10; SELECT COUNT(*) FROM t1; --echo # Set slave threads to 10 step 3 ---let $wait_condition = SELECT COUNT(*) = 10 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE = 'wsrep applier idle'; +--let $wait_condition = SELECT VARIABLE_VALUE = 10 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_applier_thread_count'; --let $wait_condition_on_error_output = SELECT COUNT(*), 10 as EXPECTED_VALUE FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE = 'wsrep applier idle'; show processlist --source include/wait_condition_with_debug.inc @@ -73,6 +70,8 @@ INSERT INTO t1 VALUES (17); INSERT INTO t1 VALUES (18); INSERT INTO t1 VALUES (19); INSERT INTO t1 VALUES (20); +INSERT INTO t1 VALUES (21); +INSERT INTO t1 VALUES (22); --connection node_1 SELECT COUNT(*) FROM t1; -- cgit v1.2.1 From 3793da44cff600843384d8c5718940d95711511a Mon Sep 17 00:00:00 2001 From: Anel Husakovic Date: Mon, 16 Apr 2018 20:49:27 +0000 Subject: Enable the auto parameter of the flag `default-character-set` Closes #739 When invoking option `--default-character-set=auto` character set from underlying OS settings should be detected for mysqldump. --- client/mysqldump.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index b9ff8caed8c..f0c53052a1f 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -1057,7 +1057,7 @@ static int get_options(int *argc, char ***argv) my_progname_short); return(EX_USAGE); } - if (strcmp(default_charset, charset_info->csname) && + if (strcmp(default_charset, MYSQL_AUTODETECT_CHARSET_NAME) && !(charset_info= get_charset_by_csname(default_charset, MY_CS_PRIMARY, MYF(MY_WME)))) exit(1); @@ -1522,6 +1522,9 @@ static int switch_character_set_results(MYSQL *mysql, const char *cs_name) char query_buffer[QUERY_LENGTH]; size_t query_length; + if (!strcmp(cs_name, MYSQL_AUTODETECT_CHARSET_NAME)) + cs_name= (char *)my_default_csname(); + /* Server lacks facility. This is not an error, by arbitrary decision . */ if (!server_supports_switching_charsets) return FALSE; -- cgit v1.2.1 From b214264aee2a6441abc7c8e73519c8267edcb8fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 13 Sep 2019 15:28:53 +0300 Subject: MDEV-20525 rocksdb debug compilation fails on Windows due to unresolved my_assert variable MYSQL_PLUGIN_IMPORT did not work correctly for the RocksDB helper library rocksdb_aux_lib, because that library was not compiled with -DMYSQL_DYNAMIC_PLUGIN. Fix DBUG such that it does not depend on exported data, only on functions (which do not need MYSQL_PLUGIN_IMPORT decoration) Use a "getter" function _db_my_assert() instead of DLL-exported variable. Also, reduce object code duplication by moving more of the DBUG_ASSERT logic inside the _db_my_assert() function, and add unlikely() and ATTRIBUTE_COLD hints to ensure that the 'assertion failed' code will be separated from the main control flow logic. Thus, the compiler can move the unlikely() code to the end of the compiled function, reachable via a forward conditional branch, which the processor's branch predictor could assume 'not taken'. --- dbug/dbug.c | 10 ++++++++++ include/my_dbug.h | 10 +++++----- include/my_sys.h | 2 +- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/dbug/dbug.c b/dbug/dbug.c index 40620b5e9c6..2d629ac0741 100644 --- a/dbug/dbug.c +++ b/dbug/dbug.c @@ -2258,6 +2258,16 @@ static int default_my_dbug_sanity(void) return 0; } +extern my_bool my_assert; +ATTRIBUTE_COLD +my_bool _db_my_assert(const char *file, int line, const char *msg) +{ + _db_flush_(); + my_bool a = my_assert; + if (!a) + fprintf(stderr, "%s:%d: assert: %s\n", file, line, msg); + return a; +} #else /* diff --git a/include/my_dbug.h b/include/my_dbug.h index bce33285788..2bbe8ff6a30 100644 --- a/include/my_dbug.h +++ b/include/my_dbug.h @@ -35,7 +35,6 @@ struct _db_stack_frame_ { }; struct _db_code_state_; -extern MYSQL_PLUGIN_IMPORT my_bool my_assert; extern my_bool _dbug_on_; extern my_bool _db_keyword_(struct _db_code_state_ *, const char *, int); extern int _db_explain_(struct _db_code_state_ *cs, char *buf, size_t len); @@ -59,6 +58,8 @@ extern void _db_dump_(uint _line_,const char *keyword, extern void _db_end_(void); extern void _db_lock_file_(void); extern void _db_unlock_file_(void); +ATTRIBUTE_COLD +extern my_bool _db_my_assert(const char *file, int line, const char *msg); extern FILE *_db_fp_(void); extern void _db_flush_(void); extern void dbug_swap_code_state(void **code_state_store); @@ -104,10 +105,9 @@ extern int (*dbug_sanity)(void); #define DBUG_END() _db_end_ () #define DBUG_LOCK_FILE _db_lock_file_() #define DBUG_UNLOCK_FILE _db_unlock_file_() -#define DBUG_ASSERT(A) do { if (!(A)) { _db_flush_(); \ - if (my_assert) assert(A); \ - else fprintf(stderr, "%s:%d: assert: %s\n", __FILE__, __LINE__, #A); \ -}} while (0) +#define DBUG_ASSERT(A) do { \ + if (unlikely(!(A)) && _db_my_assert(__FILE__, __LINE__, #A)) assert(A); \ +} while (0) #define DBUG_SLOW_ASSERT(A) DBUG_ASSERT(A) #define DBUG_ASSERT_EXISTS #define DBUG_EXPLAIN(buf,len) _db_explain_(0, (buf),(len)) diff --git a/include/my_sys.h b/include/my_sys.h index a746dd9de1b..90f37f8ca81 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -267,7 +267,7 @@ extern ulong my_sync_count; extern uint mysys_usage_id; extern int32 my_file_opened; extern my_bool my_init_done, my_thr_key_mysys_exists; -extern MYSQL_PLUGIN_IMPORT my_bool my_assert; +extern my_bool my_assert; extern my_bool my_assert_on_error; extern myf my_global_flags; /* Set to MY_WME for more error messages */ /* Point to current my_message() */ -- cgit v1.2.1 From 23657a21018d0b3d0464bbd55236113ebcd3d4b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 13 Sep 2019 17:07:58 +0300 Subject: MDEV-13893/MDEV-12699: Enable encryption.innodb-redo-badkey The test had been disabled in 10.2 due to frequent failures, in 5ec9b88e11118c798ff2381771a72f76b2b72f9e. After the problems were addressed, we failed to re-enable the test until now. --- mysql-test/suite/encryption/disabled.def | 1 - 1 file changed, 1 deletion(-) diff --git a/mysql-test/suite/encryption/disabled.def b/mysql-test/suite/encryption/disabled.def index 746faf49873..d92d3495cb8 100644 --- a/mysql-test/suite/encryption/disabled.def +++ b/mysql-test/suite/encryption/disabled.def @@ -12,4 +12,3 @@ innodb_scrub : MDEV-8139 scrubbing does not work reliably innodb_scrub_background : MDEV-8139 scrubbing does not work reliably -innodb-redo-badkey : MDEV-13893/MDEV-12699 fix recovery of corrupted pages -- cgit v1.2.1 From bfbf0f225179d79c1c568b93ddc8b5dd6a670072 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 13 Sep 2019 18:11:32 +0300 Subject: MDEV-20525: Fix the -std=c90 builds --- dbug/dbug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbug/dbug.c b/dbug/dbug.c index 2d629ac0741..356dc319b1f 100644 --- a/dbug/dbug.c +++ b/dbug/dbug.c @@ -2262,8 +2262,8 @@ extern my_bool my_assert; ATTRIBUTE_COLD my_bool _db_my_assert(const char *file, int line, const char *msg) { - _db_flush_(); my_bool a = my_assert; + _db_flush_(); if (!a) fprintf(stderr, "%s:%d: assert: %s\n", file, line, msg); return a; -- cgit v1.2.1 From 0954bcb6639af47a8b57eb426aee9bba4036e5f1 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Fri, 13 Sep 2019 15:09:28 -0700 Subject: Post fix after the patch for MDEV-20576. Adjusted test results. --- mysql-test/r/selectivity_innodb.result | 20 ++++++++++---------- mysql-test/t/selectivity.test | 2 +- storage/tokudb/mysql-test/tokudb/r/mvcc-29.result | 4 ++-- storage/tokudb/mysql-test/tokudb/r/mvcc-30.result | 4 ++-- storage/tokudb/mysql-test/tokudb/r/mvcc-31.result | 4 ++-- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/mysql-test/r/selectivity_innodb.result b/mysql-test/r/selectivity_innodb.result index 56a79001b13..719156a77de 100644 --- a/mysql-test/r/selectivity_innodb.result +++ b/mysql-test/r/selectivity_innodb.result @@ -1726,7 +1726,7 @@ b INT NOT NULL, c char(100), KEY (b, c), KEY (b, a, c) -) +) ENGINE=MyISAM DEFAULT CHARSET = utf8; INSERT INTO t1 VALUES (1, 1, 1), @@ -1749,18 +1749,18 @@ INSERT INTO t1 SELECT a + 1280, b, c FROM t1 LIMIT 80; EXPLAIN SELECT a FROM t1 WHERE b = 1 ORDER BY c DESC LIMIT 9; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref b,b_2 b_2 4 const 207 Using where; Using index; Using filesort +1 SIMPLE t1 range b,b_2 b 4 NULL 226 Using where SELECT a FROM t1 WHERE b = 1 ORDER BY c DESC LIMIT 9; a 2071 -81 -71 -61 -51 -41 -31 -21 -11 +2061 +2051 +2041 +2031 +2021 +2011 +2001 +1991 set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; DROP TABLE t1; # End of 10.1 tests diff --git a/mysql-test/t/selectivity.test b/mysql-test/t/selectivity.test index 6e93e60fff6..0deacc390db 100644 --- a/mysql-test/t/selectivity.test +++ b/mysql-test/t/selectivity.test @@ -1174,7 +1174,7 @@ CREATE TABLE t1 ( c char(100), KEY (b, c), KEY (b, a, c) -) +) ENGINE=MyISAM DEFAULT CHARSET = utf8; INSERT INTO t1 VALUES diff --git a/storage/tokudb/mysql-test/tokudb/r/mvcc-29.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-29.result index 5c02babaed3..b532eabb301 100644 --- a/storage/tokudb/mysql-test/tokudb/r/mvcc-29.result +++ b/storage/tokudb/mysql-test/tokudb/r/mvcc-29.result @@ -26,7 +26,7 @@ delete from foo where a > 5; # number of rows should be 9 explain select * from foo where a > 1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE foo range PRIMARY PRIMARY 4 NULL 9 Using where +1 SIMPLE foo range PRIMARY PRIMARY 4 NULL 5 Using where # should have just 4 values select * from foo where a > 1; a b @@ -37,7 +37,7 @@ a b # number of rows should be 9 explain select * from foo where a > 1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE foo range PRIMARY PRIMARY 4 NULL 9 Using where +1 SIMPLE foo range PRIMARY PRIMARY 4 NULL 5 Using where # 9 values select * From foo where a > 1; a b diff --git a/storage/tokudb/mysql-test/tokudb/r/mvcc-30.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-30.result index c57787f2a8d..f293fe94ab2 100644 --- a/storage/tokudb/mysql-test/tokudb/r/mvcc-30.result +++ b/storage/tokudb/mysql-test/tokudb/r/mvcc-30.result @@ -26,7 +26,7 @@ delete from foo where a < 10; # number of rows should be 9 explain select * from foo where a < 50; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE foo range PRIMARY PRIMARY 4 NULL 9 Using where +1 SIMPLE foo range PRIMARY PRIMARY 4 NULL 5 Using where # should have just 4 values select * from foo where a < 50; a b @@ -37,7 +37,7 @@ a b # number of rows should be 9 explain select * from foo where a < 50; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE foo range PRIMARY PRIMARY 4 NULL 9 Using where +1 SIMPLE foo range PRIMARY PRIMARY 4 NULL 5 Using where # 9 values select * From foo where a < 50; a b diff --git a/storage/tokudb/mysql-test/tokudb/r/mvcc-31.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-31.result index ebc5ae49535..cb55f679061 100644 --- a/storage/tokudb/mysql-test/tokudb/r/mvcc-31.result +++ b/storage/tokudb/mysql-test/tokudb/r/mvcc-31.result @@ -26,7 +26,7 @@ delete from foo where a = 2 or a = 4 or a = 10 or a = 30 or a = 50; # number of rows should be 8 explain select * from foo where a > 1 and a < 50; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE foo range PRIMARY PRIMARY 4 NULL 8 Using where +1 SIMPLE foo range PRIMARY PRIMARY 4 NULL 5 Using where # should have just 4 values select * from foo where a > 1 and a < 50; a b @@ -37,7 +37,7 @@ a b # number of rows should be 8 explain select * from foo where a > 1 and a < 50; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE foo range PRIMARY PRIMARY 4 NULL 8 Using where +1 SIMPLE foo range PRIMARY PRIMARY 4 NULL 5 Using where # 8 values select * from foo where a > 1 and a < 50; a b -- cgit v1.2.1 From ae2b88ff3f94253921fed5c48422adeebe7e623d Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Fri, 13 Sep 2019 21:10:52 -0700 Subject: Adjusted test results after the change of a test case --- mysql-test/r/selectivity.result | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/r/selectivity.result b/mysql-test/r/selectivity.result index d8b2d462952..d0bbb46cb0a 100644 --- a/mysql-test/r/selectivity.result +++ b/mysql-test/r/selectivity.result @@ -1716,7 +1716,7 @@ b INT NOT NULL, c char(100), KEY (b, c), KEY (b, a, c) -) +) ENGINE=MyISAM DEFAULT CHARSET = utf8; INSERT INTO t1 VALUES (1, 1, 1), -- cgit v1.2.1 From 2a98d0b5ca2324405d65415423258cc088fa2f8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Sat, 14 Sep 2019 12:14:20 +0300 Subject: Fix #2 for galera.MW-336 --- mysql-test/suite/galera/t/MW-336.test | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/galera/t/MW-336.test b/mysql-test/suite/galera/t/MW-336.test index 4b606d58772..0e92094da6c 100644 --- a/mysql-test/suite/galera/t/MW-336.test +++ b/mysql-test/suite/galera/t/MW-336.test @@ -25,9 +25,10 @@ INSERT INTO t1 VALUES (1); --connection node_1 SET GLOBAL wsrep_slave_threads = 10; +# Note that above insert could be handled by one of the slave threads --echo # Set slave threads to 10 step 2 ---let $wait_condition = SELECT VARIABLE_VALUE = 10 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_applier_thread_count'; ---let $wait_condition_on_error_output = SELECT COUNT(*), 10 as EXPECTED_VALUE FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE = 'wsrep applier idle'; show processlist +--let $wait_condition = SELECT VARIABLE_VALUE >= 9 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_applier_thread_count'; +--let $wait_condition_on_error_output = SELECT COUNT(*), 9 as EXPECTED_VALUE FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE = 'wsrep applier idle'; show processlist --source include/wait_condition_with_debug.inc SET GLOBAL wsrep_slave_threads = 20; -- cgit v1.2.1 From 90a9c4cae74d2ef1008e3f216026b7fd2697e46b Mon Sep 17 00:00:00 2001 From: Sujatha Date: Mon, 16 Sep 2019 15:45:24 +0530 Subject: MDEV-20217: Semi_sync: Last_IO_Error: Fatal error: Failed to run 'after_queue_event' hook Fix: === Implemented upstream fix. commit 7d3d0fc303183ef50a343680ce70df71d5675cd1 Author: He Zhenxing Backport Bug#45852 Semisynch: Last_IO_Error: Fatal error: Failed to run 'after_queue_event' hook Errors when send reply to master should never cause the IO thread to stop, because master can fall back to async replication if it does not get reply from slave. The problem is fixed by deliberately ignoring the return value of slave_reply. --- .../rpl/r/rpl_semi_sync_slave_reply_fail.result | 40 ++++++++++ .../rpl/t/rpl_semi_sync_slave_reply_fail.test | 87 ++++++++++++++++++++++ sql/slave.cc | 13 ++-- 3 files changed, 134 insertions(+), 6 deletions(-) create mode 100644 mysql-test/suite/rpl/r/rpl_semi_sync_slave_reply_fail.result create mode 100644 mysql-test/suite/rpl/t/rpl_semi_sync_slave_reply_fail.test diff --git a/mysql-test/suite/rpl/r/rpl_semi_sync_slave_reply_fail.result b/mysql-test/suite/rpl/r/rpl_semi_sync_slave_reply_fail.result new file mode 100644 index 00000000000..6b39b296cdf --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_semi_sync_slave_reply_fail.result @@ -0,0 +1,40 @@ +include/master-slave.inc +[connection master] +connection slave; +include/stop_slave.inc +connection master; +call mtr.add_suppression("Timeout waiting for reply of binlog*"); +set global rpl_semi_sync_master_enabled = ON; +SET @@GLOBAL.rpl_semi_sync_master_timeout=100; +create table t1 (i int); +connection slave; +set global rpl_semi_sync_slave_enabled = ON; +CALL mtr.add_suppression("Semi-sync slave net_flush*"); +SET @save_debug= @@global.debug; +SET GLOBAL debug_dbug="+d,semislave_failed_net_flush"; +include/start_slave.inc +connection master; +connection slave; +"Assert that the net_fulsh() reply failed is present in slave error log. +FOUND 1 /Semi-sync slave net_flush\(\) reply failed/ in mysqld.2.err +"Assert that Slave IO thread is up and running." +SHOW STATUS LIKE 'Slave_running'; +Variable_name Value +Slave_running ON +Slave_IO_Running= Yes +"Clear the network failure simulation." +SET GLOBAL debug_dbug= @save_debug; +connection master; +insert into t1 values (10); +connection slave; +connection slave; +# Compare the tables on master and slave. +include/diff_tables.inc [master:t1, slave:t1] +connection master; +drop table t1; +connection slave; +set global rpl_semi_sync_slave_enabled = OFF; +connection master; +set global rpl_semi_sync_master_enabled = OFF; +SET @@GLOBAL.rpl_semi_sync_master_timeout = 10000; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync_slave_reply_fail.test b/mysql-test/suite/rpl/t/rpl_semi_sync_slave_reply_fail.test new file mode 100644 index 00000000000..f0eb474f00e --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_semi_sync_slave_reply_fail.test @@ -0,0 +1,87 @@ +# ==== Purpose ==== +# +# Test verifies that slave IO thread doesn't report an error, when slave fails +# to send an acknowledgment to master with semi sync replication in use. +# +# ==== Implementation ==== +# +# Steps: +# 0 - Have semi synchronous replication in use. +# 1 - Enable a debug simulation point which simulates network flush failure +# at the time of slave reply operation. +# 2 - Do some operation on master and wait for it to be replicated. Master +# will timeout waiting for reply from slave. +# 3 - Check the slave error log for appropriate error message regarding +# net_flush operation failure. +# 4 - Remove the debug simulation and do some more DML operations on master +# and wait for them to be replicated. +# 5 - Slave will be able to replicate and data is consistent on both master +# and slave. Semi sync will be automatically turned on. +# +# ==== References ==== +# +# MDEV-20217: Semi_sync: Last_IO_Error: Fatal error: Failed to run +# 'after_queue_event' hook +# +--source include/have_debug.inc +--source include/master-slave.inc + +--connection slave +--source include/stop_slave.inc + +--connection master +call mtr.add_suppression("Timeout waiting for reply of binlog*"); +--let $sav_timeout_master=`SELECT @@GLOBAL.rpl_semi_sync_master_timeout` +set global rpl_semi_sync_master_enabled = ON; +SET @@GLOBAL.rpl_semi_sync_master_timeout=100; +create table t1 (i int); + +--connection slave +set global rpl_semi_sync_slave_enabled = ON; +CALL mtr.add_suppression("Semi-sync slave net_flush*"); +SET @save_debug= @@global.debug; +SET GLOBAL debug_dbug="+d,semislave_failed_net_flush"; +--source include/start_slave.inc + +--connection master +--sync_slave_with_master + +# Check error log for correct messages. +let $log_error_= `SELECT @@GLOBAL.log_error`; +if(!$log_error_) +{ + # MySQL Server on windows is started with --console and thus + # does not know the location of its .err log, use default location + let $log_error_ = $MYSQLTEST_VARDIR/log/mysqld.2.err; +} +--echo "Assert that the net_fulsh() reply failed is present in slave error log. +--let SEARCH_FILE=$log_error_ +--let SEARCH_PATTERN=Semi-sync slave net_flush\(\) reply failed +--source include/search_pattern_in_file.inc + +--echo "Assert that Slave IO thread is up and running." +SHOW STATUS LIKE 'Slave_running'; +let $status= query_get_value("show slave status", Slave_IO_Running, 1); +echo Slave_IO_Running= $status; + +--echo "Clear the network failure simulation." +SET GLOBAL debug_dbug= @save_debug; + +--connection master +insert into t1 values (10); +--sync_slave_with_master + +--connection slave +--echo # Compare the tables on master and slave. +--let $diff_tables= master:t1, slave:t1 +--source include/diff_tables.inc + +--connection master +drop table t1; +--sync_slave_with_master +set global rpl_semi_sync_slave_enabled = OFF; + +--connection master +set global rpl_semi_sync_master_enabled = OFF; +--eval SET @@GLOBAL.rpl_semi_sync_master_timeout = $sav_timeout_master +--source include/rpl_end.inc diff --git a/sql/slave.cc b/sql/slave.cc index 4007f323a6e..165aa20b1ee 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -4911,13 +4911,14 @@ Stopping slave I/O thread due to out-of-memory error from master"); goto err; } - if (rpl_semi_sync_slave_status && (mi->semi_ack & SEMI_SYNC_NEED_ACK) && - repl_semisync_slave.slave_reply(mi)) + if (rpl_semi_sync_slave_status && (mi->semi_ack & SEMI_SYNC_NEED_ACK)) { - mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, NULL, - ER_THD(thd, ER_SLAVE_FATAL_ERROR), - "Failed to run 'after_queue_event' hook"); - goto err; + /* + We deliberately ignore the error in slave_reply, such error should + not cause the slave IO thread to stop, and the error messages are + already reported. + */ + (void)repl_semisync_slave.slave_reply(mi); } if (mi->using_gtid == Master_info::USE_GTID_NO && -- cgit v1.2.1 From fb3e3a6a3d165d79331f7f359e9c1f28a332c772 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Tue, 17 Sep 2019 19:54:15 +0530 Subject: MDEV-20483 trx_lock_t::table_locks is not a subset of trx_lock_t::trx_locks Problem: ======= Transaction left with nonempty table locks list. This leads to assumption that table_locks is not subset of trx_locks. Problem is that lock_wait_timeout_thread() doesn't remove the table lock from table_locks for transaction. Solution: ======== In lock_wait_timeout_thread(), remove the lock from table vector of transaction. --- storage/innobase/lock/lock0lock.cc | 2 ++ storage/innobase/trx/trx0trx.cc | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index b7e17097546..9fdc8feee90 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -6480,6 +6480,8 @@ lock_cancel_waiting_and_release( } lock_table_dequeue(lock); + /* Remove the lock from table lock vector too. */ + lock_trx_table_locks_remove(lock); } /* Reset the wait flag and the back pointer to lock in trx. */ diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index 1dcca7c1f72..b06e15d4f37 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -561,8 +561,6 @@ inline void trx_t::release_locks() if (UT_LIST_GET_LEN(lock.trx_locks)) lock_trx_release_locks(this); - else - lock.table_locks.clear(); /* Work around MDEV-20483 */ } /********************************************************************//** -- cgit v1.2.1 From 708f1e341915b9fe2968581c60fb6a224b185af9 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Tue, 17 Sep 2019 20:47:58 +0530 Subject: MDEV-19647 Server hangs after dropping full text indexes and restart - There is no need to add the table in fts_optimize_wq if there is no fts indexes associated with it. --- mysql-test/suite/innodb_fts/r/innodb_fts_misc.result | 14 ++++++++++---- mysql-test/suite/innodb_fts/t/innodb_fts_misc.test | 7 +++++-- storage/innobase/fts/fts0opt.cc | 6 ++++++ storage/xtradb/fts/fts0opt.cc | 6 ++++++ 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/mysql-test/suite/innodb_fts/r/innodb_fts_misc.result b/mysql-test/suite/innodb_fts/r/innodb_fts_misc.result index 628fe8519ed..71eded74be4 100644 --- a/mysql-test/suite/innodb_fts/r/innodb_fts_misc.result +++ b/mysql-test/suite/innodb_fts/r/innodb_fts_misc.result @@ -734,15 +734,21 @@ count(*) DROP TABLE t1; "----------Test27---------" CREATE TABLE t1 (id INT,char_column VARCHAR(60)); +CREATE TABLE t2 (FTS_DOC_ID BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, a TEXT)ENGINE=InnoDB; +ALTER TABLE t2 DROP a; SET @@autocommit=0; CREATE FULLTEXT INDEX i ON t1 (char_column); INSERT INTO t1 values (1,'aaa'); "restart server..." -# Restart the server ---source include/restart_mysqld.inc -DELETE FROM t1 WHERE MATCH(char_column) AGAINST ('bbb') +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `FTS_DOC_ID` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + PRIMARY KEY (`FTS_DOC_ID`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +DELETE FROM t1 WHERE MATCH(char_column) AGAINST ('bbb'); SET @@autocommit=1; -DROP TABLE t1; +DROP TABLE t1, t2; "----------Test28---------" drop table if exists `fts_test`; Warnings: diff --git a/mysql-test/suite/innodb_fts/t/innodb_fts_misc.test b/mysql-test/suite/innodb_fts/t/innodb_fts_misc.test index 68ca8974512..e226b276966 100644 --- a/mysql-test/suite/innodb_fts/t/innodb_fts_misc.test +++ b/mysql-test/suite/innodb_fts/t/innodb_fts_misc.test @@ -667,15 +667,18 @@ DROP TABLE t1; --echo "----------Test27---------" #27 Crash after server restart CREATE TABLE t1 (id INT,char_column VARCHAR(60)); +CREATE TABLE t2 (FTS_DOC_ID BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, a TEXT)ENGINE=InnoDB; +ALTER TABLE t2 DROP a; SET @@autocommit=0; CREATE FULLTEXT INDEX i ON t1 (char_column); INSERT INTO t1 values (1,'aaa'); -echo "restart server..." +echo "restart server..."; # Restart the server --source include/restart_mysqld.inc +SHOW CREATE TABLE t2; DELETE FROM t1 WHERE MATCH(char_column) AGAINST ('bbb'); SET @@autocommit=1; -DROP TABLE t1; +DROP TABLE t1, t2; --echo "----------Test28---------" drop table if exists `fts_test`; diff --git a/storage/innobase/fts/fts0opt.cc b/storage/innobase/fts/fts0opt.cc index 2f8739d3d2c..553c6ff392b 100644 --- a/storage/innobase/fts/fts0opt.cc +++ b/storage/innobase/fts/fts0opt.cc @@ -2614,6 +2614,12 @@ UNIV_INTERN void fts_optimize_add_table(dict_table_t* table) return; } + /* If there is no fts index present then don't add to + optimize queue. */ + if (!ib_vector_size(table->fts->indexes)) { + return; + } + /* Make sure table with FTS index cannot be evicted */ if (table->can_be_evicted) { dict_table_move_from_lru_to_non_lru(table); diff --git a/storage/xtradb/fts/fts0opt.cc b/storage/xtradb/fts/fts0opt.cc index 2f8739d3d2c..553c6ff392b 100644 --- a/storage/xtradb/fts/fts0opt.cc +++ b/storage/xtradb/fts/fts0opt.cc @@ -2614,6 +2614,12 @@ UNIV_INTERN void fts_optimize_add_table(dict_table_t* table) return; } + /* If there is no fts index present then don't add to + optimize queue. */ + if (!ib_vector_size(table->fts->indexes)) { + return; + } + /* Make sure table with FTS index cannot be evicted */ if (table->can_be_evicted) { dict_table_move_from_lru_to_non_lru(table); -- cgit v1.2.1 From c471bfb34e970075d8649247ab088b19a097eaf4 Mon Sep 17 00:00:00 2001 From: Varun Gupta Date: Wed, 18 Sep 2019 01:44:36 +0530 Subject: Fixing a test to reset to original state --- mysql-test/r/stat_tables.result | 3 ++- mysql-test/r/stat_tables_innodb.result | 3 ++- mysql-test/t/stat_tables.test | 5 +++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/stat_tables.result b/mysql-test/r/stat_tables.result index 50767d7e3dc..c47a47cea31 100644 --- a/mysql-test/r/stat_tables.result +++ b/mysql-test/r/stat_tables.result @@ -797,9 +797,10 @@ col1 2004-01-01 2004-02-29 0000-10-31 -drop table t1; set @@sql_mode= @save_sql_mode; set use_stat_tables=@save_use_stat_tables; set @@histogram_size= @save_histogram_size; set @@optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; +drop table t1; +# please keep this at the last set @@global.histogram_size=@save_histogram_size; diff --git a/mysql-test/r/stat_tables_innodb.result b/mysql-test/r/stat_tables_innodb.result index 70c8808efbb..dcfdb55f9c9 100644 --- a/mysql-test/r/stat_tables_innodb.result +++ b/mysql-test/r/stat_tables_innodb.result @@ -824,11 +824,12 @@ col1 2004-01-01 2004-02-29 0000-10-31 -drop table t1; set @@sql_mode= @save_sql_mode; set use_stat_tables=@save_use_stat_tables; set @@histogram_size= @save_histogram_size; set @@optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; +drop table t1; +# please keep this at the last set @@global.histogram_size=@save_histogram_size; set optimizer_switch=@save_optimizer_switch_for_stat_tables_test; SET SESSION STORAGE_ENGINE=DEFAULT; diff --git a/mysql-test/t/stat_tables.test b/mysql-test/t/stat_tables.test index 4c49df82ca6..880e6378ca5 100644 --- a/mysql-test/t/stat_tables.test +++ b/mysql-test/t/stat_tables.test @@ -540,10 +540,11 @@ analyze table t1; update mysql.column_stats set min_value='2004-0-31123' where db_name='test' and table_name='t1'; select min_value from mysql.column_stats where db_name='test' and table_name='t1'; select * from t1; -drop table t1; - set @@sql_mode= @save_sql_mode; set use_stat_tables=@save_use_stat_tables; set @@histogram_size= @save_histogram_size; set @@optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; +drop table t1; + +--echo # please keep this at the last set @@global.histogram_size=@save_histogram_size; -- cgit v1.2.1 From 8a79fa0e4d0385818da056f7a4a39fde95d62fe3 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Wed, 18 Sep 2019 13:22:08 +0530 Subject: MDEV-19529 InnoDB hang on DROP FULLTEXT INDEX Problem: ======= During dropping of fts index, InnoDB waits for fts_optimize_remove_table() and it holds dict_sys->mutex and dict_operaiton_lock even though the table id is not present in the queue. But fts_optimize_thread does wait for dict_sys->mutex to process the unrelated table id from the slot. Solution: ======== Whenever table is added to fts_optimize_wq, update the fts_status of in-memory fts subsystem to TABLE_IN_QUEUE. Whenever drop index wants to remove table from the queue, it can check the fts_status to decide whether it should send the MSG_DELETE_TABLE to the queue. Removed the following functions because these are all deadcode. dict_table_wait_for_bg_threads_to_exit(), fts_wait_for_background_thread_to_start(),fts_start_shutdown(), fts_shudown(). --- .../suite/innodb_fts/r/concurrent_insert.result | 18 +++ .../suite/innodb_fts/t/concurrent_insert.test | 31 ++++++ storage/innobase/dict/dict0dict.cc | 27 ----- storage/innobase/fts/fts0config.cc | 3 +- storage/innobase/fts/fts0fts.cc | 121 ++------------------- storage/innobase/fts/fts0opt.cc | 25 +++++ storage/innobase/fts/fts0sql.cc | 3 +- storage/innobase/handler/ha_innodb.cc | 4 +- storage/innobase/handler/handler0alter.cc | 7 +- storage/innobase/include/dict0dict.h | 12 -- storage/innobase/include/fts0fts.h | 59 ++-------- storage/innobase/include/fts0priv.h | 14 --- storage/innobase/row/row0mysql.cc | 7 +- storage/innobase/trx/trx0trx.cc | 23 +--- storage/xtradb/dict/dict0dict.cc | 27 ----- storage/xtradb/fts/fts0config.cc | 3 +- storage/xtradb/fts/fts0fts.cc | 121 ++------------------- storage/xtradb/fts/fts0opt.cc | 25 +++++ storage/xtradb/fts/fts0sql.cc | 3 +- storage/xtradb/handler/ha_innodb.cc | 4 +- storage/xtradb/handler/handler0alter.cc | 7 +- storage/xtradb/include/dict0dict.h | 12 -- storage/xtradb/include/fts0fts.h | 59 ++-------- storage/xtradb/include/fts0priv.h | 14 --- storage/xtradb/row/row0mysql.cc | 7 +- storage/xtradb/trx/trx0trx.cc | 23 +--- 26 files changed, 169 insertions(+), 490 deletions(-) diff --git a/mysql-test/suite/innodb_fts/r/concurrent_insert.result b/mysql-test/suite/innodb_fts/r/concurrent_insert.result index b9798ca1a74..416e8bf432c 100644 --- a/mysql-test/suite/innodb_fts/r/concurrent_insert.result +++ b/mysql-test/suite/innodb_fts/r/concurrent_insert.result @@ -6,3 +6,21 @@ REPLACE INTO t1(a) VALUES('aaa'); SET DEBUG_SYNC = 'now SIGNAL race'; SET DEBUG_SYNC = 'RESET'; DROP TABLE t1; +# +# MDEV-19529 InnoDB hang on DROP FULLTEXT INDEX +# +CREATE TABLE t1(f1 CHAR(100), FULLTEXT(f1))ENGINE=InnoDB; +INSERT INTO t1 VALUES('test'); +CREATE TABLE t2 (f1 char(100), FULLTEXT idx1(f1))ENGINE=InnoDB; +INSERT INTO t2 VALUES('mariadb'); +SET GLOBAL debug_dbug ='+d,fts_instrument_sync_request,ib_optimize_wq_hang'; +SET DEBUG_SYNC= 'fts_instrument_sync_request + SIGNAL drop_index_start WAIT_FOR sync_op'; +INSERT INTO t1 VALUES('Keyword'); +SET DEBUG_SYNC='now WAIT_FOR drop_index_start'; +SET DEBUG_SYNC= 'norebuild_fts_drop SIGNAL sync_op WAIT_FOR fts_drop_index'; +ALTER TABLE t2 drop index idx1; +set DEBUG_SYNC= 'now SIGNAL fts_drop_index'; +SET global DEBUG_DBUG=RESET; +drop table t1, t2; +set DEBUG_SYNC=RESET; diff --git a/mysql-test/suite/innodb_fts/t/concurrent_insert.test b/mysql-test/suite/innodb_fts/t/concurrent_insert.test index e5d61cd8b05..77097d44dc5 100644 --- a/mysql-test/suite/innodb_fts/t/concurrent_insert.test +++ b/mysql-test/suite/innodb_fts/t/concurrent_insert.test @@ -18,3 +18,34 @@ reap; SET DEBUG_SYNC = 'RESET'; DROP TABLE t1; + +--echo # +--echo # MDEV-19529 InnoDB hang on DROP FULLTEXT INDEX +--echo # + +CREATE TABLE t1(f1 CHAR(100), FULLTEXT(f1))ENGINE=InnoDB; +INSERT INTO t1 VALUES('test'); +CREATE TABLE t2 (f1 char(100), FULLTEXT idx1(f1))ENGINE=InnoDB; +INSERT INTO t2 VALUES('mariadb'); + +connection default; +SET GLOBAL debug_dbug ='+d,fts_instrument_sync_request,ib_optimize_wq_hang'; +SET DEBUG_SYNC= 'fts_instrument_sync_request + SIGNAL drop_index_start WAIT_FOR sync_op'; +send INSERT INTO t1 VALUES('Keyword'); + +connect(con1,localhost,root,,,); +SET DEBUG_SYNC='now WAIT_FOR drop_index_start'; +SET DEBUG_SYNC= 'norebuild_fts_drop SIGNAL sync_op WAIT_FOR fts_drop_index'; +send ALTER TABLE t2 drop index idx1; + +connection default; +reap; +set DEBUG_SYNC= 'now SIGNAL fts_drop_index'; + +connection con1; +reap; +SET global DEBUG_DBUG=RESET; +drop table t1, t2; +connection default; +set DEBUG_SYNC=RESET; diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index c6ccc37d589..f9295e74d7c 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -2911,33 +2911,6 @@ dict_table_copy_types( } } -/******************************************************************** -Wait until all the background threads of the given table have exited, i.e., -bg_threads == 0. Note: bg_threads_mutex must be reserved when -calling this. */ -UNIV_INTERN -void -dict_table_wait_for_bg_threads_to_exit( -/*===================================*/ - dict_table_t* table, /*< in: table */ - ulint delay) /*< in: time in microseconds to wait between - checks of bg_threads. */ -{ - fts_t* fts = table->fts; - -#ifdef UNIV_SYNC_DEBUG - ut_ad(mutex_own(&fts->bg_threads_mutex)); -#endif /* UNIV_SYNC_DEBUG */ - - while (fts->bg_threads > 0) { - mutex_exit(&fts->bg_threads_mutex); - - os_thread_sleep(delay); - - mutex_enter(&fts->bg_threads_mutex); - } -} - /*******************************************************************//** Builds the internal dictionary cache representation for a clustered index, containing also system fields not defined by the user. diff --git a/storage/innobase/fts/fts0config.cc b/storage/innobase/fts/fts0config.cc index 940c944a436..b39d568575c 100644 --- a/storage/innobase/fts/fts0config.cc +++ b/storage/innobase/fts/fts0config.cc @@ -224,8 +224,7 @@ fts_config_set_value( pars_info_bind_varchar_literal(info, "value", value->f_str, value->f_len); - const bool dict_locked = fts_table->table->fts->fts_status - & TABLE_DICT_LOCKED; + const bool dict_locked = fts_table->table->fts->dict_locked; fts_table->suffix = "CONFIG"; fts_get_table_name(fts_table, table_name, dict_locked); diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index 264c520bb1e..1cf5c818a9e 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -458,7 +458,7 @@ fts_load_user_stopword( dberr_t error = DB_SUCCESS; ibool ret = TRUE; trx_t* trx; - ibool has_lock = fts->fts_status & TABLE_DICT_LOCKED; + ibool has_lock = fts->dict_locked; trx = trx_allocate_for_background(); trx->op_info = "Load user stopword table into FTS cache"; @@ -933,18 +933,16 @@ fts_que_graph_free_check_lock( const fts_index_cache_t*index_cache, /*!< in: FTS index cache */ que_t* graph) /*!< in: query graph */ { - ibool has_dict = FALSE; + bool has_dict = FALSE; if (fts_table && fts_table->table) { ut_ad(fts_table->table->fts); - has_dict = fts_table->table->fts->fts_status - & TABLE_DICT_LOCKED; + has_dict = fts_table->table->fts->dict_locked; } else if (index_cache) { ut_ad(index_cache->index->table->fts); - has_dict = index_cache->index->table->fts->fts_status - & TABLE_DICT_LOCKED; + has_dict = index_cache->index->table->fts->dict_locked; } if (!has_dict) { @@ -2831,7 +2829,7 @@ fts_update_sync_doc_id( pars_info_bind_varchar_literal(info, "doc_id", id, id_len); fts_get_table_name(&fts_table, fts_name, - table->fts->fts_status & TABLE_DICT_LOCKED); + table->fts->dict_locked); pars_info_bind_id(info, true, "table_name", fts_name); graph = fts_parse_sql( @@ -2947,7 +2945,7 @@ fts_delete( into cache from last crash (delete Doc will not initialize the sync). Avoid any added counter accounting until the FTS cache is re-established and sync-ed */ - if (table->fts->fts_status & ADDED_TABLE_SYNCED + if (table->fts->added_synced && doc_id > cache->synced_doc_id) { mutex_enter(&table->fts->cache->deleted_lock); @@ -3385,7 +3383,7 @@ fts_add_doc_by_id( /* If Doc ID has been supplied by the user, then the table might not yet be sync-ed */ - if (!(ftt->table->fts->fts_status & ADDED_TABLE_SYNCED)) { + if (!ftt->table->fts->added_synced) { fts_init_index(ftt->table, FALSE); } @@ -4933,7 +4931,7 @@ fts_init_doc_id( fts_init_index((dict_table_t*) table, TRUE); } - table->fts->fts_status |= ADDED_TABLE_SYNCED; + table->fts->added_synced = true; table->fts->cache->first_doc_id = max_doc_id; @@ -5386,69 +5384,6 @@ fts_cache_append_deleted_doc_ids( mutex_exit((ib_mutex_t*) &cache->deleted_lock); } -/*********************************************************************//** -Wait for the background thread to start. We poll to detect change -of state, which is acceptable, since the wait should happen only -once during startup. -@return true if the thread started else FALSE (i.e timed out) */ -UNIV_INTERN -ibool -fts_wait_for_background_thread_to_start( -/*====================================*/ - dict_table_t* table, /*!< in: table to which the thread - is attached */ - ulint max_wait) /*!< in: time in microseconds, if - set to 0 then it disables - timeout checking */ -{ - ulint count = 0; - ibool done = FALSE; - - ut_a(max_wait == 0 || max_wait >= FTS_MAX_BACKGROUND_THREAD_WAIT); - - for (;;) { - fts_t* fts = table->fts; - - mutex_enter(&fts->bg_threads_mutex); - - if (fts->fts_status & BG_THREAD_READY) { - - done = TRUE; - } - - mutex_exit(&fts->bg_threads_mutex); - - if (!done) { - os_thread_sleep(FTS_MAX_BACKGROUND_THREAD_WAIT); - - if (max_wait > 0) { - - max_wait -= FTS_MAX_BACKGROUND_THREAD_WAIT; - - /* We ignore the residual value. */ - if (max_wait < FTS_MAX_BACKGROUND_THREAD_WAIT) { - break; - } - } - - ++count; - } else { - break; - } - - if (count >= FTS_BACKGROUND_THREAD_WAIT_COUNT) { - ut_print_timestamp(stderr); - fprintf(stderr, " InnoDB: Error the background thread " - "for the FTS table %s refuses to start\n", - table->name); - - count = 0; - } - } - - return(done); -} - /*********************************************************************//** Add the FTS document id hidden column. */ UNIV_INTERN @@ -5589,42 +5524,6 @@ fts_free( table->fts = NULL; } -/*********************************************************************//** -Signal FTS threads to initiate shutdown. */ -UNIV_INTERN -void -fts_start_shutdown( -/*===============*/ - dict_table_t* table, /*!< in: table with FTS indexes */ - fts_t* fts) /*!< in: fts instance that needs - to be informed about shutdown */ -{ - mutex_enter(&fts->bg_threads_mutex); - - fts->fts_status |= BG_THREAD_STOP; - - mutex_exit(&fts->bg_threads_mutex); - -} - -/*********************************************************************//** -Wait for FTS threads to shutdown. */ -UNIV_INTERN -void -fts_shutdown( -/*=========*/ - dict_table_t* table, /*!< in: table with FTS indexes */ - fts_t* fts) /*!< in: fts instance to shutdown */ -{ - mutex_enter(&fts->bg_threads_mutex); - - ut_a(fts->fts_status & BG_THREAD_STOP); - - dict_table_wait_for_bg_threads_to_exit(table, 20000); - - mutex_exit(&fts->bg_threads_mutex); -} - /*********************************************************************//** Take a FTS savepoint. */ UNIV_INLINE @@ -7639,7 +7538,7 @@ fts_init_index( } rw_lock_x_unlock(&cache->init_lock); - if (table->fts->fts_status & ADDED_TABLE_SYNCED) { + if (table->fts->added_synced) { goto func_exit; } @@ -7681,7 +7580,7 @@ fts_init_index( } } - table->fts->fts_status |= ADDED_TABLE_SYNCED; + table->fts->added_synced = true; fts_get_docs_clear(cache->get_docs); diff --git a/storage/innobase/fts/fts0opt.cc b/storage/innobase/fts/fts0opt.cc index 553c6ff392b..3c15b514102 100644 --- a/storage/innobase/fts/fts0opt.cc +++ b/storage/innobase/fts/fts0opt.cc @@ -2628,6 +2628,10 @@ UNIV_INTERN void fts_optimize_add_table(dict_table_t* table) msg = fts_optimize_create_msg(FTS_MSG_ADD_TABLE, table); ib_wqueue_add(fts_optimize_wq, msg, msg->heap); + + mutex_enter(&table->fts->bg_threads_mutex); + table->fts->in_queue = true; + mutex_exit(&table->fts->bg_threads_mutex); } /**********************************************************************//** @@ -2656,6 +2660,15 @@ fts_optimize_remove_table( return; } + fts_t* fts = table->fts; + mutex_enter(&fts->bg_threads_mutex); + bool is_in_optimize_queue = fts->in_queue; + mutex_exit(&fts->bg_threads_mutex); + + if (!is_in_optimize_queue) { + return; + } + msg = fts_optimize_create_msg(FTS_MSG_DEL_TABLE, NULL); /* We will wait on this event until signalled by the consumer. */ @@ -2673,6 +2686,10 @@ fts_optimize_remove_table( os_event_wait(event); os_event_free(event); + + mutex_enter(&fts->bg_threads_mutex); + fts->in_queue = false; + mutex_exit(&fts->bg_threads_mutex); } /** Send sync fts cache for the table. @@ -2706,6 +2723,10 @@ fts_optimize_request_sync_table( msg->ptr = table_id; ib_wqueue_add(fts_optimize_wq, msg, msg->heap); + + mutex_enter(&table->fts->bg_threads_mutex); + table->fts->in_queue = true; + mutex_exit(&table->fts->bg_threads_mutex); } /** Add a table to fts_slots if it doesn't already exist. */ @@ -2850,6 +2871,10 @@ static void fts_optimize_sync_table(table_id_t table_id) fts_sync_table(table, true, false, false); } + DBUG_EXECUTE_IF( + "ib_optimize_wq_hang", + os_thread_sleep(6000000);); + dict_table_close(table, FALSE, FALSE); } } diff --git a/storage/innobase/fts/fts0sql.cc b/storage/innobase/fts/fts0sql.cc index 258164415f4..2c91115281b 100644 --- a/storage/innobase/fts/fts0sql.cc +++ b/storage/innobase/fts/fts0sql.cc @@ -165,8 +165,7 @@ fts_parse_sql( str = ut_str3cat(fts_sql_begin, sql, fts_sql_end); dict_locked = (fts_table && fts_table->table->fts - && (fts_table->table->fts->fts_status - & TABLE_DICT_LOCKED)); + && fts_table->table->fts->dict_locked); if (!dict_locked) { ut_ad(!mutex_own(&(dict_sys->mutex))); diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 5dfe240631b..fd8f0d3787f 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -10094,10 +10094,10 @@ ha_innobase::ft_init_ext( return(NULL); } - if (!(ft_table->fts->fts_status & ADDED_TABLE_SYNCED)) { + if (!(ft_table->fts->added_synced)) { fts_init_index(ft_table, FALSE); - ft_table->fts->fts_status |= ADDED_TABLE_SYNCED; + ft_table->fts->added_synced = true; } error = fts_query(trx, index, flags, query, query_len, &result); diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 24db706d0bc..682f09992a4 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -3245,15 +3245,13 @@ op_ok: goto error_handling; } - ctx->new_table->fts->fts_status - |= TABLE_DICT_LOCKED; + ctx->new_table->fts->dict_locked = true; error = innobase_fts_load_stopword( ctx->new_table, ctx->trx, ctx->prebuilt->trx->mysql_thd) ? DB_SUCCESS : DB_ERROR; - ctx->new_table->fts->fts_status - &= ~TABLE_DICT_LOCKED; + ctx->new_table->fts->dict_locked = false; if (error != DB_SUCCESS) { goto error_handling; @@ -5624,6 +5622,7 @@ commit_cache_norebuild( || (index->type & DICT_CORRUPT)); DBUG_ASSERT(index->table->fts); + DEBUG_SYNC_C("norebuild_fts_drop"); fts_drop_index(index->table, index, trx); } diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index 37f2a4e2b23..93ca3692141 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -1016,18 +1016,6 @@ dict_table_copy_types( dtuple_t* tuple, /*!< in/out: data tuple */ const dict_table_t* table) /*!< in: table */ MY_ATTRIBUTE((nonnull)); -/******************************************************************** -Wait until all the background threads of the given table have exited, i.e., -bg_threads == 0. Note: bg_threads_mutex must be reserved when -calling this. */ -UNIV_INTERN -void -dict_table_wait_for_bg_threads_to_exit( -/*===================================*/ - dict_table_t* table, /* in: table */ - ulint delay) /* in: time in microseconds to wait between - checks of bg_threads. */ - MY_ATTRIBUTE((nonnull)); /**********************************************************************//** Looks for an index with the given id. NOTE that we do not reserve the dictionary mutex: this function is for emergency purposes like diff --git a/storage/innobase/include/fts0fts.h b/storage/innobase/include/fts0fts.h index a1fab659732..5c50e381f91 100644 --- a/storage/innobase/include/fts0fts.h +++ b/storage/innobase/include/fts0fts.h @@ -279,40 +279,21 @@ struct fts_table_t { index auxiliary table */ }; -enum fts_status { - BG_THREAD_STOP = 1, /*!< TRUE if the FTS background thread - has finished reading the ADDED table, - meaning more items can be added to - the table. */ - - BG_THREAD_READY = 2, /*!< TRUE if the FTS background thread - is ready */ - - ADD_THREAD_STARTED = 4, /*!< TRUE if the FTS add thread - has started */ - - ADDED_TABLE_SYNCED = 8, /*!< TRUE if the ADDED table record is - sync-ed after crash recovery */ - - TABLE_DICT_LOCKED = 16 /*!< Set if the table has - dict_sys->mutex */ -}; - -typedef enum fts_status fts_status_t; - /** The state of the FTS sub system. */ struct fts_t { /*!< mutex protecting bg_threads* and fts_add_wq. */ ib_mutex_t bg_threads_mutex; - ulint bg_threads; /*!< number of background threads - accessing this table */ - - /*!< TRUE if background threads running - should stop themselves */ - ulint fts_status; /*!< Status bit regarding fts - running state */ + /* Wheter the table was added to fts_optimize_wq(); + protected by bg_threads mutex */ + unsigned in_queue:1; + /* Whether the ADDED table record sync-ed after + crash recovery; protected by bg_threads mutex */ + unsigned added_synced:1; + /* Whether the table hold dict_sys->mutex; + protected by bg_threads mutex */ + unsigned dict_locked:1; ib_wqueue_t* add_wq; /*!< Work queue for scheduling jobs for the FTS 'Add' thread, or NULL @@ -614,28 +595,6 @@ void fts_startup(void); /*==============*/ -/******************************************************************//** -Signal FTS threads to initiate shutdown. */ -UNIV_INTERN -void -fts_start_shutdown( -/*===============*/ - dict_table_t* table, /*!< in: table with FTS - indexes */ - fts_t* fts); /*!< in: fts instance to - shutdown */ - -/******************************************************************//** -Wait for FTS threads to shutdown. */ -UNIV_INTERN -void -fts_shutdown( -/*=========*/ - dict_table_t* table, /*!< in: table with FTS - indexes */ - fts_t* fts); /*!< in: fts instance to - shutdown */ - /******************************************************************//** Create an instance of fts_t. @return instance of fts_t */ diff --git a/storage/innobase/include/fts0priv.h b/storage/innobase/include/fts0priv.h index 266534c9511..1622eaa07ae 100644 --- a/storage/innobase/include/fts0priv.h +++ b/storage/innobase/include/fts0priv.h @@ -521,20 +521,6 @@ fts_cache_append_deleted_doc_ids( const fts_cache_t* cache, /*!< in: cache to use */ ib_vector_t* vector); /*!< in: append to this vector */ -/******************************************************************//** -Wait for the background thread to start. We poll to detect change -of state, which is acceptable, since the wait should happen only -once during startup. -@return true if the thread started else FALSE (i.e timed out) */ -UNIV_INTERN -ibool -fts_wait_for_background_thread_to_start( -/*====================================*/ - dict_table_t* table, /*!< in: table to which the thread - is attached */ - ulint max_wait); /*!< in: time in microseconds, if set - to 0 then it disables timeout - checking */ #ifdef FTS_DOC_STATS_DEBUG /******************************************************************//** Get the total number of words in the FTS for a particular FTS index. diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 52aa43384f7..c6d9909a6fc 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -3829,11 +3829,11 @@ next_rec: DBUG_EXECUTE_IF("ib_trunc_sleep_before_fts_cache_clear", os_thread_sleep(10000000);); - table->fts->fts_status |= TABLE_DICT_LOCKED; + table->fts->dict_locked = true; fts_update_next_doc_id(trx, table, 0); fts_cache_clear(table->fts->cache); fts_cache_init(table->fts->cache); - table->fts->fts_status &= ~TABLE_DICT_LOCKED; + table->fts->dict_locked = false; } } @@ -4434,8 +4434,7 @@ do_drop: /* Need to set TABLE_DICT_LOCKED bit, since fts_que_graph_free_check_lock would try to acquire dict mutex lock */ - table->fts->fts_status |= TABLE_DICT_LOCKED; - + table->fts->dict_locked = true; fts_free(table); } diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index 06de737a5b3..76d501aad53 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -1062,27 +1062,16 @@ trx_finalize_for_fts_table( { fts_t* fts = ftt->table->fts; fts_doc_ids_t* doc_ids = ftt->added_doc_ids; + mem_heap_t* heap; - mutex_enter(&fts->bg_threads_mutex); + ut_a(fts->add_wq); - if (fts->fts_status & BG_THREAD_STOP) { - /* The table is about to be dropped, no use - adding anything to its work queue. */ + heap = static_cast(doc_ids->self_heap->arg); - mutex_exit(&fts->bg_threads_mutex); - } else { - mem_heap_t* heap; - mutex_exit(&fts->bg_threads_mutex); - - ut_a(fts->add_wq); - - heap = static_cast(doc_ids->self_heap->arg); + ib_wqueue_add(fts->add_wq, doc_ids, heap); - ib_wqueue_add(fts->add_wq, doc_ids, heap); - - /* fts_trx_table_t no longer owns the list. */ - ftt->added_doc_ids = NULL; - } + /* fts_trx_table_t no longer owns the list. */ + ftt->added_doc_ids = NULL; } /******************************************************************//** diff --git a/storage/xtradb/dict/dict0dict.cc b/storage/xtradb/dict/dict0dict.cc index 73d255f7adc..73e4fe6bb5b 100644 --- a/storage/xtradb/dict/dict0dict.cc +++ b/storage/xtradb/dict/dict0dict.cc @@ -2921,33 +2921,6 @@ dict_table_copy_types( } } -/******************************************************************** -Wait until all the background threads of the given table have exited, i.e., -bg_threads == 0. Note: bg_threads_mutex must be reserved when -calling this. */ -UNIV_INTERN -void -dict_table_wait_for_bg_threads_to_exit( -/*===================================*/ - dict_table_t* table, /*< in: table */ - ulint delay) /*< in: time in microseconds to wait between - checks of bg_threads. */ -{ - fts_t* fts = table->fts; - -#ifdef UNIV_SYNC_DEBUG - ut_ad(mutex_own(&fts->bg_threads_mutex)); -#endif /* UNIV_SYNC_DEBUG */ - - while (fts->bg_threads > 0) { - mutex_exit(&fts->bg_threads_mutex); - - os_thread_sleep(delay); - - mutex_enter(&fts->bg_threads_mutex); - } -} - /*******************************************************************//** Builds the internal dictionary cache representation for a clustered index, containing also system fields not defined by the user. diff --git a/storage/xtradb/fts/fts0config.cc b/storage/xtradb/fts/fts0config.cc index 940c944a436..b39d568575c 100644 --- a/storage/xtradb/fts/fts0config.cc +++ b/storage/xtradb/fts/fts0config.cc @@ -224,8 +224,7 @@ fts_config_set_value( pars_info_bind_varchar_literal(info, "value", value->f_str, value->f_len); - const bool dict_locked = fts_table->table->fts->fts_status - & TABLE_DICT_LOCKED; + const bool dict_locked = fts_table->table->fts->dict_locked; fts_table->suffix = "CONFIG"; fts_get_table_name(fts_table, table_name, dict_locked); diff --git a/storage/xtradb/fts/fts0fts.cc b/storage/xtradb/fts/fts0fts.cc index 264c520bb1e..1cf5c818a9e 100644 --- a/storage/xtradb/fts/fts0fts.cc +++ b/storage/xtradb/fts/fts0fts.cc @@ -458,7 +458,7 @@ fts_load_user_stopword( dberr_t error = DB_SUCCESS; ibool ret = TRUE; trx_t* trx; - ibool has_lock = fts->fts_status & TABLE_DICT_LOCKED; + ibool has_lock = fts->dict_locked; trx = trx_allocate_for_background(); trx->op_info = "Load user stopword table into FTS cache"; @@ -933,18 +933,16 @@ fts_que_graph_free_check_lock( const fts_index_cache_t*index_cache, /*!< in: FTS index cache */ que_t* graph) /*!< in: query graph */ { - ibool has_dict = FALSE; + bool has_dict = FALSE; if (fts_table && fts_table->table) { ut_ad(fts_table->table->fts); - has_dict = fts_table->table->fts->fts_status - & TABLE_DICT_LOCKED; + has_dict = fts_table->table->fts->dict_locked; } else if (index_cache) { ut_ad(index_cache->index->table->fts); - has_dict = index_cache->index->table->fts->fts_status - & TABLE_DICT_LOCKED; + has_dict = index_cache->index->table->fts->dict_locked; } if (!has_dict) { @@ -2831,7 +2829,7 @@ fts_update_sync_doc_id( pars_info_bind_varchar_literal(info, "doc_id", id, id_len); fts_get_table_name(&fts_table, fts_name, - table->fts->fts_status & TABLE_DICT_LOCKED); + table->fts->dict_locked); pars_info_bind_id(info, true, "table_name", fts_name); graph = fts_parse_sql( @@ -2947,7 +2945,7 @@ fts_delete( into cache from last crash (delete Doc will not initialize the sync). Avoid any added counter accounting until the FTS cache is re-established and sync-ed */ - if (table->fts->fts_status & ADDED_TABLE_SYNCED + if (table->fts->added_synced && doc_id > cache->synced_doc_id) { mutex_enter(&table->fts->cache->deleted_lock); @@ -3385,7 +3383,7 @@ fts_add_doc_by_id( /* If Doc ID has been supplied by the user, then the table might not yet be sync-ed */ - if (!(ftt->table->fts->fts_status & ADDED_TABLE_SYNCED)) { + if (!ftt->table->fts->added_synced) { fts_init_index(ftt->table, FALSE); } @@ -4933,7 +4931,7 @@ fts_init_doc_id( fts_init_index((dict_table_t*) table, TRUE); } - table->fts->fts_status |= ADDED_TABLE_SYNCED; + table->fts->added_synced = true; table->fts->cache->first_doc_id = max_doc_id; @@ -5386,69 +5384,6 @@ fts_cache_append_deleted_doc_ids( mutex_exit((ib_mutex_t*) &cache->deleted_lock); } -/*********************************************************************//** -Wait for the background thread to start. We poll to detect change -of state, which is acceptable, since the wait should happen only -once during startup. -@return true if the thread started else FALSE (i.e timed out) */ -UNIV_INTERN -ibool -fts_wait_for_background_thread_to_start( -/*====================================*/ - dict_table_t* table, /*!< in: table to which the thread - is attached */ - ulint max_wait) /*!< in: time in microseconds, if - set to 0 then it disables - timeout checking */ -{ - ulint count = 0; - ibool done = FALSE; - - ut_a(max_wait == 0 || max_wait >= FTS_MAX_BACKGROUND_THREAD_WAIT); - - for (;;) { - fts_t* fts = table->fts; - - mutex_enter(&fts->bg_threads_mutex); - - if (fts->fts_status & BG_THREAD_READY) { - - done = TRUE; - } - - mutex_exit(&fts->bg_threads_mutex); - - if (!done) { - os_thread_sleep(FTS_MAX_BACKGROUND_THREAD_WAIT); - - if (max_wait > 0) { - - max_wait -= FTS_MAX_BACKGROUND_THREAD_WAIT; - - /* We ignore the residual value. */ - if (max_wait < FTS_MAX_BACKGROUND_THREAD_WAIT) { - break; - } - } - - ++count; - } else { - break; - } - - if (count >= FTS_BACKGROUND_THREAD_WAIT_COUNT) { - ut_print_timestamp(stderr); - fprintf(stderr, " InnoDB: Error the background thread " - "for the FTS table %s refuses to start\n", - table->name); - - count = 0; - } - } - - return(done); -} - /*********************************************************************//** Add the FTS document id hidden column. */ UNIV_INTERN @@ -5589,42 +5524,6 @@ fts_free( table->fts = NULL; } -/*********************************************************************//** -Signal FTS threads to initiate shutdown. */ -UNIV_INTERN -void -fts_start_shutdown( -/*===============*/ - dict_table_t* table, /*!< in: table with FTS indexes */ - fts_t* fts) /*!< in: fts instance that needs - to be informed about shutdown */ -{ - mutex_enter(&fts->bg_threads_mutex); - - fts->fts_status |= BG_THREAD_STOP; - - mutex_exit(&fts->bg_threads_mutex); - -} - -/*********************************************************************//** -Wait for FTS threads to shutdown. */ -UNIV_INTERN -void -fts_shutdown( -/*=========*/ - dict_table_t* table, /*!< in: table with FTS indexes */ - fts_t* fts) /*!< in: fts instance to shutdown */ -{ - mutex_enter(&fts->bg_threads_mutex); - - ut_a(fts->fts_status & BG_THREAD_STOP); - - dict_table_wait_for_bg_threads_to_exit(table, 20000); - - mutex_exit(&fts->bg_threads_mutex); -} - /*********************************************************************//** Take a FTS savepoint. */ UNIV_INLINE @@ -7639,7 +7538,7 @@ fts_init_index( } rw_lock_x_unlock(&cache->init_lock); - if (table->fts->fts_status & ADDED_TABLE_SYNCED) { + if (table->fts->added_synced) { goto func_exit; } @@ -7681,7 +7580,7 @@ fts_init_index( } } - table->fts->fts_status |= ADDED_TABLE_SYNCED; + table->fts->added_synced = true; fts_get_docs_clear(cache->get_docs); diff --git a/storage/xtradb/fts/fts0opt.cc b/storage/xtradb/fts/fts0opt.cc index 553c6ff392b..4472482da81 100644 --- a/storage/xtradb/fts/fts0opt.cc +++ b/storage/xtradb/fts/fts0opt.cc @@ -2628,6 +2628,10 @@ UNIV_INTERN void fts_optimize_add_table(dict_table_t* table) msg = fts_optimize_create_msg(FTS_MSG_ADD_TABLE, table); ib_wqueue_add(fts_optimize_wq, msg, msg->heap); + + mutex_enter(&table->fts->bg_threads_mutex); + table->fts->in_queue = true; + mutex_exit(&table->fts->bg_threads_mutex); } /**********************************************************************//** @@ -2656,6 +2660,15 @@ fts_optimize_remove_table( return; } + fts_t* fts = table->fts; + mutex_enter(&fts->bg_threads_mutex); + bool is_in_optimize_queue = fts->in_queue; + mutex_exit(&fts->bg_threads_mutex); + + if (!is_in_optimize_queue) { + return; + } + msg = fts_optimize_create_msg(FTS_MSG_DEL_TABLE, NULL); /* We will wait on this event until signalled by the consumer. */ @@ -2673,6 +2686,10 @@ fts_optimize_remove_table( os_event_wait(event); os_event_free(event); + + mutex_enter(&fts->bg_threads_mutex); + fts->in_queue = false; + mutex_exit(&fts->bg_threads_mutex); } /** Send sync fts cache for the table. @@ -2706,6 +2723,10 @@ fts_optimize_request_sync_table( msg->ptr = table_id; ib_wqueue_add(fts_optimize_wq, msg, msg->heap); + + mutex_enter(&table->fts->bg_threads_mutex); + table->fts->in_queue = true; + mutex_exit(&table->fts->bg_threads_mutex); } /** Add a table to fts_slots if it doesn't already exist. */ @@ -2850,6 +2871,10 @@ static void fts_optimize_sync_table(table_id_t table_id) fts_sync_table(table, true, false, false); } + DBUG_EXECUTE_IF( + "ib_optimize_wq_hang", + os_thread_sleep(6000000);); + dict_table_close(table, FALSE, FALSE); } } diff --git a/storage/xtradb/fts/fts0sql.cc b/storage/xtradb/fts/fts0sql.cc index 258164415f4..2c91115281b 100644 --- a/storage/xtradb/fts/fts0sql.cc +++ b/storage/xtradb/fts/fts0sql.cc @@ -165,8 +165,7 @@ fts_parse_sql( str = ut_str3cat(fts_sql_begin, sql, fts_sql_end); dict_locked = (fts_table && fts_table->table->fts - && (fts_table->table->fts->fts_status - & TABLE_DICT_LOCKED)); + && fts_table->table->fts->dict_locked); if (!dict_locked) { ut_ad(!mutex_own(&(dict_sys->mutex))); diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index b5002187e3b..55e231ef770 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -10640,10 +10640,10 @@ ha_innobase::ft_init_ext( return(NULL); } - if (!(ft_table->fts->fts_status & ADDED_TABLE_SYNCED)) { + if (!(ft_table->fts->added_synced)) { fts_init_index(ft_table, FALSE); - ft_table->fts->fts_status |= ADDED_TABLE_SYNCED; + ft_table->fts->added_synced = true; } error = fts_query(trx, index, flags, query, query_len, &result); diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc index 12257ec0f8f..e1b2dcd2441 100644 --- a/storage/xtradb/handler/handler0alter.cc +++ b/storage/xtradb/handler/handler0alter.cc @@ -3252,15 +3252,13 @@ op_ok: goto error_handling; } - ctx->new_table->fts->fts_status - |= TABLE_DICT_LOCKED; + ctx->new_table->fts->dict_locked = true; error = innobase_fts_load_stopword( ctx->new_table, ctx->trx, ctx->prebuilt->trx->mysql_thd) ? DB_SUCCESS : DB_ERROR; - ctx->new_table->fts->fts_status - &= ~TABLE_DICT_LOCKED; + ctx->new_table->fts->dict_locked = false; if (error != DB_SUCCESS) { goto error_handling; @@ -5642,6 +5640,7 @@ commit_cache_norebuild( || (index->type & DICT_CORRUPT)); DBUG_ASSERT(index->table->fts); + DEBUG_SYNC_C("norebuild_fts_drop"); fts_drop_index(index->table, index, trx); } diff --git a/storage/xtradb/include/dict0dict.h b/storage/xtradb/include/dict0dict.h index dde8368a0ce..783578eb91c 100644 --- a/storage/xtradb/include/dict0dict.h +++ b/storage/xtradb/include/dict0dict.h @@ -1015,18 +1015,6 @@ dict_table_copy_types( dtuple_t* tuple, /*!< in/out: data tuple */ const dict_table_t* table) /*!< in: table */ MY_ATTRIBUTE((nonnull)); -/******************************************************************** -Wait until all the background threads of the given table have exited, i.e., -bg_threads == 0. Note: bg_threads_mutex must be reserved when -calling this. */ -UNIV_INTERN -void -dict_table_wait_for_bg_threads_to_exit( -/*===================================*/ - dict_table_t* table, /* in: table */ - ulint delay) /* in: time in microseconds to wait between - checks of bg_threads. */ - MY_ATTRIBUTE((nonnull)); /**********************************************************************//** Looks for an index with the given id. NOTE that we do not reserve the dictionary mutex: this function is for emergency purposes like diff --git a/storage/xtradb/include/fts0fts.h b/storage/xtradb/include/fts0fts.h index a1fab659732..9c70157a0c8 100644 --- a/storage/xtradb/include/fts0fts.h +++ b/storage/xtradb/include/fts0fts.h @@ -279,40 +279,21 @@ struct fts_table_t { index auxiliary table */ }; -enum fts_status { - BG_THREAD_STOP = 1, /*!< TRUE if the FTS background thread - has finished reading the ADDED table, - meaning more items can be added to - the table. */ - - BG_THREAD_READY = 2, /*!< TRUE if the FTS background thread - is ready */ - - ADD_THREAD_STARTED = 4, /*!< TRUE if the FTS add thread - has started */ - - ADDED_TABLE_SYNCED = 8, /*!< TRUE if the ADDED table record is - sync-ed after crash recovery */ - - TABLE_DICT_LOCKED = 16 /*!< Set if the table has - dict_sys->mutex */ -}; - -typedef enum fts_status fts_status_t; - /** The state of the FTS sub system. */ struct fts_t { /*!< mutex protecting bg_threads* and fts_add_wq. */ ib_mutex_t bg_threads_mutex; - ulint bg_threads; /*!< number of background threads - accessing this table */ - - /*!< TRUE if background threads running - should stop themselves */ - ulint fts_status; /*!< Status bit regarding fts - running state */ + /* Whether the table was added to fts_optimize_wq(); + protected by bg_threads mutex */ + unsigned in_queue:1; + /* Whether the ADDED table record sync-ed afer + crash recovery; protected by bg_threads mutex */ + unsigned added_synced:1; + /* Whether the table hold dict_sys->mutex; + protected by bg_threads mutex */ + unsigned dict_locked:1; ib_wqueue_t* add_wq; /*!< Work queue for scheduling jobs for the FTS 'Add' thread, or NULL @@ -614,28 +595,6 @@ void fts_startup(void); /*==============*/ -/******************************************************************//** -Signal FTS threads to initiate shutdown. */ -UNIV_INTERN -void -fts_start_shutdown( -/*===============*/ - dict_table_t* table, /*!< in: table with FTS - indexes */ - fts_t* fts); /*!< in: fts instance to - shutdown */ - -/******************************************************************//** -Wait for FTS threads to shutdown. */ -UNIV_INTERN -void -fts_shutdown( -/*=========*/ - dict_table_t* table, /*!< in: table with FTS - indexes */ - fts_t* fts); /*!< in: fts instance to - shutdown */ - /******************************************************************//** Create an instance of fts_t. @return instance of fts_t */ diff --git a/storage/xtradb/include/fts0priv.h b/storage/xtradb/include/fts0priv.h index 266534c9511..1622eaa07ae 100644 --- a/storage/xtradb/include/fts0priv.h +++ b/storage/xtradb/include/fts0priv.h @@ -521,20 +521,6 @@ fts_cache_append_deleted_doc_ids( const fts_cache_t* cache, /*!< in: cache to use */ ib_vector_t* vector); /*!< in: append to this vector */ -/******************************************************************//** -Wait for the background thread to start. We poll to detect change -of state, which is acceptable, since the wait should happen only -once during startup. -@return true if the thread started else FALSE (i.e timed out) */ -UNIV_INTERN -ibool -fts_wait_for_background_thread_to_start( -/*====================================*/ - dict_table_t* table, /*!< in: table to which the thread - is attached */ - ulint max_wait); /*!< in: time in microseconds, if set - to 0 then it disables timeout - checking */ #ifdef FTS_DOC_STATS_DEBUG /******************************************************************//** Get the total number of words in the FTS for a particular FTS index. diff --git a/storage/xtradb/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc index 34a91b9e5fd..b5bd626db63 100644 --- a/storage/xtradb/row/row0mysql.cc +++ b/storage/xtradb/row/row0mysql.cc @@ -3839,11 +3839,11 @@ next_rec: DBUG_EXECUTE_IF("ib_trunc_sleep_before_fts_cache_clear", os_thread_sleep(10000000);); - table->fts->fts_status |= TABLE_DICT_LOCKED; + table->fts->dict_locked = true; fts_update_next_doc_id(trx, table, 0); fts_cache_clear(table->fts->cache); fts_cache_init(table->fts->cache); - table->fts->fts_status &= ~TABLE_DICT_LOCKED; + table->fts->dict_locked = false; } } @@ -4444,8 +4444,7 @@ do_drop: /* Need to set TABLE_DICT_LOCKED bit, since fts_que_graph_free_check_lock would try to acquire dict mutex lock */ - table->fts->fts_status |= TABLE_DICT_LOCKED; - + table->fts->dict_locked = true; fts_free(table); } diff --git a/storage/xtradb/trx/trx0trx.cc b/storage/xtradb/trx/trx0trx.cc index e072976d6cd..a65132cf572 100644 --- a/storage/xtradb/trx/trx0trx.cc +++ b/storage/xtradb/trx/trx0trx.cc @@ -1269,27 +1269,16 @@ trx_finalize_for_fts_table( { fts_t* fts = ftt->table->fts; fts_doc_ids_t* doc_ids = ftt->added_doc_ids; + mem_heap_t* heap; - mutex_enter(&fts->bg_threads_mutex); + ut_a(fts->add_wq); - if (fts->fts_status & BG_THREAD_STOP) { - /* The table is about to be dropped, no use - adding anything to its work queue. */ + heap = static_cast(doc_ids->self_heap->arg); - mutex_exit(&fts->bg_threads_mutex); - } else { - mem_heap_t* heap; - mutex_exit(&fts->bg_threads_mutex); - - ut_a(fts->add_wq); - - heap = static_cast(doc_ids->self_heap->arg); + ib_wqueue_add(fts->add_wq, doc_ids, heap); - ib_wqueue_add(fts->add_wq, doc_ids, heap); - - /* fts_trx_table_t no longer owns the list. */ - ftt->added_doc_ids = NULL; - } + /* fts_trx_table_t no longer owns the list. */ + ftt->added_doc_ids = NULL; } /******************************************************************//** -- cgit v1.2.1 From 13c2fd36c18cbd23ae33bba538982ebceae04ac6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Otto=20Kek=C3=A4l=C3=A4inen?= Date: Sun, 2 Jun 2019 12:05:53 +0300 Subject: Deb: Implement proper version detection in maintainer scripts Fixes bug introduced in commit 5415002. Using script run-time filename does not always work. One cannot assume that the filename is always the same as there might be temporary file names used by dpkg in certain situations. See Debian #920415. The same fix has been successfully in use in Debian official packages since February 2019: https://salsa.debian.org/mariadb-team/mariadb-10.3/commit/6440c0d6e75 --- debian/mariadb-server-10.1.postinst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/debian/mariadb-server-10.1.postinst b/debian/mariadb-server-10.1.postinst index 5382d3d0690..2a92cbe81db 100644 --- a/debian/mariadb-server-10.1.postinst +++ b/debian/mariadb-server-10.1.postinst @@ -2,16 +2,16 @@ . /usr/share/debconf/confmodule -# assume the filename is /path/to/mariadb-server-##.#.postinst -VER=${0: -13:4} +# Automatically set version to ease maintenance of this file +MAJOR_VER="${DPKG_MAINTSCRIPT_PACKAGE#mariadb-server-}" if [ -n "$DEBIAN_SCRIPT_DEBUG" ]; then set -v -x; DEBIAN_SCRIPT_TRACE=1; fi ${DEBIAN_SCRIPT_TRACE:+ echo "#42#DEBUG# RUNNING $0 $*" 1>&2 } - + export PATH=$PATH:/sbin:/usr/sbin:/bin:/usr/bin # This command can be used as pipe to syslog. With "-s" it also logs to stderr. -ERR_LOGGER="logger -p daemon.err -t mariadb-server-$VER.postinst -i" +ERR_LOGGER="logger -p daemon.err -t mariadb-server-$MAJOR_VER.postinst -i" # This will make an error in a logged command immediately apparent by aborting # the install, rather than failing silently and leaving a broken install. set -o pipefail @@ -134,8 +134,8 @@ EOF db_set mysql-server/postrm_remove_database false || true # To avoid downgrades. - touch $mysql_statedir/debian-$VER.flag - + touch $mysql_statedir/debian-$MAJOR_VER.flag + ## On every reconfiguration the maintenance user is recreated. # # - It is easier to regenerate the password every time but as people -- cgit v1.2.1 From 273d8eb12c40a6dcd05a8148bdfba3f1fd96e764 Mon Sep 17 00:00:00 2001 From: Varun Gupta Date: Wed, 18 Sep 2019 01:59:29 +0530 Subject: MDEV-20589: Server still crashes in Field::set_warning_truncated_wrong_value The flag is_stat_field is not set for the min_value and max_value of field items inside table share. This is a must requirement as we don't want to throw warnings of truncation when we read values from the statistics table to the column statistics of table share fields. --- mysql-test/r/stat_tables.result | 23 +++++++++++++++++++++++ mysql-test/r/stat_tables_innodb.result | 23 +++++++++++++++++++++++ mysql-test/t/stat_tables.test | 22 ++++++++++++++++++++++ sql/field.cc | 14 ++------------ sql/field.h | 1 - sql/sql_statistics.cc | 4 +++- 6 files changed, 73 insertions(+), 14 deletions(-) diff --git a/mysql-test/r/stat_tables.result b/mysql-test/r/stat_tables.result index c47a47cea31..bb3a0a80f7e 100644 --- a/mysql-test/r/stat_tables.result +++ b/mysql-test/r/stat_tables.result @@ -802,5 +802,28 @@ set use_stat_tables=@save_use_stat_tables; set @@histogram_size= @save_histogram_size; set @@optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; drop table t1; +# +# MDEV-20589: Server still crashes in Field::set_warning_truncated_wrong_value +# +set names utf8; +create table t1 ( a varchar(255) character set utf8); +insert into t1 values (REPEAT('ำฅ',255)), (REPEAT('รง',255)); +set use_stat_tables='preferably'; +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +set @save_sql_mode= @@sql_mode; +set sql_mode='ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'; +update mysql.column_stats set min_value= REPEAT('ำฅ',256) where db_name='test' and table_name='t1'; +Warnings: +Warning 1265 Data truncated for column 'min_value' at row 1 +set @@sql_mode= @save_sql_mode; +select length(a) from t1 where a=REPEAT('ำฅ',255); +length(a) +510 +set names latin1; +set @@use_stat_tables=@save_use_stat_tables; +drop table t1; # please keep this at the last set @@global.histogram_size=@save_histogram_size; diff --git a/mysql-test/r/stat_tables_innodb.result b/mysql-test/r/stat_tables_innodb.result index dcfdb55f9c9..a436efb5fea 100644 --- a/mysql-test/r/stat_tables_innodb.result +++ b/mysql-test/r/stat_tables_innodb.result @@ -829,6 +829,29 @@ set use_stat_tables=@save_use_stat_tables; set @@histogram_size= @save_histogram_size; set @@optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; drop table t1; +# +# MDEV-20589: Server still crashes in Field::set_warning_truncated_wrong_value +# +set names utf8; +create table t1 ( a varchar(255) character set utf8); +insert into t1 values (REPEAT('ำฅ',255)), (REPEAT('รง',255)); +set use_stat_tables='preferably'; +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +set @save_sql_mode= @@sql_mode; +set sql_mode='ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'; +update mysql.column_stats set min_value= REPEAT('ำฅ',256) where db_name='test' and table_name='t1'; +Warnings: +Warning 1265 Data truncated for column 'min_value' at row 1 +set @@sql_mode= @save_sql_mode; +select length(a) from t1 where a=REPEAT('ำฅ',255); +length(a) +510 +set names latin1; +set @@use_stat_tables=@save_use_stat_tables; +drop table t1; # please keep this at the last set @@global.histogram_size=@save_histogram_size; set optimizer_switch=@save_optimizer_switch_for_stat_tables_test; diff --git a/mysql-test/t/stat_tables.test b/mysql-test/t/stat_tables.test index 880e6378ca5..4c21e21ea70 100644 --- a/mysql-test/t/stat_tables.test +++ b/mysql-test/t/stat_tables.test @@ -546,5 +546,27 @@ set @@histogram_size= @save_histogram_size; set @@optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; drop table t1; +--echo # +--echo # MDEV-20589: Server still crashes in Field::set_warning_truncated_wrong_value +--echo # + +set names utf8; +create table t1 ( a varchar(255) character set utf8); +insert into t1 values (REPEAT('ำฅ',255)), (REPEAT('รง',255)); + +set use_stat_tables='preferably'; +analyze table t1 persistent for all; + +set @save_sql_mode= @@sql_mode; +set sql_mode='ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'; +update mysql.column_stats set min_value= REPEAT('ำฅ',256) where db_name='test' and table_name='t1'; +set @@sql_mode= @save_sql_mode; + +select length(a) from t1 where a=REPEAT('ำฅ',255); + +set names latin1; +set @@use_stat_tables=@save_use_stat_tables; +drop table t1; + --echo # please keep this at the last set @@global.histogram_size=@save_histogram_size; diff --git a/sql/field.cc b/sql/field.cc index 2b1ba0e1372..fd4cd8d5c54 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -2436,14 +2436,14 @@ Field *Field::clone(MEM_ROOT *root, TABLE *new_table) } - Field *Field::clone(MEM_ROOT *root, TABLE *new_table, my_ptrdiff_t diff, bool stat_flag) { Field *tmp; if ((tmp= (Field*) memdup_root(root,(char*) this,size_of()))) { - tmp->init(new_table); + if (new_table) + tmp->init(new_table); tmp->move_field_offset(diff); } tmp->is_stat_field= stat_flag; @@ -2451,16 +2451,6 @@ Field *Field::clone(MEM_ROOT *root, TABLE *new_table, my_ptrdiff_t diff, } -Field *Field::clone(MEM_ROOT *root, my_ptrdiff_t diff) -{ - Field *tmp; - if ((tmp= (Field*) memdup_root(root,(char*) this,size_of()))) - { - tmp->move_field_offset(diff); - } - return tmp; -} - int Field::set_default() { if (default_value) diff --git a/sql/field.h b/sql/field.h index 19a716cfd5d..3f027868c3c 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1220,7 +1220,6 @@ public: Field *clone(MEM_ROOT *mem_root, TABLE *new_table); Field *clone(MEM_ROOT *mem_root, TABLE *new_table, my_ptrdiff_t diff, bool stat_flag= FALSE); - Field *clone(MEM_ROOT *mem_root, my_ptrdiff_t diff); inline void move_field(uchar *ptr_arg,uchar *null_ptr_arg,uchar null_bit_arg) { ptr=ptr_arg; null_ptr=null_ptr_arg; null_bit=null_bit_arg; diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index 26032d8d535..578d3fac641 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -1153,12 +1153,14 @@ public: case COLUMN_STAT_MIN_VALUE: table_field->read_stats->min_value->set_notnull(); stat_field->val_str(&val); + DBUG_ASSERT(table_field->read_stats->min_value->is_stat_field); table_field->read_stats->min_value->store(val.ptr(), val.length(), &my_charset_bin); break; case COLUMN_STAT_MAX_VALUE: table_field->read_stats->max_value->set_notnull(); stat_field->val_str(&val); + DBUG_ASSERT(table_field->read_stats->min_value->is_stat_field); table_field->read_stats->max_value->store(val.ptr(), val.length(), &my_charset_bin); break; @@ -2045,7 +2047,7 @@ void create_min_max_statistical_fields_for_table_share(THD *thd, Field *fld; Field *table_field= *field_ptr; my_ptrdiff_t diff= record - table_share->default_values; - if (!(fld= table_field->clone(&stats_cb->mem_root, diff))) + if (!(fld= table_field->clone(&stats_cb->mem_root, NULL, diff, TRUE))) continue; if (i == 0) table_field->read_stats->min_value= fld; -- cgit v1.2.1 From a624b99f91fa059c392b11a56eabf96c76618543 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 18 Sep 2019 12:17:09 +0300 Subject: Remove an unused declaration --- storage/innobase/include/fts0fts.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/storage/innobase/include/fts0fts.h b/storage/innobase/include/fts0fts.h index fa657b72e70..5c6ad09a827 100644 --- a/storage/innobase/include/fts0fts.h +++ b/storage/innobase/include/fts0fts.h @@ -247,13 +247,6 @@ struct fts_doc_ids_t { doc_ids vector */ }; -// FIXME: Get rid of this if possible. -/** Since MySQL's character set support for Unicode is woefully inadequate -(it supports basic operations like isalpha etc. only for 8-bit characters), -we have to implement our own. We use UTF-16 without surrogate processing -as our in-memory format. This typedef is a single such character. */ -typedef unsigned short ib_uc_t; - /** An UTF-16 ro UTF-8 string. */ struct fts_string_t { byte* f_str; /*!< string, not necessary terminated in -- cgit v1.2.1 From 24859049c6b2d0b6f83f1f93ced15414d7266fb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 18 Sep 2019 16:04:43 +0300 Subject: MDEV-20485: Disable galera.galera_var_node_address --- mysql-test/suite/galera/disabled.def | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index d97b7a1ff14..4af2513076e 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -26,6 +26,7 @@ galera_ist_mariabackup : MDEV-18829 test leaves port open galera_ist_progress : MDEV-15236 fails when trying to read transfer status galera_migrate : MariaDB does not support START SLAVE USER galera_ssl_upgrade : MDEV-19950 Galera test failure on galera_ssl_upgrade +galera_var_node_address : MDEV-20485 Galera test failure galera_wan : MDEV-17259 Test failure on galera.galera_wan partition : MDEV-19958 Galera test failure on galera.partition -query_cache: MDEV-15805 Test failure on galera.query_cache \ No newline at end of file +query_cache: MDEV-15805 Test failure on galera.query_cache -- cgit v1.2.1 From b3a7c07eae000f20c62812ecf7a8b9349aedc8a1 Mon Sep 17 00:00:00 2001 From: Stepan Patryshev Date: Wed, 18 Sep 2019 16:50:46 +0300 Subject: Enable galera.MW-286 test case. --- mysql-test/suite/galera/disabled.def | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index 4af2513076e..f6853e35ca3 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -5,12 +5,11 @@ # Separate the test case name and the comment with ':'. # # : MDEV- -# +# # Do not use any TAB characters for whitespace. # ############################################################################## -MW-286 : MDEV-19992 Galera test failure on MW-286 MW-329 : MDEV-19962 Galera test failure on MW-329 MW-388: MDEV-19803 Long semaphore wait error on galera.MW-388 galera_account_management : MariaDB 10.0 does not support ALTER USER -- cgit v1.2.1 From f94d9ab9f8f03585f01f426e2479833a292527c4 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Wed, 18 Sep 2019 20:19:03 +0530 Subject: MDEV-20483 Follow-up fix At commit, trx->lock.table_locks (which is a cache of trx_locks) can consist of NULL pointers. Add a debug assertion for that, and clear the vector. --- storage/innobase/trx/trx0trx.cc | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index 88fe5e548a9..869fe08a6ba 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -561,6 +561,8 @@ inline void trx_t::release_locks() if (UT_LIST_GET_LEN(lock.trx_locks)) lock_trx_release_locks(this); + else + lock.table_locks.clear(); } /********************************************************************//** @@ -1681,6 +1683,16 @@ trx_commit_in_memory( DBUG_LOG("trx", "Autocommit in memory: " << trx); trx->state = TRX_STATE_NOT_STARTED; } else { +#ifdef UNIV_DEBUG + if (!UT_LIST_GET_LEN(trx->lock.trx_locks)) { + for (lock_list::iterator it + = trx->lock.table_locks.begin(); + it != trx->lock.table_locks.end(); + it++) { + ut_ad(!*it); + } + } +#endif /* UNIV_DEBUG */ trx_mutex_enter(trx); trx->commit_state(); trx_mutex_exit(trx); -- cgit v1.2.1 From c0db3fe6dabd2cb0df9bf532f54f9e8d233fa499 Mon Sep 17 00:00:00 2001 From: Simon Lipp Date: Mon, 27 May 2019 13:52:27 +0200 Subject: MDEV-18438 Don't stream xtrabackup_info of extra-lsndir --- extra/mariabackup/backup_copy.cc | 3 +- extra/mariabackup/backup_mysql.cc | 43 ++++++++++++++++++---- extra/mariabackup/backup_mysql.h | 3 +- extra/mariabackup/xtrabackup.cc | 2 +- .../suite/mariabackup/extra_lsndir_stream.result | 2 + .../suite/mariabackup/extra_lsndir_stream.test | 7 ++++ mysql-test/suite/mariabackup/mdev-18438.result | 1 + mysql-test/suite/mariabackup/mdev-18438.test | 11 ++++++ 8 files changed, 62 insertions(+), 10 deletions(-) create mode 100644 mysql-test/suite/mariabackup/extra_lsndir_stream.result create mode 100644 mysql-test/suite/mariabackup/extra_lsndir_stream.test create mode 100644 mysql-test/suite/mariabackup/mdev-18438.result create mode 100644 mysql-test/suite/mariabackup/mdev-18438.test diff --git a/extra/mariabackup/backup_copy.cc b/extra/mariabackup/backup_copy.cc index 28e5728bd3e..1db5eb16a52 100644 --- a/extra/mariabackup/backup_copy.cc +++ b/extra/mariabackup/backup_copy.cc @@ -1610,7 +1610,8 @@ bool backup_finish() return(false); } - if (!write_xtrabackup_info(mysql_connection, XTRABACKUP_INFO, opt_history != 0)) { + if (!write_xtrabackup_info(mysql_connection, XTRABACKUP_INFO, + opt_history != 0, true)) { return(false); } diff --git a/extra/mariabackup/backup_mysql.cc b/extra/mariabackup/backup_mysql.cc index 4c29b1e10c9..843ebf2663e 100644 --- a/extra/mariabackup/backup_mysql.cc +++ b/extra/mariabackup/backup_mysql.cc @@ -1472,9 +1472,12 @@ PERCONA_SCHEMA.xtrabackup_history and writes a new history record to the table containing all the history info particular to the just completed backup. */ bool -write_xtrabackup_info(MYSQL *connection, const char * filename, bool history) +write_xtrabackup_info(MYSQL *connection, const char * filename, bool history, + bool stream) { + bool result = true; + FILE *fp = NULL; char *uuid = NULL; char *server_version = NULL; char buf_start_time[100]; @@ -1500,7 +1503,8 @@ write_xtrabackup_info(MYSQL *connection, const char * filename, bool history) || xtrabackup_databases_exclude ); - backup_file_printf(filename, + char *buf = NULL; + int buf_len = asprintf(&buf, "uuid = %s\n" "name = %s\n" "tool_name = %s\n" @@ -1512,8 +1516,8 @@ write_xtrabackup_info(MYSQL *connection, const char * filename, bool history) "end_time = %s\n" "lock_time = %d\n" "binlog_pos = %s\n" - "innodb_from_lsn = %llu\n" - "innodb_to_lsn = %llu\n" + "innodb_from_lsn = " LSN_PF "\n" + "innodb_to_lsn = " LSN_PF "\n" "partial = %s\n" "incremental = %s\n" "format = %s\n" @@ -1530,12 +1534,34 @@ write_xtrabackup_info(MYSQL *connection, const char * filename, bool history) (int)history_lock_time, /* lock_time */ mysql_binlog_position ? mysql_binlog_position : "", /* binlog_pos */ - incremental_lsn, /* innodb_from_lsn */ - metadata_to_lsn, /* innodb_to_lsn */ + incremental_lsn, + /* innodb_from_lsn */ + metadata_to_lsn, + /* innodb_to_lsn */ is_partial? "Y" : "N", xtrabackup_incremental ? "Y" : "N", /* incremental */ xb_stream_name[xtrabackup_stream_fmt], /* format */ xtrabackup_compress ? "compressed" : "N"); /* compressed */ + if (buf_len < 0) { + msg("Error: cannot generate xtrabackup_info"); + result = false; + goto cleanup; + } + + if (stream) { + backup_file_printf(filename, "%s", buf); + } else { + fp = fopen(filename, "w"); + if (!fp) { + msg("Error: cannot open %s", filename); + result = false; + goto cleanup; + } + if (fwrite(buf, buf_len, 1, fp) < 1) { + result = false; + goto cleanup; + } + } if (!history) { goto cleanup; @@ -1597,8 +1623,11 @@ cleanup: free(uuid); free(server_version); + free(buf); + if (fp) + fclose(fp); - return(true); + return(result); } extern const char *innodb_checksum_algorithm_names[]; diff --git a/extra/mariabackup/backup_mysql.h b/extra/mariabackup/backup_mysql.h index e2c56f88a8c..b61fa2362c6 100644 --- a/extra/mariabackup/backup_mysql.h +++ b/extra/mariabackup/backup_mysql.h @@ -68,7 +68,8 @@ bool write_binlog_info(MYSQL *connection); bool -write_xtrabackup_info(MYSQL *connection, const char * filename, bool history); +write_xtrabackup_info(MYSQL *connection, const char * filename, bool history, + bool stream); bool write_backup_config_file(); diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index bc7149a87fd..46b67705700 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -3984,7 +3984,7 @@ static bool xtrabackup_backup_low() } sprintf(filename, "%s/%s", xtrabackup_extra_lsndir, XTRABACKUP_INFO); - if (!write_xtrabackup_info(mysql_connection, filename, false)) { + if (!write_xtrabackup_info(mysql_connection, filename, false, false)) { msg("Error: failed to write info " "to '%s'.", filename); return false; diff --git a/mysql-test/suite/mariabackup/extra_lsndir_stream.result b/mysql-test/suite/mariabackup/extra_lsndir_stream.result new file mode 100644 index 00000000000..a25c45a13d1 --- /dev/null +++ b/mysql-test/suite/mariabackup/extra_lsndir_stream.result @@ -0,0 +1,2 @@ +xtrabackup_checkpoints +xtrabackup_info diff --git a/mysql-test/suite/mariabackup/extra_lsndir_stream.test b/mysql-test/suite/mariabackup/extra_lsndir_stream.test new file mode 100644 index 00000000000..97023cb179d --- /dev/null +++ b/mysql-test/suite/mariabackup/extra_lsndir_stream.test @@ -0,0 +1,7 @@ +let $extra_lsndir=$MYSQLTEST_VARDIR/tmp/extra_lsndir; +mkdir $extra_lsndir; +--disable_result_log +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --stream=xbstream --extra-lsndir=$extra_lsndir > /dev/null; +--enable_result_log +list_files $extra_lsndir; +rmdir $extra_lsndir; diff --git a/mysql-test/suite/mariabackup/mdev-18438.result b/mysql-test/suite/mariabackup/mdev-18438.result new file mode 100644 index 00000000000..ab3b81bd484 --- /dev/null +++ b/mysql-test/suite/mariabackup/mdev-18438.result @@ -0,0 +1 @@ +stream.xb diff --git a/mysql-test/suite/mariabackup/mdev-18438.test b/mysql-test/suite/mariabackup/mdev-18438.test new file mode 100644 index 00000000000..a6ec45476ff --- /dev/null +++ b/mysql-test/suite/mariabackup/mdev-18438.test @@ -0,0 +1,11 @@ +let $basedir=$MYSQLTEST_VARDIR/tmp/mdev-18438; +mkdir $basedir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --extra-lsndir=$basedir/extra_lsndir --stream=xbstream > $basedir/stream.xb; +mkdir $basedir/backup; +rmdir $basedir/extra_lsndir; +--disable_result_log +exec $XBSTREAM -x -C $basedir/backup < $basedir/stream.xb; +--enable_result_log +rmdir $basedir/backup; +list_files $basedir; +rmdir $basedir; -- cgit v1.2.1 From 4afe9d4b6dbffcebe8f9e5842fb79f0ff22b5aa0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 20 Sep 2019 08:30:31 +0300 Subject: MDEV-16222: Move the test to gcol.innodb_virtual_debug_purge --- .../suite/gcol/r/innodb_virtual_debug_purge.result | 27 +++++++++ .../suite/gcol/t/innodb_virtual_debug_purge.opt | 1 + .../suite/gcol/t/innodb_virtual_debug_purge.test | 61 ++++++++++++++++++++ .../innodb/r/purge_secondary_mdev-16222.result | 30 ---------- .../suite/innodb/t/purge_secondary_mdev-16222.opt | 1 - .../suite/innodb/t/purge_secondary_mdev-16222.test | 67 ---------------------- 6 files changed, 89 insertions(+), 98 deletions(-) delete mode 100644 mysql-test/suite/innodb/r/purge_secondary_mdev-16222.result delete mode 100644 mysql-test/suite/innodb/t/purge_secondary_mdev-16222.opt delete mode 100644 mysql-test/suite/innodb/t/purge_secondary_mdev-16222.test diff --git a/mysql-test/suite/gcol/r/innodb_virtual_debug_purge.result b/mysql-test/suite/gcol/r/innodb_virtual_debug_purge.result index 08f8d2098f6..647ba47a880 100644 --- a/mysql-test/suite/gcol/r/innodb_virtual_debug_purge.result +++ b/mysql-test/suite/gcol/r/innodb_virtual_debug_purge.result @@ -204,5 +204,32 @@ connection truncate; disconnect truncate; connection default; DROP TABLE t1, t2; +# +# MDEV-16222 Assertion `0' failed in row_purge_remove_sec_if_poss_leaf +# on table with virtual columns and indexes +# +set @saved_dbug= @@global.debug_dbug; +set global debug_dbug= "+d,ib_purge_virtual_mdev_16222_1,ib_purge_virtual_mdev_16222_2"; +create table t1 ( +pk serial, vb tinyblob as (b) virtual, b tinyblob, +primary key(pk), index (vb(64))) +engine innodb; +insert ignore into t1 (b) values ('foo'); +select * into outfile 'load.data' from t1; +load data infile 'load.data' replace into table t1; +set debug_sync= "now WAIT_FOR latch_released TIMEOUT 1"; +set global debug_dbug= "-d,ib_purge_virtual_mdev_16222_1"; +drop table t1; +set debug_sync= "now SIGNAL drop_started WAIT_FOR got_no_such_table TIMEOUT 1"; +create table t1 ( +pk serial, vb tinyblob as (b) virtual, b tinyblob, +primary key(pk), index (vb(64))) +engine innodb; +insert ignore into t1 (b) values ('foo'); +select * into outfile 'load.data' from t1; +load data infile 'load.data' replace into table t1; +set debug_sync= "now WAIT_FOR got_no_such_table TIMEOUT 1"; +set global debug_dbug= @saved_dbug; +drop table t1; set debug_sync=reset; SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; diff --git a/mysql-test/suite/gcol/t/innodb_virtual_debug_purge.opt b/mysql-test/suite/gcol/t/innodb_virtual_debug_purge.opt index 9622465d71f..98a5a463ce4 100644 --- a/mysql-test/suite/gcol/t/innodb_virtual_debug_purge.opt +++ b/mysql-test/suite/gcol/t/innodb_virtual_debug_purge.opt @@ -1 +1,2 @@ --loose-innodb-safe-truncate=1 +--innodb-purge-threads=1 diff --git a/mysql-test/suite/gcol/t/innodb_virtual_debug_purge.test b/mysql-test/suite/gcol/t/innodb_virtual_debug_purge.test index 1541920d3ae..ee88789dec4 100644 --- a/mysql-test/suite/gcol/t/innodb_virtual_debug_purge.test +++ b/mysql-test/suite/gcol/t/innodb_virtual_debug_purge.test @@ -259,6 +259,67 @@ disconnect truncate; connection default; DROP TABLE t1, t2; +--echo # +--echo # MDEV-16222 Assertion `0' failed in row_purge_remove_sec_if_poss_leaf +--echo # on table with virtual columns and indexes +--echo # + +--let $datadir= `select @@datadir` +set @saved_dbug= @@global.debug_dbug; +set global debug_dbug= "+d,ib_purge_virtual_mdev_16222_1,ib_purge_virtual_mdev_16222_2"; + +create table t1 ( + pk serial, vb tinyblob as (b) virtual, b tinyblob, + primary key(pk), index (vb(64))) +engine innodb; + +insert ignore into t1 (b) values ('foo'); + +select * into outfile 'load.data' from t1; +load data infile 'load.data' replace into table t1; + +# FIXME: case does not work on 10.2 as it does not pass this condition: +# +# if (!*table) +# *table= innodb_find_table_for_vc(thd, index->table); +# +# in innobase_allocate_row_for_vcol() + +--disable_warnings +set debug_sync= "now WAIT_FOR latch_released TIMEOUT 1"; +--enable_warnings +set global debug_dbug= "-d,ib_purge_virtual_mdev_16222_1"; +drop table t1; +--remove_file $datadir/test/load.data + +--disable_warnings +set debug_sync= "now SIGNAL drop_started WAIT_FOR got_no_such_table TIMEOUT 1"; +--enable_warnings + +create table t1 ( + pk serial, vb tinyblob as (b) virtual, b tinyblob, + primary key(pk), index (vb(64))) +engine innodb; + +insert ignore into t1 (b) values ('foo'); + +select * into outfile 'load.data' from t1; +load data infile 'load.data' replace into table t1; + +--disable_warnings +set debug_sync= "now WAIT_FOR got_no_such_table TIMEOUT 1"; +--enable_warnings + +# FIXME: Race condition here: +# 1. purge thread goes into sending got_no_such_table +# 2. test thread finishes debug_sync= "RESET" below +# 3. purge thread sends got_no_such_table +set global debug_dbug= @saved_dbug; + +# cleanup +drop table t1; +--remove_file $datadir/test/load.data + --source include/wait_until_count_sessions.inc set debug_sync=reset; SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; diff --git a/mysql-test/suite/innodb/r/purge_secondary_mdev-16222.result b/mysql-test/suite/innodb/r/purge_secondary_mdev-16222.result deleted file mode 100644 index 6efadc16792..00000000000 --- a/mysql-test/suite/innodb/r/purge_secondary_mdev-16222.result +++ /dev/null @@ -1,30 +0,0 @@ -# -# MDEV-16222 Assertion `0' failed in row_purge_remove_sec_if_poss_leaf on table with virtual columns and indexes -# -set @saved_frequency= @@global.innodb_purge_rseg_truncate_frequency; -set global innodb_purge_rseg_truncate_frequency= 1; -set @saved_dbug= @@global.debug_dbug; -set global debug_dbug= "+d,ib_purge_virtual_mdev_16222_1,ib_purge_virtual_mdev_16222_2"; -create table t1 ( -pk serial, vb tinyblob as (b) virtual, b tinyblob, -primary key(pk), index (vb(64))) -engine innodb; -insert ignore into t1 (b) values ('foo'); -select * into outfile 'load.data' from t1; -load data infile 'load.data' replace into table t1; -set debug_sync= "now WAIT_FOR latch_released TIMEOUT 1"; -set global debug_dbug= "-d,ib_purge_virtual_mdev_16222_1"; -drop table t1; -set debug_sync= "now SIGNAL drop_started WAIT_FOR got_no_such_table TIMEOUT 1"; -create table t1 ( -pk serial, vb tinyblob as (b) virtual, b tinyblob, -primary key(pk), index (vb(64))) -engine innodb; -insert ignore into t1 (b) values ('foo'); -select * into outfile 'load.data' from t1; -load data infile 'load.data' replace into table t1; -set debug_sync= "now WAIT_FOR got_no_such_table TIMEOUT 1"; -set global debug_dbug= @saved_dbug; -drop table t1; -set global innodb_purge_rseg_truncate_frequency= @saved_frequency; -set debug_sync= "RESET"; diff --git a/mysql-test/suite/innodb/t/purge_secondary_mdev-16222.opt b/mysql-test/suite/innodb/t/purge_secondary_mdev-16222.opt deleted file mode 100644 index a1207721427..00000000000 --- a/mysql-test/suite/innodb/t/purge_secondary_mdev-16222.opt +++ /dev/null @@ -1 +0,0 @@ ---innodb-purge-threads=1 diff --git a/mysql-test/suite/innodb/t/purge_secondary_mdev-16222.test b/mysql-test/suite/innodb/t/purge_secondary_mdev-16222.test deleted file mode 100644 index ca0e4fad133..00000000000 --- a/mysql-test/suite/innodb/t/purge_secondary_mdev-16222.test +++ /dev/null @@ -1,67 +0,0 @@ ---source include/have_debug.inc ---source include/have_innodb.inc - ---echo # ---echo # MDEV-16222 Assertion `0' failed in row_purge_remove_sec_if_poss_leaf on table with virtual columns and indexes ---echo # - ---let $datadir= `select @@datadir` -set @saved_frequency= @@global.innodb_purge_rseg_truncate_frequency; -set global innodb_purge_rseg_truncate_frequency= 1; -set @saved_dbug= @@global.debug_dbug; -set global debug_dbug= "+d,ib_purge_virtual_mdev_16222_1,ib_purge_virtual_mdev_16222_2"; - -create table t1 ( - pk serial, vb tinyblob as (b) virtual, b tinyblob, - primary key(pk), index (vb(64))) -engine innodb; - -insert ignore into t1 (b) values ('foo'); - -select * into outfile 'load.data' from t1; -load data infile 'load.data' replace into table t1; - -# FIXME: case does not work on 10.2 as it does not pass this condition: -# -# if (!*table) -# *table= innodb_find_table_for_vc(thd, index->table); -# -# in innobase_allocate_row_for_vcol() - ---disable_warnings -set debug_sync= "now WAIT_FOR latch_released TIMEOUT 1"; ---enable_warnings -set global debug_dbug= "-d,ib_purge_virtual_mdev_16222_1"; -drop table t1; ---remove_file $datadir/test/load.data - ---disable_warnings -set debug_sync= "now SIGNAL drop_started WAIT_FOR got_no_such_table TIMEOUT 1"; ---enable_warnings - -create table t1 ( - pk serial, vb tinyblob as (b) virtual, b tinyblob, - primary key(pk), index (vb(64))) -engine innodb; - -insert ignore into t1 (b) values ('foo'); - -select * into outfile 'load.data' from t1; -load data infile 'load.data' replace into table t1; - ---disable_warnings -set debug_sync= "now WAIT_FOR got_no_such_table TIMEOUT 1"; ---enable_warnings - -# FIXME: Racing condition here: -# 1. purge thread goes into sending got_no_such_table -# 2. test thread finishes debug_sync= "RESET" below -# 3. purge thread sends got_no_such_table -set global debug_dbug= @saved_dbug; - -# cleanup -drop table t1; ---remove_file $datadir/test/load.data - -set global innodb_purge_rseg_truncate_frequency= @saved_frequency; -set debug_sync= "RESET"; -- cgit v1.2.1 From 75bcf1f9ad4a4bb5fa9cb8818abe6ace52e53d85 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Mon, 8 May 2017 16:36:37 +1000 Subject: MDEV-12646: systemd service file changes from Fedora Include comment header that describes overrides. Unit description now includes @VERSION@. After=syslog.target removed - redunant Add --basedir=@prefix to prevent /root/.my.cnf lookups. This is placed after $MYSQLD_OPTIONS in case a user sets a --{no,}default type options which has to be first in the mysqld arguements. Additional changes to multi instance (support-files/mariadb@.service.in): * added @SYSTEMD_EXECSTARTPRE@ / @SYSTEMD_EXECSTARTPOST@ * removed mariadb@bootstrap reference as galera_new_cluster as it's a little too proment. * use_galera_new_cluster.conf updated to override pre/post steps to ensure it has no side effects Signed-off-by: Daniel Black --- support-files/mariadb.service.in | 28 ++++++++++++++-------- support-files/mariadb@.service.in | 39 ++++++++++++++++++++----------- support-files/use_galera_new_cluster.conf | 3 +++ 3 files changed, 47 insertions(+), 23 deletions(-) diff --git a/support-files/mariadb.service.in b/support-files/mariadb.service.in index ef9fa5c2a22..e7976a8f3e2 100644 --- a/support-files/mariadb.service.in +++ b/support-files/mariadb.service.in @@ -1,23 +1,28 @@ +# It's not recommended to modify this file in-place, because it will be +# overwritten during package upgrades. If you want to customize, the +# best way is to create a file "/etc/systemd/system/mariadb.service", +# containing +# .include /usr/lib/systemd/system/mariadb.service +# ...make your changes here... +# or create a file "/etc/systemd/system/mariadb.service.d/foo.conf", +# which doesn't need to include ".include" call and which will be parsed +# after the file mariadb.service itself is parsed. # -# /etc/systemd/system/mariadb.service +# For more info about custom unit files, see systemd.unit(5) or +# https://mariadb.com/kb/en/mariadb/systemd/ +# +# Copyright notice: # # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; either version 2.1 of the License, or # (at your option) any later version. -# -# Thanks to: -# Daniel Black -# Erkan Yanar -# David Strauss -# and probably others [Unit] Description=MariaDB @VERSION@ database server Documentation=man:mysqld(8) Documentation=https://mariadb.com/kb/en/library/systemd/ After=network.target -After=syslog.target [Install] WantedBy=multi-user.target @@ -81,12 +86,15 @@ ExecStartPre=/bin/sh -c "[ ! -e @bindir@/galera_recovery ] && VAR= || \ # 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 -@SYSTEMD_EXECSTARTPOST@ +# Note: we set --basedir to prevent probes that might trigger SELinux alarms, +# per bug https://bugzilla.redhat.com/show_bug.cgi?id=547485 +ExecStart=@sbindir@/mysqld $MYSQLD_OPTS --basedir=@prefix@ $_WSREP_NEW_CLUSTER $_WSREP_START_POSITION # Unset _WSREP_START_POSITION environment variable. ExecStartPost=/bin/sh -c "systemctl unset-environment _WSREP_START_POSITION" +@SYSTEMD_EXECSTARTPOST@ + KillSignal=SIGTERM # Don't want to see an automated SIGKILL ever diff --git a/support-files/mariadb@.service.in b/support-files/mariadb@.service.in index 465a0d94c62..3d18daba491 100644 --- a/support-files/mariadb@.service.in +++ b/support-files/mariadb@.service.in @@ -1,29 +1,35 @@ # Multi instance version of mariadb. For if you run multiple versions at once. -# Also used for mariadb@bootstrap to bootstrap Galera. # -# create config file @sysconf2dir@/my{instancename}.cnf +# create config file @sysconf2dir@/my{instancename}.cnf to be used as the +# configuration file for this service. # # start as systemctl start mariadb@{instancename}.server - +# +# It's not recommended to modify this file in-place, because it will be +# overwritten during package upgrades. If you want to customize, the +# best way is to create a file "/etc/systemd/system/mariadb@.service", +# containing +# .include /usr/lib/systemd/system/mariadb@.service +# ...make your changes here... +# or create a file "/etc/systemd/system/mariadb@.service.d/foo.conf", +# which doesn't need to include ".include" call and which will be parsed +# after the file mariadb@.service itself is parsed. +# +# For more info about custom unit files, see systemd.unit(5) or +# https://mariadb.com/kb/en/mariadb/systemd/ +# +# Copyright notice: +# # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; either version 2.1 of the License, or # (at your option) any later version. -# -# Thanks to: -# Daniel Black -# Erkan Yanar -# David Strauss -# and probably others -# Inspired from https://gitweb.gentoo.org/repo/gentoo.git/tree/dev-db/mysql-init-scripts/files/mysqld_at.service [Unit] 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 - ConditionPathExists=@sysconf2dir@/my%I.cnf [Install] @@ -68,6 +74,8 @@ ProtectHome=true # Execute pre and post scripts as root, otherwise it does it as User= PermissionsStartOnly=true +@SYSTEMD_EXECSTARTPRE@ + # Perform automatic wsrep recovery. When server is started without wsrep, # galera_recovery simply returns an empty string. In any case, however, # the script is not expected to return with a non-zero status. @@ -95,9 +103,12 @@ ExecStartPre=/bin/sh -c "[ ! -e @bindir@/galera_recovery ] && VAR= || \ # This isn't a replacement for my.cnf. # _WSREP_NEW_CLUSTER is for the exclusive use of the script galera_new_cluster +# Note: we set --basedir to prevent probes that might trigger SELinux alarms, +# per bug https://bugzilla.redhat.com/show_bug.cgi?id=547485 +# # Note: Place $MYSQLD_OPTS at the very end for its options to take precedence. -ExecStart=@sbindir@/mysqld --defaults-file=@sysconf2dir@/my%I.cnf \ +ExecStart=@sbindir@/mysqld --defaults-file=@sysconf2dir@/my%I.cnf --basedir=@prefix@ \ $_WSREP_NEW_CLUSTER $_WSREP_START_POSITION%I $MYSQLD_OPTS # Alternate: (remove ConditionPathExists above) # use [mysqld.INSTANCENAME] as sections in my.cnf @@ -108,6 +119,8 @@ ExecStart=@sbindir@/mysqld --defaults-file=@sysconf2dir@/my%I.cnf \ # Unset _WSREP_START_POSITION environment variable. ExecStartPost=/bin/sh -c "systemctl unset-environment _WSREP_START_POSITION%I" +@SYSTEMD_EXECSTARTPOST@ + KillSignal=SIGTERM # Don't want to see an automated SIGKILL ever diff --git a/support-files/use_galera_new_cluster.conf b/support-files/use_galera_new_cluster.conf index 90e0365ffd8..4d8ad253ce5 100644 --- a/support-files/use_galera_new_cluster.conf +++ b/support-files/use_galera_new_cluster.conf @@ -15,8 +15,11 @@ ConditionPathExists= Type=oneshot Restart=no +ExecStartPre= + # Override the multi instance service for a bootstrap start instance ExecStart= ExecStart=/usr/bin/echo "Please use galera_new_cluster to start the mariadb service with --wsrep-new-cluster" ExecStart=/usr/bin/false +ExecStartPost= -- cgit v1.2.1 From 9611d7e08a9f69cd91dfa3b313c5ed1c324121d5 Mon Sep 17 00:00:00 2001 From: Caribe 1999 Date: Wed, 3 Jan 2018 11:27:20 +0100 Subject: Fix There's an annoying bug that prevents a Sphinx table to connect to a searchd using a host name. So the example table in the documentation https://mariadb.com/kb/en/library/about-sphinxse/#basic-usage that point's to "localhost" actually doesn't work. After some investigation I found two errors. The first one is a wrong check after the getaddrinfo call. The second is a wrong usage of the returned struct. --- storage/sphinx/ha_sphinx.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/storage/sphinx/ha_sphinx.cc b/storage/sphinx/ha_sphinx.cc index 65ad286f5d9..67bf0744c78 100644 --- a/storage/sphinx/ha_sphinx.cc +++ b/storage/sphinx/ha_sphinx.cc @@ -2162,7 +2162,7 @@ int ha_sphinx::Connect ( const char * sHost, ushort uPort ) #if MYSQL_VERSION_ID>=50515 struct addrinfo *hp = NULL; tmp_errno = getaddrinfo ( sHost, NULL, NULL, &hp ); - if ( !tmp_errno || !hp || !hp->ai_addr ) + if ( tmp_errno || !hp || !hp->ai_addr ) { bError = true; if ( hp ) @@ -2189,8 +2189,9 @@ int ha_sphinx::Connect ( const char * sHost, ushort uPort ) } #if MYSQL_VERSION_ID>=50515 - memcpy ( &sin.sin_addr, hp->ai_addr, Min ( sizeof(sin.sin_addr), (size_t)hp->ai_addrlen ) ); - freeaddrinfo ( hp ); + struct sockaddr_in *in = (sockaddr_in *)hp->ai_addr; + memcpy ( &sin.sin_addr, &in->sin_addr, Min ( sizeof(sin.sin_addr), sizeof(in->sin_addr) ) ); + freeaddrinfo ( hp ); #else memcpy ( &sin.sin_addr, hp->h_addr, Min ( sizeof(sin.sin_addr), (size_t)hp->h_length ) ); my_gethostbyname_r_free(); -- cgit v1.2.1 From fd5cd073cc5a65a1f713eaf830b21b1fb962834e Mon Sep 17 00:00:00 2001 From: Anel Husakovic Date: Wed, 8 May 2019 06:40:37 -0700 Subject: MDEV 19205 Sphinx unable to connect using a host name - Enable the test `sphinx.sphinx` which was disabled by MDEV 10986, comit ee0094d2fd48dac0c - Add test case to `sphinx.sphinx` to cover host as localhost instead of `127.0.0.1` - Add result file for single test --- storage/sphinx/mysql-test/sphinx/sphinx.result | 20 ++++++++++++++++++++ storage/sphinx/mysql-test/sphinx/sphinx.test | 13 +++++++++++++ 2 files changed, 33 insertions(+) diff --git a/storage/sphinx/mysql-test/sphinx/sphinx.result b/storage/sphinx/mysql-test/sphinx/sphinx.result index 3536ba42af8..c462d0cc883 100644 --- a/storage/sphinx/mysql-test/sphinx/sphinx.result +++ b/storage/sphinx/mysql-test/sphinx/sphinx.result @@ -75,3 +75,23 @@ id w q 1 2 test;range=meta.foo_count,100,500 5 1 test;range=meta.foo_count,100,500 drop table ts; +# +# MDEV-19205: Sphinx unable to connect using a host name +# +create table ts ( id bigint unsigned not null, w int not null, q varchar(255) not null, index(q) ) engine=sphinx connection="sphinx://localhost:SPHINXSEARCH_PORT/*"; +select * from ts where q=';filter=meta.foo_count,100'; +id w q +1 1 ;filter=meta.foo_count,100 +select * from ts where q='test;filter=meta.sub.int,7'; +id w q +5 1 test;filter=meta.sub.int,7 +select * from ts where q=';filter=meta.sub.list[0],4'; +id w q +select * from ts where q=';filter=meta.sub.list[1],4'; +id w q +5 1 ;filter=meta.sub.list[1],4 +select * from ts where q='test;range=meta.foo_count,100,500'; +id w q +1 2 test;range=meta.foo_count,100,500 +5 1 test;range=meta.foo_count,100,500 +drop table ts; diff --git a/storage/sphinx/mysql-test/sphinx/sphinx.test b/storage/sphinx/mysql-test/sphinx/sphinx.test index fe388f7ddd2..b733a3fc5ff 100644 --- a/storage/sphinx/mysql-test/sphinx/sphinx.test +++ b/storage/sphinx/mysql-test/sphinx/sphinx.test @@ -41,3 +41,16 @@ select * from ts where q=';filter=meta.sub.list[0],4'; select * from ts where q=';filter=meta.sub.list[1],4'; select * from ts where q='test;range=meta.foo_count,100,500'; drop table ts; + +--echo # +--echo # MDEV-19205: Sphinx unable to connect using a host name +--echo # + +--replace_result $SPHINXSEARCH_PORT SPHINXSEARCH_PORT +eval create table ts ( id bigint unsigned not null, w int not null, q varchar(255) not null, index(q) ) engine=sphinx connection="sphinx://localhost:$SPHINXSEARCH_PORT/*"; +select * from ts where q=';filter=meta.foo_count,100'; +select * from ts where q='test;filter=meta.sub.int,7'; +select * from ts where q=';filter=meta.sub.list[0],4'; +select * from ts where q=';filter=meta.sub.list[1],4'; +select * from ts where q='test;range=meta.foo_count,100,500'; +drop table ts; -- cgit v1.2.1 From 1ad79c818780aafe1aaf1c25bbf975eb31a38a40 Mon Sep 17 00:00:00 2001 From: Anel Husakovic Date: Tue, 18 Jun 2019 06:58:41 -0700 Subject: MDEV-19679 - CREATE SERVER needs tweaks for compatibility with CONNECT engine --- mysql-test/r/create_drop_server.result | 4 ++-- mysql-test/r/system_mysql_db.result | 4 ++-- mysql-test/r/system_mysql_db_fix40123.result | 4 ++-- mysql-test/suite/funcs_1/r/is_columns_mysql.result | 8 ++++---- mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result | 8 ++++---- mysql-test/suite/funcs_1/r/is_tables_mysql.result | 2 +- mysql-test/suite/funcs_1/r/is_tables_mysql_embedded.result | 4 ++-- scripts/mysql_system_tables.sql | 2 +- sql/sql_yacc.yy | 1 - 9 files changed, 18 insertions(+), 19 deletions(-) diff --git a/mysql-test/r/create_drop_server.result b/mysql-test/r/create_drop_server.result index 29c4fe7e123..4f5d13b3541 100644 --- a/mysql-test/r/create_drop_server.result +++ b/mysql-test/r/create_drop_server.result @@ -38,9 +38,9 @@ DROP SERVER server_1; CREATE SERVER server_1 FOREIGN DATA WRAPPER mysql OPTIONS (USER 'Remote', HOST 'Server.Example.Com', DATABASE 'test'); SELECT Host FROM mysql.servers WHERE Server_Name = 'server_1'; Host -server.example.com +Server.Example.Com ALTER SERVER server_1 OPTIONS(HOST 'Server.Example.Org'); SELECT Host FROM mysql.servers WHERE Server_Name = 'server_1'; Host -server.example.org +Server.Example.Org DROP SERVER server_1; diff --git a/mysql-test/r/system_mysql_db.result b/mysql-test/r/system_mysql_db.result index b88497dbd9b..444072fe23c 100644 --- a/mysql-test/r/system_mysql_db.result +++ b/mysql-test/r/system_mysql_db.result @@ -187,14 +187,14 @@ show create table servers; Table Create Table servers CREATE TABLE `servers` ( `Server_name` char(64) NOT NULL DEFAULT '', - `Host` char(64) NOT NULL DEFAULT '', + `Host` varchar(2048) NOT NULL DEFAULT '', `Db` char(64) NOT NULL DEFAULT '', `Username` char(80) NOT NULL DEFAULT '', `Password` char(64) NOT NULL DEFAULT '', `Port` int(4) NOT NULL DEFAULT 0, `Socket` char(64) NOT NULL DEFAULT '', `Wrapper` char(64) NOT NULL DEFAULT '', - `Owner` char(64) NOT NULL DEFAULT '', + `Owner` varchar(512) NOT NULL DEFAULT '', PRIMARY KEY (`Server_name`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='MySQL Foreign Servers table' show create table proc; diff --git a/mysql-test/r/system_mysql_db_fix40123.result b/mysql-test/r/system_mysql_db_fix40123.result index b88497dbd9b..444072fe23c 100644 --- a/mysql-test/r/system_mysql_db_fix40123.result +++ b/mysql-test/r/system_mysql_db_fix40123.result @@ -187,14 +187,14 @@ show create table servers; Table Create Table servers CREATE TABLE `servers` ( `Server_name` char(64) NOT NULL DEFAULT '', - `Host` char(64) NOT NULL DEFAULT '', + `Host` varchar(2048) NOT NULL DEFAULT '', `Db` char(64) NOT NULL DEFAULT '', `Username` char(80) NOT NULL DEFAULT '', `Password` char(64) NOT NULL DEFAULT '', `Port` int(4) NOT NULL DEFAULT 0, `Socket` char(64) NOT NULL DEFAULT '', `Wrapper` char(64) NOT NULL DEFAULT '', - `Owner` char(64) NOT NULL DEFAULT '', + `Owner` varchar(512) NOT NULL DEFAULT '', PRIMARY KEY (`Server_name`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='MySQL Foreign Servers table' show create table proc; diff --git a/mysql-test/suite/funcs_1/r/is_columns_mysql.result b/mysql-test/suite/funcs_1/r/is_columns_mysql.result index 25dbb185e44..69972256078 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_mysql.result +++ b/mysql-test/suite/funcs_1/r/is_columns_mysql.result @@ -173,8 +173,8 @@ def mysql roles_mapping Host 1 '' NO char 60 180 NULL NULL NULL utf8 utf8_bin ch def mysql roles_mapping Role 3 '' NO char 80 240 NULL NULL NULL utf8 utf8_bin char(80) PRI select,insert,update,references NEVER NULL def mysql roles_mapping User 2 '' NO char 80 240 NULL NULL NULL utf8 utf8_bin char(80) PRI select,insert,update,references NEVER NULL def mysql servers Db 3 '' NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) select,insert,update,references NEVER NULL -def mysql servers Host 2 '' NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) select,insert,update,references NEVER NULL -def mysql servers Owner 9 '' NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) select,insert,update,references NEVER NULL +def mysql servers Host 2 '' NO varchar 2048 6144 NULL NULL NULL utf8 utf8_general_ci varchar(2048) select,insert,update,references NEVER NULL +def mysql servers Owner 9 '' NO varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512) select,insert,update,references NEVER NULL def mysql servers Password 5 '' NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) select,insert,update,references NEVER NULL def mysql servers Port 6 0 NO int NULL NULL 10 0 NULL NULL NULL int(4) select,insert,update,references NEVER NULL def mysql servers Server_name 1 '' NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) PRI select,insert,update,references NEVER NULL @@ -508,14 +508,14 @@ NULL mysql proxies_priv Timestamp timestamp NULL NULL NULL NULL timestamp 3.0000 mysql roles_mapping Role char 80 240 utf8 utf8_bin char(80) 3.0000 mysql roles_mapping Admin_option enum 1 3 utf8 utf8_general_ci enum('N','Y') 3.0000 mysql servers Server_name char 64 192 utf8 utf8_general_ci char(64) -3.0000 mysql servers Host char 64 192 utf8 utf8_general_ci char(64) +3.0000 mysql servers Host varchar 2048 6144 utf8 utf8_general_ci varchar(2048) 3.0000 mysql servers Db char 64 192 utf8 utf8_general_ci char(64) 3.0000 mysql servers Username char 80 240 utf8 utf8_general_ci char(80) 3.0000 mysql servers Password char 64 192 utf8 utf8_general_ci char(64) NULL mysql servers Port int NULL NULL NULL NULL int(4) 3.0000 mysql servers Socket char 64 192 utf8 utf8_general_ci char(64) 3.0000 mysql servers Wrapper char 64 192 utf8 utf8_general_ci char(64) -3.0000 mysql servers Owner char 64 192 utf8 utf8_general_ci char(64) +3.0000 mysql servers Owner varchar 512 1536 utf8 utf8_general_ci varchar(512) NULL mysql slow_log start_time timestamp NULL NULL NULL NULL timestamp(6) 1.0000 mysql slow_log user_host mediumtext 16777215 16777215 utf8 utf8_general_ci mediumtext NULL mysql slow_log query_time time NULL NULL NULL NULL time(6) diff --git a/mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result b/mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result index 22b4ddfc311..87ff00d346f 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result +++ b/mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result @@ -159,8 +159,8 @@ def mysql roles_mapping Host 1 '' NO char 60 180 NULL NULL NULL utf8 utf8_bin ch def mysql roles_mapping Role 3 '' NO char 80 240 NULL NULL NULL utf8 utf8_bin char(80) PRI NEVER NULL def mysql roles_mapping User 2 '' NO char 80 240 NULL NULL NULL utf8 utf8_bin char(80) PRI NEVER NULL def mysql servers Db 3 '' NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) NEVER NULL -def mysql servers Host 2 '' NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) NEVER NULL -def mysql servers Owner 9 '' NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) NEVER NULL +def mysql servers Host 2 '' NO varchar 2048 6144 NULL NULL NULL utf8 utf8_general_ci varchar(2048) NEVER NULL +def mysql servers Owner 9 '' NO varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512) NEVER NULL def mysql servers Password 5 '' NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) NEVER NULL def mysql servers Port 6 0 NO int NULL NULL 10 0 NULL NULL NULL int(4) NEVER NULL def mysql servers Server_name 1 '' NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) PRI NEVER NULL @@ -492,14 +492,14 @@ NULL mysql proxies_priv Timestamp timestamp NULL NULL NULL NULL timestamp 3.0000 mysql roles_mapping Role char 80 240 utf8 utf8_bin char(80) 3.0000 mysql roles_mapping Admin_option enum 1 3 utf8 utf8_general_ci enum('N','Y') 3.0000 mysql servers Server_name char 64 192 utf8 utf8_general_ci char(64) -3.0000 mysql servers Host char 64 192 utf8 utf8_general_ci char(64) +3.0000 mysql servers Host varchar 2048 6144 utf8 utf8_general_ci varchar(2048) 3.0000 mysql servers Db char 64 192 utf8 utf8_general_ci char(64) 3.0000 mysql servers Username char 80 240 utf8 utf8_general_ci char(80) 3.0000 mysql servers Password char 64 192 utf8 utf8_general_ci char(64) NULL mysql servers Port int NULL NULL NULL NULL int(4) 3.0000 mysql servers Socket char 64 192 utf8 utf8_general_ci char(64) 3.0000 mysql servers Wrapper char 64 192 utf8 utf8_general_ci char(64) -3.0000 mysql servers Owner char 64 192 utf8 utf8_general_ci char(64) +3.0000 mysql servers Owner varchar 512 1536 utf8 utf8_general_ci varchar(512) NULL mysql slow_log start_time timestamp NULL NULL NULL NULL timestamp(6) 1.0000 mysql slow_log user_host mediumtext 16777215 16777215 utf8 utf8_general_ci mediumtext NULL mysql slow_log query_time time NULL NULL NULL NULL time(6) diff --git a/mysql-test/suite/funcs_1/r/is_tables_mysql.result b/mysql-test/suite/funcs_1/r/is_tables_mysql.result index 8e0c9b64dab..81eca31f35d 100644 --- a/mysql-test/suite/funcs_1/r/is_tables_mysql.result +++ b/mysql-test/suite/funcs_1/r/is_tables_mysql.result @@ -476,7 +476,7 @@ TABLE_NAME servers TABLE_TYPE BASE TABLE ENGINE MYISAM_OR_MARIA VERSION 10 -ROW_FORMAT Fixed +ROW_FORMAT DYNAMIC_OR_PAGE TABLE_ROWS #TBLR# AVG_ROW_LENGTH #ARL# DATA_LENGTH #DL# diff --git a/mysql-test/suite/funcs_1/r/is_tables_mysql_embedded.result b/mysql-test/suite/funcs_1/r/is_tables_mysql_embedded.result index f40294491cc..d81b16e6e8e 100644 --- a/mysql-test/suite/funcs_1/r/is_tables_mysql_embedded.result +++ b/mysql-test/suite/funcs_1/r/is_tables_mysql_embedded.result @@ -476,7 +476,7 @@ TABLE_NAME servers TABLE_TYPE BASE TABLE ENGINE MYISAM_OR_MARIA VERSION 10 -ROW_FORMAT Fixed +ROW_FORMAT DYNAMIC_OR_PAGE TABLE_ROWS #TBLR# AVG_ROW_LENGTH #ARL# DATA_LENGTH #DL# @@ -1180,7 +1180,7 @@ TABLE_NAME servers TABLE_TYPE BASE TABLE ENGINE MYISAM_OR_MARIA VERSION 10 -ROW_FORMAT Fixed +ROW_FORMAT DYNAMIC_OR_PAGE TABLE_ROWS #TBLR# AVG_ROW_LENGTH #ARL# DATA_LENGTH #DL# diff --git a/scripts/mysql_system_tables.sql b/scripts/mysql_system_tables.sql index 252b5e611fe..7a5f472bd57 100644 --- a/scripts/mysql_system_tables.sql +++ b/scripts/mysql_system_tables.sql @@ -46,7 +46,7 @@ CREATE TABLE IF NOT EXISTS func ( name char(64) binary DEFAULT '' NOT NULL, ret CREATE TABLE IF NOT EXISTS plugin ( name varchar(64) DEFAULT '' NOT NULL, dl varchar(128) DEFAULT '' NOT NULL, PRIMARY KEY (name) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_general_ci comment='MySQL plugins'; -CREATE TABLE IF NOT EXISTS servers ( Server_name char(64) NOT NULL DEFAULT '', Host char(64) NOT NULL DEFAULT '', Db char(64) NOT NULL DEFAULT '', Username char(80) NOT NULL DEFAULT '', Password char(64) NOT NULL DEFAULT '', Port INT(4) NOT NULL DEFAULT '0', Socket char(64) NOT NULL DEFAULT '', Wrapper char(64) NOT NULL DEFAULT '', Owner char(64) NOT NULL DEFAULT '', PRIMARY KEY (Server_name)) CHARACTER SET utf8 comment='MySQL Foreign Servers table'; +CREATE TABLE IF NOT EXISTS servers ( Server_name char(64) NOT NULL DEFAULT '', Host varchar(2048) NOT NULL DEFAULT '', Db char(64) NOT NULL DEFAULT '', Username char(80) NOT NULL DEFAULT '', Password char(64) NOT NULL DEFAULT '', Port INT(4) NOT NULL DEFAULT '0', Socket char(64) NOT NULL DEFAULT '', Wrapper char(64) NOT NULL DEFAULT '', Owner varchar(512) NOT NULL DEFAULT '', PRIMARY KEY (Server_name)) CHARACTER SET utf8 comment='MySQL Foreign Servers table'; CREATE TABLE IF NOT EXISTS tables_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(80) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Grantor char(141) DEFAULT '' NOT NULL, Timestamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Table privileges'; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 468729b9bf9..ba349e478b8 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -2668,7 +2668,6 @@ server_option: { MYSQL_YYABORT_UNLESS(Lex->server_options.host.str == 0); Lex->server_options.host= $2; - my_casedn_str(system_charset_info, Lex->server_options.host.str); } | DATABASE TEXT_STRING_sys { -- cgit v1.2.1 From 6a7d51b1cb338081aa111f3ec774aaf4d90c994b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vicen=C8=9Biu=20Ciorbaru?= Date: Sat, 21 Sep 2019 01:04:07 +0300 Subject: MDEV-19211 Fix mysqld_safe --dry-run mysqld_safe --dry-run needs to either call exit or return, depending if it is being sourced or not, otherise return can lead to the error: return: can only `return' from a function or sourced script The original fix suggestion was proposed by FaramosCZ --- scripts/mysqld_safe.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh index d51867d9d17..85f66fed075 100644 --- a/scripts/mysqld_safe.sh +++ b/scripts/mysqld_safe.sh @@ -970,7 +970,13 @@ do cmd="$cmd "`shell_quote_string "$i"` done cmd="$cmd $args" -[ $dry_run -eq 1 ] && return + +if [ $dry_run -eq 1 ] +then + # RETURN or EXIT depending if the script is being sourced or not. + (return 2> /dev/null) && return || exit +fi + # Avoid 'nohup: ignoring input' warning test -n "$NOHUP_NICENESS" && cmd="$cmd < /dev/null" -- cgit v1.2.1 From ba7725dace48d403187eb2a418a2081703fe5c9d Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Fri, 20 Sep 2019 15:59:54 -0700 Subject: MDEV-20229 CTE defined with table value constructor cannot be used in views A CTE can be defined as a table values constructor. In this case the CTE is always materialized in a temporary table. If the definition of the CTE contains a list of the names of the CTE columns then the query expression that uses this CTE can refer to the CTE columns by these names. Otherwise the names of the columns are taken from the names of the columns in the result set of the query that specifies the CTE. Thus if the column names of a CTE are provided in the definition the columns of result set should be renamed. In a general case renaming of the columns is done in the select lists of the query specifying the CTE. If a CTE is specified by a table value constructor then there are no such select lists and renaming is actually done for the columns of the result of materialization. Now if a view is specified by a query expression that uses a CTE specified by a table value constructor saving the column names of the CTE in the stored view definition becomes critical: without these names the query expression is not able to refer to the columns of the CTE. This patch saves the given column names of CTEs in stored view definitions that use them. --- mysql-test/main/cte_nonrecursive.result | 4 ++-- mysql-test/main/cte_recursive.result | 6 +++--- mysql-test/main/table_value_constr.result | 13 +++++++++++++ mysql-test/main/table_value_constr.test | 10 ++++++++++ sql/sql_cte.cc | 16 ++++++++++++++++ sql/sql_union.cc | 1 + 6 files changed, 45 insertions(+), 5 deletions(-) diff --git a/mysql-test/main/cte_nonrecursive.result b/mysql-test/main/cte_nonrecursive.result index 69494d0c602..d6904b8a70a 100644 --- a/mysql-test/main/cte_nonrecursive.result +++ b/mysql-test/main/cte_nonrecursive.result @@ -606,7 +606,7 @@ with t(c) as (select a from t1 where b >= 'c') select * from t r1 where r1.c=4; show create view v3; View Create View character_set_client collation_connection -v3 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v3` AS with t as (select `t1`.`a` AS `c` from `t1` where `t1`.`b` >= 'c')select `r1`.`c` AS `c` from `t` `r1` where `r1`.`c` = 4 latin1 latin1_swedish_ci +v3 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v3` AS with t(c) as (select `t1`.`a` AS `c` from `t1` where `t1`.`b` >= 'c')select `r1`.`c` AS `c` from `t` `r1` where `r1`.`c` = 4 latin1 latin1_swedish_ci select * from v3; c 4 @@ -618,7 +618,7 @@ with t(c) as (select a from t1 where b >= 'c') select * from t r1, t r2 where r1.c=r2.c and r2.c=4; show create view v4; View Create View character_set_client collation_connection -v4 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v4` AS with t as (select `test`.`t1`.`a` AS `c` from `test`.`t1` where `test`.`t1`.`b` >= 'c')select `r1`.`c` AS `c`,`r2`.`c` AS `d` from (`t` `r1` join (select `test`.`t1`.`a` AS `c` from `test`.`t1` where `test`.`t1`.`b` >= 'c') `r2`) where `r1`.`c` = `r2`.`c` and `r2`.`c` = 4 latin1 latin1_swedish_ci +v4 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v4` AS with t(c) as (select `test`.`t1`.`a` AS `c` from `test`.`t1` where `test`.`t1`.`b` >= 'c')select `r1`.`c` AS `c`,`r2`.`c` AS `d` from (`t` `r1` join (select `test`.`t1`.`a` AS `c` from `test`.`t1` where `test`.`t1`.`b` >= 'c') `r2`) where `r1`.`c` = `r2`.`c` and `r2`.`c` = 4 latin1 latin1_swedish_ci select * from v4; c d 4 4 diff --git a/mysql-test/main/cte_recursive.result b/mysql-test/main/cte_recursive.result index f2ae9929145..9b2aa2b27b8 100644 --- a/mysql-test/main/cte_recursive.result +++ b/mysql-test/main/cte_recursive.result @@ -699,7 +699,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 5 RECURSIVE UNION p ALL NULL NULL NULL NULL 12 100.00 Using where; Using join buffer (flat, BNL join) NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL Warnings: -Note 1003 with recursive ancestor_couple_ids as (/* select#2 */ select `a`.`father` AS `h_id`,`a`.`mother` AS `w_id` from `coupled_ancestors` `a` where `a`.`father` is not null and `a`.`mother` is not null), coupled_ancestors as (/* select#3 */ select `test`.`folks`.`id` AS `id`,`test`.`folks`.`name` AS `name`,`test`.`folks`.`dob` AS `dob`,`test`.`folks`.`father` AS `father`,`test`.`folks`.`mother` AS `mother` from `test`.`folks` where `test`.`folks`.`name` = 'Me' union all /* select#4 */ select `test`.`p`.`id` AS `id`,`test`.`p`.`name` AS `name`,`test`.`p`.`dob` AS `dob`,`test`.`p`.`father` AS `father`,`test`.`p`.`mother` AS `mother` from `test`.`folks` `p` join `ancestor_couple_ids` `fa` where `test`.`p`.`id` = `fa`.`h_id` union all /* select#5 */ select `test`.`p`.`id` AS `id`,`test`.`p`.`name` AS `name`,`test`.`p`.`dob` AS `dob`,`test`.`p`.`father` AS `father`,`test`.`p`.`mother` AS `mother` from `test`.`folks` `p` join `ancestor_couple_ids` `ma` where `test`.`p`.`id` = `ma`.`w_id`)/* select#1 */ select `h`.`name` AS `name`,`h`.`dob` AS `dob`,`w`.`name` AS `name`,`w`.`dob` AS `dob` from `ancestor_couple_ids` `c` join `coupled_ancestors` `h` join `coupled_ancestors` `w` where `h`.`id` = `c`.`h_id` and `w`.`id` = `c`.`w_id` +Note 1003 with recursive ancestor_couple_ids(h_id,w_id) as (/* select#2 */ select `a`.`father` AS `h_id`,`a`.`mother` AS `w_id` from `coupled_ancestors` `a` where `a`.`father` is not null and `a`.`mother` is not null), coupled_ancestors(id,name,dob,father,mother) as (/* select#3 */ select `test`.`folks`.`id` AS `id`,`test`.`folks`.`name` AS `name`,`test`.`folks`.`dob` AS `dob`,`test`.`folks`.`father` AS `father`,`test`.`folks`.`mother` AS `mother` from `test`.`folks` where `test`.`folks`.`name` = 'Me' union all /* select#4 */ select `test`.`p`.`id` AS `id`,`test`.`p`.`name` AS `name`,`test`.`p`.`dob` AS `dob`,`test`.`p`.`father` AS `father`,`test`.`p`.`mother` AS `mother` from `test`.`folks` `p` join `ancestor_couple_ids` `fa` where `test`.`p`.`id` = `fa`.`h_id` union all /* select#5 */ select `test`.`p`.`id` AS `id`,`test`.`p`.`name` AS `name`,`test`.`p`.`dob` AS `dob`,`test`.`p`.`father` AS `father`,`test`.`p`.`mother` AS `mother` from `test`.`folks` `p` join `ancestor_couple_ids` `ma` where `test`.`p`.`id` = `ma`.`w_id`)/* select#1 */ select `h`.`name` AS `name`,`h`.`dob` AS `dob`,`w`.`name` AS `name`,`w`.`dob` AS `dob` from `ancestor_couple_ids` `c` join `coupled_ancestors` `h` join `coupled_ancestors` `w` where `h`.`id` = `c`.`h_id` and `w`.`id` = `c`.`w_id` # simple mutual recursion with recursive ancestor_couple_ids(h_id, w_id) @@ -3091,7 +3091,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 4 DEPENDENT SUBQUERY ALL NULL NULL NULL NULL 16 100.00 Using where NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL Warnings: -Note 1003 with recursive destinations as (/* select#2 */ select `test`.`a`.`arrival` AS `city`,1 AS `legs` from `test`.`flights` `a` where `test`.`a`.`departure` = 'Cairo' union /* select#3 */ select `test`.`b`.`arrival` AS `arrival`,`r`.`legs` + 1 AS `r.legs + 1` from `destinations` `r` join `test`.`flights` `b` where `r`.`city` = `test`.`b`.`departure` and !(`test`.`b`.`arrival`,(/* select#4 */ select `destinations`.`city` from `destinations` where trigcond(`test`.`b`.`arrival` = `destinations`.`city` or `destinations`.`city` is null) having trigcond(`destinations`.`city` is null))))/* select#1 */ select `destinations`.`city` AS `city`,`destinations`.`legs` AS `legs` from `destinations` +Note 1003 with recursive destinations(city,legs) as (/* select#2 */ select `test`.`a`.`arrival` AS `city`,1 AS `legs` from `test`.`flights` `a` where `test`.`a`.`departure` = 'Cairo' union /* select#3 */ select `test`.`b`.`arrival` AS `arrival`,`r`.`legs` + 1 AS `r.legs + 1` from `destinations` `r` join `test`.`flights` `b` where `r`.`city` = `test`.`b`.`departure` and !(`test`.`b`.`arrival`,(/* select#4 */ select `destinations`.`city` from `destinations` where trigcond(`test`.`b`.`arrival` = `destinations`.`city` or `destinations`.`city` is null) having trigcond(`destinations`.`city` is null))))/* select#1 */ select `destinations`.`city` AS `city`,`destinations`.`legs` AS `legs` from `destinations` set standard_compliant_cte=default; drop table flights; # @@ -3378,7 +3378,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 3 RECURSIVE UNION ALL NULL NULL NULL NULL 2 100.00 Using where NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL Warnings: -Note 1003 with recursive rcte as (/* select#2 */ select 1 AS `a` union /* select#3 */ select cast(`rcte`.`a` + 1 as unsigned) AS `cast(a+1 as unsigned)` from `rcte` where `rcte`.`a` < 10), cte1 as (/* select#4 */ select count(0) AS `c1` from `rcte` join `test`.`t1` where `rcte`.`a` between 3 and 5 and `test`.`t1`.`id` = `rcte`.`a` - 3), cte2 as (/* select#5 */ select count(0) AS `c2` from `rcte` join `test`.`t1` where `rcte`.`a` between 7 and 8 and `test`.`t1`.`id` = `rcte`.`a` - 7)/* select#1 */ select `cte1`.`c1` AS `c1`,`cte2`.`c2` AS `c2` from `cte1` join `cte2` +Note 1003 with recursive rcte(a) as (/* select#2 */ select 1 AS `a` union /* select#3 */ select cast(`rcte`.`a` + 1 as unsigned) AS `cast(a+1 as unsigned)` from `rcte` where `rcte`.`a` < 10), cte1 as (/* select#4 */ select count(0) AS `c1` from `rcte` join `test`.`t1` where `rcte`.`a` between 3 and 5 and `test`.`t1`.`id` = `rcte`.`a` - 3), cte2 as (/* select#5 */ select count(0) AS `c2` from `rcte` join `test`.`t1` where `rcte`.`a` between 7 and 8 and `test`.`t1`.`id` = `rcte`.`a` - 7)/* select#1 */ select `cte1`.`c1` AS `c1`,`cte2`.`c2` AS `c2` from `cte1` join `cte2` prepare stmt from "with recursive rcte(a) as (select 1 union select cast(a+1 as unsigned) from rcte where a < 10), diff --git a/mysql-test/main/table_value_constr.result b/mysql-test/main/table_value_constr.result index 6356d4ecd75..03e378e68f2 100644 --- a/mysql-test/main/table_value_constr.result +++ b/mysql-test/main/table_value_constr.result @@ -2586,3 +2586,16 @@ create view v1 as union ( values (5), (7), (1), (3), (4) order by 2 limit 2 ); ERROR 42S22: Unknown column '2' in 'order clause' +# +# MDEV-20229: view defined as select using +# CTE with named columns defined as TVC +# +create view v1 as with t(a) as (values (2), (1)) select a from t; +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 with t(a) as (values (2),(1))select `t`.`a` AS `a` from `t` latin1 latin1_swedish_ci +select * from v1; +a +2 +1 +drop view v1; diff --git a/mysql-test/main/table_value_constr.test b/mysql-test/main/table_value_constr.test index 6b89816cc0c..4464eb7b77b 100644 --- a/mysql-test/main/table_value_constr.test +++ b/mysql-test/main/table_value_constr.test @@ -1316,3 +1316,13 @@ create view v1 as ( values (5), (7), (1), (3), (4) limit 2 offset 1 ) union ( values (5), (7), (1), (3), (4) order by 2 limit 2 ); + +--echo # +--echo # MDEV-20229: view defined as select using +--echo # CTE with named columns defined as TVC +--echo # + +create view v1 as with t(a) as (values (2), (1)) select a from t; +show create view v1; +select * from v1; +drop view v1; diff --git a/sql/sql_cte.cc b/sql/sql_cte.cc index 247d7e5a3d1..08d5e20f99a 100644 --- a/sql/sql_cte.cc +++ b/sql/sql_cte.cc @@ -1430,6 +1430,22 @@ void With_clause::print(String *str, enum_query_type query_type) void With_element::print(String *str, enum_query_type query_type) { str->append(query_name); + if (column_list.elements) + { + List_iterator_fast li(column_list); + str->append('('); + for (LEX_CSTRING *col_name= li++; ; ) + { + str->append(col_name); + col_name= li++; + if (!col_name) + { + str->append(')'); + break; + } + str->append(','); + } + } str->append(STRING_WITH_LEN(" as ")); str->append('('); spec->print(str, query_type); diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 6ab2619e8e2..c119f1e0116 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -1858,6 +1858,7 @@ bool st_select_lex_unit::cleanup() DBUG_RETURN(FALSE); } } + columns_are_renamed= false; cleaned= 1; for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select()) -- cgit v1.2.1 From 7a4019a1c7bcefceef9b6c2624c89088db3991cc Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Fri, 1 Mar 2019 10:00:27 +0100 Subject: MDEV-19207 systemd service: add instance name in description The unit files made systemd print: systemd[1]: Started MariaDB 10.3.13 database server (multi-instance). Let's add the instance name, so starting mariadb@foo.service makes it print: systemd[1]: Started MariaDB 10.3.13 database server (multi-instance foo). --- support-files/mariadb@.service.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/support-files/mariadb@.service.in b/support-files/mariadb@.service.in index 465a0d94c62..4838620b8cd 100644 --- a/support-files/mariadb@.service.in +++ b/support-files/mariadb@.service.in @@ -18,7 +18,7 @@ # Inspired from https://gitweb.gentoo.org/repo/gentoo.git/tree/dev-db/mysql-init-scripts/files/mysqld_at.service [Unit] -Description=MariaDB @VERSION@ database server (multi-instance) +Description=MariaDB @VERSION@ database server (multi-instance %I) Documentation=man:mysqld(8) Documentation=https://mariadb.com/kb/en/library/systemd/ After=network.target -- cgit v1.2.1 From 896974fc3d721aabe1afbf637a566cab856a731d Mon Sep 17 00:00:00 2001 From: Varun Gupta Date: Sat, 21 Sep 2019 12:14:05 +0530 Subject: MDEV-18094: Query with order by limit picking index scan over filesort In the function test_if_cheaper_ordering we make a decision if using an index is better than using filesort for ordering. If we chose to do range access then in test_quick_select we should make sure that cost for table scan is set to DBL_MAX so that it is not picked. --- mysql-test/r/group_min_max.result | 4 ++-- mysql-test/r/order_by_innodb.result | 25 ++++++++++++++++++++++ mysql-test/suite/maria/icp.result | 2 +- mysql-test/t/order_by_innodb.test | 24 +++++++++++++++++++++ sql/opt_range.cc | 14 +++++++----- .../tokudb/mysql-test/tokudb_bugs/r/2970.result | 2 +- 6 files changed, 62 insertions(+), 9 deletions(-) diff --git a/mysql-test/r/group_min_max.result b/mysql-test/r/group_min_max.result index 777780f8400..c535550d5f9 100644 --- a/mysql-test/r/group_min_max.result +++ b/mysql-test/r/group_min_max.result @@ -2119,12 +2119,12 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index NULL idx_t1_2 147 NULL 128 Using index explain extended select a1,a2,count(a2) from t1 where (a1 > 'a') group by a1,a2,b; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 index idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_2 147 NULL 128 75.00 Using where; Using index +1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_2 65 NULL 102 94.12 Using where; Using index Warnings: Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,count(`test`.`t1`.`a2`) AS `count(a2)` from `test`.`t1` where (`test`.`t1`.`a1` > 'a') group by `test`.`t1`.`a1`,`test`.`t1`.`a2`,`test`.`t1`.`b` explain extended select sum(ord(a1)) from t1 where (a1 > 'a') group by a1,a2,b; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 index idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_2 147 NULL 128 75.00 Using where; Using index +1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_2 65 NULL 102 94.12 Using where; Using index Warnings: Note 1003 select sum(ord(`test`.`t1`.`a1`)) AS `sum(ord(a1))` from `test`.`t1` where (`test`.`t1`.`a1` > 'a') group by `test`.`t1`.`a1`,`test`.`t1`.`a2`,`test`.`t1`.`b` create table t4 as select distinct a1, a2, b, c from t1; diff --git a/mysql-test/r/order_by_innodb.result b/mysql-test/r/order_by_innodb.result index 4f59a2f8c20..10c041c0c28 100644 --- a/mysql-test/r/order_by_innodb.result +++ b/mysql-test/r/order_by_innodb.result @@ -48,3 +48,28 @@ where key1<3 or key2<3; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index_merge key1,key2 key1,key2 5,5 NULL # Using sort_union(key1,key2); Using where drop table t0, t1; +# +# MDEV-18094: Query with order by limit picking index scan over filesort +# +create table t0 (a int); +INSERT INTO t0 VALUES (0),(0),(0),(0),(2),(0),(0),(1),(1),(0); +CREATE TABLE t1 ( +a int(11), +b int(11), +c int(11), +KEY a_c (a,c), +KEY a_b (a,b) +) ENGINE=InnoDB; +insert into t1 select A.a , B.a, C.a from t0 A, t0 B, t0 C; +# should use ref access +explain select a,b,c from t1 where a=1 and c=2 order by b; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref a_c,a_b a_c 10 const,const 20 Using where; Using filesort +# both should use range access +explain select a,b,c from t1 where a=1 and c=2 order by b limit 1000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range a_c,a_b a_b 5 NULL 200 Using where +explain select a,b,c from t1 where a=1 and c=2 order by b limit 2000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range a_c,a_b a_b 5 NULL 200 Using where +drop table t1,t0; diff --git a/mysql-test/suite/maria/icp.result b/mysql-test/suite/maria/icp.result index e37877c8527..49eaed9dd6d 100644 --- a/mysql-test/suite/maria/icp.result +++ b/mysql-test/suite/maria/icp.result @@ -167,7 +167,7 @@ WHERE ts BETWEEN '0000-00-00' AND '2010-00-01 00:00:00' ORDER BY ts DESC LIMIT 2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index PRIMARY PRIMARY 4 NULL 2 Using where +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using where DROP TABLE t1; # diff --git a/mysql-test/t/order_by_innodb.test b/mysql-test/t/order_by_innodb.test index 097eddd24f1..10769367c39 100644 --- a/mysql-test/t/order_by_innodb.test +++ b/mysql-test/t/order_by_innodb.test @@ -61,3 +61,27 @@ from t1 where key1<3 or key2<3; drop table t0, t1; + +--echo # +--echo # MDEV-18094: Query with order by limit picking index scan over filesort +--echo # + +create table t0 (a int); +INSERT INTO t0 VALUES (0),(0),(0),(0),(2),(0),(0),(1),(1),(0); + +CREATE TABLE t1 ( +a int(11), +b int(11), +c int(11), +KEY a_c (a,c), +KEY a_b (a,b) +) ENGINE=InnoDB; +insert into t1 select A.a , B.a, C.a from t0 A, t0 B, t0 C; + +--echo # should use ref access +explain select a,b,c from t1 where a=1 and c=2 order by b; + +--echo # both should use range access +explain select a,b,c from t1 where a=1 and c=2 order by b limit 1000; +explain select a,b,c from t1 where a=1 and c=2 order by b limit 2000; +drop table t1,t0; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 45dad8882a1..7e987c3cfba 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -2420,12 +2420,16 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, records= head->stat_records(); if (!records) records++; /* purecov: inspected */ - scan_time= (double) records / TIME_FOR_COMPARE + 1; - read_time= (double) head->file->scan_time() + scan_time + 1.1; - if (head->force_index) + + if (head->force_index || force_quick_range) scan_time= read_time= DBL_MAX; - if (limit < records) - read_time= (double) records + scan_time + 1; // Force to use index + else + { + scan_time= (double) records / TIME_FOR_COMPARE + 1; + read_time= (double) head->file->scan_time() + scan_time + 1.1; + if (limit < records) + read_time= (double) records + scan_time + 1; // Force to use index + } possible_keys.clear_all(); diff --git a/storage/tokudb/mysql-test/tokudb_bugs/r/2970.result b/storage/tokudb/mysql-test/tokudb_bugs/r/2970.result index 83ba8821f27..c322865b09d 100644 --- a/storage/tokudb/mysql-test/tokudb_bugs/r/2970.result +++ b/storage/tokudb/mysql-test/tokudb_bugs/r/2970.result @@ -6,5 +6,5 @@ create table t2970 (a int, b int, c int, d int, key(a), key(a,b)); insert into t2970 values (1,1,1,1),(1,2,3,4); explain select a,count(b),max(b) from t2970 where a > 0 group by a order by a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2970 index a,a_2 a_2 10 NULL 2 Using where; Using index +1 SIMPLE t2970 range a,a_2 a_2 5 NULL 2 Using where; Using index drop table t2970; -- cgit v1.2.1 From 1bbe8c5e0f6823acd4780d7563e8c02f8b4c5a01 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Sun, 22 Sep 2019 04:08:48 +0300 Subject: Proper fix for disabling warnings in read_statistics_for_table(). MDEV-20589: Server still crashes in Field::set_warning_truncated_wrong_value - Use dbug_tmp_use_all_columns() to mark that all fields can be used - Remove field->is_stat_field (not needed) - Remove extra arguments to Field::clone() that should not be there - Safety fix for Field::set_warning_truncated_wrong_value() to not crash if table is zero in production builds (We have got crashes several times here so better to be safe than sorry). - Threat wrong character string warnings identical to other field conversion warnings. This removes some warnings we before got from internal conversion errors. There is no good reason why a user would get an error in case of 'key_field='wrong-utf8-string' but not for 'field=wrong-utf8-string'. The old code could also easily give thousands of no-sence warnings for one single statement. --- mysql-test/include/ctype_utf8_ilseq.inc | 1 + mysql-test/main/compare.result | 20 +++++++++ mysql-test/main/compare.test | 14 ++++++ mysql-test/main/ctype_uca.result | 46 +++----------------- mysql-test/main/ctype_uca_innodb.result | 31 ++----------- mysql-test/main/ctype_utf8.result | 77 ++++----------------------------- mysql-test/main/processlist.result | 4 -- mysql-test/main/range.result | 10 ----- mysql-test/main/range_mrr_icp.result | 10 ----- sql/field.cc | 35 ++++++++------- sql/field.h | 3 +- sql/sql_statistics.cc | 11 ++++- 12 files changed, 83 insertions(+), 179 deletions(-) diff --git a/mysql-test/include/ctype_utf8_ilseq.inc b/mysql-test/include/ctype_utf8_ilseq.inc index 1bb009f2a8b..3586946659e 100644 --- a/mysql-test/include/ctype_utf8_ilseq.inc +++ b/mysql-test/include/ctype_utf8_ilseq.inc @@ -14,6 +14,7 @@ SHOW CREATE TABLE t1; INSERT INTO t1 (ch) VALUES ('admin'),('admin1'); SELECT ch FROM t1 WHERE ch='admin๐Œ†'; +EXPLAIN SELECT ch FROM t1 WHERE ch='admin๐Œ†'; SELECT ch FROM t1 IGNORE KEY (ch) WHERE ch='admin๐Œ†'; SELECT ch FROM t1 FORCE KEY (ch) WHERE ch='admin๐Œ†'; DELETE FROM t1; diff --git a/mysql-test/main/compare.result b/mysql-test/main/compare.result index b4a6b22ba3a..c4650014326 100644 --- a/mysql-test/main/compare.result +++ b/mysql-test/main/compare.result @@ -100,3 +100,23 @@ CREATE TABLE t1(a INT ZEROFILL); SELECT 1 FROM t1 WHERE t1.a IN (1, t1.a) AND t1.a=2; 1 DROP TABLE t1; +CREATE TABLE t1 (a char(2), index (a)); +insert into t1 values ("aa"),("bb"); +select * from t1 where a="aa"; +a +aa +select * from t1 where a="aaa"; +a +select * from t1 where a="aa "; +a +aa +select * from t1 where a>="aaa"; +a +bb +explain select * from t1 where a="aaa"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref a a 3 const 1 Using where; Using index +explain select * from t1 where a="aa "; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref a a 3 const 1 Using where; Using index +drop table t1; diff --git a/mysql-test/main/compare.test b/mysql-test/main/compare.test index d2b2a7e5523..38bda6754d8 100644 --- a/mysql-test/main/compare.test +++ b/mysql-test/main/compare.test @@ -94,3 +94,17 @@ DROP TABLE t1; CREATE TABLE t1(a INT ZEROFILL); SELECT 1 FROM t1 WHERE t1.a IN (1, t1.a) AND t1.a=2; DROP TABLE t1; + +# +# Check what happens when comparing to long string +# + +CREATE TABLE t1 (a char(2), index (a)); +insert into t1 values ("aa"),("bb"); +select * from t1 where a="aa"; +select * from t1 where a="aaa"; +select * from t1 where a="aa "; +select * from t1 where a>="aaa"; +explain select * from t1 where a="aaa"; +explain select * from t1 where a="aa "; +drop table t1; diff --git a/mysql-test/main/ctype_uca.result b/mysql-test/main/ctype_uca.result index 41d2a1149ee..d4b242d035f 100644 --- a/mysql-test/main/ctype_uca.result +++ b/mysql-test/main/ctype_uca.result @@ -6748,14 +6748,13 @@ t1 CREATE TABLE `t1` ( INSERT INTO t1 (ch) VALUES ('admin'),('admin1'); SELECT ch FROM t1 WHERE ch='admin๐Œ†'; ch -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86' for column `test`.`t1`.`ch` at row 1 +EXPLAIN SELECT ch FROM t1 WHERE ch='admin๐Œ†'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables SELECT ch FROM t1 IGNORE KEY (ch) WHERE ch='admin๐Œ†'; ch SELECT ch FROM t1 FORCE KEY (ch) WHERE ch='admin๐Œ†'; ch -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86' for column `test`.`t1`.`ch` at row 1 DELETE FROM t1; INSERT INTO t1 (ch) VALUES ('a'), ('a?'), ('a??'), ('a???'), ('a????'); INSERT INTO t1 (ch) VALUES ('ab'),('a?b'),('a??b'),('a???b'),('a????b'); @@ -6771,22 +6770,14 @@ EXPLAIN SELECT ch FROM t1 FORCE KEY (ch) WHERE ch='a๐Œ†' ORDER BY ch; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL # Impossible WHERE noticed after reading const tables -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86' for column `test`.`t1`.`ch` at row 1 SELECT ch FROM t1 FORCE KEY (ch) WHERE ch='a๐Œ†' ORDER BY ch; ch -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86' for column `test`.`t1`.`ch` at row 1 EXPLAIN SELECT ch FROM t1 FORCE KEY (ch) WHERE ch='a๐Œ†b' ORDER BY ch; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL # Impossible WHERE noticed after reading const tables -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86b' for column `test`.`t1`.`ch` at row 1 SELECT ch FROM t1 FORCE KEY (ch) WHERE ch='a๐Œ†b' ORDER BY ch; ch -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86b' for column `test`.`t1`.`ch` at row 1 SELECT ch FROM t1 IGNORE KEY (ch) WHERE ch<'a๐Œ†' ORDER BY ch; ch a @@ -6829,8 +6820,6 @@ EXPLAIN SELECT ch FROM t1 FORCE KEY (ch) WHERE ch<'a๐Œ†' ORDER BY ch; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index ch ch 183 NULL # Using where; Using index -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86' for column `test`.`t1`.`ch` at row 1 SELECT ch FROM t1 FORCE KEY (ch) WHERE ch<'a๐Œ†' ORDER BY ch; ch a @@ -6850,14 +6839,10 @@ ab az aะ€ aึ€ -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86' for column `test`.`t1`.`ch` at row 1 EXPLAIN SELECT ch FROM t1 FORCE KEY (ch) WHERE ch<'a๐Œ†b' ORDER BY ch; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index ch ch 183 NULL # Using where; Using index -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86b' for column `test`.`t1`.`ch` at row 1 SELECT ch FROM t1 FORCE KEY (ch) WHERE ch<'a๐Œ†b' ORDER BY ch; ch a @@ -6877,8 +6862,6 @@ ab az aะ€ aึ€ -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86b' for column `test`.`t1`.`ch` at row 1 SELECT ch FROM t1 IGNORE KEY (ch) WHERE ch>'a๐Œ†' ORDER BY ch; ch z @@ -6889,24 +6872,16 @@ EXPLAIN SELECT ch FROM t1 FORCE KEY (ch) WHERE ch>'a๐Œ†' ORDER BY ch; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index ch ch 183 NULL # Using where; Using index -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86' for column `test`.`t1`.`ch` at row 1 SELECT ch FROM t1 FORCE KEY (ch) WHERE ch>'a๐Œ†' ORDER BY ch; ch z -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86' for column `test`.`t1`.`ch` at row 1 EXPLAIN SELECT ch FROM t1 FORCE KEY (ch) WHERE ch>'a๐Œ†b' ORDER BY ch; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index ch ch 183 NULL # Using where; Using index -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86b' for column `test`.`t1`.`ch` at row 1 SELECT ch FROM t1 FORCE KEY (ch) WHERE ch>'a๐Œ†b' ORDER BY ch; ch z -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86b' for column `test`.`t1`.`ch` at row 1 ALTER TABLE t1 DROP KEY ch; # 0xD18F would be a good 2-byte character, 0xD1 is an incomplete sequence SET @query=CONCAT('SELECT ch FROM t1 WHERE ch=''a', 0xD1,''''); @@ -6992,14 +6967,13 @@ t1 CREATE TABLE `t1` ( INSERT INTO t1 (ch) VALUES ('admin'),('admin1'); SELECT ch FROM t1 WHERE ch='admin๐Œ†'; ch -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86' for column `test`.`t1`.`ch` at row 1 +EXPLAIN SELECT ch FROM t1 WHERE ch='admin๐Œ†'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables SELECT ch FROM t1 IGNORE KEY (ch) WHERE ch='admin๐Œ†'; ch SELECT ch FROM t1 FORCE KEY (ch) WHERE ch='admin๐Œ†'; ch -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86' for column `test`.`t1`.`ch` at row 1 DELETE FROM t1; INSERT INTO t1 (ch) VALUES ('a'), ('a?'), ('a??'), ('a???'), ('a????'); INSERT INTO t1 (ch) VALUES ('ab'),('a?b'),('a??b'),('a???b'),('a????b'); @@ -7015,22 +6989,14 @@ EXPLAIN SELECT ch FROM t1 FORCE KEY (ch) WHERE ch='a๐Œ†' ORDER BY ch; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL # Impossible WHERE noticed after reading const tables -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86' for column `test`.`t1`.`ch` at row 1 SELECT ch FROM t1 FORCE KEY (ch) WHERE ch='a๐Œ†' ORDER BY ch; ch -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86' for column `test`.`t1`.`ch` at row 1 EXPLAIN SELECT ch FROM t1 FORCE KEY (ch) WHERE ch='a๐Œ†b' ORDER BY ch; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL # Impossible WHERE noticed after reading const tables -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86b' for column `test`.`t1`.`ch` at row 1 SELECT ch FROM t1 FORCE KEY (ch) WHERE ch='a๐Œ†b' ORDER BY ch; ch -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86b' for column `test`.`t1`.`ch` at row 1 SELECT ch FROM t1 IGNORE KEY (ch) WHERE ch<'a๐Œ†' ORDER BY ch; ch a diff --git a/mysql-test/main/ctype_uca_innodb.result b/mysql-test/main/ctype_uca_innodb.result index bd6f3b8a21f..7c64f17190e 100644 --- a/mysql-test/main/ctype_uca_innodb.result +++ b/mysql-test/main/ctype_uca_innodb.result @@ -23,14 +23,13 @@ t1 CREATE TABLE `t1` ( INSERT INTO t1 (ch) VALUES ('admin'),('admin1'); SELECT ch FROM t1 WHERE ch='admin๐Œ†'; ch -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86' for column `test`.`t1`.`ch` at row 1 +EXPLAIN SELECT ch FROM t1 WHERE ch='admin๐Œ†'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables SELECT ch FROM t1 IGNORE KEY (ch) WHERE ch='admin๐Œ†'; ch SELECT ch FROM t1 FORCE KEY (ch) WHERE ch='admin๐Œ†'; ch -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86' for column `test`.`t1`.`ch` at row 1 DELETE FROM t1; INSERT INTO t1 (ch) VALUES ('a'), ('a?'), ('a??'), ('a???'), ('a????'); INSERT INTO t1 (ch) VALUES ('ab'),('a?b'),('a??b'),('a???b'),('a????b'); @@ -46,22 +45,14 @@ EXPLAIN SELECT ch FROM t1 FORCE KEY (ch) WHERE ch='a๐Œ†' ORDER BY ch; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL # Impossible WHERE noticed after reading const tables -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86' for column `test`.`t1`.`ch` at row 1 SELECT ch FROM t1 FORCE KEY (ch) WHERE ch='a๐Œ†' ORDER BY ch; ch -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86' for column `test`.`t1`.`ch` at row 1 EXPLAIN SELECT ch FROM t1 FORCE KEY (ch) WHERE ch='a๐Œ†b' ORDER BY ch; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL # Impossible WHERE noticed after reading const tables -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86b' for column `test`.`t1`.`ch` at row 1 SELECT ch FROM t1 FORCE KEY (ch) WHERE ch='a๐Œ†b' ORDER BY ch; ch -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86b' for column `test`.`t1`.`ch` at row 1 SELECT ch FROM t1 IGNORE KEY (ch) WHERE ch<'a๐Œ†' ORDER BY ch; ch a @@ -104,8 +95,6 @@ EXPLAIN SELECT ch FROM t1 FORCE KEY (ch) WHERE ch<'a๐Œ†' ORDER BY ch; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index ch ch 183 NULL # Using where; Using index -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86' for column `test`.`t1`.`ch` at row 1 SELECT ch FROM t1 FORCE KEY (ch) WHERE ch<'a๐Œ†' ORDER BY ch; ch a @@ -125,14 +114,10 @@ ab az aะ€ aึ€ -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86' for column `test`.`t1`.`ch` at row 1 EXPLAIN SELECT ch FROM t1 FORCE KEY (ch) WHERE ch<'a๐Œ†b' ORDER BY ch; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index ch ch 183 NULL # Using where; Using index -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86b' for column `test`.`t1`.`ch` at row 1 SELECT ch FROM t1 FORCE KEY (ch) WHERE ch<'a๐Œ†b' ORDER BY ch; ch a @@ -152,8 +137,6 @@ ab az aะ€ aึ€ -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86b' for column `test`.`t1`.`ch` at row 1 SELECT ch FROM t1 IGNORE KEY (ch) WHERE ch>'a๐Œ†' ORDER BY ch; ch z @@ -164,24 +147,16 @@ EXPLAIN SELECT ch FROM t1 FORCE KEY (ch) WHERE ch>'a๐Œ†' ORDER BY ch; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index ch ch 183 NULL # Using where; Using index -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86' for column `test`.`t1`.`ch` at row 1 SELECT ch FROM t1 FORCE KEY (ch) WHERE ch>'a๐Œ†' ORDER BY ch; ch z -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86' for column `test`.`t1`.`ch` at row 1 EXPLAIN SELECT ch FROM t1 FORCE KEY (ch) WHERE ch>'a๐Œ†b' ORDER BY ch; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index ch ch 183 NULL # Using where; Using index -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86b' for column `test`.`t1`.`ch` at row 1 SELECT ch FROM t1 FORCE KEY (ch) WHERE ch>'a๐Œ†b' ORDER BY ch; ch z -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86b' for column `test`.`t1`.`ch` at row 1 ALTER TABLE t1 DROP KEY ch; # 0xD18F would be a good 2-byte character, 0xD1 is an incomplete sequence SET @query=CONCAT('SELECT ch FROM t1 WHERE ch=''a', 0xD1,''''); diff --git a/mysql-test/main/ctype_utf8.result b/mysql-test/main/ctype_utf8.result index a1f5537a8d7..45d9d1d7e5a 100644 --- a/mysql-test/main/ctype_utf8.result +++ b/mysql-test/main/ctype_utf8.result @@ -5467,14 +5467,13 @@ t1 CREATE TABLE `t1` ( INSERT INTO t1 (ch) VALUES ('admin'),('admin1'); SELECT ch FROM t1 WHERE ch='admin๐Œ†'; ch -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86' for column `test`.`t1`.`ch` at row 1 +EXPLAIN SELECT ch FROM t1 WHERE ch='admin๐Œ†'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables SELECT ch FROM t1 IGNORE KEY (ch) WHERE ch='admin๐Œ†'; ch SELECT ch FROM t1 FORCE KEY (ch) WHERE ch='admin๐Œ†'; ch -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86' for column `test`.`t1`.`ch` at row 1 DELETE FROM t1; INSERT INTO t1 (ch) VALUES ('a'), ('a?'), ('a??'), ('a???'), ('a????'); INSERT INTO t1 (ch) VALUES ('ab'),('a?b'),('a??b'),('a???b'),('a????b'); @@ -5490,22 +5489,14 @@ EXPLAIN SELECT ch FROM t1 FORCE KEY (ch) WHERE ch='a๐Œ†' ORDER BY ch; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL # Impossible WHERE noticed after reading const tables -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86' for column `test`.`t1`.`ch` at row 1 SELECT ch FROM t1 FORCE KEY (ch) WHERE ch='a๐Œ†' ORDER BY ch; ch -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86' for column `test`.`t1`.`ch` at row 1 EXPLAIN SELECT ch FROM t1 FORCE KEY (ch) WHERE ch='a๐Œ†b' ORDER BY ch; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL # Impossible WHERE noticed after reading const tables -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86b' for column `test`.`t1`.`ch` at row 1 SELECT ch FROM t1 FORCE KEY (ch) WHERE ch='a๐Œ†b' ORDER BY ch; ch -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86b' for column `test`.`t1`.`ch` at row 1 SELECT ch FROM t1 IGNORE KEY (ch) WHERE ch<'a๐Œ†' ORDER BY ch; ch a @@ -5548,8 +5539,6 @@ EXPLAIN SELECT ch FROM t1 FORCE KEY (ch) WHERE ch<'a๐Œ†' ORDER BY ch; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index ch ch 183 NULL # Using where; Using index -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86' for column `test`.`t1`.`ch` at row 1 SELECT ch FROM t1 FORCE KEY (ch) WHERE ch<'a๐Œ†' ORDER BY ch; ch a @@ -5569,14 +5558,10 @@ ab az aะ€ aึ€ -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86' for column `test`.`t1`.`ch` at row 1 EXPLAIN SELECT ch FROM t1 FORCE KEY (ch) WHERE ch<'a๐Œ†b' ORDER BY ch; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index ch ch 183 NULL # Using where; Using index -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86b' for column `test`.`t1`.`ch` at row 1 SELECT ch FROM t1 FORCE KEY (ch) WHERE ch<'a๐Œ†b' ORDER BY ch; ch a @@ -5596,8 +5581,6 @@ ab az aะ€ aึ€ -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86b' for column `test`.`t1`.`ch` at row 1 SELECT ch FROM t1 IGNORE KEY (ch) WHERE ch>'a๐Œ†' ORDER BY ch; ch z @@ -5608,24 +5591,16 @@ EXPLAIN SELECT ch FROM t1 FORCE KEY (ch) WHERE ch>'a๐Œ†' ORDER BY ch; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index ch ch 183 NULL # Using where; Using index -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86' for column `test`.`t1`.`ch` at row 1 SELECT ch FROM t1 FORCE KEY (ch) WHERE ch>'a๐Œ†' ORDER BY ch; ch z -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86' for column `test`.`t1`.`ch` at row 1 EXPLAIN SELECT ch FROM t1 FORCE KEY (ch) WHERE ch>'a๐Œ†b' ORDER BY ch; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index ch ch 183 NULL # Using where; Using index -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86b' for column `test`.`t1`.`ch` at row 1 SELECT ch FROM t1 FORCE KEY (ch) WHERE ch>'a๐Œ†b' ORDER BY ch; ch z -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86b' for column `test`.`t1`.`ch` at row 1 ALTER TABLE t1 DROP KEY ch; # 0xD18F would be a good 2-byte character, 0xD1 is an incomplete sequence SET @query=CONCAT('SELECT ch FROM t1 WHERE ch=''a', 0xD1,''''); @@ -5711,14 +5686,13 @@ t1 CREATE TABLE `t1` ( INSERT INTO t1 (ch) VALUES ('admin'),('admin1'); SELECT ch FROM t1 WHERE ch='admin๐Œ†'; ch -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86' for column `test`.`t1`.`ch` at row 1 +EXPLAIN SELECT ch FROM t1 WHERE ch='admin๐Œ†'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables SELECT ch FROM t1 IGNORE KEY (ch) WHERE ch='admin๐Œ†'; ch SELECT ch FROM t1 FORCE KEY (ch) WHERE ch='admin๐Œ†'; ch -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86' for column `test`.`t1`.`ch` at row 1 DELETE FROM t1; INSERT INTO t1 (ch) VALUES ('a'), ('a?'), ('a??'), ('a???'), ('a????'); INSERT INTO t1 (ch) VALUES ('ab'),('a?b'),('a??b'),('a???b'),('a????b'); @@ -5734,22 +5708,14 @@ EXPLAIN SELECT ch FROM t1 FORCE KEY (ch) WHERE ch='a๐Œ†' ORDER BY ch; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL # Impossible WHERE noticed after reading const tables -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86' for column `test`.`t1`.`ch` at row 1 SELECT ch FROM t1 FORCE KEY (ch) WHERE ch='a๐Œ†' ORDER BY ch; ch -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86' for column `test`.`t1`.`ch` at row 1 EXPLAIN SELECT ch FROM t1 FORCE KEY (ch) WHERE ch='a๐Œ†b' ORDER BY ch; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL # Impossible WHERE noticed after reading const tables -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86b' for column `test`.`t1`.`ch` at row 1 SELECT ch FROM t1 FORCE KEY (ch) WHERE ch='a๐Œ†b' ORDER BY ch; ch -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86b' for column `test`.`t1`.`ch` at row 1 SELECT ch FROM t1 IGNORE KEY (ch) WHERE ch<'a๐Œ†' ORDER BY ch; ch a @@ -5792,8 +5758,6 @@ EXPLAIN SELECT ch FROM t1 FORCE KEY (ch) WHERE ch<'a๐Œ†' ORDER BY ch; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index ch ch 183 NULL # Using where; Using index -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86' for column `test`.`t1`.`ch` at row 1 SELECT ch FROM t1 FORCE KEY (ch) WHERE ch<'a๐Œ†' ORDER BY ch; ch a @@ -5813,14 +5777,10 @@ ab az aะ€ aึ€ -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86' for column `test`.`t1`.`ch` at row 1 EXPLAIN SELECT ch FROM t1 FORCE KEY (ch) WHERE ch<'a๐Œ†b' ORDER BY ch; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index ch ch 183 NULL # Using where; Using index -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86b' for column `test`.`t1`.`ch` at row 1 SELECT ch FROM t1 FORCE KEY (ch) WHERE ch<'a๐Œ†b' ORDER BY ch; ch a @@ -5840,8 +5800,6 @@ ab az aะ€ aึ€ -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86b' for column `test`.`t1`.`ch` at row 1 SELECT ch FROM t1 IGNORE KEY (ch) WHERE ch>'a๐Œ†' ORDER BY ch; ch z @@ -5852,24 +5810,16 @@ EXPLAIN SELECT ch FROM t1 FORCE KEY (ch) WHERE ch>'a๐Œ†' ORDER BY ch; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index ch ch 183 NULL # Using where; Using index -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86' for column `test`.`t1`.`ch` at row 1 SELECT ch FROM t1 FORCE KEY (ch) WHERE ch>'a๐Œ†' ORDER BY ch; ch z -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86' for column `test`.`t1`.`ch` at row 1 EXPLAIN SELECT ch FROM t1 FORCE KEY (ch) WHERE ch>'a๐Œ†b' ORDER BY ch; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index ch ch 183 NULL # Using where; Using index -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86b' for column `test`.`t1`.`ch` at row 1 SELECT ch FROM t1 FORCE KEY (ch) WHERE ch>'a๐Œ†b' ORDER BY ch; ch z -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86b' for column `test`.`t1`.`ch` at row 1 ALTER TABLE t1 DROP KEY ch; # 0xD18F would be a good 2-byte character, 0xD1 is an incomplete sequence SET @query=CONCAT('SELECT ch FROM t1 WHERE ch=''a', 0xD1,''''); @@ -5955,14 +5905,13 @@ t1 CREATE TABLE `t1` ( INSERT INTO t1 (ch) VALUES ('admin'),('admin1'); SELECT ch FROM t1 WHERE ch='admin๐Œ†'; ch -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86' for column `test`.`t1`.`ch` at row 1 +EXPLAIN SELECT ch FROM t1 WHERE ch='admin๐Œ†'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables SELECT ch FROM t1 IGNORE KEY (ch) WHERE ch='admin๐Œ†'; ch SELECT ch FROM t1 FORCE KEY (ch) WHERE ch='admin๐Œ†'; ch -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86' for column `test`.`t1`.`ch` at row 1 DELETE FROM t1; INSERT INTO t1 (ch) VALUES ('a'), ('a?'), ('a??'), ('a???'), ('a????'); INSERT INTO t1 (ch) VALUES ('ab'),('a?b'),('a??b'),('a???b'),('a????b'); @@ -5978,22 +5927,14 @@ EXPLAIN SELECT ch FROM t1 FORCE KEY (ch) WHERE ch='a๐Œ†' ORDER BY ch; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL # Impossible WHERE noticed after reading const tables -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86' for column `test`.`t1`.`ch` at row 1 SELECT ch FROM t1 FORCE KEY (ch) WHERE ch='a๐Œ†' ORDER BY ch; ch -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86' for column `test`.`t1`.`ch` at row 1 EXPLAIN SELECT ch FROM t1 FORCE KEY (ch) WHERE ch='a๐Œ†b' ORDER BY ch; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL # Impossible WHERE noticed after reading const tables -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86b' for column `test`.`t1`.`ch` at row 1 SELECT ch FROM t1 FORCE KEY (ch) WHERE ch='a๐Œ†b' ORDER BY ch; ch -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9D\x8C\x86b' for column `test`.`t1`.`ch` at row 1 SELECT ch FROM t1 IGNORE KEY (ch) WHERE ch<'a๐Œ†' ORDER BY ch; ch a diff --git a/mysql-test/main/processlist.result b/mysql-test/main/processlist.result index ab518d961ef..4be643c1790 100644 --- a/mysql-test/main/processlist.result +++ b/mysql-test/main/processlist.result @@ -36,10 +36,6 @@ SELECT INFO, INFO_BINARY, 'xxx๐Ÿ˜Žyyy' AS utf8mb4_string FROM INFORMATION_SCHEMA INFO SELECT INFO, INFO_BINARY, 'xxx????yyy' AS utf8mb4_string FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO LIKE '%xxx%yyy%' INFO_BINARY SELECT INFO, INFO_BINARY, 'xxx๐Ÿ˜Žyyy' AS utf8mb4_string FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO LIKE '%xxx%yyy%' utf8mb4_string xxx๐Ÿ˜Žyyy -Warnings: -Level Warning -Code 1366 -Message Incorrect string value: '\xF0\x9F\x98\x8Eyy...' for column `information_schema`.`(temporary)`.`INFO` at row 1 # # End of 10.1 tests # diff --git a/mysql-test/main/range.result b/mysql-test/main/range.result index 3ad577c79e9..aa322a59274 100644 --- a/mysql-test/main/range.result +++ b/mysql-test/main/range.result @@ -2056,23 +2056,15 @@ explain SELECT * FROM t1 WHERE fd='๐Ÿ˜'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9F\x98\x81' for column `test`.`t1`.`fd` at row 1 SELECT * FROM t1 WHERE fd='๐Ÿ˜'; id fd -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9F\x98\x81' for column `test`.`t1`.`fd` at row 1 # The following must not use range access: explain select count(*) from t1 where fd <'๐Ÿ˜'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index ix_fd ix_fd 63 NULL # Using where; Using index -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9F\x98\x81' for column `test`.`t1`.`fd` at row 1 select count(*) from t1 where fd <'๐Ÿ˜'; count(*) 40960 -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9F\x98\x81' for column `test`.`t1`.`fd` at row 1 select count(*) from t1 ignore index (ix_fd) where fd <'๐Ÿ˜'; count(*) 40960 @@ -2293,8 +2285,6 @@ INSERT INTO t1 VALUES ('a'),('b'),('c'),('d'),('e'); EXPLAIN SELECT * FROM t1 WHERE a<=>'๐Ÿ˜Ž'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9F\x98\x8E' for column `test`.`t1`.`a` at row 1 DROP TABLE t1; # # MDEV-10185: Assertion `tree1->keys[key_no] && tree2->keys[key_no]' failed in diff --git a/mysql-test/main/range_mrr_icp.result b/mysql-test/main/range_mrr_icp.result index 05b2b700d47..4af7dd77d7e 100644 --- a/mysql-test/main/range_mrr_icp.result +++ b/mysql-test/main/range_mrr_icp.result @@ -2058,23 +2058,15 @@ explain SELECT * FROM t1 WHERE fd='๐Ÿ˜'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9F\x98\x81' for column `test`.`t1`.`fd` at row 1 SELECT * FROM t1 WHERE fd='๐Ÿ˜'; id fd -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9F\x98\x81' for column `test`.`t1`.`fd` at row 1 # The following must not use range access: explain select count(*) from t1 where fd <'๐Ÿ˜'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index ix_fd ix_fd 63 NULL # Using where; Using index -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9F\x98\x81' for column `test`.`t1`.`fd` at row 1 select count(*) from t1 where fd <'๐Ÿ˜'; count(*) 40960 -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9F\x98\x81' for column `test`.`t1`.`fd` at row 1 select count(*) from t1 ignore index (ix_fd) where fd <'๐Ÿ˜'; count(*) 40960 @@ -2295,8 +2287,6 @@ INSERT INTO t1 VALUES ('a'),('b'),('c'),('d'),('e'); EXPLAIN SELECT * FROM t1 WHERE a<=>'๐Ÿ˜Ž'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables -Warnings: -Warning 1366 Incorrect string value: '\xF0\x9F\x98\x8E' for column `test`.`t1`.`a` at row 1 DROP TABLE t1; # # MDEV-10185: Assertion `tree1->keys[key_no] && tree2->keys[key_no]' failed in diff --git a/sql/field.cc b/sql/field.cc index 0d9797143fa..14d78433503 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -71,7 +71,7 @@ const char field_separator=','; ptr < table->record[0] + table->s->reclength)))) #define ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED \ - DBUG_ASSERT(is_stat_field || !table || \ + DBUG_ASSERT(!table || \ (!table->write_set || \ bitmap_is_set(table->write_set, field_index) || \ (!(ptr >= table->record[0] && \ @@ -2406,8 +2406,7 @@ Field *Field::clone(MEM_ROOT *root, TABLE *new_table) -Field *Field::clone(MEM_ROOT *root, TABLE *new_table, my_ptrdiff_t diff, - bool stat_flag) +Field *Field::clone(MEM_ROOT *root, TABLE *new_table, my_ptrdiff_t diff) { Field *tmp; if ((tmp= (Field*) memdup_root(root,(char*) this,size_of()))) @@ -2415,7 +2414,6 @@ Field *Field::clone(MEM_ROOT *root, TABLE *new_table, my_ptrdiff_t diff, tmp->init(new_table); tmp->move_field_offset(diff); } - tmp->is_stat_field= stat_flag; return tmp; } @@ -2853,7 +2851,7 @@ int Field_decimal::store(const char *from_arg, size_t len, CHARSET_INFO *cs) /* Write digits of the frac_% parts ; - Depending on get_thd()->count_cutted_fields, we may also want + Depending on get_thd()->count_cuted_fields, we may also want to know if some non-zero tail of these parts will be truncated (for example, 0.002->0.00 will generate a warning, while 0.000->0.00 will not) @@ -6991,7 +6989,8 @@ Field_longstr::check_string_copy_error(const String_copier *copier, if (likely(!(pos= copier->most_important_error_pos()))) return FALSE; - if (!is_stat_field) + /* Ignore errors from internal expressions */ + if (get_thd()->count_cuted_fields > CHECK_FIELD_EXPRESSION) { convert_to_printable(tmp, sizeof(tmp), pos, (end - pos), cs, 6); set_warning_truncated_wrong_value("string", tmp); @@ -7024,8 +7023,9 @@ int Field_longstr::report_if_important_data(const char *pstr, const char *end, bool count_spaces) { - THD *thd= get_thd(); - if ((pstr < end) && thd->count_cuted_fields > CHECK_FIELD_EXPRESSION) + THD *thd; + if ((pstr < end) && + (thd= get_thd())->count_cuted_fields > CHECK_FIELD_EXPRESSION) { if (test_if_important_data(field_charset, pstr, end)) { @@ -7036,7 +7036,8 @@ Field_longstr::report_if_important_data(const char *pstr, const char *end, return 2; } else if (count_spaces) - { /* If we lost only spaces then produce a NOTE, not a WARNING */ + { + /* If we lost only spaces then produce a NOTE, not a WARNING */ set_note(WARN_DATA_TRUNCATED, 1); return 2; } @@ -11381,13 +11382,17 @@ void Field::set_warning_truncated_wrong_value(const char *type_arg, const char *value) { THD *thd= get_thd(); - const char *db_name= table->s->db.str; - const char *table_name= table->s->table_name.str; + const char *db_name; + const char *table_name; + /* + table has in the past been 0 in case of wrong calls when processing + statistics tables. Let's protect against that. + */ + DBUG_ASSERT(table); - if (!db_name) - db_name= ""; - if (!table_name) - table_name= ""; + db_name= (table && table->s->db.str) ? table->s->db.str : ""; + table_name= ((table && table->s->table_name.str) ? table->s->table_name.str : + ""); push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_TRUNCATED_WRONG_VALUE_FOR_FIELD, diff --git a/sql/field.h b/sql/field.h index c2d1d241e27..053236133d0 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1253,8 +1253,7 @@ public: uchar *new_ptr, uint32 length, uchar *new_null_ptr, uint new_null_bit); Field *clone(MEM_ROOT *mem_root, TABLE *new_table); - Field *clone(MEM_ROOT *mem_root, TABLE *new_table, my_ptrdiff_t diff, - bool stat_flag= FALSE); + Field *clone(MEM_ROOT *mem_root, TABLE *new_table, my_ptrdiff_t diff); Field *clone(MEM_ROOT *mem_root, my_ptrdiff_t diff); inline void move_field(uchar *ptr_arg,uchar *null_ptr_arg,uchar null_bit_arg) { diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index 8d1342773f7..5e0275fa65d 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -1042,7 +1042,9 @@ public: { char buff[MAX_FIELD_WIDTH]; String val(buff, sizeof(buff), &my_charset_bin); + my_bitmap_map *old_map; + old_map= dbug_tmp_use_all_columns(stat_table, stat_table->read_set); for (uint i= COLUMN_STAT_MIN_VALUE; i <= COLUMN_STAT_HISTOGRAM; i++) { Field *stat_field= stat_table->field[i]; @@ -1100,6 +1102,7 @@ public: } } } + dbug_tmp_restore_column_map(stat_table->read_set, old_map); } @@ -1973,7 +1976,7 @@ void create_min_max_statistical_fields_for_table(TABLE *table) my_ptrdiff_t diff= record-table->record[0]; if (!bitmap_is_set(table->read_set, table_field->field_index)) continue; - if (!(fld= table_field->clone(&table->mem_root, table, diff, TRUE))) + if (!(fld= table_field->clone(&table->mem_root, table, diff))) continue; if (i == 0) table_field->collected_stats->min_value= fld; @@ -2984,9 +2987,12 @@ int read_statistics_for_table(THD *thd, TABLE *table, TABLE_LIST *stat_tables) KEY *key_info, *key_info_end; TABLE_SHARE *table_share= table->s; Table_statistics *read_stats= table_share->stats_cb.table_stats; - + enum_check_fields old_check_level= thd->count_cuted_fields; DBUG_ENTER("read_statistics_for_table"); + /* Don't write warnings for internal field conversions */ + thd->count_cuted_fields= CHECK_FIELD_IGNORE; + /* Read statistics from the statistical table table_stats */ stat_table= stat_tables[TABLE_STAT].table; Table_stat table_stat(stat_table, table); @@ -3067,6 +3073,7 @@ int read_statistics_for_table(THD *thd, TABLE *table, TABLE_LIST *stat_tables) } table->stats_is_read= TRUE; + thd->count_cuted_fields= old_check_level; DBUG_RETURN(0); } -- cgit v1.2.1 From 60cb5559a90b9889cec9bbeb2fc2a6ba44633dda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 23 Sep 2019 08:29:39 +0300 Subject: MDEV-17614 post-fix: Remove dead dup_chk_only=true code. The parameter dup_chk_only was always passed as a constant false. Remove the parameter and the dead code related to it. --- storage/innobase/include/row0ins.h | 22 +++++-------------- storage/innobase/row/row0ins.cc | 43 +++++++++----------------------------- storage/innobase/row/row0log.cc | 7 +++---- storage/innobase/row/row0upd.cc | 4 ++-- 4 files changed, 20 insertions(+), 56 deletions(-) diff --git a/storage/innobase/include/row0ins.h b/storage/innobase/include/row0ins.h index 3a85d7a21c4..164f6fe1ddb 100644 --- a/storage/innobase/include/row0ins.h +++ b/storage/innobase/include/row0ins.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2018, MariaDB Corporation. +Copyright (c) 2017, 2019, 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 @@ -92,10 +92,7 @@ row_ins_clust_index_entry_low( ulint n_uniq, /*!< in: 0 or index->n_uniq */ dtuple_t* entry, /*!< in/out: index entry to insert */ ulint n_ext, /*!< in: number of externally stored columns */ - que_thr_t* thr, /*!< in: query thread or NULL */ - bool dup_chk_only) - /*!< in: if true, just do duplicate check - and return. don't execute actual insert. */ + que_thr_t* thr) /*!< in: query thread or NULL */ MY_ATTRIBUTE((warn_unused_result)); /***************************************************************//** @@ -120,10 +117,7 @@ row_ins_sec_index_entry_low( dtuple_t* entry, /*!< in/out: index entry to insert */ trx_id_t trx_id, /*!< in: PAGE_MAX_TRX_ID during row_log_table_apply(), or 0 */ - que_thr_t* thr, /*!< in: query thread */ - bool dup_chk_only) - /*!< in: if true, just do duplicate check - and return. don't execute actual insert. */ + que_thr_t* thr) /*!< in: query thread */ MY_ATTRIBUTE((warn_unused_result)); /***************************************************************//** @@ -138,10 +132,7 @@ row_ins_clust_index_entry( dict_index_t* index, /*!< in: clustered index */ dtuple_t* entry, /*!< in/out: index entry to insert */ que_thr_t* thr, /*!< in: query thread */ - ulint n_ext, /*!< in: number of externally stored columns */ - bool dup_chk_only) - /*!< in: if true, just do duplicate check - and return. don't execute actual insert. */ + ulint n_ext) /*!< in: number of externally stored columns */ MY_ATTRIBUTE((warn_unused_result)); /***************************************************************//** Inserts an entry into a secondary index. Tries first optimistic, @@ -154,10 +145,7 @@ row_ins_sec_index_entry( /*====================*/ dict_index_t* index, /*!< in: secondary index */ dtuple_t* entry, /*!< in/out: index entry to insert */ - que_thr_t* thr, /*!< in: query thread */ - bool dup_chk_only) - /*!< in: if true, just do duplicate check - and return. don't execute actual insert. */ + que_thr_t* thr) /*!< in: query thread */ MY_ATTRIBUTE((warn_unused_result)); /***********************************************************//** Inserts a row to a table. This is a high-level function used in diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index 2cda0e3d03c..17c45503cc1 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -2553,10 +2553,7 @@ row_ins_clust_index_entry_low( ulint n_uniq, /*!< in: 0 or index->n_uniq */ dtuple_t* entry, /*!< in/out: index entry to insert */ ulint n_ext, /*!< in: number of externally stored columns */ - que_thr_t* thr, /*!< in: query thread */ - bool dup_chk_only) - /*!< in: if true, just do duplicate check - and return. don't execute actual insert. */ + que_thr_t* thr) /*!< in: query thread */ { btr_pcur_t pcur; btr_cur_t* cursor; @@ -2676,11 +2673,6 @@ err_exit: } } - if (dup_chk_only) { - mtr_commit(&mtr); - goto func_exit; - } - /* Note: Allowing duplicates would qualify for modification of an existing record as the new entry is exactly same as old entry. */ if (row_ins_must_modify_rec(cursor)) { @@ -2840,10 +2832,7 @@ row_ins_sec_index_entry_low( dtuple_t* entry, /*!< in/out: index entry to insert */ trx_id_t trx_id, /*!< in: PAGE_MAX_TRX_ID during row_log_table_apply(), or 0 */ - que_thr_t* thr, /*!< in: query thread */ - bool dup_chk_only) - /*!< in: if true, just do duplicate check - and return. don't execute actual insert. */ + que_thr_t* thr) /*!< in: query thread */ { DBUG_ENTER("row_ins_sec_index_entry_low"); @@ -3040,10 +3029,6 @@ row_ins_sec_index_entry_low( &cursor, 0, __FILE__, __LINE__, &mtr); } - if (dup_chk_only) { - goto func_exit; - } - if (row_ins_must_modify_rec(&cursor)) { /* There is already an index entry with a long enough common prefix, we must convert the insert into a modify of an @@ -3132,10 +3117,7 @@ row_ins_clust_index_entry( dict_index_t* index, /*!< in: clustered index */ dtuple_t* entry, /*!< in/out: index entry to insert */ que_thr_t* thr, /*!< in: query thread */ - ulint n_ext, /*!< in: number of externally stored columns */ - bool dup_chk_only) - /*!< in: if true, just do duplicate check - and return. don't execute actual insert. */ + ulint n_ext) /*!< in: number of externally stored columns */ { dberr_t err; ulint n_uniq; @@ -3170,8 +3152,7 @@ row_ins_clust_index_entry( err = row_ins_clust_index_entry_low( flags, BTR_MODIFY_LEAF, index, n_uniq, entry, - n_ext, thr, dup_chk_only); - + n_ext, thr); DEBUG_SYNC_C_IF_THD(thr_get_trx(thr)->mysql_thd, "after_row_ins_clust_index_entry_leaf"); @@ -3186,7 +3167,7 @@ row_ins_clust_index_entry( err = row_ins_clust_index_entry_low( flags, BTR_MODIFY_TREE, index, n_uniq, entry, - n_ext, thr, dup_chk_only); + n_ext, thr); DBUG_RETURN(err); } @@ -3202,10 +3183,7 @@ row_ins_sec_index_entry( /*====================*/ dict_index_t* index, /*!< in: secondary index */ dtuple_t* entry, /*!< in/out: index entry to insert */ - que_thr_t* thr, /*!< in: query thread */ - bool dup_chk_only) - /*!< in: if true, just do duplicate check - and return. don't execute actual insert. */ + que_thr_t* thr) /*!< in: query thread */ { dberr_t err; mem_heap_t* offsets_heap; @@ -3248,7 +3226,7 @@ row_ins_sec_index_entry( err = row_ins_sec_index_entry_low( flags, BTR_MODIFY_LEAF, index, offsets_heap, heap, entry, - trx_id, thr, dup_chk_only); + trx_id, thr); if (err == DB_FAIL) { mem_heap_empty(heap); @@ -3262,8 +3240,7 @@ row_ins_sec_index_entry( err = row_ins_sec_index_entry_low( flags, BTR_MODIFY_TREE, index, - offsets_heap, heap, entry, 0, thr, - dup_chk_only); + offsets_heap, heap, entry, 0, thr); } mem_heap_free(heap); @@ -3292,9 +3269,9 @@ row_ins_index_entry( return(DB_LOCK_WAIT);}); if (dict_index_is_clust(index)) { - return(row_ins_clust_index_entry(index, entry, thr, 0, false)); + return(row_ins_clust_index_entry(index, entry, thr, 0)); } else { - return(row_ins_sec_index_entry(index, entry, thr, false)); + return(row_ins_sec_index_entry(index, entry, thr)); } } diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc index 3924a07fb0f..6da08872a9a 100644 --- a/storage/innobase/row/row0log.cc +++ b/storage/innobase/row/row0log.cc @@ -1524,7 +1524,7 @@ row_log_table_apply_insert_low( error = row_ins_clust_index_entry_low( flags, BTR_MODIFY_TREE, index, index->n_uniq, - entry, 0, thr, false); + entry, 0, thr); switch (error) { case DB_SUCCESS: @@ -1547,8 +1547,7 @@ row_log_table_apply_insert_low( entry = row_build_index_entry(row, NULL, index, heap); error = row_ins_sec_index_entry_low( flags, BTR_MODIFY_TREE, - index, offsets_heap, heap, entry, trx_id, thr, - false); + index, offsets_heap, heap, entry, trx_id, thr); if (error != DB_SUCCESS) { if (error == DB_DUPLICATE_KEY) { @@ -2178,7 +2177,7 @@ func_exit_committed: BTR_CREATE_FLAG | BTR_NO_LOCKING_FLAG | BTR_NO_UNDO_LOG_FLAG | BTR_KEEP_SYS_FLAG, BTR_MODIFY_TREE, index, offsets_heap, heap, - entry, trx_id, thr, false); + entry, trx_id, thr); /* Report correct index name for duplicate key error. */ if (error == DB_DUPLICATE_KEY) { diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc index 0f69289eaab..021e3d69f8a 100644 --- a/storage/innobase/row/row0upd.cc +++ b/storage/innobase/row/row0upd.cc @@ -2524,7 +2524,7 @@ row_upd_sec_index_entry( ut_a(entry); /* Insert new index entry */ - err = row_ins_sec_index_entry(index, entry, thr, false); + err = row_ins_sec_index_entry(index, entry, thr); func_exit: mem_heap_free(heap); @@ -2795,7 +2795,7 @@ check_fk: err = row_ins_clust_index_entry( index, entry, thr, - node->upd_ext ? node->upd_ext->n_ext : 0, false); + node->upd_ext ? node->upd_ext->n_ext : 0); node->state = UPD_NODE_INSERT_CLUSTERED; mem_heap_free(heap); -- cgit v1.2.1 From 2931fd2917cc130e34e5f3d9d6c571a2b013e49c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 23 Sep 2019 09:04:51 +0300 Subject: After-merge fix: Adjust a result --- storage/rocksdb/mysql-test/rocksdb/r/group_min_max.result | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/storage/rocksdb/mysql-test/rocksdb/r/group_min_max.result b/storage/rocksdb/mysql-test/rocksdb/r/group_min_max.result index 61c6dcae8d9..e6a3dee961c 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/group_min_max.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/group_min_max.result @@ -2204,19 +2204,19 @@ id select_type table type possible_keys key key_len ref rows Extra explain extended select a1,a2,min(b),max(b) from t1 where (a1 = 'b' or a1 = 'd' or a1 = 'a' or a1 = 'c') and (a2 > 'a') and (c > 'a111') group by a1,a2; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 index idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 163 NULL 1000 100.00 Using where; Using index +1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 130 NULL 1000 100.00 Using where; Using index Warnings: Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,min(`test`.`t1`.`b`) AS `min(b)`,max(`test`.`t1`.`b`) AS `max(b)` from `test`.`t1` where (`test`.`t1`.`a1` = 'b' or `test`.`t1`.`a1` = 'd' or `test`.`t1`.`a1` = 'a' or `test`.`t1`.`a1` = 'c') and `test`.`t1`.`a2` > 'a' and `test`.`t1`.`c` > 'a111' group by `test`.`t1`.`a1`,`test`.`t1`.`a2` explain extended select a1,a2,b,min(c),max(c) from t1 where (a1 = 'b' or a1 = 'd' or a1 = 'a' or a1 = 'c') and (a2 > 'a') and (d > 'xy2') group by a1,a2,b; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 index idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_2 147 NULL 1000 100.00 Using where +1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_2 130 NULL 1000 100.00 Using where Warnings: Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,`test`.`t1`.`b` AS `b`,min(`test`.`t1`.`c`) AS `min(c)`,max(`test`.`t1`.`c`) AS `max(c)` from `test`.`t1` where (`test`.`t1`.`a1` = 'b' or `test`.`t1`.`a1` = 'd' or `test`.`t1`.`a1` = 'a' or `test`.`t1`.`a1` = 'c') and `test`.`t1`.`a2` > 'a' and `test`.`t1`.`d` > 'xy2' group by `test`.`t1`.`a1`,`test`.`t1`.`a2`,`test`.`t1`.`b` explain extended select a1,a2,b,c from t1 where (a1 = 'b' or a1 = 'd' or a1 = 'a' or a1 = 'c') and (a2 > 'a') and (d > 'xy2') group by a1,a2,b,c; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 index idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 163 NULL 1000 100.00 Using where +1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 130 NULL 1000 100.00 Using where Warnings: Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where (`test`.`t1`.`a1` = 'b' or `test`.`t1`.`a1` = 'd' or `test`.`t1`.`a1` = 'a' or `test`.`t1`.`a1` = 'c') and `test`.`t1`.`a2` > 'a' and `test`.`t1`.`d` > 'xy2' group by `test`.`t1`.`a1`,`test`.`t1`.`a2`,`test`.`t1`.`b`,`test`.`t1`.`c` explain select a1,a2,b,max(c),min(c) from t2 where (a2 = 'a') and (b = 'b') or (b < 'b') group by a1; @@ -2233,7 +2233,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 index NULL idx_t2_1 163 NULL 1000 Using where; Using index explain extended select a1,a2,b from t1 where (a1 = 'b' or a1 = 'd' or a1 = 'a' or a1 = 'c') and (a2 > 'a') and (c > 'a111') group by a1,a2,b; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 index idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 163 NULL 1000 100.00 Using where; Using index +1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 130 NULL 1000 100.00 Using where; Using index Warnings: Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a1` = 'b' or `test`.`t1`.`a1` = 'd' or `test`.`t1`.`a1` = 'a' or `test`.`t1`.`a1` = 'c') and `test`.`t1`.`a2` > 'a' and `test`.`t1`.`c` > 'a111' group by `test`.`t1`.`a1`,`test`.`t1`.`a2`,`test`.`t1`.`b` explain select a1,a2,min(b),c from t2 where (a2 = 'a') and (c = 'a111') group by a1; @@ -2257,12 +2257,12 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index NULL idx_t1_2 147 NULL 1000 Using index explain extended select a1,a2,count(a2) from t1 where (a1 > 'a') group by a1,a2,b; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 index idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_2 147 NULL 1000 100.00 Using where; Using index +1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_2 65 NULL 1000 100.00 Using where; Using index Warnings: Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,count(`test`.`t1`.`a2`) AS `count(a2)` from `test`.`t1` where `test`.`t1`.`a1` > 'a' group by `test`.`t1`.`a1`,`test`.`t1`.`a2`,`test`.`t1`.`b` explain extended select sum(ord(a1)) from t1 where (a1 > 'a') group by a1,a2,b; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 index idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_2 147 NULL 1000 100.00 Using where; Using index +1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_2 65 NULL 1000 100.00 Using where; Using index Warnings: Note 1003 select sum(ord(`test`.`t1`.`a1`)) AS `sum(ord(a1))` from `test`.`t1` where `test`.`t1`.`a1` > 'a' group by `test`.`t1`.`a1`,`test`.`t1`.`a2`,`test`.`t1`.`b` explain select a1,a2,b,max(c),min(c) from t2 where (a2 = 'a') and (b = 'a' or b = 'b') group by a1; -- cgit v1.2.1