From b7cfd197591bb69a292bd610a650f004d6a29565 Mon Sep 17 00:00:00 2001 From: Varun Gupta Date: Thu, 16 Apr 2020 13:11:30 +0530 Subject: [PATCH 1/3] Minor fixup to MDEV-22191 --- sql/opt_range.cc | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 746f25c57ab..9e96e94ac91 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -4673,6 +4673,7 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge, double roru_index_costs; ha_rows roru_total_records; double roru_intersect_part= 1.0; + bool only_ror_scans_required= FALSE; DBUG_ENTER("get_best_disjunct_quick"); DBUG_PRINT("info", ("Full table scan cost: %g", read_time)); @@ -4698,6 +4699,9 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge, sizeof(TRP_RANGE*)* n_child_scans))) DBUG_RETURN(NULL); + + only_ror_scans_required= !optimizer_flag(param->thd, + OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION); /* Collect best 'range' scan for each of disjuncts, and, while doing so, analyze possibility of ROR scans. Also calculate some values needed by @@ -4710,7 +4714,8 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge, DBUG_EXECUTE("info", print_sel_tree(param, *ptree, &(*ptree)->keys_map, "tree in SEL_IMERGE");); if (!(*cur_child= get_key_scans_params(param, *ptree, TRUE, FALSE, - read_time, TRUE))) + read_time, + only_ror_scans_required))) { /* One of index scans in this index_merge is more expensive than entire @@ -5032,7 +5037,7 @@ TABLE_READ_PLAN *merge_same_index_scans(PARAM *param, SEL_IMERGE *imerge, index merge retrievals are not well calibrated */ trp= get_key_scans_params(param, *imerge->trees, FALSE, TRUE, - read_time, TRUE); + read_time, FALSE); } DBUG_RETURN(trp); @@ -6749,7 +6754,8 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param, index_read_must_be_used if TRUE, assume 'index only' option will be set (except for clustered PK indexes) read_time don't create read plans with cost > read_time. - ror_scans_required set to TRUE for index merge + only_ror_scans_required set to TRUE when we are only interested + in ROR scan RETURN Best range read plan NULL if no plan found or error occurred @@ -6759,7 +6765,7 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree, bool index_read_must_be_used, bool update_tbl_stats, double read_time, - bool ror_scans_required) + bool only_ror_scans_required) { uint idx; SEL_ARG **key,**end, **key_to_read= NULL; @@ -6806,8 +6812,7 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree, update_tbl_stats, &mrr_flags, &buf_size, &cost); - if (ror_scans_required && !param->is_ror_scan && - !optimizer_flag(param->thd, OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION)) + if (only_ror_scans_required && !param->is_ror_scan) { /* The scan is not a ROR-scan, just skip it */ continue; From 7198c6ab2dc8f8286f6732824ab985a76ebaaddc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 17 Apr 2020 10:49:07 +0300 Subject: [PATCH 2/3] MDEV-22271 Excessive stack memory usage due to WSREP_LOG Several tests that involve stored procedures fail on 10.4 kvm-asan (clang 10) due to stack overrun. The main contributor to this stack overrun is mysql_execute_command(), which is invoked recursively during stored procedure execution. Rebuilding with cmake -DWITH_WSREP=OFF shrunk the stack frame size of mysql_execute_command() by more than 10 kilobytes in a WITH_ASAN=ON, CMAKE_BUILD_TYPE=Debug build. The culprit turned out to be the macro WSREP_LOG, which is allocating a separate 1KiB buffer for every occurrence. We replace the macro with a function, so that the stack will be allocated only when the function is actually invoked. In this way, no stack space will be wasted by default (when WSREP and Galera are disabled). This backports commit b6c5657ef27de034439b1505a8b4815c263d6455 from MariaDB 10.3.1. Without ASAN, compilers can be smarter and optimize the stack usage. The original commit message mentions that 1KiB was saved on GCC 5.4, and 4KiB on Mac OS X Lion, which presumably uses a clang-based compiler. --- sql/wsrep_mysqld.cc | 11 +++++++++++ sql/wsrep_mysqld.h | 9 ++------- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index c256467706b..f38bf85cd1a 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -233,6 +233,17 @@ static void wsrep_log_cb(wsrep_log_level_t level, const char *msg) { } } +void wsrep_log(void (*fun)(const char *, ...), const char *format, ...) +{ + va_list args; + char msg[1024]; + va_start(args, format); + vsnprintf(msg, sizeof(msg) - 1, format, args); + va_end(args); + (fun)("WSREP: %s", msg); +} + + static void wsrep_log_states (wsrep_log_level_t const level, const wsrep_uuid_t* const group_uuid, wsrep_seqno_t const group_seqno, diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h index 0f0a65f97b6..a5ec69268d4 100644 --- a/sql/wsrep_mysqld.h +++ b/sql/wsrep_mysqld.h @@ -201,13 +201,8 @@ extern wsrep_seqno_t wsrep_locked_seqno; ? wsrep_forced_binlog_format : (ulong)(my_format)) // prefix all messages with "WSREP" -#define WSREP_LOG(fun, ...) \ - do { \ - char msg[1024] = {'\0'}; \ - snprintf(msg, sizeof(msg) - 1, ## __VA_ARGS__); \ - fun("WSREP: %s", msg); \ - } while(0) - +void wsrep_log(void (*fun)(const char *, ...), const char *format, ...); +#define WSREP_LOG(fun, ...) wsrep_log(fun, ## __VA_ARGS__) #define WSREP_LOG_CONFLICT_THD(thd, role) \ WSREP_LOG(sql_print_information, \ "%s: \n " \ From ad4b70562bb94dd063eebde5189c6e730d3120a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 17 Apr 2020 11:59:23 +0300 Subject: [PATCH 3/3] Fix GCC 10 -Woverflow maria_page_crc_check_index(): Do not attempt to convert HA_ERR_WRONG_CRC (176) to my_bool (char). On platforms where char is signed, the 176 will be converted to -80. It turns out that the callers only care whether the result is zero. Let us return 1 in this case, like we do in all other error cases. --- storage/maria/ma_pagecrc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/storage/maria/ma_pagecrc.c b/storage/maria/ma_pagecrc.c index b0c02e60929..4d73ced3b11 100644 --- a/storage/maria/ma_pagecrc.c +++ b/storage/maria/ma_pagecrc.c @@ -251,7 +251,8 @@ my_bool maria_page_crc_check_index(int res, PAGECACHE_IO_HOOK_ARGS *args) if (length > share->block_size - CRC_SIZE) { DBUG_PRINT("error", ("Wrong page length: %u", length)); - return (my_errno= HA_ERR_WRONG_CRC); + my_errno= HA_ERR_WRONG_CRC; + return 1; } return maria_page_crc_check(page, (uint32) page_no, share, MARIA_NO_CRC_NORMAL_PAGE,