From ae688808fab96f7d3995839d07a61b7990fe51cd Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Tue, 31 Mar 2020 11:39:36 +1100 Subject: [PATCH 01/16] mtr: Only old windows patch-2.5.9 needs --binary Windows GNU patch 2.7.6 is ok without it. So account for the old buildbot version for now. Linux works without it. --binary fails on FreeBSD-12.0: $ patch --version patch 2.0-12u11 FreeBSD $ patch --binary patch: unrecognized option `--binary' --- mysql-test/mysql-test-run.pl | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 677dd58f99b..fc152b232ca 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -3385,8 +3385,11 @@ sub do_before_run_mysqltest($) # to be able to distinguish them from manually created # version-controlled results, and to ignore them in git. my $dest = "$base_file$suites.result~"; - my @cmd = ($exe_patch, qw/--binary -r - -f -s -o/, - $dest, $base_result, $resfile); + my @cmd = ($exe_patch); + if ($^O eq "MSWin32") { + push @cmd, '--binary'; + } + push @cmd, (qw/-r - -f -s -o/, $dest, $base_result, $resfile); if (-w $resdir) { # don't rebuild a file if it's up to date unless (-e $dest and -M $dest < -M $resfile From a215e2132db41c2b1b3f9a6898fcb37e9ae4734f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 15 Apr 2020 14:47:56 +0300 Subject: [PATCH 02/16] mbstream: Remove duplicate definition of datasink_buffer For some reason, when mbstream is compiled with GCC 10, ld will fail to link it due to a multiple definition of datasink_buffer. The code appears to have been like that since the very beginning. Let us remove the duplicate dummy definition. --- extra/mariabackup/xbstream.c | 1 - 1 file changed, 1 deletion(-) diff --git a/extra/mariabackup/xbstream.c b/extra/mariabackup/xbstream.c index 59e0095f63c..6a4b203a684 100644 --- a/extra/mariabackup/xbstream.c +++ b/extra/mariabackup/xbstream.c @@ -45,7 +45,6 @@ datasink_t datasink_archive; datasink_t datasink_xbstream; datasink_t datasink_compress; datasink_t datasink_tmpfile; -datasink_t datasink_buffer; static run_mode_t opt_mode; static char * opt_directory = NULL; From f8166a05af085aeb22be8bc1f41bac9affe4a96f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 15 Apr 2020 14:51:49 +0300 Subject: [PATCH 03/16] MDEV-21549 IMPORT TABLESPACE fails to adjust all tablespace ID in root pages After MDEV-12353, the consistency check that I originally added for commit 1b9fe0bbac72d49a32863241b2b5081438b5f691 (InnoDB Plugin for MySQL 5.1) started randomly failing. It turns out that the IMPORT TABLESPACE code was always incorrect: it did not update the (redundantly stored) tablespace ID in index tree root pages. It only does that for page headers and BLOB pointers. PageConverter::update_index_page(): Update the tablespace ID in the BTR_SEG_TOP and BTR_SEG_LEAF of index root pages. This is a backport of commit b8b3edff1376dc68c13d819470edfb33c339a64b. --- storage/innobase/row/row0import.cc | 19 ++++++++++++++++++- storage/xtradb/row/row0import.cc | 23 ++++++++++++++++++++--- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index e1554949127..f5e882f96fe 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2015, 2018, MariaDB Corporation. +Copyright (c) 2015, 2020, 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 @@ -1924,6 +1924,23 @@ PageConverter::update_index_page( return(DB_SUCCESS); } + if (m_index && block->page.offset == m_index->m_page_no) { + byte *b = FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF + FSEG_HDR_SPACE + + page; + mach_write_to_4(b, block->page.space); + + memcpy(FIL_PAGE_DATA + PAGE_BTR_SEG_TOP + FSEG_HDR_SPACE + + page, b, 4); + if (UNIV_LIKELY_NULL(block->page.zip.data)) { + memcpy(&block->page.zip.data[FIL_PAGE_DATA + + PAGE_BTR_SEG_TOP + + FSEG_HDR_SPACE], b, 4); + memcpy(&block->page.zip.data[FIL_PAGE_DATA + + PAGE_BTR_SEG_LEAF + + FSEG_HDR_SPACE], b, 4); + } + } + #ifdef UNIV_ZIP_DEBUG ut_a(!is_compressed_table() || page_zip_validate(m_page_zip_ptr, page, m_index->m_srv_index)); diff --git a/storage/xtradb/row/row0import.cc b/storage/xtradb/row/row0import.cc index 5b371cfbf74..f5e882f96fe 100644 --- a/storage/xtradb/row/row0import.cc +++ b/storage/xtradb/row/row0import.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2015, 2018, MariaDB Corporation. +Copyright (c) 2015, 2020, 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 @@ -1353,8 +1353,8 @@ uncompressed: return(DB_ERROR); } else if (m_table->n_cols != m_n_cols) { ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_TABLE_SCHEMA_MISMATCH, - "Number of columns don't match, table has %u" - " columns but the tablespace meta-data file has " + "Number of columns don't match, table has %u " + "columns but the tablespace meta-data file has " ULINTPF " columns", m_table->n_cols, m_n_cols); @@ -1924,6 +1924,23 @@ PageConverter::update_index_page( return(DB_SUCCESS); } + if (m_index && block->page.offset == m_index->m_page_no) { + byte *b = FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF + FSEG_HDR_SPACE + + page; + mach_write_to_4(b, block->page.space); + + memcpy(FIL_PAGE_DATA + PAGE_BTR_SEG_TOP + FSEG_HDR_SPACE + + page, b, 4); + if (UNIV_LIKELY_NULL(block->page.zip.data)) { + memcpy(&block->page.zip.data[FIL_PAGE_DATA + + PAGE_BTR_SEG_TOP + + FSEG_HDR_SPACE], b, 4); + memcpy(&block->page.zip.data[FIL_PAGE_DATA + + PAGE_BTR_SEG_LEAF + + FSEG_HDR_SPACE], b, 4); + } + } + #ifdef UNIV_ZIP_DEBUG ut_a(!is_compressed_table() || page_zip_validate(m_page_zip_ptr, page, m_index->m_srv_index)); From b7cfd197591bb69a292bd610a650f004d6a29565 Mon Sep 17 00:00:00 2001 From: Varun Gupta Date: Thu, 16 Apr 2020 13:11:30 +0530 Subject: [PATCH 04/16] 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 05/16] 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 06/16] 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, From 70bb61414b7450aac6fccecb80cf7e6ffe2a4f4e Mon Sep 17 00:00:00 2001 From: Monty Date: Fri, 17 Apr 2020 19:06:39 +0300 Subject: [PATCH 07/16] Fixed compiler warning in mysqltest.cc --- client/mysqltest.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index b699dbbacc9..b363a3217cd 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -716,7 +716,7 @@ public: DBUG_ASSERT(ds->str); #ifdef EXTRA_DEBUG - DBUG_PRINT("extra", ("str: %*b", (int) ds->length, ds->str)); + DBUG_DUMP("extra", (uchar*) ds->str, ds->length); #endif if (fwrite(ds->str, 1, ds->length, m_file) != ds->length) From a6d32976aee8e77caae66e1592011df248c7ffbb Mon Sep 17 00:00:00 2001 From: Monty Date: Fri, 17 Apr 2020 18:55:48 +0300 Subject: [PATCH 08/16] Fixed memory leak with fulltext indexes MDEV-22275 Assertion `global_status_var.global_memory_used == 0' failed, bytes lost, or LeakSanitizer: detected memory leaks after using temporary table with fulltext key This affected MyISAM and Aria temporary tables --- mysql-test/r/fulltext.result | 11 +++++++++++ mysql-test/t/fulltext.test | 14 ++++++++++++++ storage/maria/ma_close.c | 3 ++- storage/myisam/mi_close.c | 4 +++- 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result index 2844f053728..5118cc38fdf 100644 --- a/mysql-test/r/fulltext.result +++ b/mysql-test/r/fulltext.result @@ -776,3 +776,14 @@ CREATE FULLTEXT INDEX IF NOT EXISTS ft1 ON t1(title); Warnings: Note 1061 Duplicate key name 'ft1' DROP TABLE t1; +# +# MDEV-22275 (Memory leak) +# +CREATE TEMPORARY TABLE tmp (a TEXT) ENGINE=MyISAM; +ALTER TABLE tmp ADD FULLTEXT (a); +INSERT INTO tmp VALUES ('foo'); +DROP TABLE tmp; +CREATE TEMPORARY TABLE tmp (a TEXT) ENGINE=Aria; +ALTER TABLE tmp ADD FULLTEXT (a); +INSERT INTO tmp VALUES ('foo'); +DROP TABLE tmp; diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test index 2e53ce7f112..d52f13ab978 100644 --- a/mysql-test/t/fulltext.test +++ b/mysql-test/t/fulltext.test @@ -716,3 +716,17 @@ CREATE TABLE t1 ( CREATE FULLTEXT INDEX IF NOT EXISTS ft1 ON t1(title); CREATE FULLTEXT INDEX IF NOT EXISTS ft1 ON t1(title); DROP TABLE t1; + +--echo # +--echo # MDEV-22275 (Memory leak) +--echo # + +CREATE TEMPORARY TABLE tmp (a TEXT) ENGINE=MyISAM; +ALTER TABLE tmp ADD FULLTEXT (a); +INSERT INTO tmp VALUES ('foo'); +DROP TABLE tmp; + +CREATE TEMPORARY TABLE tmp (a TEXT) ENGINE=Aria; +ALTER TABLE tmp ADD FULLTEXT (a); +INSERT INTO tmp VALUES ('foo'); +DROP TABLE tmp; diff --git a/storage/maria/ma_close.c b/storage/maria/ma_close.c index 03501dc49cf..7d4271c794c 100644 --- a/storage/maria/ma_close.c +++ b/storage/maria/ma_close.c @@ -20,7 +20,7 @@ to open other files during the time we flush the cache and close this file */ -#include "maria_def.h" +#include "ma_ftdefs.h" #include "ma_crypt.h" int maria_close(register MARIA_HA *info) @@ -86,6 +86,7 @@ int maria_close(register MARIA_HA *info) share->open_list= list_delete(share->open_list, &info->share_list); } + maria_ftparser_call_deinitializer(info); my_free(info->rec_buff); (*share->end)(info); diff --git a/storage/myisam/mi_close.c b/storage/myisam/mi_close.c index e09219e1c85..ca5c7355812 100644 --- a/storage/myisam/mi_close.c +++ b/storage/myisam/mi_close.c @@ -20,7 +20,7 @@ to open other files during the time we flush the cache and close this file */ -#include "myisamdef.h" +#include "ftdefs.h" int mi_close(register MI_INFO *info) { @@ -60,6 +60,8 @@ int mi_close(register MI_INFO *info) mysql_mutex_unlock(&share->intern_lock); my_free(mi_get_rec_buff_ptr(info, info->rec_buff)); + ftparser_call_deinitializer(info); + if (flag) { DBUG_EXECUTE_IF("crash_before_flush_keys", From 48eda61cd41725498908308e0004897f10dd7307 Mon Sep 17 00:00:00 2001 From: Monty Date: Sat, 18 Apr 2020 00:22:52 +0300 Subject: [PATCH 09/16] Fixed memory leak with DEFAULT(f) on Geometry field MDEV-21056 Assertion `global_status_var.global_memory_used == 0' failed upon shutdown after query with DEFAULT on a geometry field --- mysql-test/r/gis.result | 7 +++++++ mysql-test/t/gis.test | 8 ++++++++ sql/field.cc | 2 +- sql/item.cc | 8 ++++++++ sql/item.h | 8 +++++--- 5 files changed, 29 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result index ecbdd5b586c..48618a7c2d8 100644 --- a/mysql-test/r/gis.result +++ b/mysql-test/r/gis.result @@ -2283,5 +2283,12 @@ ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field drop table t1; SET timestamp=default; # +# MDEV-21056 Memory leak after query with DEFAULT on a geometry field +# +CREATE TABLE t1 (f POINT DEFAULT ST_GEOMFROMTEXT('Point(0 0)')); +SELECT ST_GEOMFROMTEXT('Point(1 1)') IN ( DEFAULT( `f` ), ST_GEOMFROMTEXT('Point(2 2)') ) AS x FROM t1; +x +DROP TABLE t1; +# # End of 10.2 tests # diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test index f630a6dc8bf..d1dff584c8f 100644 --- a/mysql-test/t/gis.test +++ b/mysql-test/t/gis.test @@ -1805,6 +1805,14 @@ alter table t1 add column i int; drop table t1; SET timestamp=default; +--echo # +--echo # MDEV-21056 Memory leak after query with DEFAULT on a geometry field +--echo # + +CREATE TABLE t1 (f POINT DEFAULT ST_GEOMFROMTEXT('Point(0 0)')); +SELECT ST_GEOMFROMTEXT('Point(1 1)') IN ( DEFAULT( `f` ), ST_GEOMFROMTEXT('Point(2 2)') ) AS x FROM t1; +DROP TABLE t1; + --echo # --echo # End of 10.2 tests --echo # diff --git a/sql/field.cc b/sql/field.cc index 857ba8d0e0c..f96755f5f51 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -8857,7 +8857,7 @@ int Field_geom::store(const char *from, uint length, CHARSET_INFO *cs) my_error(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD, MYF(0), Geometry::ci_collection[geom_type]->m_name.str, - wkt.c_ptr(), db, tab_name, field_name, + wkt.c_ptr_safe(), db, tab_name, field_name, (ulong) table->in_use->get_stmt_da()-> current_row_for_warning()); diff --git a/sql/item.cc b/sql/item.cc index ab7340a4689..141263f7bba 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -8968,8 +8968,10 @@ bool Item_default_value::fix_fields(THD *thd, Item **items) } if (!(def_field= (Field*) thd->alloc(field_arg->field->size_of()))) goto error; + cached_field= def_field; memcpy((void *)def_field, (void *)field_arg->field, field_arg->field->size_of()); + def_field->reset_fields(); // If non-constant default value expression if (def_field->default_value && def_field->default_value->flags) { @@ -8997,6 +8999,12 @@ error: return TRUE; } +void Item_default_value::cleanup() +{ + delete cached_field; // Free cached blob data + cached_field= 0; + Item_field::cleanup(); +} void Item_default_value::print(String *str, enum_query_type query_type) { diff --git a/sql/item.h b/sql/item.h index 4f02b2085f4..1742ff9e23f 100644 --- a/sql/item.h +++ b/sql/item.h @@ -5358,21 +5358,23 @@ class Item_default_value : public Item_field void calculate(); public: Item *arg; + Field *cached_field; Item_default_value(THD *thd, Name_resolution_context *context_arg) :Item_field(thd, context_arg, (const char *)NULL, (const char *)NULL, (const char *)NULL), - arg(NULL) {} + arg(NULL), cached_field(NULL) {} Item_default_value(THD *thd, Name_resolution_context *context_arg, Item *a) :Item_field(thd, context_arg, (const char *)NULL, (const char *)NULL, (const char *)NULL), - arg(a) {} + arg(a), cached_field(NULL) {} Item_default_value(THD *thd, Name_resolution_context *context_arg, Field *a) :Item_field(thd, context_arg, (const char *)NULL, (const char *)NULL, (const char *)NULL), - arg(NULL) {} + arg(NULL),cached_field(NULL) {} enum Type type() const { return DEFAULT_VALUE_ITEM; } bool eq(const Item *item, bool binary_cmp) const; bool fix_fields(THD *, Item **); + void cleanup(); void print(String *str, enum_query_type query_type); String *val_str(String *str); double val_real(); From 749b9887943dadbed027412a2d6df2ab6c5ee275 Mon Sep 17 00:00:00 2001 From: Monty Date: Sat, 18 Apr 2020 00:32:24 +0300 Subject: [PATCH 10/16] Fixed memory leaks in resolve_stack_dump - Remove memory leaks reported by safemalloc - Changed that all 0x strings are converted. This is needed to easily be able to resolve safemalloc backtraces --- extra/resolve_stack_dump.c | 45 +++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/extra/resolve_stack_dump.c b/extra/resolve_stack_dump.c index 92cd4c0de18..6d6adccfe32 100644 --- a/extra/resolve_stack_dump.c +++ b/extra/resolve_stack_dump.c @@ -53,7 +53,7 @@ static struct my_option my_long_options[] = 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"symbols-file", 's', "Use specified symbols file.", &sym_fname, + {"symbols-file", 's', "Use specified symbols file", &sym_fname, &sym_fname, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"numeric-dump-file", 'n', "Read the dump from specified file.", &dump_fname, &dump_fname, 0, GET_STR, REQUIRED_ARG, @@ -63,7 +63,7 @@ static struct my_option my_long_options[] = static void verify_sort(); - +static void clean_up(); static void print_version(void) { @@ -97,9 +97,18 @@ static void die(const char* fmt, ...) vfprintf(stderr, fmt, args); fprintf(stderr, "\n"); va_end(args); + clean_up(); + my_end(0); exit(1); } +void local_exit(int error) +{ + clean_up(); + my_end(0); + exit(error); +} + static my_bool get_one_option(int optid, const struct my_option *opt __attribute__((unused)), @@ -108,10 +117,12 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), switch(optid) { case 'V': print_version(); - exit(0); + local_exit(0); + break; case '?': usage(); - exit(0); + local_exit(0); + break; } return 0; } @@ -122,7 +133,7 @@ static int parse_args(int argc, char **argv) int ho_error; if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option))) - exit(ho_error); + local_exit(ho_error); /* The following code is to make the command compatible with the old @@ -143,13 +154,13 @@ static int parse_args(int argc, char **argv) else { usage(); - exit(1); + local_exit(1); } } else if (argc != 0 || !sym_fname) { usage(); - exit(1); + local_exit(1); } return 0; } @@ -242,6 +253,10 @@ static void init_sym_table() static void clean_up() { delete_dynamic(&sym_table); + if (fp_dump && fp_dump != stdin) + my_fclose(fp_dump, MYF(0)); + if (fp_sym) + my_fclose(fp_sym, MYF(0)); } static void verify_sort() @@ -283,7 +298,7 @@ static SYM_ENTRY* resolve_addr(uchar* addr, SYM_ENTRY* se) /* - Resolve anything that starts with [0x or (+0x or start of line and 0x + Resolve anything that starts with [0x or (+0x or 0x Skip '_end' as this is an indication of a wrong symbol (stack?) */ @@ -299,9 +314,7 @@ static void do_resolve() found= 3; if (p[0] == '(' && p[1] == '+' && p[2] == '0' && p[3] == 'x') found= 4; - - /* For stdin */ - if (p == buf && p[0] == '0' && p[1] == 'x') + if (p[0] == '0' && p[1] == 'x') found= 2; if (found) @@ -312,14 +325,15 @@ static void do_resolve() addr= (uchar*)read_addr(&tmp); if (resolve_addr(addr, &se) && strcmp(se.symbol, "_end")) { - fprintf(fp_out, "%c%p %s + %d", *p, addr, se.symbol, - (int) (addr - se.addr)); + found-= 2; /* Don't print 0x as it's added by %p */ + while (found--) + fputc(*p++, stdout); + fprintf(fp_out, "%p %s + %d", addr, + se.symbol, (int) (addr - se.addr)); p= tmp-1; } else - { fputc(*p, stdout); - } } else fputc(*p, stdout); @@ -336,5 +350,6 @@ int main(int argc, char** argv) init_sym_table(); do_resolve(); clean_up(); + my_end(0); return 0; } From 0bcb65d358087bf94e217254f812f913343a6f5d Mon Sep 17 00:00:00 2001 From: Monty Date: Fri, 17 Apr 2020 19:21:03 +0300 Subject: [PATCH 11/16] Don't write warning about uninitialized mutex if there is a memory leak Part of: MDEV-21056 Assertion `global_status_var.global_memory_used == 0' failed upon shutdown after query with DEFAULT on a geometry field Fixed by changing the ASSERT for memory leaks to a printf() on stderr. This has needed as all mutex in mysys has been deleted and we can't call functions like my_open() anymore. Also added printing of leaks if safemalloc is used (like we do in 10.5) --- sql/mysqld.cc | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 83e93110ad1..9cc841be735 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2172,13 +2172,12 @@ static void mysqld_exit(int exit_code) shutdown_performance_schema(); // we do it as late as possible #endif set_malloc_size_cb(NULL); - if (opt_endinfo && global_status_var.global_memory_used) - fprintf(stderr, "Warning: Memory not freed: %ld\n", - (long) global_status_var.global_memory_used); - if (!opt_debugging && !my_disable_leak_check && exit_code == 0 && - debug_assert_on_not_freed_memory) + if (global_status_var.global_memory_used) { - DBUG_ASSERT(global_status_var.global_memory_used == 0); + fprintf(stderr, "Warning: Memory not freed: %lld\n", + (longlong) global_status_var.global_memory_used); + if (exit_code == 0) + SAFEMALLOC_REPORT_MEMORY(0); } cleanup_tls(); DBUG_LEAVE; From 36bddacf6b9177587eb5364e81f42a482df7d73f Mon Sep 17 00:00:00 2001 From: Monty Date: Sat, 18 Apr 2020 11:51:21 +0300 Subject: [PATCH 12/16] Fixed multi_update_debug.test Backported fix from 10.5 --- mysql-test/r/multi_update_debug.result | 3 ++- mysql-test/t/multi_update_debug.test | 5 ++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/multi_update_debug.result b/mysql-test/r/multi_update_debug.result index 799b6821e48..8649172d0c9 100644 --- a/mysql-test/r/multi_update_debug.result +++ b/mysql-test/r/multi_update_debug.result @@ -5,9 +5,10 @@ insert t2 values (5,6),(7,8); create table t0 (x int); insert t0 values (11), (22); create trigger tr1 before update on t1 for each row insert t0 values (new.b); -set debug_sync='open_tables_after_open_and_process_table WAIT_FOR cont'; +set debug_sync='open_tables_after_open_and_process_table SIGNAL ready WAIT_FOR cont'; update t1 join t2 on (a=c+4) set b=d; connect con1, localhost, root; +set debug_sync='now WAIT_FOR ready'; set debug_sync='mdl_acquire_lock_wait SIGNAL cont'; lock table t1 write, t0 write; disconnect con1; diff --git a/mysql-test/t/multi_update_debug.test b/mysql-test/t/multi_update_debug.test index 2da376e1b87..479405124b0 100644 --- a/mysql-test/t/multi_update_debug.test +++ b/mysql-test/t/multi_update_debug.test @@ -10,12 +10,11 @@ create table t0 (x int); insert t0 values (11), (22); create trigger tr1 before update on t1 for each row insert t0 values (new.b); -set debug_sync='open_tables_after_open_and_process_table WAIT_FOR cont'; +set debug_sync='open_tables_after_open_and_process_table SIGNAL ready WAIT_FOR cont'; send update t1 join t2 on (a=c+4) set b=d; connect con1, localhost, root; -let $wait_condition= select count(*) from information_schema.processlist where state = ' debug sync point: open_tables_after_open_and_process_table' -source include/wait_condition.inc; +set debug_sync='now WAIT_FOR ready'; set debug_sync='mdl_acquire_lock_wait SIGNAL cont'; lock table t1 write, t0 write; let $wait_condition= select count(*) from information_schema.processlist where state = 'Waiting for table metadata lock' From 0efe1971c6f0c7c2edf906372550bef234ebb8a1 Mon Sep 17 00:00:00 2001 From: Vlad Lesin Date: Mon, 20 Apr 2020 17:23:43 +0300 Subject: [PATCH 13/16] MDEV-19347: Mariabackup does not honor ignore_db_dirs from server config. The solution is to read the system variable value on startup and to fill databases_exclude_hash. xb_load_list_string() became non-static and was reformatted. The system variable value is read and processed in get_mysql_vars(), which was also reformatted. --- extra/mariabackup/backup_mysql.cc | 334 +++++++++--------- extra/mariabackup/xtrabackup.cc | 35 +- extra/mariabackup/xtrabackup.h | 10 + .../suite/mariabackup/partial_exclude.opt | 2 + .../suite/mariabackup/partial_exclude.result | 3 + .../suite/mariabackup/partial_exclude.test | 18 + 6 files changed, 228 insertions(+), 174 deletions(-) create mode 100644 mysql-test/suite/mariabackup/partial_exclude.opt diff --git a/extra/mariabackup/backup_mysql.cc b/extra/mariabackup/backup_mysql.cc index 843ebf2663e..d5d0c90376e 100644 --- a/extra/mariabackup/backup_mysql.cc +++ b/extra/mariabackup/backup_mysql.cc @@ -326,194 +326,212 @@ check_server_version(unsigned long version_number, /*********************************************************************//** Receive options important for XtraBackup from MySQL server. @return true on success. */ -bool -get_mysql_vars(MYSQL *connection) +bool get_mysql_vars(MYSQL *connection) { - char *gtid_mode_var = NULL; - char *version_var = NULL; - char *version_comment_var = NULL; - char *innodb_version_var = NULL; - char *have_backup_locks_var = NULL; - char *log_bin_var = NULL; - char *lock_wait_timeout_var= NULL; - char *wsrep_on_var = NULL; - char *slave_parallel_workers_var = NULL; - char *gtid_slave_pos_var = NULL; - char *innodb_buffer_pool_filename_var = NULL; - char *datadir_var = NULL; - char *innodb_log_group_home_dir_var = NULL; - char *innodb_log_file_size_var = NULL; - char *innodb_log_files_in_group_var = NULL; - char *innodb_data_file_path_var = NULL; - char *innodb_data_home_dir_var = NULL; - char *innodb_undo_directory_var = NULL; - char *innodb_page_size_var = NULL; - char *innodb_undo_tablespaces_var = NULL; - char *page_zip_level_var = NULL; - char *endptr; - unsigned long server_version = mysql_get_server_version(connection); + char *gtid_mode_var= NULL; + char *version_var= NULL; + char *version_comment_var= NULL; + char *innodb_version_var= NULL; + char *have_backup_locks_var= NULL; + char *log_bin_var= NULL; + char *lock_wait_timeout_var= NULL; + char *wsrep_on_var= NULL; + char *slave_parallel_workers_var= NULL; + char *gtid_slave_pos_var= NULL; + char *innodb_buffer_pool_filename_var= NULL; + char *datadir_var= NULL; + char *innodb_log_group_home_dir_var= NULL; + char *innodb_log_file_size_var= NULL; + char *innodb_log_files_in_group_var= NULL; + char *innodb_data_file_path_var= NULL; + char *innodb_data_home_dir_var= NULL; + char *innodb_undo_directory_var= NULL; + char *innodb_page_size_var= NULL; + char *innodb_undo_tablespaces_var= NULL; + char *page_zip_level_var= NULL; + char *ignore_db_dirs= NULL; + char *endptr; + unsigned long server_version= mysql_get_server_version(connection); - bool ret = true; + bool ret= true; - mysql_variable mysql_vars[] = { - {"have_backup_locks", &have_backup_locks_var}, - {"log_bin", &log_bin_var}, - {"lock_wait_timeout", &lock_wait_timeout_var}, - {"gtid_mode", >id_mode_var}, - {"version", &version_var}, - {"version_comment", &version_comment_var}, - {"innodb_version", &innodb_version_var}, - {"wsrep_on", &wsrep_on_var}, - {"slave_parallel_workers", &slave_parallel_workers_var}, - {"gtid_slave_pos", >id_slave_pos_var}, - {"innodb_buffer_pool_filename", - &innodb_buffer_pool_filename_var}, - {"datadir", &datadir_var}, - {"innodb_log_group_home_dir", &innodb_log_group_home_dir_var}, - {"innodb_log_file_size", &innodb_log_file_size_var}, - {"innodb_log_files_in_group", &innodb_log_files_in_group_var}, - {"innodb_data_file_path", &innodb_data_file_path_var}, - {"innodb_data_home_dir", &innodb_data_home_dir_var}, - {"innodb_undo_directory", &innodb_undo_directory_var}, - {"innodb_page_size", &innodb_page_size_var}, - {"innodb_undo_tablespaces", &innodb_undo_tablespaces_var}, - {"innodb_compression_level", &page_zip_level_var}, - {NULL, NULL} - }; + mysql_variable mysql_vars[]= { + {"have_backup_locks", &have_backup_locks_var}, + {"log_bin", &log_bin_var}, + {"lock_wait_timeout", &lock_wait_timeout_var}, + {"gtid_mode", >id_mode_var}, + {"version", &version_var}, + {"version_comment", &version_comment_var}, + {"innodb_version", &innodb_version_var}, + {"wsrep_on", &wsrep_on_var}, + {"slave_parallel_workers", &slave_parallel_workers_var}, + {"gtid_slave_pos", >id_slave_pos_var}, + {"innodb_buffer_pool_filename", &innodb_buffer_pool_filename_var}, + {"datadir", &datadir_var}, + {"innodb_log_group_home_dir", &innodb_log_group_home_dir_var}, + {"innodb_log_file_size", &innodb_log_file_size_var}, + {"innodb_log_files_in_group", &innodb_log_files_in_group_var}, + {"innodb_data_file_path", &innodb_data_file_path_var}, + {"innodb_data_home_dir", &innodb_data_home_dir_var}, + {"innodb_undo_directory", &innodb_undo_directory_var}, + {"innodb_page_size", &innodb_page_size_var}, + {"innodb_undo_tablespaces", &innodb_undo_tablespaces_var}, + {"innodb_compression_level", &page_zip_level_var}, + {"ignore_db_dirs", &ignore_db_dirs}, + {NULL, NULL}}; - read_mysql_variables(connection, "SHOW VARIABLES", - mysql_vars, true); + read_mysql_variables(connection, "SHOW VARIABLES", mysql_vars, true); - if (have_backup_locks_var != NULL && !opt_no_backup_locks) { - have_backup_locks = true; - } + if (have_backup_locks_var != NULL && !opt_no_backup_locks) + { + have_backup_locks= true; + } - if (opt_binlog_info == BINLOG_INFO_AUTO) { - if (log_bin_var != NULL && !strcmp(log_bin_var, "ON")) - opt_binlog_info = BINLOG_INFO_ON; - else - opt_binlog_info = BINLOG_INFO_OFF; - } + if (opt_binlog_info == BINLOG_INFO_AUTO) + { + if (log_bin_var != NULL && !strcmp(log_bin_var, "ON")) + opt_binlog_info= BINLOG_INFO_ON; + else + opt_binlog_info= BINLOG_INFO_OFF; + } - if (lock_wait_timeout_var != NULL) { - have_lock_wait_timeout = true; - } + if (lock_wait_timeout_var != NULL) + { + have_lock_wait_timeout= true; + } - if (wsrep_on_var != NULL) { - have_galera_enabled = true; - } + if (wsrep_on_var != NULL) + { + have_galera_enabled= true; + } - /* Check server version compatibility and detect server flavor */ + /* Check server version compatibility and detect server flavor */ - if (!(ret = check_server_version(server_version, version_var, - version_comment_var, - innodb_version_var))) { - goto out; - } + if (!(ret= check_server_version(server_version, version_var, + version_comment_var, innodb_version_var))) + { + goto out; + } - if (server_version > 50500) { - have_flush_engine_logs = true; - } + if (server_version > 50500) + { + have_flush_engine_logs= true; + } - if (slave_parallel_workers_var != NULL - && atoi(slave_parallel_workers_var) > 0) { - have_multi_threaded_slave = true; - } + if (slave_parallel_workers_var != NULL && + atoi(slave_parallel_workers_var) > 0) + { + have_multi_threaded_slave= true; + } - if (innodb_buffer_pool_filename_var != NULL) { - buffer_pool_filename = strdup(innodb_buffer_pool_filename_var); - } + if (innodb_buffer_pool_filename_var != NULL) + { + buffer_pool_filename= strdup(innodb_buffer_pool_filename_var); + } - if ((gtid_mode_var && strcmp(gtid_mode_var, "ON") == 0) || - (gtid_slave_pos_var && *gtid_slave_pos_var)) { - have_gtid_slave = true; - } + if ((gtid_mode_var && strcmp(gtid_mode_var, "ON") == 0) || + (gtid_slave_pos_var && *gtid_slave_pos_var)) + { + have_gtid_slave= true; + } - msg("Using server version %s", version_var); + msg("Using server version %s", version_var); - if (!(ret = detect_mysql_capabilities_for_backup())) { - goto out; - } + if (!(ret= detect_mysql_capabilities_for_backup())) + { + goto out; + } - /* make sure datadir value is the same in configuration file */ - if (check_if_param_set("datadir")) { - if (!directory_exists(mysql_data_home, false)) { - msg("Warning: option 'datadir' points to " - "nonexistent directory '%s'", mysql_data_home); - } - if (!directory_exists(datadir_var, false)) { - msg("Warning: MySQL variable 'datadir' points to " - "nonexistent directory '%s'", datadir_var); - } - if (!equal_paths(mysql_data_home, datadir_var)) { - msg("Warning: option 'datadir' has different " - "values:\n" - " '%s' in defaults file\n" - " '%s' in SHOW VARIABLES", - mysql_data_home, datadir_var); - } - } + /* make sure datadir value is the same in configuration file */ + if (check_if_param_set("datadir")) + { + if (!directory_exists(mysql_data_home, false)) + { + msg("Warning: option 'datadir' points to " + "nonexistent directory '%s'", + mysql_data_home); + } + if (!directory_exists(datadir_var, false)) + { + msg("Warning: MySQL variable 'datadir' points to " + "nonexistent directory '%s'", + datadir_var); + } + if (!equal_paths(mysql_data_home, datadir_var)) + { + msg("Warning: option 'datadir' has different " + "values:\n" + " '%s' in defaults file\n" + " '%s' in SHOW VARIABLES", + mysql_data_home, datadir_var); + } + } - /* get some default values is they are missing from my.cnf */ - if (datadir_var && *datadir_var) { - strmake(mysql_real_data_home, datadir_var, FN_REFLEN - 1); - mysql_data_home= mysql_real_data_home; - } + /* get some default values is they are missing from my.cnf */ + if (datadir_var && *datadir_var) + { + strmake(mysql_real_data_home, datadir_var, FN_REFLEN - 1); + mysql_data_home= mysql_real_data_home; + } - if (innodb_data_file_path_var && *innodb_data_file_path_var) { - innobase_data_file_path = my_strdup( - innodb_data_file_path_var, MYF(MY_FAE)); - } + if (innodb_data_file_path_var && *innodb_data_file_path_var) + { + innobase_data_file_path= my_strdup(innodb_data_file_path_var, MYF(MY_FAE)); + } - if (innodb_data_home_dir_var) { - innobase_data_home_dir = my_strdup( - innodb_data_home_dir_var, MYF(MY_FAE)); - } + if (innodb_data_home_dir_var) + { + innobase_data_home_dir= my_strdup(innodb_data_home_dir_var, MYF(MY_FAE)); + } - if (innodb_log_group_home_dir_var - && *innodb_log_group_home_dir_var) { - srv_log_group_home_dir = my_strdup( - innodb_log_group_home_dir_var, MYF(MY_FAE)); - } + if (innodb_log_group_home_dir_var && *innodb_log_group_home_dir_var) + { + srv_log_group_home_dir= + my_strdup(innodb_log_group_home_dir_var, MYF(MY_FAE)); + } - if (innodb_undo_directory_var && *innodb_undo_directory_var) { - srv_undo_dir = my_strdup( - innodb_undo_directory_var, MYF(MY_FAE)); - } + if (innodb_undo_directory_var && *innodb_undo_directory_var) + { + srv_undo_dir= my_strdup(innodb_undo_directory_var, MYF(MY_FAE)); + } - if (innodb_log_files_in_group_var) { - srv_n_log_files = strtol( - innodb_log_files_in_group_var, &endptr, 10); - ut_ad(*endptr == 0); - } + if (innodb_log_files_in_group_var) + { + srv_n_log_files= strtol(innodb_log_files_in_group_var, &endptr, 10); + ut_ad(*endptr == 0); + } - if (innodb_log_file_size_var) { - srv_log_file_size = strtoll( - innodb_log_file_size_var, &endptr, 10); - ut_ad(*endptr == 0); - } + if (innodb_log_file_size_var) + { + srv_log_file_size= strtoll(innodb_log_file_size_var, &endptr, 10); + ut_ad(*endptr == 0); + } - if (innodb_page_size_var) { - innobase_page_size = strtoll( - innodb_page_size_var, &endptr, 10); - ut_ad(*endptr == 0); - } + if (innodb_page_size_var) + { + innobase_page_size= strtoll(innodb_page_size_var, &endptr, 10); + ut_ad(*endptr == 0); + } - if (innodb_undo_tablespaces_var) { - srv_undo_tablespaces = strtoul(innodb_undo_tablespaces_var, - &endptr, 10); - ut_ad(*endptr == 0); - } + if (innodb_undo_tablespaces_var) + { + srv_undo_tablespaces= strtoul(innodb_undo_tablespaces_var, &endptr, 10); + ut_ad(*endptr == 0); + } - if (page_zip_level_var != NULL) { - page_zip_level = strtoul(page_zip_level_var, &endptr, 10); - ut_ad(*endptr == 0); - } + if (page_zip_level_var != NULL) + { + page_zip_level= strtoul(page_zip_level_var, &endptr, 10); + ut_ad(*endptr == 0); + } + + if (ignore_db_dirs) + xb_load_list_string(ignore_db_dirs, ",", register_ignore_db_dirs_filter); out: - free_mysql_variables(mysql_vars); + free_mysql_variables(mysql_vars); - return(ret); + return (ret); } /*********************************************************************//** diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index d11f7295f8e..040fbeb8f32 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -3632,6 +3632,11 @@ xb_register_exclude_filter_entry( &tables_exclude_hash); } +void register_ignore_db_dirs_filter(const char *name) +{ + xb_add_filter(name, &databases_exclude_hash); +} + /*********************************************************************** Register new table for the filter. */ static @@ -3694,26 +3699,24 @@ xb_register_exclude_regex( typedef void (*insert_entry_func_t)(const char*); -/*********************************************************************** -Scan string and load filter entries from it. */ -static -void -xb_load_list_string( -/*================*/ - char* list, /*!< in: string representing a list */ - const char* delimiters, /*!< in: delimiters of entries */ - insert_entry_func_t ins) /*!< in: callback to add entry */ +/* Scan string and load filter entries from it. +@param[in] list string representing a list +@param[in] delimiters delimiters of entries +@param[in] ins callback to add entry */ +void xb_load_list_string(char *list, const char *delimiters, + insert_entry_func_t ins) { - char* p; - char* saveptr; + char *p; + char *saveptr; - p = strtok_r(list, delimiters, &saveptr); - while (p) { + p= strtok_r(list, delimiters, &saveptr); + while (p) + { - ins(p); + ins(p); - p = strtok_r(NULL, delimiters, &saveptr); - } + p= strtok_r(NULL, delimiters, &saveptr); + } } /*********************************************************************** diff --git a/extra/mariabackup/xtrabackup.h b/extra/mariabackup/xtrabackup.h index c56e83f7a32..2dbdd442f95 100644 --- a/extra/mariabackup/xtrabackup.h +++ b/extra/mariabackup/xtrabackup.h @@ -194,4 +194,14 @@ void mdl_lock_init(); void mdl_lock_table(ulint space_id); void mdl_unlock_all(); bool ends_with(const char *str, const char *suffix); + +typedef void (*insert_entry_func_t)(const char*); + +/* Scan string and load filter entries from it. +@param[in] list string representing a list +@param[in] delimiters delimiters of entries +@param[in] ins callback to add entry */ +void xb_load_list_string(char *list, const char *delimiters, + insert_entry_func_t ins); +void register_ignore_db_dirs_filter(const char *name); #endif /* XB_XTRABACKUP_H */ diff --git a/mysql-test/suite/mariabackup/partial_exclude.opt b/mysql-test/suite/mariabackup/partial_exclude.opt new file mode 100644 index 00000000000..872335edb71 --- /dev/null +++ b/mysql-test/suite/mariabackup/partial_exclude.opt @@ -0,0 +1,2 @@ +--ignore-db-dirs=db3 +--ignore-db-dirs=db4 diff --git a/mysql-test/suite/mariabackup/partial_exclude.result b/mysql-test/suite/mariabackup/partial_exclude.result index 0da9b547caa..628613040e0 100644 --- a/mysql-test/suite/mariabackup/partial_exclude.result +++ b/mysql-test/suite/mariabackup/partial_exclude.result @@ -1,3 +1,6 @@ +select @@ignore_db_dirs; +@@ignore_db_dirs +db3,db4 CREATE TABLE t1(i INT) ENGINE INNODB; INSERT INTO t1 VALUES(1); CREATE TABLE t2(i int) ENGINE INNODB; diff --git a/mysql-test/suite/mariabackup/partial_exclude.test b/mysql-test/suite/mariabackup/partial_exclude.test index cd21ecff29b..99d14e58231 100644 --- a/mysql-test/suite/mariabackup/partial_exclude.test +++ b/mysql-test/suite/mariabackup/partial_exclude.test @@ -1,6 +1,13 @@ #--source include/innodb_page_size.inc # Test --databases-exclude and --tables-exclude feature of xtrabackup 2.3.8 +select @@ignore_db_dirs; + +let $MYSQLD_DATADIR= `select @@datadir`; + +mkdir $MYSQLD_DATADIR/db3; +mkdir $MYSQLD_DATADIR/db4; +mkdir $MYSQLD_DATADIR/db5; CREATE TABLE t1(i INT) ENGINE INNODB; INSERT INTO t1 VALUES(1); @@ -24,8 +31,19 @@ list_files $targetdir/test *.ibd; # check that db2 database is not in the backup (excluded) --error 1 list_files $targetdir/db2 *.ibd; +# check that db3 database is not in the backup (excluded) +--error 1 +list_files $targetdir/db3 *.ibd; +# check that db4 database is not in the backup (excluded) +--error 1 +list_files $targetdir/db4 *.ibd; +# check that db5 database is in the backup +list_files $targetdir/db5 *.ibd; DROP TABLE t1; DROP TABLE t2; DROP DATABASE db2; +rmdir $MYSQLD_DATADIR/db3; +rmdir $MYSQLD_DATADIR/db4; +rmdir $MYSQLD_DATADIR/db5; rmdir $targetdir; From a6a8774d47a4598f9fcff9d96602a9a550b85feb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Wed, 22 Apr 2020 07:35:41 +0300 Subject: [PATCH 14/16] MDEV-22181 : galera.galera_sst_mysqldump_with_key MTR failed: INSERT failed: 1146: Table 'test.t1' doesn't exist Add wait condition to make sure table test.t1 is replicated to node_2 before we insert to it. --- mysql-test/suite/galera/include/galera_st_shutdown_slave.inc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mysql-test/suite/galera/include/galera_st_shutdown_slave.inc b/mysql-test/suite/galera/include/galera_st_shutdown_slave.inc index 6c09b0ceb0c..207282c8237 100644 --- a/mysql-test/suite/galera/include/galera_st_shutdown_slave.inc +++ b/mysql-test/suite/galera/include/galera_st_shutdown_slave.inc @@ -12,6 +12,9 @@ INSERT INTO t1 VALUES ('node1_committed_before'); COMMIT; --connection node_2 +--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE 'test/t1'; +--source include/wait_condition.inc + SET AUTOCOMMIT=OFF; START TRANSACTION; INSERT INTO t1 VALUES ('node2_committed_before'); From efa3b3de35c7c57e30e45c3963d7bb1fbd57f499 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Otto=20Kek=C3=A4l=C3=A4inen?= Date: Tue, 21 Apr 2020 21:14:54 +0300 Subject: [PATCH 15/16] MDEV-22159: Don't redirect as root to a tmp file not owned by root Also add a check for tmp file being empty and bail out with a clear error message in such a case, as mysqld_safe prevents normal stderr from being displayed anywhere and would fail silently on this. --- scripts/mysqld_safe.sh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh index 290f43e9e84..07fa304a4cf 100644 --- a/scripts/mysqld_safe.sh +++ b/scripts/mysqld_safe.sh @@ -263,7 +263,9 @@ wsrep_recover_position() { fi if [ -f $wr_logfile ]; then - [ "$euid" = "0" ] && chown $user $wr_logfile + # NOTE! Do not change ownership of the temporary file, as on newer kernel + # versions fs.protected_regular is set to '2' and redirecting output with > + # as root to a file not owned by root will fail with "Permission denied" chmod 600 $wr_logfile else log_error "WSREP: mktemp failed" @@ -278,6 +280,11 @@ wsrep_recover_position() { eval "$mysqld_cmd --wsrep_recover $wr_options 2> $wr_logfile" + if [ ! -s "$wr_logfile" ]; then + log_error "Log file $wr_logfile was empty, cannot proceed. Is system running fs.protected_regular?" + exit 1 + fi + local rp="$(grep 'WSREP: Recovered position:' $wr_logfile)" if [ -z "$rp" ]; then local skipped="$(grep WSREP $wr_logfile | grep 'skipping position recovery')" From 8760ba652188f1f409f3a57b58fc0ce6e25ea6ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Wed, 22 Apr 2020 09:21:39 +0300 Subject: [PATCH 16/16] MDEV-21807 : galera.galera_slave_replay MTR failed: WSREP: Unknown parameter 'dbug Test do we have galera debug library with debug_sync functionality needs to be earlier. --- mysql-test/suite/galera/t/galera_slave_replay.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/suite/galera/t/galera_slave_replay.test b/mysql-test/suite/galera/t/galera_slave_replay.test index 96f6a3e26fc..b3bdaeaa532 100644 --- a/mysql-test/suite/galera/t/galera_slave_replay.test +++ b/mysql-test/suite/galera/t/galera_slave_replay.test @@ -9,12 +9,12 @@ --source include/have_innodb.inc --source include/have_debug.inc --source include/have_debug_sync.inc +--source include/galera_have_debug_sync.inc --connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2 --connection node_2a --source include/galera_cluster.inc ---source include/galera_have_debug_sync.inc # # node 1 is native MariaDB server operating as async replication master