From 77cce2074166f9c2a5bb99091f0f85aced3e0bc8 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 14 Feb 2018 19:07:33 +1100 Subject: [PATCH 001/106] MDEV-13129: apport - sanitize wsrep_sst_auth from report --- debian/dist/Ubuntu/mariadb-galera-server-5.5.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/debian/dist/Ubuntu/mariadb-galera-server-5.5.py b/debian/dist/Ubuntu/mariadb-galera-server-5.5.py index 1a94e1399a2..6d42cdb955c 100644 --- a/debian/dist/Ubuntu/mariadb-galera-server-5.5.py +++ b/debian/dist/Ubuntu/mariadb-galera-server-5.5.py @@ -13,8 +13,9 @@ def _add_my_conf_files(report, filename): report[key] = "" for line in read_file(filename).split('\n'): try: - if 'password' in line.split('=')[0]: - line = "%s = @@APPORTREPLACED@@" % (line.split('=')[0]) + sysvar = line.split('=')[0] + if sysvar in ['password', 'wsrep_sst_auth']: + line = "%s = @@APPORTREPLACED@@" % (sysvar) report[key] += line + '\n' except IndexError: continue From b3814af310e290033041625ee3070fcdbb90009a Mon Sep 17 00:00:00 2001 From: Daniel Bartholomew Date: Fri, 3 Aug 2018 11:44:54 -0400 Subject: [PATCH 002/106] bump the VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 23e938e60e1..4acb69e9e07 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ MYSQL_VERSION_MAJOR=5 MYSQL_VERSION_MINOR=5 -MYSQL_VERSION_PATCH=61 +MYSQL_VERSION_PATCH=62 MYSQL_VERSION_EXTRA= From 93ff64ebd7a7b2a534acc3ee8bf14cbfd8658d0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Sat, 8 Sep 2018 08:07:25 +0300 Subject: [PATCH 003/106] Remove incorrect install command. --- support-files/CMakeLists.txt | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/support-files/CMakeLists.txt b/support-files/CMakeLists.txt index 36340a2fbe7..c6ce2c04eb3 100644 --- a/support-files/CMakeLists.txt +++ b/support-files/CMakeLists.txt @@ -102,12 +102,8 @@ IF(UNIX) DESTINATION ${inst_location} COMPONENT SupportFiles PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) - CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/wsrep.cnf.sh + CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/wsrep.cnf.sh ${CMAKE_CURRENT_BINARY_DIR}/wsrep.cnf @ONLY) - INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/wsrep.cnf - DESTINATION ${inst_location} COMPONENT SupportFiles - PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ - GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) IF (INSTALL_SYSCONFDIR) INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/mysql-log-rotate DESTINATION ${INSTALL_SYSCONFDIR}/logrotate.d From 6aa578ec5a4009e33757d91d15947f51c98a5c88 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Fri, 15 Jun 2018 20:30:42 +0200 Subject: [PATCH 004/106] Generalize "bool shared/exclusive" argument to enum wsrep_append_foreign_key() and wsrep_append_key() used to take a boolean argument denoting whether the relevant certification key type is shared (assuming it is exclusive if the argument is false). Change that argument to the enum wsrep_key_type from wsrep_api.h, so that eventually other types can also be passed (like WSREP_KEY_SEMI). This is a non-functional change. (cherry picked from commit 360bf36dbb9378b36ef57921c725a9505e19e0d9) --- storage/innobase/handler/ha_innodb.cc | 69 ++++++++++++++++++--------- storage/innobase/handler/ha_innodb.h | 6 ++- storage/innobase/row/row0ins.c | 12 +++-- storage/xtradb/handler/ha_innodb.cc | 68 +++++++++++++++++--------- storage/xtradb/handler/ha_innodb.h | 6 ++- storage/xtradb/row/row0ins.c | 14 ++++-- 6 files changed, 123 insertions(+), 52 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 7aab200fed1..e6689f68704 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -110,6 +110,7 @@ enum_tx_isolation thd_get_trx_isolation(const THD* thd); # endif /* MYSQL_PLUGIN_IMPORT */ #ifdef WITH_WSREP +#include "../../../wsrep/wsrep_api.h" #include #include extern my_bool wsrep_certify_nonPK; @@ -6019,7 +6020,8 @@ report_error: BINLOG_FORMAT_ROW)) { */ - if (wsrep_append_keys(user_thd, false, record, NULL)) { + if (wsrep_append_keys(user_thd, WSREP_KEY_EXCLUSIVE, record, + NULL)) { DBUG_PRINT("wsrep", ("row key failed")); error_result = HA_ERR_INTERNAL_ERROR; goto wsrep_error; @@ -6391,7 +6393,8 @@ ha_innobase::update_row( DBUG_PRINT("wsrep", ("update row key")); - if (wsrep_append_keys(user_thd, false, old_row, new_row)) { + if (wsrep_append_keys(user_thd, WSREP_KEY_EXCLUSIVE, old_row, + new_row)) { DBUG_PRINT("wsrep", ("row key failed")); error = HA_ERR_INTERNAL_ERROR; goto wsrep_error; @@ -6446,7 +6449,8 @@ ha_innobase::delete_row( if (!error && wsrep_thd_exec_mode(user_thd) == LOCAL_STATE && wsrep_on(user_thd)) { - if (wsrep_append_keys(user_thd, false, record, NULL)) { + if (wsrep_append_keys(user_thd, WSREP_KEY_EXCLUSIVE, record, + NULL)) { DBUG_PRINT("wsrep", ("delete fail")); error = HA_ERR_INTERNAL_ERROR; goto wsrep_error; @@ -7259,6 +7263,21 @@ wsrep_dict_foreign_find_index( ibool check_charsets, ulint check_null); +inline +const char* +wsrep_key_type_to_str(wsrep_key_type type) +{ + switch (type) { + case WSREP_KEY_SHARED: + return "shared"; + case WSREP_KEY_SEMI: + return "semi"; + case WSREP_KEY_EXCLUSIVE: + return "exclusive"; + }; + return "unknown"; +} + ulint wsrep_append_foreign_key( /*===========================*/ @@ -7267,7 +7286,8 @@ wsrep_append_foreign_key( const rec_t* rec, /*!mysql_thd; @@ -7363,19 +7383,21 @@ wsrep_append_foreign_key( key[0] = (char)i; rcode = wsrep_rec_get_foreign_key( - &key[1], &len, rec, index, idx, + &key[1], &len, rec, index, idx, wsrep_protocol_version > 1); + if (rcode != DB_SUCCESS) { WSREP_ERROR( - "FK key set failed: %lu (%lu %lu), index: %s %s, %s", - rcode, referenced, shared, + "FK key set failed: %lu (%lu %s), index: %s %s, %s", + rcode, referenced, wsrep_key_type_to_str(key_type), (index && index->name) ? index->name : - "void index", - (index && index->table_name) ? index->table_name : - "void table", + "void index", + (index && index->table_name) ? index->table_name : + "void table", wsrep_thd_query(thd)); return rcode; } + strncpy(cache_key, (wsrep_protocol_version > 1) ? ((referenced) ? @@ -7419,7 +7441,7 @@ wsrep_append_foreign_key( wsrep_ws_handle(thd, trx), &wkey, 1, - shared ? WSREP_KEY_SHARED : WSREP_KEY_EXCLUSIVE, + key_type, copy); if (rcode) { DBUG_PRINT("wsrep", ("row key failed: %lu", rcode)); @@ -7442,15 +7464,16 @@ wsrep_append_key( TABLE *table, const char* key, uint16_t key_len, - bool shared + wsrep_key_type key_type /*!< in: access type of this key + (shared, exclusive, semi...) */ ) { DBUG_ENTER("wsrep_append_key"); bool const copy = true; #ifdef WSREP_DEBUG_PRINT fprintf(stderr, "%s conn %ld, trx %llu, keylen %d, table %s\n Query: %s ", - (shared) ? "Shared" : "Exclusive", - wsrep_thd_thread_id(thd), trx->id, key_len, + wsrep_key_type_to_str(key_type), + wsrep_thd_thread_id(thd), trx->id, key_len, table_share->table_name.str, wsrep_thd_query(thd)); for (int i=0; iflags & HA_NOSAME || shared) + if (key_info->flags & HA_NOSAME || + key_type == WSREP_KEY_SHARED) key_appended = true; } else @@ -7599,7 +7624,7 @@ ha_innobase::wsrep_append_keys( int rcode = wsrep_append_key( thd, trx, table_share, table, - keyval1, len+1, shared); + keyval1, len+1, key_type); if (rcode) DBUG_RETURN(rcode); } } @@ -7615,7 +7640,7 @@ ha_innobase::wsrep_append_keys( wsrep_calc_row_hash(digest, record0, table, prebuilt, thd); if ((rcode = wsrep_append_key(thd, trx, table_share, table, (const char*) digest, 16, - shared))) { + key_type))) { DBUG_RETURN(rcode); } @@ -7625,7 +7650,7 @@ ha_innobase::wsrep_append_keys( if ((rcode = wsrep_append_key(thd, trx, table_share, table, (const char*) digest, - 16, shared))) { + 16, key_type))) { DBUG_RETURN(rcode); } } diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h index f5660b79027..c239a3218b1 100644 --- a/storage/innobase/handler/ha_innodb.h +++ b/storage/innobase/handler/ha_innodb.h @@ -28,6 +28,10 @@ this program; if not, write to the Free Software Foundation, Inc., #pragma interface /* gcc class implementation */ #endif +#ifdef WITH_WSREP +#include "../../../wsrep/wsrep_api.h" +#endif /* WITH_WSREP */ + /* Structure defines translation table between mysql index and innodb index structures */ typedef struct innodb_idx_translate_struct { @@ -115,7 +119,7 @@ class ha_innobase: public handler int info_low(uint flag, bool called_from_analyze); #ifdef WITH_WSREP - int wsrep_append_keys(THD *thd, bool shared, + int wsrep_append_keys(THD *thd, wsrep_key_type key_type, const uchar* record0, const uchar* record1); #endif /* Init values for the class: */ diff --git a/storage/innobase/row/row0ins.c b/storage/innobase/row/row0ins.c index 28cfcc582f3..21e7f1609ff 100644 --- a/storage/innobase/row/row0ins.c +++ b/storage/innobase/row/row0ins.c @@ -56,6 +56,10 @@ Created 4/20/1996 Heikki Tuuri #define ROW_INS_PREV 1 #define ROW_INS_NEXT 2 +#ifdef WITH_WSREP +#include "../../../wsrep/wsrep_api.h" +#endif /* WITH_WSREP */ + /************************************************************************* IMPORTANT NOTE: Any operation that generates redo MUST check that there is enough space in the redo log before for that operation. This is @@ -767,7 +771,7 @@ ulint wsrep_append_foreign_key(trx_t *trx, const rec_t* clust_rec, dict_index_t* clust_index, ibool referenced, - ibool shared); + enum wsrep_key_type key_type); #endif /* WITH_WSREP */ /*********************************************************************//** @@ -1088,7 +1092,7 @@ row_ins_foreign_check_on_constraint( foreign, clust_rec, clust_index, - FALSE, FALSE); + FALSE, WSREP_KEY_EXCLUSIVE); if (err != DB_SUCCESS) { fprintf(stderr, "WSREP: foreign key append failed: %lu\n", err); @@ -1437,7 +1441,9 @@ run_again: rec, check_index, check_ref, - (upd_node) ? TRUE : FALSE); + upd_node != NULL + ? WSREP_KEY_SHARED + : WSREP_KEY_EXCLUSIVE); #endif /* WITH_WSREP */ goto end_scan; } else if (foreign->type != 0) { diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index fca29d50e0a..363f6634c2d 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -127,6 +127,7 @@ extern ib_int64_t trx_sys_mysql_relay_log_pos; # endif /* MYSQL_PLUGIN_IMPORT */ #ifdef WITH_WSREP +#include "../../../wsrep/wsrep_api.h" #include #include extern my_bool wsrep_certify_nonPK; @@ -7043,7 +7044,7 @@ report_error: thd_binlog_format(user_thd) == BINLOG_FORMAT_ROW)) { */ - if (wsrep_append_keys(user_thd, false, record, NULL)) { + if (wsrep_append_keys(user_thd, WSREP_KEY_EXCLUSIVE, record, NULL)) { DBUG_PRINT("wsrep", ("row key failed")); error_result = HA_ERR_INTERNAL_ERROR; goto wsrep_error; @@ -7437,7 +7438,8 @@ ha_innobase::update_row( DBUG_PRINT("wsrep", ("update row key")); - if (wsrep_append_keys(user_thd, false, old_row, new_row)) { + if (wsrep_append_keys(user_thd, WSREP_KEY_EXCLUSIVE, old_row, + new_row)) { DBUG_PRINT("wsrep", ("row key failed")); error = HA_ERR_INTERNAL_ERROR; goto wsrep_error; @@ -7506,7 +7508,8 @@ ha_innobase::delete_row( if (!error && wsrep_thd_exec_mode(user_thd) == LOCAL_STATE && wsrep_on(user_thd)) { - if (wsrep_append_keys(user_thd, false, record, NULL)) { + if (wsrep_append_keys(user_thd, WSREP_KEY_EXCLUSIVE, record, + NULL)) { DBUG_PRINT("wsrep", ("delete fail")); error = HA_ERR_INTERNAL_ERROR; goto wsrep_error; @@ -8366,6 +8369,21 @@ wsrep_dict_foreign_find_index( ibool check_charsets, ulint check_null); +inline +const char* +wsrep_key_type_to_str(wsrep_key_type type) +{ + switch (type) { + case WSREP_KEY_SHARED: + return "shared"; + case WSREP_KEY_SEMI: + return "semi"; + case WSREP_KEY_EXCLUSIVE: + return "exclusive"; + }; + return "unknown"; +} + ulint wsrep_append_foreign_key( /*===========================*/ @@ -8374,7 +8392,8 @@ wsrep_append_foreign_key( const rec_t* rec, /*!mysql_thd; @@ -8470,19 +8489,21 @@ wsrep_append_foreign_key( key[0] = (char)i; rcode = wsrep_rec_get_foreign_key( - &key[1], &len, rec, index, idx, + &key[1], &len, rec, index, idx, wsrep_protocol_version > 1); + if (rcode != DB_SUCCESS) { WSREP_ERROR( - "FK key set failed: %lu (%lu %lu), index: %s %s, %s", - rcode, referenced, shared, + "FK key set failed: %lu (%lu %s), index: %s %s, %s", + rcode, referenced, wsrep_key_type_to_str(key_type), (index && index->name) ? index->name : - "void index", - (index && index->table_name) ? index->table_name : - "void table", + "void index", + (index && index->table_name) ? index->table_name : + "void table", wsrep_thd_query(thd)); return rcode; } + strncpy(cache_key, (wsrep_protocol_version > 1) ? ((referenced) ? @@ -8526,7 +8547,7 @@ wsrep_append_foreign_key( wsrep_ws_handle(thd, trx), &wkey, 1, - shared ? WSREP_KEY_SHARED : WSREP_KEY_EXCLUSIVE, + key_type, copy); if (rcode) { DBUG_PRINT("wsrep", ("row key failed: %lu", rcode)); @@ -8549,15 +8570,16 @@ wsrep_append_key( TABLE *table, const char* key, uint16_t key_len, - bool shared + wsrep_key_type key_type /*!< in: access type of this key + (shared, exclusive, semi...) */ ) { DBUG_ENTER("wsrep_append_key"); bool const copy = true; #ifdef WSREP_DEBUG_PRINT fprintf(stderr, "%s conn %ld, trx %llu, keylen %d, table %s\n Query: %s ", - (shared) ? "Shared" : "Exclusive", - wsrep_thd_thread_id(thd), trx->id, key_len, + wsrep_key_type_to_str(key_type), + wsrep_thd_thread_id(thd), trx->id, key_len, table_share->table_name.str, wsrep_thd_query(thd)); for (int i=0; iflags & HA_NOSAME || shared) + if (key_info->flags & HA_NOSAME || + key_type == WSREP_KEY_SHARED) key_appended = true; } else @@ -8706,7 +8730,7 @@ ha_innobase::wsrep_append_keys( int rcode = wsrep_append_key( thd, trx, table_share, table, - keyval1, len+1, shared); + keyval1, len+1, key_type); if (rcode) DBUG_RETURN(rcode); } } @@ -8722,7 +8746,7 @@ ha_innobase::wsrep_append_keys( wsrep_calc_row_hash(digest, record0, table, prebuilt, thd); if ((rcode = wsrep_append_key(thd, trx, table_share, table, (const char*) digest, 16, - shared))) { + key_type))) { DBUG_RETURN(rcode); } @@ -8732,7 +8756,7 @@ ha_innobase::wsrep_append_keys( if ((rcode = wsrep_append_key(thd, trx, table_share, table, (const char*) digest, - 16, shared))) { + 16, key_type))) { DBUG_RETURN(rcode); } } diff --git a/storage/xtradb/handler/ha_innodb.h b/storage/xtradb/handler/ha_innodb.h index f087a2d6ea0..4f177fb7a79 100644 --- a/storage/xtradb/handler/ha_innodb.h +++ b/storage/xtradb/handler/ha_innodb.h @@ -28,6 +28,10 @@ this program; if not, write to the Free Software Foundation, Inc., #pragma interface /* gcc class implementation */ #endif +#ifdef WITH_WSREP +#include "../../../wsrep/wsrep_api.h" +#endif /* WITH_WSREP */ + /* Structure defines translation table between mysql index and innodb index structures */ typedef struct innodb_idx_translate_struct { @@ -116,7 +120,7 @@ class ha_innobase: public handler int info_low(uint flag, bool called_from_analyze); #ifdef WITH_WSREP - int wsrep_append_keys(THD *thd, bool shared, + int wsrep_append_keys(THD *thd, wsrep_key_type key_type, const uchar* record0, const uchar* record1); #endif /* Init values for the class: */ diff --git a/storage/xtradb/row/row0ins.c b/storage/xtradb/row/row0ins.c index 6187a1149f8..f0cea9e847d 100644 --- a/storage/xtradb/row/row0ins.c +++ b/storage/xtradb/row/row0ins.c @@ -56,6 +56,10 @@ Created 4/20/1996 Heikki Tuuri #define ROW_INS_PREV 1 #define ROW_INS_NEXT 2 +#ifdef WITH_WSREP +#include "../../../wsrep/wsrep_api.h" +#endif /* WITH_WSREP */ + /************************************************************************* IMPORTANT NOTE: Any operation that generates redo MUST check that there is enough space in the redo log before for that operation. This is @@ -768,7 +772,7 @@ ulint wsrep_append_foreign_key(trx_t *trx, const rec_t* clust_rec, dict_index_t* clust_index, ibool referenced, - ibool shared); + enum wsrep_key_type key_type); #endif /* WITH_WSREP */ /*********************************************************************//** @@ -1090,7 +1094,9 @@ row_ins_foreign_check_on_constraint( clust_rec, clust_index, FALSE, - (node) ? TRUE : FALSE); + node != NULL + ? WSREP_KEY_SHARED + : WSREP_KEY_EXCLUSIVE); if (err != DB_SUCCESS) { fprintf(stderr, "WSREP: foreign key append failed: %lu\n", err); @@ -1445,7 +1451,9 @@ run_again: rec, check_index, check_ref, - (upd_node) ? TRUE : FALSE); + upd_node != NULL + ? WSREP_KEY_SHARED + : WSREP_KEY_EXCLUSIVE); #endif /* WITH_WSREP */ goto end_scan; } else if (foreign->type != 0) { From 27dcef390026ab2ac547ed8592b9fed22cd93b70 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Wed, 6 Jun 2018 17:25:51 +0200 Subject: [PATCH 005/106] Add a new config variable wsrep_certification_rules This is used for controlling whether to use a new/optimized certification rules or the old/classic ones that could cause more certification failures - when foreign keys are used and two INSERTs are done concurrently to the child table from different nodes. (cherry picked from commit 815d73e6af8daace6262ab63ca6c043ffc4204b3) --- sql/sys_vars.cc | 13 +++++++++++++ sql/wsrep_mysqld.cc | 1 + sql/wsrep_mysqld.h | 2 +- storage/innobase/row/row0ins.c | 18 +++++++++++++++--- storage/xtradb/row/row0ins.c | 1 + 5 files changed, 31 insertions(+), 4 deletions(-) diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 8a9120abdd0..d0b07472894 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -3887,6 +3887,19 @@ static Sys_var_mybool Sys_wsrep_certify_nonPK( GLOBAL_VAR(wsrep_certify_nonPK), CMD_LINE(OPT_ARG), DEFAULT(TRUE)); +static const char *wsrep_certification_rules_names[]= { "strict", "optimized", NullS }; +static Sys_var_enum Sys_wsrep_certification_rules( + "wsrep_certification_rules", + "Certification rules to use in the cluster. Possible values are: " + "\"strict\": stricter rules that could result in more certification " + "failures. " + "\"optimized\": relaxed rules that allow more concurrency and " + "cause less certification failures.", + READ_ONLY GLOBAL_VAR(wsrep_certification_rules), CMD_LINE(REQUIRED_ARG), + wsrep_certification_rules_names, DEFAULT(WSREP_CERTIFICATION_RULES_STRICT), + NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), + ON_UPDATE(0)); + static Sys_var_mybool Sys_wsrep_causal_reads( "wsrep_causal_reads", "(DEPRECATED) Setting this variable is equivalent " "to setting wsrep_sync_wait READ flag", diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index a7950754666..b61cebf6334 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -51,6 +51,7 @@ ulong wsrep_max_ws_size = 1073741824UL;//max ws (RBR buffer) size ulong wsrep_max_ws_rows = 65536; // max number of rows in ws int wsrep_to_isolation = 0; // # of active TO isolation threads my_bool wsrep_certify_nonPK = 1; // certify, even when no primary key +ulong wsrep_certification_rules = WSREP_CERTIFICATION_RULES_STRICT; long wsrep_max_protocol_version = 3; // maximum protocol version to use ulong wsrep_forced_binlog_format = BINLOG_FORMAT_UNSPEC; my_bool wsrep_recovery = 0; // recovery diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h index b1dc5ba452b..e2800c8c2a8 100644 --- a/sql/wsrep_mysqld.h +++ b/sql/wsrep_mysqld.h @@ -20,6 +20,7 @@ typedef struct st_mysql_show_var SHOW_VAR; #include #include "../wsrep/wsrep_api.h" +#include "wsrep_mysqld_c.h" #define WSREP_UNDEFINED_TRX_ID ULONGLONG_MAX @@ -58,7 +59,6 @@ enum wsrep_consistency_check_mode { CONSISTENCY_CHECK_RUNNING, }; - // Global wsrep parameters extern wsrep_t* wsrep; diff --git a/storage/innobase/row/row0ins.c b/storage/innobase/row/row0ins.c index 21e7f1609ff..b2706de2bbb 100644 --- a/storage/innobase/row/row0ins.c +++ b/storage/innobase/row/row0ins.c @@ -58,6 +58,7 @@ Created 4/20/1996 Heikki Tuuri #ifdef WITH_WSREP #include "../../../wsrep/wsrep_api.h" +#include "wsrep_mysqld_c.h" #endif /* WITH_WSREP */ /************************************************************************* @@ -1435,15 +1436,26 @@ run_again: if (check_ref) { err = DB_SUCCESS; #ifdef WITH_WSREP + enum wsrep_key_type key_type = WSREP_KEY_EXCLUSIVE; + if (upd_node != NULL) { + key_type = WSREP_KEY_SHARED; + } else { + switch (wsrep_certification_rules) { + case WSREP_CERTIFICATION_RULES_STRICT: + key_type = WSREP_KEY_EXCLUSIVE; + break; + case WSREP_CERTIFICATION_RULES_OPTIMIZED: + key_type = WSREP_KEY_SEMI; + break; + } + } err = wsrep_append_foreign_key( thr_get_trx(thr), foreign, rec, check_index, check_ref, - upd_node != NULL - ? WSREP_KEY_SHARED - : WSREP_KEY_EXCLUSIVE); + key_type); #endif /* WITH_WSREP */ goto end_scan; } else if (foreign->type != 0) { diff --git a/storage/xtradb/row/row0ins.c b/storage/xtradb/row/row0ins.c index f0cea9e847d..92103e815ae 100644 --- a/storage/xtradb/row/row0ins.c +++ b/storage/xtradb/row/row0ins.c @@ -58,6 +58,7 @@ Created 4/20/1996 Heikki Tuuri #ifdef WITH_WSREP #include "../../../wsrep/wsrep_api.h" +#include "wsrep_mysqld_c.h" #endif /* WITH_WSREP */ /************************************************************************* From 508e715cb801d2d7775ee5f4d69d1ac2f68f7fee Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Fri, 17 Aug 2018 18:14:22 +0200 Subject: [PATCH 006/106] Fix compilation error in row0ins.c row0ins.c:1437:6: error: ISO C90 forbids mixed declarations and code [-Werror=declaration-after-statement] enum wsrep_key_type key_type = WSREP_KEY_EXCLUSIVE; ^ --- storage/innobase/row/row0ins.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/storage/innobase/row/row0ins.c b/storage/innobase/row/row0ins.c index b2706de2bbb..a809a1d7d7f 100644 --- a/storage/innobase/row/row0ins.c +++ b/storage/innobase/row/row0ins.c @@ -1434,9 +1434,11 @@ run_again: } if (check_ref) { - err = DB_SUCCESS; #ifdef WITH_WSREP enum wsrep_key_type key_type = WSREP_KEY_EXCLUSIVE; +#endif /* WITH_WSREP */ + err = DB_SUCCESS; +#ifdef WITH_WSREP if (upd_node != NULL) { key_type = WSREP_KEY_SHARED; } else { From b47a2182f68abb2044294fbb1d6925d363eb80a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Wed, 10 Oct 2018 13:30:56 +0300 Subject: [PATCH 007/106] MariaDB adjustments. --- storage/innobase/row/row0ins.c | 4 +++- storage/xtradb/row/row0ins.c | 26 +++++++++++++++++++------- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/storage/innobase/row/row0ins.c b/storage/innobase/row/row0ins.c index a809a1d7d7f..5b327d11e16 100644 --- a/storage/innobase/row/row0ins.c +++ b/storage/innobase/row/row0ins.c @@ -1093,7 +1093,8 @@ row_ins_foreign_check_on_constraint( foreign, clust_rec, clust_index, - FALSE, WSREP_KEY_EXCLUSIVE); + FALSE, + WSREP_KEY_EXCLUSIVE); if (err != DB_SUCCESS) { fprintf(stderr, "WSREP: foreign key append failed: %lu\n", err); @@ -1451,6 +1452,7 @@ run_again: break; } } + err = wsrep_append_foreign_key( thr_get_trx(thr), foreign, diff --git a/storage/xtradb/row/row0ins.c b/storage/xtradb/row/row0ins.c index 92103e815ae..3acdc093907 100644 --- a/storage/xtradb/row/row0ins.c +++ b/storage/xtradb/row/row0ins.c @@ -1095,9 +1095,7 @@ row_ins_foreign_check_on_constraint( clust_rec, clust_index, FALSE, - node != NULL - ? WSREP_KEY_SHARED - : WSREP_KEY_EXCLUSIVE); + WSREP_KEY_EXCLUSIVE); if (err != DB_SUCCESS) { fprintf(stderr, "WSREP: foreign key append failed: %lu\n", err); @@ -1444,17 +1442,31 @@ run_again: } if (check_ref) { +#ifdef WITH_WSREP + enum wsrep_key_type key_type = WSREP_KEY_EXCLUSIVE; +#endif /* WITH_WSREP */ err = DB_SUCCESS; #ifdef WITH_WSREP - err = wsrep_append_foreign_key( + if (upd_node != NULL) { + key_type = WSREP_KEY_SHARED; + } else { + switch (wsrep_certification_rules) { + case WSREP_CERTIFICATION_RULES_STRICT: + key_type = WSREP_KEY_EXCLUSIVE; + break; + case WSREP_CERTIFICATION_RULES_OPTIMIZED: + key_type = WSREP_KEY_SEMI; + break; + } + } + + err = wsrep_append_foreign_key( thr_get_trx(thr), foreign, rec, check_index, check_ref, - upd_node != NULL - ? WSREP_KEY_SHARED - : WSREP_KEY_EXCLUSIVE); + key_type); #endif /* WITH_WSREP */ goto end_scan; } else if (foreign->type != 0) { From 8524c81254521673bb78926cc37d77455bba792e Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 28 Aug 2018 13:02:36 +0200 Subject: [PATCH 008/106] Make config knob wsrep_certification_rules dynamic There is no reason for it to be readonly at runtime and it is dynamic in 5.6+ already. --- sql/sys_vars.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index d0b07472894..6f6e7da531e 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -3895,7 +3895,7 @@ static Sys_var_enum Sys_wsrep_certification_rules( "failures. " "\"optimized\": relaxed rules that allow more concurrency and " "cause less certification failures.", - READ_ONLY GLOBAL_VAR(wsrep_certification_rules), CMD_LINE(REQUIRED_ARG), + GLOBAL_VAR(wsrep_certification_rules), CMD_LINE(REQUIRED_ARG), wsrep_certification_rules_names, DEFAULT(WSREP_CERTIFICATION_RULES_STRICT), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(0)); From f5003994211dc648c83441f9466b4e7ac1cf9067 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Wed, 29 Aug 2018 11:16:34 +0200 Subject: [PATCH 009/106] Bump WSREP_PATCH_VERSION --- cmake/wsrep.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/wsrep.cmake b/cmake/wsrep.cmake index 5020a2669b4..2ccd1b388f3 100644 --- a/cmake/wsrep.cmake +++ b/cmake/wsrep.cmake @@ -18,7 +18,7 @@ # so WSREP_VERSION is produced regardless # Set the patch version -SET(WSREP_PATCH_VERSION "23") +SET(WSREP_PATCH_VERSION "24") # MariaDB addition: Revision number of the last revision merged from # codership branch visible in @@visible_comment. From 48924ae9c5660396f0bc8a1f56abcaa3c3d6a501 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Wed, 10 Oct 2018 14:28:42 +0300 Subject: [PATCH 010/106] Add missing file. --- sql/wsrep_mysqld_c.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 sql/wsrep_mysqld_c.h diff --git a/sql/wsrep_mysqld_c.h b/sql/wsrep_mysqld_c.h new file mode 100644 index 00000000000..15ca0ae2a6d --- /dev/null +++ b/sql/wsrep_mysqld_c.h @@ -0,0 +1,26 @@ +/* Copyright 2018-2018 Codership Oy + + 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 Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifndef WSREP_MYSQLD_C_H +#define WSREP_MYSQLD_C_H + +enum enum_wsrep_certification_rules { + WSREP_CERTIFICATION_RULES_STRICT, + WSREP_CERTIFICATION_RULES_OPTIMIZED +}; + +extern ulong wsrep_certification_rules; + +#endif /* WSREP_MYSQLD_C_H */ From 8b92c642981e7b226e0d93b958cc470bb1e6fad0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Wed, 10 Oct 2018 18:30:42 +0300 Subject: [PATCH 011/106] Fix tests affected by new configuration variable on Galera. --- mysql-test/r/mysqld--help.result | 7 +++++++ mysql-test/suite/sys_vars/r/all_vars.result | 1 + 2 files changed, 8 insertions(+) diff --git a/mysql-test/r/mysqld--help.result b/mysql-test/r/mysqld--help.result index 5b25b4d01a7..aff1cb6bace 100644 --- a/mysql-test/r/mysqld--help.result +++ b/mysql-test/r/mysqld--help.result @@ -866,6 +866,12 @@ The following specify which files/extra groups are read (specified before remain --wsrep-causal-reads (DEPRECATED) Setting this variable is equivalent to setting wsrep_sync_wait READ flag + --wsrep-certification-rules=name + Certification rules to use in the cluster. Possible + values are: "strict": stricter rules that could result in + more certification failures. "optimized": relaxed rules + that allow more concurrency and cause less certification + failures. --wsrep-certify-nonPK Certify tables with no primary key (Defaults to on; use --skip-wsrep-certify-nonPK to disable.) @@ -1198,6 +1204,7 @@ wait-timeout 28800 wsrep-OSU-method TOI wsrep-auto-increment-control TRUE wsrep-causal-reads FALSE +wsrep-certification-rules strict wsrep-certify-nonPK TRUE wsrep-cluster-address wsrep-cluster-name my_wsrep_cluster diff --git a/mysql-test/suite/sys_vars/r/all_vars.result b/mysql-test/suite/sys_vars/r/all_vars.result index 1bd4e394f6a..b7beb7b5347 100644 --- a/mysql-test/suite/sys_vars/r/all_vars.result +++ b/mysql-test/suite/sys_vars/r/all_vars.result @@ -10,5 +10,6 @@ there should be *no* long test name listed below: select distinct variable_name as `there should be *no* variables listed below:` from t2 left join t1 on variable_name=test_name where test_name is null; there should be *no* variables listed below: +wsrep_certification_rules drop table t1; drop table t2; From e16d91b889c3307ff1512d20221082e78cc8fcc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Wed, 31 Oct 2018 18:28:33 +0200 Subject: [PATCH 012/106] Fix merge error on tests. --- mysql-test/t/alter_table.test | 81 ++++++++++++++++++----------------- mysql-test/t/grant.test | 38 ++++++++-------- mysql-test/t/type_float.test | 41 +++++++++--------- 3 files changed, 82 insertions(+), 78 deletions(-) diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test index 30300efb34e..aea1a880a81 100644 --- a/mysql-test/t/alter_table.test +++ b/mysql-test/t/alter_table.test @@ -287,7 +287,7 @@ drop table t1; # set names koi8r; create table t1 (a char(10) character set koi8r); -insert into t1 values ('����'); +insert into t1 values (''); select a,hex(a) from t1; alter table t1 change a a char(10) character set cp1251; select a,hex(a) from t1; @@ -367,7 +367,7 @@ DROP TABLE T12207; # modified. In other words, the values were reinterpreted # as UTF8 instead of being converted. create table t1 (a text) character set koi8r; -insert into t1 values (_koi8r'����'); +insert into t1 values (_koi8r''); select hex(a) from t1; alter table t1 convert to character set cp1251; select hex(a) from t1; @@ -1346,52 +1346,55 @@ DROP TABLE t1, t2, t3; SET SQL_MODE=default; SET GLOBAL max_allowed_packet=default; +# +# Test of ALTER TABLE IF [NOT] EXISTS +# -SET GLOBAL max_allowed_packet=17825792; +CREATE TABLE t1 ( + id INT(11) NOT NULL, + x_param INT(11) DEFAULT NULL, + PRIMARY KEY (id) +) ENGINE=MYISAM; ---connect(con1, localhost, root,,) -CREATE TABLE t1 (t1_fld1 TEXT); -CREATE TABLE t2 (t2_fld1 MEDIUMTEXT); -CREATE TABLE t3 (t3_fld1 LONGTEXT); +ALTER TABLE t1 ADD COLUMN IF NOT EXISTS id INT, + ADD COLUMN IF NOT EXISTS lol INT AFTER id; +ALTER TABLE t1 ADD COLUMN IF NOT EXISTS lol INT AFTER id; +ALTER TABLE t1 DROP COLUMN IF EXISTS lol; +ALTER TABLE t1 DROP COLUMN IF EXISTS lol; -INSERT INTO t1 VALUES (REPEAT('a',300)); -INSERT INTO t2 VALUES (REPEAT('b',65680)); -INSERT INTO t3 VALUES (REPEAT('c',16777300)); +ALTER TABLE t1 ADD KEY IF NOT EXISTS x_param(x_param); +ALTER TABLE t1 ADD KEY IF NOT EXISTS x_param(x_param); +ALTER TABLE t1 MODIFY IF EXISTS lol INT; -SELECT LENGTH(t1_fld1) FROM t1; -SELECT LENGTH(t2_fld1) FROM t2; -SELECT LENGTH(t3_fld1) FROM t3; +DROP INDEX IF EXISTS x_param ON t1; +DROP INDEX IF EXISTS x_param ON t1; +CREATE INDEX IF NOT EXISTS x_param1 ON t1(x_param); +CREATE INDEX IF NOT EXISTS x_param1 ON t1(x_param); +SHOW CREATE TABLE t1; +DROP TABLE t1; ---echo # With strict mode -SET SQL_MODE='STRICT_ALL_TABLES'; +CREATE TABLE t1 ( + id INT(11) NOT NULL, + x_param INT(11) DEFAULT NULL, + PRIMARY KEY (id) +) ENGINE=INNODB; ---error ER_DATA_TOO_LONG -ALTER TABLE t1 CHANGE `t1_fld1` `my_t1_fld1` TINYTEXT; ---error ER_DATA_TOO_LONG -ALTER TABLE t2 CHANGE `t2_fld1` `my_t2_fld1` TEXT; ---error ER_DATA_TOO_LONG -ALTER TABLE t3 CHANGE `t3_fld1` `my_t3_fld1` MEDIUMTEXT; +CREATE TABLE t2 ( + id INT(11) NOT NULL) ENGINE=INNODB; ---echo # With non-strict mode -SET SQL_MODE=''; +ALTER TABLE t1 ADD COLUMN IF NOT EXISTS id INT, + ADD COLUMN IF NOT EXISTS lol INT AFTER id; +ALTER TABLE t1 ADD COLUMN IF NOT EXISTS lol INT AFTER id; +ALTER TABLE t1 DROP COLUMN IF EXISTS lol; +ALTER TABLE t1 DROP COLUMN IF EXISTS lol; -ALTER TABLE t1 CHANGE `t1_fld1` `my_t1_fld1` TINYTEXT; -ALTER TABLE t2 CHANGE `t2_fld1` `my_t2_fld1` TEXT; -ALTER TABLE t3 CHANGE `t3_fld1` `my_t3_fld1` MEDIUMTEXT; +ALTER TABLE t1 ADD KEY IF NOT EXISTS x_param(x_param); +ALTER TABLE t1 ADD KEY IF NOT EXISTS x_param(x_param); +ALTER TABLE t1 MODIFY IF EXISTS lol INT; -SELECT LENGTH(my_t1_fld1) FROM t1; -SELECT LENGTH(my_t2_fld1) FROM t2; -SELECT LENGTH(my_t3_fld1) FROM t3; - -# Cleanup ---disconnect con1 ---source include/wait_until_disconnected.inc - ---connection default -DROP TABLE t1, t2, t3; - -SET SQL_MODE=default; -SET GLOBAL max_allowed_packet=default; +DROP INDEX IF EXISTS x_param ON t1; +DROP INDEX IF EXISTS x_param ON t1; +CREATE INDEX IF NOT EXISTS x_param1 ON t1(x_param); CREATE INDEX IF NOT EXISTS x_param1 ON t1(x_param); SHOW CREATE TABLE t1; diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test index b96f8033be5..f2dfb01cc39 100644 --- a/mysql-test/t/grant.test +++ b/mysql-test/t/grant.test @@ -210,26 +210,26 @@ drop user mysqltest_1@localhost; # Bug#3403 Wrong encoding in SHOW GRANTS output # SET NAMES koi8r; -CREATE DATABASE ��; -USE ��; -CREATE TABLE ��� (��� INT); +CREATE DATABASE ; +USE ; +CREATE TABLE ( INT); -GRANT SELECT ON ��.* TO ����@localhost; -SHOW GRANTS FOR ����@localhost; -REVOKE SELECT ON ��.* FROM ����@localhost; +GRANT SELECT ON .* TO @localhost; +SHOW GRANTS FOR @localhost; +REVOKE SELECT ON .* FROM @localhost; -GRANT SELECT ON ��.��� TO ����@localhost; -SHOW GRANTS FOR ����@localhost; -REVOKE SELECT ON ��.��� FROM ����@localhost; +GRANT SELECT ON . TO @localhost; +SHOW GRANTS FOR @localhost; +REVOKE SELECT ON . FROM @localhost; -GRANT SELECT (���) ON ��.��� TO ����@localhost; -SHOW GRANTS FOR ����@localhost; -REVOKE SELECT (���) ON ��.��� FROM ����@localhost; +GRANT SELECT () ON . TO @localhost; +SHOW GRANTS FOR @localhost; +REVOKE SELECT () ON . FROM @localhost; # Revoke does not drop user. Leave a clean user table for the next tests. -DROP USER ����@localhost; +DROP USER @localhost; -DROP DATABASE ��; +DROP DATABASE ; SET NAMES latin1; # @@ -512,14 +512,14 @@ set @user123="non-existent"; select * from mysql.db where user=@user123; set names koi8r; -create database ��; -grant select on ��.* to root@localhost; -select hex(Db) from mysql.db where Db='��'; +create database ; +grant select on .* to root@localhost; +select hex(Db) from mysql.db where Db=''; show grants for root@localhost; flush privileges; show grants for root@localhost; -drop database ��; -revoke all privileges on ��.* from root@localhost; +drop database ; +revoke all privileges on .* from root@localhost; show grants for root@localhost; set names latin1; diff --git a/mysql-test/t/type_float.test b/mysql-test/t/type_float.test index ebed9550afe..5dfb4a75bb3 100644 --- a/mysql-test/t/type_float.test +++ b/mysql-test/t/type_float.test @@ -363,32 +363,33 @@ DROP TABLE t1; --echo # ---echo # MDEV-17249 MAKETIME(-1e50,0,0) returns a wrong result +--echo # Bug #13500371 63704: CONVERSION OF '1.' TO A NUMBER GIVES ERROR 1265 +--echo # (WARN_DATA_TRUNCATED) --echo # -SELECT LEFT('a',EXP(50)); -SELECT LEFT('a', COALESCE(1e30)); - -CREATE TABLE t1 (a FLOAT); -INSERT INTO t1 VALUES (1e30); -SELECT LEFT('a',a), LEFT('a',1e30) FROM t1; +CREATE TABLE t1 (f FLOAT); +INSERT INTO t1 VALUES ('1.'); +INSERT INTO t1 VALUES ('2.0.'); +INSERT INTO t1 VALUES ('.'); +SELECT * FROM t1 ORDER BY f; DROP TABLE t1; -PREPARE stmt FROM 'SELECT LEFT(111,?)'; -SET @a=1e30; -EXECUTE stmt USING @a; -DEALLOCATE PREPARE stmt; -CREATE TABLE t1 (a INT); -INSERT INTO t1 VALUES (1),(2),(3); -SELECT LEFT('a',(SELECT 1e30 FROM t1 LIMIT 1)); -DROP TABLE t1; +--echo # +--echo # Start of 10.0 tests +--echo # -CREATE TABLE t1 (a DOUBLE); -INSERT INTO t1 VALUES (1e30),(0); -SELECT LEFT('a', SUM(a)) FROM t1; -SELECT LEFT('a', AVG(a)) FROM t1; -DROP TABLE t1; +--echo # +--echo # MDEV-6950 Bad results with joins comparing DATE/DATETIME and INT/DECIMAL/DOUBLE/ENUM/VARCHAR columns +--echo # +CREATE TABLE t1 (a DATETIME PRIMARY KEY); +INSERT INTO t1 VALUES ('1999-01-01 00:00:00'); +CREATE TABLE t2 (a DOUBLE); +INSERT INTO t2 VALUES (19990101000000); +INSERT INTO t2 VALUES (990101000000); +SELECT t1.* FROM t1,t2 WHERE t1.a=t2.a; +SELECT t1.* FROM t1 LEFT JOIN t2 ON t1.a=t2.a; +ALTER TABLE t2 ADD PRIMARY KEY(a); SELECT t1.* FROM t1,t2 WHERE t1.a=t2.a; SELECT t1.* FROM t1 LEFT JOIN t2 ON t1.a=t2.a; --echo # t2 should NOT be eliminated From b9a69f776d3dea825bc23759660258c28bf58cc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Thu, 1 Nov 2018 10:49:53 +0200 Subject: [PATCH 013/106] Fix wsrep.cnf installation. --- support-files/CMakeLists.txt | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/support-files/CMakeLists.txt b/support-files/CMakeLists.txt index c6ce2c04eb3..e51a78038ac 100644 --- a/support-files/CMakeLists.txt +++ b/support-files/CMakeLists.txt @@ -50,6 +50,13 @@ FOREACH(inifile my-huge my-innodb-heavy-4G my-large my-medium my-small) ENDFOREACH() ENDIF() +IF(WITH_WSREP) + CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/wsrep.cnf.sh + ${CMAKE_CURRENT_BINARY_DIR}/wsrep.${ini_file_extension} @ONLY) + INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/wsrep.${ini_file_extension} + DESTINATION ${inst_location} COMPONENT IniFiles) +ENDIF() + IF(UNIX) SET(prefix ${CMAKE_INSTALL_PREFIX}) FOREACH(script mysqld_multi.server mysql-log-rotate binary-configure) @@ -102,8 +109,6 @@ IF(UNIX) DESTINATION ${inst_location} COMPONENT SupportFiles PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) - CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/wsrep.cnf.sh - ${CMAKE_CURRENT_BINARY_DIR}/wsrep.cnf @ONLY) IF (INSTALL_SYSCONFDIR) INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/mysql-log-rotate DESTINATION ${INSTALL_SYSCONFDIR}/logrotate.d From 4cdeee1e770007d57afee15f9e598c39a15c560e Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Tue, 1 Jan 2019 14:05:54 +0100 Subject: [PATCH 014/106] - Fix a few bug mainly concerning discovery and call from OEM (and prepare new table types) modified: storage/connect/tabjson.cpp modified: storage/connect/tabjson.h modified: storage/connect/tabxml.cpp modified: storage/connect/tabxml.h - Fix wrong line estimate modified: storage/connect/mysql-test/connect/r/part_table.result modified: storage/connect/mysql-test/connect/t/part_table.test --- .../mysql-test/connect/r/part_table.result | 4 +- .../mysql-test/connect/t/part_table.test | 2 +- storage/connect/tabjson.cpp | 42 ++-- storage/connect/tabjson.h | 2 +- storage/connect/tabxml.cpp | 235 ++++++++++-------- storage/connect/tabxml.h | 1 + 6 files changed, 163 insertions(+), 123 deletions(-) diff --git a/storage/connect/mysql-test/connect/r/part_table.result b/storage/connect/mysql-test/connect/r/part_table.result index f3a556ae784..4c74f1a6f49 100644 --- a/storage/connect/mysql-test/connect/r/part_table.result +++ b/storage/connect/mysql-test/connect/r/part_table.result @@ -23,7 +23,7 @@ id msg CREATE TABLE xt3 ( id INT KEY NOT NULL, msg VARCHAR(32)) -ENGINE=CONNECT TABLE_TYPE=CSV AVG_ROW_LENGTH=10; +ENGINE=CONNECT TABLE_TYPE=CSV AVG_ROW_LENGTH=5; Warnings: Warning 1105 No file name. Table will use xt3.csv INSERT INTO xt3 VALUES(60,'sixty'),(81,'eighty one'),(72,'seventy two'); @@ -92,7 +92,7 @@ id msg EXPLAIN PARTITIONS SELECT * FROM t1 WHERE id = 81; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 3 ALL NULL NULL NULL NULL 4 Using where +1 SIMPLE t1 3 ALL NULL NULL NULL NULL 6 Using where DELETE FROM t1; Warnings: Note 1105 xt1: 4 affected rows diff --git a/storage/connect/mysql-test/connect/t/part_table.test b/storage/connect/mysql-test/connect/t/part_table.test index 5edd5766bd6..8c0eb4cac70 100644 --- a/storage/connect/mysql-test/connect/t/part_table.test +++ b/storage/connect/mysql-test/connect/t/part_table.test @@ -22,7 +22,7 @@ SELECT * FROM xt2; CREATE TABLE xt3 ( id INT KEY NOT NULL, msg VARCHAR(32)) -ENGINE=CONNECT TABLE_TYPE=CSV AVG_ROW_LENGTH=10; +ENGINE=CONNECT TABLE_TYPE=CSV AVG_ROW_LENGTH=5; INSERT INTO xt3 VALUES(60,'sixty'),(81,'eighty one'),(72,'seventy two'); SELECT * FROM xt3; diff --git a/storage/connect/tabjson.cpp b/storage/connect/tabjson.cpp index d20e793ff88..c0d36efcf42 100644 --- a/storage/connect/tabjson.cpp +++ b/storage/connect/tabjson.cpp @@ -1,6 +1,6 @@ /************* tabjson C++ Program Source Code File (.CPP) *************/ -/* PROGRAM NAME: tabjson Version 1.5 */ -/* (C) Copyright to the author Olivier BERTRAND 2014 - 2017 */ +/* PROGRAM NAME: tabjson Version 1.6 */ +/* (C) Copyright to the author Olivier BERTRAND 2014 - 2018 */ /* This program are the JSON class DB execution routines. */ /***********************************************************************/ @@ -173,6 +173,7 @@ JSONDISC::JSONDISC(PGLOBAL g, uint *lg) int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt) { + char filename[_MAX_PATH]; bool mgo = (GetTypeID(topt->type) == TAB_MONGO); PCSZ level = GetStringTableOption(g, topt, "Level", NULL); @@ -209,6 +210,12 @@ int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt) return 0; } // endif Fn + if (tdp->Fn) { + // We used the file name relative to recorded datapath + PlugSetPath(filename, tdp->Fn, tdp->GetPath()); + tdp->Fn = PlugDup(g, filename); + } // endif Fn + if (trace(1)) htrc("File %s objname=%s pretty=%d lvl=%d\n", tdp->Fn, tdp->Objname, tdp->Pretty, lvl); @@ -342,7 +349,7 @@ int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt) strncpy(colname, jpp->GetKey(), 64); fmt[bf] = 0; - if (Find(g, jpp->GetVal(), MY_MIN(lvl, 0))) + if (Find(g, jpp->GetVal(), colname, MY_MIN(lvl, 0))) goto err; } // endfor jpp @@ -385,7 +392,7 @@ err: return 0; } // end of GetColumns -bool JSONDISC::Find(PGLOBAL g, PJVAL jvp, int j) +bool JSONDISC::Find(PGLOBAL g, PJVAL jvp, PCSZ key, int j) { char *p, *pc = colname + strlen(colname); int ars; @@ -413,12 +420,14 @@ bool JSONDISC::Find(PGLOBAL g, PJVAL jvp, int j) job = (PJOB)jsp; for (PJPR jrp = job->GetFirst(); jrp; jrp = jrp->GetNext()) { - if (*jrp->GetKey() != '$') { - strncat(strncat(fmt, sep, 128), jrp->GetKey(), 128); - strncat(strncat(colname, "_", 64), jrp->GetKey(), 64); + PCSZ k = jrp->GetKey(); + + if (*k != '$') { + strncat(strncat(fmt, sep, 128), k, 128); + strncat(strncat(colname, "_", 64), k, 64); } // endif Key - if (Find(g, jrp->GetVal(), j + 1)) + if (Find(g, jrp->GetVal(), k, j + 1)) return true; *p = *pc = 0; @@ -428,13 +437,13 @@ bool JSONDISC::Find(PGLOBAL g, PJVAL jvp, int j) case TYPE_JAR: jar = (PJAR)jsp; - if (all || (tdp->Xcol && !stricmp(tdp->Xcol, colname))) + if (all || (tdp->Xcol && !stricmp(tdp->Xcol, key))) ars = jar->GetSize(false); else ars = MY_MIN(jar->GetSize(false), 1); for (int k = 0; k < ars; k++) { - if (!tdp->Xcol || stricmp(tdp->Xcol, colname)) { + if (!tdp->Xcol || stricmp(tdp->Xcol, key)) { sprintf(buf, "%d", k); if (tdp->Uri) @@ -448,7 +457,7 @@ bool JSONDISC::Find(PGLOBAL g, PJVAL jvp, int j) } else strncat(fmt, (tdp->Uri ? sep : "[*]"), 128); - if (Find(g, jar->GetValue(k), j)) + if (Find(g, jar->GetValue(k), "", j)) return true; *p = *pc = 0; @@ -522,7 +531,9 @@ void JSONDISC::AddColumn(PGLOBAL g) n++; } // endif jcp - pjcp = jcp; + if (jcp) + pjcp = jcp; + } // end of AddColumn @@ -549,7 +560,7 @@ JSONDEF::JSONDEF(void) /***********************************************************************/ /* DefineAM: define specific AM block values. */ /***********************************************************************/ -bool JSONDEF::DefineAM(PGLOBAL g, LPCSTR, int poff) +bool JSONDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) { Schema = GetStringCatInfo(g, "DBname", Schema); Jmode = (JMODE)GetIntCatInfo("Jmode", MODE_OBJECT); @@ -561,7 +572,8 @@ bool JSONDEF::DefineAM(PGLOBAL g, LPCSTR, int poff) Sep = *GetStringCatInfo(g, "Separator", "."); Accept = GetBoolCatInfo("Accept", false); - if (Uri = GetStringCatInfo(g, "Connect", NULL)) { + // Don't use url as uri when called from REST OEM module + if (stricmp(am, "REST") && (Uri = GetStringCatInfo(g, "Connect", NULL))) { #if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT) Collname = GetStringCatInfo(g, "Name", (Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name); @@ -2340,7 +2352,7 @@ void TDBJSON::CloseDB(PGLOBAL g) TDBJCL::TDBJCL(PJDEF tdp) : TDBCAT(tdp) { Topt = tdp->GetTopt(); - Db = tdp->Schema; + Db = tdp->Schema; Dsn = tdp->Uri; } // end of TDBJCL constructor diff --git a/storage/connect/tabjson.h b/storage/connect/tabjson.h index fcbfe4ed1ec..8721a2a5ab7 100644 --- a/storage/connect/tabjson.h +++ b/storage/connect/tabjson.h @@ -52,7 +52,7 @@ public: // Functions int GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt); - bool Find(PGLOBAL g, PJVAL jvp, int j); + bool Find(PGLOBAL g, PJVAL jvp, PCSZ key, int j); void AddColumn(PGLOBAL g); // Members diff --git a/storage/connect/tabxml.cpp b/storage/connect/tabxml.cpp index fa4854bb618..d808bd5ecd4 100644 --- a/storage/connect/tabxml.cpp +++ b/storage/connect/tabxml.cpp @@ -163,8 +163,11 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info) return NULL; tdp->Tabname = tab; + tdp->Tabname = (char*)GetStringTableOption(g, topt, "Tabname", tab); + tdp->Rowname = (char*)GetStringTableOption(g, topt, "Rownode", NULL); tdp->Zipped = GetBooleanTableOption(g, topt, "Zipped", false); tdp->Entry = GetStringTableOption(g, topt, "Entry", NULL); + tdp->Skip = GetBooleanTableOption(g, topt, "Skipnull", false); if (!(op = GetStringTableOption(g, topt, "Xmlsup", NULL))) #if defined(__WIN__) @@ -280,7 +283,9 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info) if (!vp->atp) node = vp->nl->GetItem(g, vp->k++, tdp->Usedom ? node : NULL); - strncat(fmt, colname, XLEN(fmt)); + if (!j) + strncat(fmt, colname, XLEN(fmt)); + strncat(fmt, "/", XLEN(fmt)); strncat(xcol->Name, "_", XLEN(xcol->Name)); j++; @@ -302,6 +307,7 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info) case RC_INFO: PushWarning(g, txmp); case RC_OK: + xcol->Cbn = !strlen(buf); break; default: goto err; @@ -327,9 +333,9 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info) xcp->Len = MY_MAX(xcp->Len, xcol->Len); xcp->Scale = MY_MAX(xcp->Scale, xcol->Scale); - xcp->Cbn |= xcol->Cbn; + xcp->Cbn |= (xcol->Cbn || !xcol->Len); xcp->Found = true; - } else { + } else if(xcol->Len || !tdp->Skip) { // New column xcp = new(g) XMCOL(g, xcol, fmt, i); length[0] = MY_MAX(length[0], strlen(xcol->Name)); @@ -344,7 +350,8 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info) n++; } // endif xcp - pxcp = xcp; + if (xcp) + pxcp = xcp; if (vp->atp) vp->atp = vp->atp->GetNext(g); @@ -445,6 +452,7 @@ XMLDEF::XMLDEF(void) Usedom = false; Zipped = false; Mulentries = false; + Skip = false; } // end of XMLDEF constructor /***********************************************************************/ @@ -814,127 +822,141 @@ bool TDBXML::Initialize(PGLOBAL g) } // endif Bufdone #if !defined(UNIX) - if (!Root) try { + if (!Root) try { #else - if (!Root) { + if (!Root) { #endif - char tabpath[64], filename[_MAX_PATH]; + char tabpath[64], filename[_MAX_PATH]; - // We used the file name relative to recorded datapath - PlugSetPath(filename, Xfile, GetPath()); + // We used the file name relative to recorded datapath + PlugSetPath(filename, Xfile, GetPath()); - // Load or re-use the table file - rc = LoadTableFile(g, filename); + // Load or re-use the table file + rc = LoadTableFile(g, filename); - if (rc == RC_OK) { - // Get root node - if (!(Root = Docp->GetRoot(g))) { - // This should never happen as load should have failed - strcpy(g->Message, MSG(EMPTY_DOC)); - goto error; - } // endif Root + if (rc == RC_OK) { + // Get root node + if (!(Root = Docp->GetRoot(g))) { + // This should never happen as load should have failed + strcpy(g->Message, MSG(EMPTY_DOC)); + goto error; + } // endif Root - // If tabname is not an Xpath, - // construct one that will find it anywhere - if (!strchr(Tabname, '/')) - strcat(strcpy(tabpath, "//"), Tabname); - else - strcpy(tabpath, Tabname); + // If tabname is not an Xpath, + // construct one that will find it anywhere + if (!strchr(Tabname, '/')) + strcat(strcpy(tabpath, "//"), Tabname); + else + strcpy(tabpath, Tabname); - // Evaluate table xpath - if ((TabNode = Root->SelectSingleNode(g, tabpath))) { - if (TabNode->GetType() != XML_ELEMENT_NODE) { - sprintf(g->Message, MSG(BAD_NODE_TYPE), TabNode->GetType()); - goto error; - } // endif Type + // Evaluate table xpath + if ((TabNode = Root->SelectSingleNode(g, tabpath))) { + if (TabNode->GetType() != XML_ELEMENT_NODE) { + sprintf(g->Message, MSG(BAD_NODE_TYPE), TabNode->GetType()); + goto error; + } // endif Type - } else if (Mode == MODE_INSERT && XmlDB) { - // We are adding a new table to a multi-table file + } else if (Mode == MODE_INSERT && XmlDB) { + // We are adding a new table to a multi-table file - // If XmlDB is not an Xpath, - // construct one that will find it anywhere - if (!strchr(XmlDB, '/')) - strcat(strcpy(tabpath, "//"), XmlDB); - else - strcpy(tabpath, XmlDB); + // If XmlDB is not an Xpath, + // construct one that will find it anywhere + if (!strchr(XmlDB, '/')) + strcat(strcpy(tabpath, "//"), XmlDB); + else + strcpy(tabpath, XmlDB); - if (!(DBnode = Root->SelectSingleNode(g, tabpath))) { - // DB node does not exist yet; we cannot create it - // because we don't know where it should be placed - sprintf(g->Message, MSG(MISSING_NODE), XmlDB, Xfile); - goto error; - } // endif DBnode + if (!(DBnode = Root->SelectSingleNode(g, tabpath))) { + // DB node does not exist yet; we cannot create it + // because we don't know where it should be placed + sprintf(g->Message, MSG(MISSING_NODE), XmlDB, Xfile); + goto error; + } // endif DBnode - if (!(TabNode = DBnode->AddChildNode(g, Tabname))) { - sprintf(g->Message, MSG(FAIL_ADD_NODE), Tabname); - goto error; - } // endif TabNode + if (!(TabNode = DBnode->AddChildNode(g, Tabname))) { + sprintf(g->Message, MSG(FAIL_ADD_NODE), Tabname); + goto error; + } // endif TabNode - DBnode->AddText(g, "\n"); - } else - TabNode = Root; // Try this ? + DBnode->AddText(g, "\n"); + } else { + TabNode = Root; // Try this ? + Tabname = TabNode->GetName(g); + } // endif's - } else if (rc == RC_NF || rc == RC_EF) { - // The XML file does not exist or is void - if (Mode == MODE_INSERT) { - // New Document - char buf[64]; + } else if (rc == RC_NF || rc == RC_EF) { + // The XML file does not exist or is void + if (Mode == MODE_INSERT) { + // New Document + char buf[64]; - // Create the XML node - if (Docp->NewDoc(g, "1.0")) { - strcpy(g->Message, MSG(NEW_DOC_FAILED)); - goto error; - } // endif NewDoc + // Create the XML node + if (Docp->NewDoc(g, "1.0")) { + strcpy(g->Message, MSG(NEW_DOC_FAILED)); + goto error; + } // endif NewDoc - // Now we can link the Xblock - To_Xb = Docp->LinkXblock(g, Mode, rc, filename); + // Now we can link the Xblock + To_Xb = Docp->LinkXblock(g, Mode, rc, filename); - // Add a CONNECT comment node - strcpy(buf, " Created by the MariaDB CONNECT Storage Engine"); - Docp->AddComment(g, buf); + // Add a CONNECT comment node + strcpy(buf, " Created by the MariaDB CONNECT Storage Engine"); + Docp->AddComment(g, buf); - if (XmlDB) { - // This is a multi-table file - DBnode = Root = Docp->NewRoot(g, XmlDB); - DBnode->AddText(g, "\n"); - TabNode = DBnode->AddChildNode(g, Tabname); - DBnode->AddText(g, "\n"); - } else - TabNode = Root = Docp->NewRoot(g, Tabname); + if (XmlDB) { + // This is a multi-table file + DBnode = Root = Docp->NewRoot(g, XmlDB); + DBnode->AddText(g, "\n"); + TabNode = DBnode->AddChildNode(g, Tabname); + DBnode->AddText(g, "\n"); + } else + TabNode = Root = Docp->NewRoot(g, Tabname); - if (TabNode == NULL || Root == NULL) { - strcpy(g->Message, MSG(XML_INIT_ERROR)); - goto error; - } else if (SetTabNode(g)) - goto error; + if (TabNode == NULL || Root == NULL) { + strcpy(g->Message, MSG(XML_INIT_ERROR)); + goto error; + } else if (SetTabNode(g)) + goto error; - } else { - sprintf(g->Message, MSG(FILE_UNFOUND), Xfile); + } else { + sprintf(g->Message, MSG(FILE_UNFOUND), Xfile); - if (Mode == MODE_READ) { - PushWarning(g, this); - Void = true; - } // endif Mode + if (Mode == MODE_READ) { + PushWarning(g, this); + Void = true; + } // endif Mode - goto error; - } // endif Mode + goto error; + } // endif Mode - } else if (rc == RC_INFO) { - // Loading failed - sprintf(g->Message, MSG(LOADING_FAILED), Xfile); - goto error; - } else // (rc == RC_FX) - goto error; + } else if (rc == RC_INFO) { + // Loading failed + sprintf(g->Message, MSG(LOADING_FAILED), Xfile); + goto error; + } else // (rc == RC_FX) + goto error; - // Get row node list - if (Rowname) - Nlist = TabNode->SelectNodes(g, Rowname); - else - Nlist = TabNode->GetChildElements(g); + if (!Rowname) { + for (PXNODE n = TabNode->GetChild(g); n; n = n->GetNext(g)) + if (n->GetType() == XML_ELEMENT_NODE) { + Rowname = n->GetName(g); + break; + } // endif Type - Docp->SetNofree(true); // For libxml2 + if (!Rowname) + Rowname = TabNode->GetName(g); + } // endif Rowname + + // Get row node list + if (strcmp(Rowname, Tabname)) + Nlist = TabNode->SelectNodes(g, Rowname); + else + Nrow = 1; + + + Docp->SetNofree(true); // For libxml2 #if defined(__WIN__) - } catch(_com_error e) { + } catch (_com_error e) { // We come here if a DOM command threw an error char buf[128]; @@ -1221,10 +1243,14 @@ int TDBXML::ReadDB(PGLOBAL g) htrc("TDBXML ReadDB: Irow=%d RowNode=%p\n", Irow, RowNode); // Get the new row node - if ((RowNode = Nlist->GetItem(g, Irow, RowNode)) == NULL) { - sprintf(g->Message, MSG(MISSING_ROWNODE), Irow); - return RC_FX; - } // endif RowNode + if (Nlist) { + if ((RowNode = Nlist->GetItem(g, Irow, RowNode)) == NULL) { + sprintf(g->Message, MSG(MISSING_ROWNODE), Irow); + return RC_FX; + } // endif RowNode + + } else + RowNode = TabNode; if (Colname && Coltype == 2) Clist = RowNode->SelectNodes(g, Colname, Clist); @@ -1279,6 +1305,7 @@ int TDBXML::WriteDB(PGLOBAL g) /***********************************************************************/ int TDBXML::DeleteDB(PGLOBAL g, int irc) { + // TODO: Handle null Nlist if (irc == RC_FX) { // Delete all rows for (Irow = 0; Irow < Nrow; Irow++) diff --git a/storage/connect/tabxml.h b/storage/connect/tabxml.h index 102767e965a..fb3913f08ea 100644 --- a/storage/connect/tabxml.h +++ b/storage/connect/tabxml.h @@ -52,6 +52,7 @@ class DllExport XMLDEF : public TABDEF { /* Logical table description */ bool Usedom; /* True: DOM, False: libxml2 */ bool Zipped; /* True: Zipped XML file(s) */ bool Mulentries; /* True: multiple entries in zip file*/ + bool Skip; /* Skip null columns */ }; // end of XMLDEF #if defined(INCLUDE_TDBXML) From 4b3b3bfe5652e72c138ddf74085dc46d8e223639 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Tue, 1 Jan 2019 16:08:04 +0100 Subject: [PATCH 015/106] Modified because different result on Windows and Linux --- storage/connect/mysql-test/connect/t/part_table.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/connect/mysql-test/connect/t/part_table.test b/storage/connect/mysql-test/connect/t/part_table.test index 8c0eb4cac70..0fb2a11f0f9 100644 --- a/storage/connect/mysql-test/connect/t/part_table.test +++ b/storage/connect/mysql-test/connect/t/part_table.test @@ -22,7 +22,7 @@ SELECT * FROM xt2; CREATE TABLE xt3 ( id INT KEY NOT NULL, msg VARCHAR(32)) -ENGINE=CONNECT TABLE_TYPE=CSV AVG_ROW_LENGTH=5; +ENGINE=CONNECT TABLE_TYPE=CSV AVG_ROW_LENGTH=6; INSERT INTO xt3 VALUES(60,'sixty'),(81,'eighty one'),(72,'seventy two'); SELECT * FROM xt3; From 720dedb33390bc0e2ae262c4de378386fae0e52e Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Tue, 1 Jan 2019 16:57:23 +0100 Subject: [PATCH 016/106] Modified because different result on Windows and Linux --- storage/connect/mysql-test/connect/r/part_table.result | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/connect/mysql-test/connect/r/part_table.result b/storage/connect/mysql-test/connect/r/part_table.result index 4c74f1a6f49..ee17a1d32b9 100644 --- a/storage/connect/mysql-test/connect/r/part_table.result +++ b/storage/connect/mysql-test/connect/r/part_table.result @@ -23,7 +23,7 @@ id msg CREATE TABLE xt3 ( id INT KEY NOT NULL, msg VARCHAR(32)) -ENGINE=CONNECT TABLE_TYPE=CSV AVG_ROW_LENGTH=5; +ENGINE=CONNECT TABLE_TYPE=CSV AVG_ROW_LENGTH=6; Warnings: Warning 1105 No file name. Table will use xt3.csv INSERT INTO xt3 VALUES(60,'sixty'),(81,'eighty one'),(72,'seventy two'); From dc42b3c4d9546153e2f0049393e3771e21551679 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Fri, 11 Jan 2019 01:44:07 +0100 Subject: [PATCH 017/106] Backport MDEV-17504 to 5.5 mysql_install_db.exe should not remove datadir, if it was not created by it. --- sql/CMakeLists.txt | 2 +- sql/mysql_install_db.cc | 72 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 67 insertions(+), 7 deletions(-) diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index 02196a7e366..6648b7a2612 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -351,7 +351,7 @@ IF(WIN32) ${CMAKE_CURRENT_BINARY_DIR}/mysql_bootstrap_sql.c COMPONENT Server ) - TARGET_LINK_LIBRARIES(mysql_install_db mysys) + TARGET_LINK_LIBRARIES(mysql_install_db mysys shlwapi) ADD_LIBRARY(winservice STATIC winservice.c) TARGET_LINK_LIBRARIES(winservice shell32) diff --git a/sql/mysql_install_db.cc b/sql/mysql_install_db.cc index 9c1a234241f..9d2b261b46c 100644 --- a/sql/mysql_install_db.cc +++ b/sql/mysql_install_db.cc @@ -28,6 +28,8 @@ #include #include #include +struct IUnknown; +#include #define USAGETEXT \ "mysql_install_db.exe Ver 1.00 for Windows\n" \ @@ -532,20 +534,78 @@ static int create_db_instance() DWORD cwd_len= MAX_PATH; char cmdline[3*MAX_PATH]; FILE *in; + bool cleanup_datadir= true; + DWORD last_error; verbose("Running bootstrap"); GetCurrentDirectory(cwd_len, cwd); - CreateDirectory(opt_datadir, NULL); /*ignore error, it might already exist */ + + /* Create datadir and datadir/mysql, if they do not already exist. */ + + if (!CreateDirectory(opt_datadir, NULL) && (GetLastError() != ERROR_ALREADY_EXISTS)) + { + last_error = GetLastError(); + switch(last_error) + { + case ERROR_ACCESS_DENIED: + die("Can't create data directory '%s' (access denied)\n", + opt_datadir); + break; + case ERROR_PATH_NOT_FOUND: + die("Can't create data directory '%s' " + "(one or more intermediate directories do not exist)\n", + opt_datadir); + break; + default: + die("Can't create data directory '%s', last error %u\n", + opt_datadir, last_error); + break; + } + } if (!SetCurrentDirectory(opt_datadir)) { - die("Cannot set current directory to '%s'\n",opt_datadir); - return -1; + last_error = GetLastError(); + switch (last_error) + { + case ERROR_DIRECTORY: + die("Can't set current directory to '%s', the path is not a valid directory \n", + opt_datadir); + break; + default: + die("Can' set current directory to '%s', last error %u\n", + opt_datadir, last_error); + break; + } } - CreateDirectory("mysql",NULL); - CreateDirectory("test", NULL); + if (PathIsDirectoryEmpty(opt_datadir)) + { + cleanup_datadir= false; + } + + if (!CreateDirectory("mysql",NULL)) + { + last_error = GetLastError(); + DWORD attributes; + switch(last_error) + { + case ERROR_ACCESS_DENIED: + die("Can't create subdirectory 'mysql' in '%s' (access denied)\n",opt_datadir); + break; + case ERROR_ALREADY_EXISTS: + attributes = GetFileAttributes("mysql"); + + if (attributes == INVALID_FILE_ATTRIBUTES) + die("GetFileAttributes() failed for existing file '%s\\mysql', last error %u", + opt_datadir, GetLastError()); + else if (!(attributes & FILE_ATTRIBUTE_DIRECTORY)) + die("File '%s\\mysql' exists, but it is not a directory", opt_datadir); + + break; + } + } /* Set data directory permissions for both current user and @@ -642,7 +702,7 @@ static int create_db_instance() } end: - if (ret) + if (ret && cleanup_datadir) { SetCurrentDirectory(cwd); clean_directory(opt_datadir); From 235374aee3c4b08d34026c2bcd7d88db515966cb Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Tue, 15 Jan 2019 18:44:03 +0100 Subject: [PATCH 018/106] MDEV-18254 upgrade HeidiSQL to 9.5 --- win/packaging/heidisql.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/packaging/heidisql.cmake b/win/packaging/heidisql.cmake index 772834e7c7d..29ecdd8eb4f 100644 --- a/win/packaging/heidisql.cmake +++ b/win/packaging/heidisql.cmake @@ -1,4 +1,4 @@ -SET(HEIDISQL_BASE_NAME "HeidiSQL_9.4_Portable") +SET(HEIDISQL_BASE_NAME "HeidiSQL_9.5_Portable") SET(HEIDISQL_ZIP "${HEIDISQL_BASE_NAME}.zip") SET(HEIDISQL_URL "http://www.heidisql.com/downloads/releases/${HEIDISQL_ZIP}") SET(HEIDISQL_DOWNLOAD_DIR ${THIRD_PARTY_DOWNLOAD_LOCATION}/${HEIDISQL_BASE_NAME}) From 1ecccb509c9dfa57976a2e2c3af07753a5356188 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Wed, 16 Jan 2019 13:16:41 +0100 Subject: [PATCH 019/106] MDEV-17085: CHECKSUM TABLE EXTENDED does not work correctly The problem was in calculating of the mask to clear unused null bits in case of using full byte. --- mysql-test/r/row-checksum-old.result | 16 ++++++++++++++++ mysql-test/r/row-checksum.result | 16 ++++++++++++++++ mysql-test/t/row-checksum.test | 17 +++++++++++++++++ sql/sql_table.cc | 5 ++++- 4 files changed, 53 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/row-checksum-old.result b/mysql-test/r/row-checksum-old.result index ef523463860..920c5dbe838 100644 --- a/mysql-test/r/row-checksum-old.result +++ b/mysql-test/r/row-checksum-old.result @@ -85,3 +85,19 @@ checksum table t1 extended; Table Checksum test.t1 4108368782 drop table t1; +# +# MDEV-17085: CHECKSUM TABLE EXTENDED does not work correctly +# +CREATE TABLE t1 ( c1 int NOT NULL, c2 int NOT NULL, c4 varchar(20), c5 varchar(20), c6 varchar(20), c7 varchar(20), c8 varchar(20), c9 varchar(20), c10 varchar(20), c11 varchar(20), c12 varchar(20), c13 varchar(20), c14 varchar(20), c15 varchar(20), c16 varchar(20), c19 int NOT NULL, c20 int NOT NULL, c21 varchar(20), c22 VARCHAR(20), c23 varchar(20)); +insert into t1 values (5,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,0,"dog",NULL,NULL); +# Important is that checksum is different from following +CHECKSUM TABLE t1 EXTENDED; +Table Checksum +test.t1 2514025256 +UPDATE t1 SET c21='cat' WHERE c1=5; +# Important is that checksum is different from above +CHECKSUM TABLE t1 EXTENDED; +Table Checksum +test.t1 2326430205 +drop table t1; +# End of 5.5 tests diff --git a/mysql-test/r/row-checksum.result b/mysql-test/r/row-checksum.result index fb8a1260a1d..0f8311b703a 100644 --- a/mysql-test/r/row-checksum.result +++ b/mysql-test/r/row-checksum.result @@ -85,3 +85,19 @@ checksum table t1 extended; Table Checksum test.t1 3885665021 drop table t1; +# +# MDEV-17085: CHECKSUM TABLE EXTENDED does not work correctly +# +CREATE TABLE t1 ( c1 int NOT NULL, c2 int NOT NULL, c4 varchar(20), c5 varchar(20), c6 varchar(20), c7 varchar(20), c8 varchar(20), c9 varchar(20), c10 varchar(20), c11 varchar(20), c12 varchar(20), c13 varchar(20), c14 varchar(20), c15 varchar(20), c16 varchar(20), c19 int NOT NULL, c20 int NOT NULL, c21 varchar(20), c22 VARCHAR(20), c23 varchar(20)); +insert into t1 values (5,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,0,"dog",NULL,NULL); +# Important is that checksum is different from following +CHECKSUM TABLE t1 EXTENDED; +Table Checksum +test.t1 2514025256 +UPDATE t1 SET c21='cat' WHERE c1=5; +# Important is that checksum is different from above +CHECKSUM TABLE t1 EXTENDED; +Table Checksum +test.t1 2326430205 +drop table t1; +# End of 5.5 tests diff --git a/mysql-test/t/row-checksum.test b/mysql-test/t/row-checksum.test index 920a2384aa8..6b79827d066 100644 --- a/mysql-test/t/row-checksum.test +++ b/mysql-test/t/row-checksum.test @@ -60,3 +60,20 @@ checksum table t1; checksum table t1 quick; checksum table t1 extended; drop table t1; + +--echo # +--echo # MDEV-17085: CHECKSUM TABLE EXTENDED does not work correctly +--echo # + +CREATE TABLE t1 ( c1 int NOT NULL, c2 int NOT NULL, c4 varchar(20), c5 varchar(20), c6 varchar(20), c7 varchar(20), c8 varchar(20), c9 varchar(20), c10 varchar(20), c11 varchar(20), c12 varchar(20), c13 varchar(20), c14 varchar(20), c15 varchar(20), c16 varchar(20), c19 int NOT NULL, c20 int NOT NULL, c21 varchar(20), c22 VARCHAR(20), c23 varchar(20)); + +insert into t1 values (5,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,0,"dog",NULL,NULL); +--echo # Important is that checksum is different from following +CHECKSUM TABLE t1 EXTENDED; +UPDATE t1 SET c21='cat' WHERE c1=5; +--echo # Important is that checksum is different from above +CHECKSUM TABLE t1 EXTENDED; + +drop table t1; + +--echo # End of 5.5 tests diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 1b83b513c2d..d3448c167c4 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -7844,7 +7844,10 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables, { /* calculating table's checksum */ ha_checksum crc= 0; - uchar null_mask=256 - (1 << t->s->last_null_bit_pos); + DBUG_ASSERT(t->s->last_null_bit_pos < 8); + uchar null_mask= (t->s->last_null_bit_pos ? + (256 - (1 << t->s->last_null_bit_pos)): + 0); t->use_all_columns(); From 459d6da86955c89e96f6e9a8d3bc2a9b1756629b Mon Sep 17 00:00:00 2001 From: Natanael Copa Date: Wed, 16 Jan 2019 14:28:37 +0000 Subject: [PATCH 020/106] MDEV-18269 - fix off-by-one bug in unittest Fix the off-by-one overflow which was introduced with commit b0fd06a6f2721 (MDEV-15670 - unit.my_atomic failed in buildbot with Signal 11 thrown) Closes #1098. --- unittest/mysys/thr_template.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unittest/mysys/thr_template.c b/unittest/mysys/thr_template.c index d1bc0868ca0..0e06bf6e731 100644 --- a/unittest/mysys/thr_template.c +++ b/unittest/mysys/thr_template.c @@ -34,7 +34,7 @@ void test_concurrently(const char *test, pthread_handler handler, int n, int m) bad= 0; diag("Testing %s with %d threads, %d iterations... ", test, n, m); - for (i= n; i; i--) + for (i= 0; i < n; i++) { if (pthread_create(&threads[i], 0, handler, &m) != 0) { @@ -43,7 +43,7 @@ void test_concurrently(const char *test, pthread_handler handler, int n, int m) } } - for (i= n; i; i--) + for (i= 0; i < n; i++) pthread_join(threads[i], 0); now= my_interval_timer() - now; From 78f62e9079b6ad3705bb2abb7b48b31143297e86 Mon Sep 17 00:00:00 2001 From: Alexander Kuleshov Date: Fri, 4 Jan 2019 13:32:51 +0600 Subject: [PATCH 021/106] remove duplicated paragraph from mysql_install_db.sh Signed-off-by: Alexander Kuleshov --- scripts/mysql_install_db.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh index 0272a19931f..f56de12d931 100644 --- a/scripts/mysql_install_db.sh +++ b/scripts/mysql_install_db.sh @@ -207,9 +207,6 @@ cannot_find_file() done fi - echo - echo "If you compiled from source, you need to run 'make install' to" - echo "copy the software into the correct location ready for operation." echo echo "If you compiled from source, you need to either run 'make install' to" echo "copy the software into the correct location ready for operation." From e292d1a800312f4e0330a519e0d980e27a7172f3 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Sat, 19 Jan 2019 14:01:09 +0100 Subject: [PATCH 022/106] Avoid noisy Clang 7 warning about unused variable. Patch by Eugene Kosov. --- include/my_valgrind.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/my_valgrind.h b/include/my_valgrind.h index 5d08a271d4a..a85e610f049 100644 --- a/include/my_valgrind.h +++ b/include/my_valgrind.h @@ -42,7 +42,7 @@ https://github.com/google/sanitizers/wiki/AddressSanitizerManualPoisoning */ # define MEM_CHECK_ADDRESSABLE(a,len) ((void) 0) # define MEM_CHECK_DEFINED(a,len) ((void) 0) #else -# define MEM_UNDEFINED(a,len) ((void) 0) +# define MEM_UNDEFINED(a,len) ((void) (a), (void) (len)) # define MEM_NOACCESS(a,len) ((void) 0) # define MEM_CHECK_ADDRESSABLE(a,len) ((void) 0) # define MEM_CHECK_DEFINED(a,len) ((void) 0) @@ -51,7 +51,7 @@ https://github.com/google/sanitizers/wiki/AddressSanitizerManualPoisoning */ #ifndef DBUG_OFF #define TRASH_FILL(A,B,C) do { const size_t trash_tmp= (B); MEM_UNDEFINED(A, trash_tmp); memset(A, C, trash_tmp); } while (0) #else -#define TRASH_FILL(A,B,C) do { const size_t trash_tmp __attribute__((unused))= (B); MEM_UNDEFINED(A,trash_tmp); } while (0) +#define TRASH_FILL(A,B,C) do { MEM_UNDEFINED((A), (B)); } while (0) #endif #define TRASH_ALLOC(A,B) do { TRASH_FILL(A,B,0xA5); MEM_UNDEFINED(A,B); } while(0) #define TRASH_FREE(A,B) do { TRASH_FILL(A,B,0x8F); MEM_NOACCESS(A,B); } while(0) From 0d3c49ef5de3fa7356851dd7a05052f5360d0ae6 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 14 Jan 2019 12:33:52 +0100 Subject: [PATCH 023/106] MDEV-17615 cmake ssl error on musl/libressl don't shortcut trying to test for openssl version, test what is actually needed for a code to compile --- cmake/ssl.cmake | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/cmake/ssl.cmake b/cmake/ssl.cmake index 0c6cde31299..60d2cb48387 100644 --- a/cmake/ssl.cmake +++ b/cmake/ssl.cmake @@ -71,15 +71,23 @@ MACRO (MYSQL_CHECK_SSL) FIND_LIBRARY(CRYPTO_LIBRARY crypto) MARK_AS_ADVANCED(CRYPTO_LIBRARY) INCLUDE(CheckSymbolExists) + INCLUDE(CheckCSourceCompiles) SET(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR}) SET(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES}) CHECK_SYMBOL_EXISTS(SHA512_DIGEST_LENGTH "openssl/sha.h" HAVE_SHA512_DIGEST_LENGTH) CHECK_SYMBOL_EXISTS(ERR_remove_thread_state "openssl/err.h" HAVE_ERR_remove_thread_state) + CHECK_C_SOURCE_COMPILES(" + #include + int main() + { + DH dh; + return sizeof(dh.version); + }" OLD_OPENSSL_API) SET(CMAKE_REQUIRED_INCLUDES) SET(CMAKE_REQUIRED_LIBRARIES) - IF(OPENSSL_FOUND AND OPENSSL_VERSION VERSION_LESS "1.1.0" AND + IF(OPENSSL_FOUND AND OLD_OPENSSL_API AND CRYPTO_LIBRARY AND HAVE_SHA512_DIGEST_LENGTH) SET(SSL_SOURCES "") SET(SSL_LIBRARIES ${OPENSSL_LIBRARIES} ${CRYPTO_LIBRARY}) From 50e593386fcbaa1ca7bd2ed9fdfc51fd5102cdab Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Fri, 11 Jan 2019 19:35:46 +1100 Subject: [PATCH 024/106] MDEV-14580: mysql_install_db elements based on dirname of mysql_install_db Closes #1086 --- scripts/mysql_install_db.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh index f56de12d931..f1249e1d06b 100644 --- a/scripts/mysql_install_db.sh +++ b/scripts/mysql_install_db.sh @@ -253,6 +253,9 @@ then cannot_find_file my_print_defaults $basedir/bin $basedir/extra exit 1 fi +elif test -x "$(dirname $0)/../@bindir@/my_print_defaults" +then + print_defaults="$(dirname $0)/../@bindir@/my_print_defaults" else print_defaults="@bindir@/my_print_defaults" fi @@ -304,6 +307,14 @@ then cannot_find_file fill_help_tables.sql @pkgdata_locations@ exit 1 fi +# relative from where the script was run for a relocatable install +elif test -x "$(dirname $0)/../@INSTALL_SBINDIR@/mysqld" +then + basedir="$(dirname $0)/../" + bindir="$basedir/@INSTALL_SBINDIR@" + resolveip="$bindir/resolveip" + mysqld="$basedir/@INSTALL_SBINDIR@/mysqld" + pkgdatadir="$basedir/@INSTALL_MYSQLSHAREDIR@" else basedir="@prefix@" bindir="@bindir@" From 9c5be7d131f7eb7f27df722463faa2cd8135fd1b Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 14 Jan 2019 15:55:21 +0100 Subject: [PATCH 025/106] MDEV-14580: mysql_install_db elements based on dirname of mysql_install_db Avoid introducing new dependencies or new syntax. That is, don't use $(...) and don't assume dirname is present. And remove unsighty /foo/bar/../xyz from the path. Use dirname instead of ../ --- scripts/mysql_install_db.sh | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh index f1249e1d06b..9f00562f4bd 100644 --- a/scripts/mysql_install_db.sh +++ b/scripts/mysql_install_db.sh @@ -36,6 +36,9 @@ in_rpm=0 ip_only=0 cross_bootstrap=0 +dirname0=`dirname $0 2>/dev/null` +dirname0=`dirname $dirname0 2>/dev/null` + usage() { cat < Date: Wed, 23 Jan 2019 09:51:06 +0200 Subject: [PATCH 026/106] MDEV-18349 InnoDB file size changes are not safe when file system crashes fil_extend_space_to_desired_size(): Invoke fsync() after posix_fallocate() in order to durably extend the file in a crash-safe file system. --- storage/innobase/fil/fil0fil.c | 4 +++- storage/xtradb/fil/fil0fil.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/storage/innobase/fil/fil0fil.c b/storage/innobase/fil/fil0fil.c index 4006ce4acce..32bf0b8ccd8 100644 --- a/storage/innobase/fil/fil0fil.c +++ b/storage/innobase/fil/fil0fil.c @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2014, 2017, MariaDB Corporation. All Rights Reserved. +Copyright (c) 2014, 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 @@ -4155,6 +4155,8 @@ fil_extend_space_to_desired_size( " failed with error %d\n", node->name, start_offset, len + start_offset, err); + } else { + os_file_flush(node->handle); } mutex_enter(&fil_system->mutex); diff --git a/storage/xtradb/fil/fil0fil.c b/storage/xtradb/fil/fil0fil.c index 004a80e9b13..fc305c7e01f 100644 --- a/storage/xtradb/fil/fil0fil.c +++ b/storage/xtradb/fil/fil0fil.c @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2014, 2017, MariaDB Corporation. All Rights Reserved. +Copyright (c) 2014, 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 @@ -4990,6 +4990,8 @@ fil_extend_space_to_desired_size( " failed with error %d\n", node->name, start_offset, len + start_offset, err); + } else { + os_file_flush(node->handle, TRUE); } mutex_enter(&fil_system->mutex); From 6de2928d5bf912ace5fb5a1e2254025efe202b67 Mon Sep 17 00:00:00 2001 From: Aditya A Date: Mon, 10 Sep 2018 16:00:29 +0530 Subject: [PATCH 027/106] Bug #28178776 COMPARISON OF UNINITAILIZED MEMORY IN LOG_IN_USE PROBLEM ------- Memory sanitizer reports uninitialized comparisons in log_in_use(), because strings are compared with memcmp() instead of strncmp. FIX --- Use strncmp() to compare strings --- sql/log.cc | 6 +++--- sql/sql_repl.cc | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/sql/log.cc b/sql/log.cc index 2504b5e2d06..7db4985ad48 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1,5 +1,5 @@ -/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. - Copyright (c) 2009, 2016, MariaDB +/* Copyright (c) 2000, 2018, Oracle and/or its affiliates. + Copyright (c) 2009, 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 @@ -3413,7 +3413,7 @@ int MYSQL_BIN_LOG::find_log_pos(LOG_INFO *linfo, const char *log_name, // if the log entry matches, null string matching anything if (!log_name || (log_name_len == fname_len-1 && full_fname[log_name_len] == '\n' && - !memcmp(full_fname, full_log_name, log_name_len))) + !strncmp(full_fname, full_log_name, log_name_len))) { DBUG_PRINT("info", ("Found log file entry")); full_fname[fname_len-1]= 0; // remove last \n diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index ca6e8d15e7a..cb4904bb5a6 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -1,5 +1,5 @@ -/* Copyright (c) 2000, 2017, Oracle and/or its affiliates. - Copyright (c) 2008, 2017, MariaDB Corporation +/* Copyright (c) 2000, 2018, Oracle and/or its affiliates. + Copyright (c) 2008, 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 @@ -365,7 +365,7 @@ bool log_in_use(const char* log_name) if ((linfo = tmp->current_linfo)) { mysql_mutex_lock(&linfo->lock); - result = !memcmp(log_name, linfo->log_file_name, log_name_len); + result = !strncmp(log_name, linfo->log_file_name, log_name_len); mysql_mutex_unlock(&linfo->lock); if (result) break; From b20d94da356fa274a49ac38497e0cb20ce760d93 Mon Sep 17 00:00:00 2001 From: Sreeharsha Ramanavarapu Date: Tue, 9 Oct 2018 12:03:35 +0530 Subject: [PATCH 028/106] Bug #28499924: INCORRECT BEHAVIOR WITH UNION IN SUBQUERY Issue: ------ When a subquery contains UNION the count of the number of subquery columns is calculated incorrectly. Only the first query block in the subquery's UNION is considered and an array indexing goes out-of-bounds, and this is caught by an assert. Solution: --------- Sum up the columns from all query blocks of the query expression. Change specific to 5.6/5.5: --------------------------- The "child" points to the last query block of the UNION (as opposed to 5.7+ where it points to the first member of UNION). So "child->master_unit()->first_select()" is used to reach the first query block of UNION. --- sql/sql_yacc.yy | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 34f7c6e3481..ba0041cf477 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -14627,19 +14627,21 @@ subselect_end: lex->current_select = lex->current_select->return_after_parsing(); lex->nest_level--; lex->current_select->n_child_sum_items += child->n_sum_items; - /* - A subselect can add fields to an outer select. Reserve space for - them. - */ - lex->current_select->select_n_where_fields+= - child->select_n_where_fields; /* - Aggregate functions in having clause may add fields to an outer - select. Count them also. + A subquery (and all the subsequent query blocks in a UNION) can + add columns to an outer query block. Reserve space for them. + Aggregate functions in having clause can also add fields to an + outer select. */ - lex->current_select->select_n_having_items+= - child->select_n_having_items; + for (SELECT_LEX *temp= child->master_unit()->first_select(); + temp != NULL; temp= temp->next_select()) + { + lex->current_select->select_n_where_fields+= + temp->select_n_where_fields; + lex->current_select->select_n_having_items+= + temp->select_n_having_items; + } } ; From a8da66f8c56211417289b0e40a10faf49e225a54 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 22 Jan 2019 00:15:57 +0100 Subject: [PATCH 029/106] Bug #28499924: INCORRECT BEHAVIOR WITH UNION IN SUBQUERY test case --- mysql-test/r/subselect2.result | 22 ++++++++++++++++++++++ mysql-test/t/subselect2.test | 20 ++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/mysql-test/r/subselect2.result b/mysql-test/r/subselect2.result index 64bd86707cc..8d555aa798b 100644 --- a/mysql-test/r/subselect2.result +++ b/mysql-test/r/subselect2.result @@ -394,3 +394,25 @@ select null in (select a from t1 where a < out3.a union select a from t2 where (select a from t3) +1 < out3.a+1) from t3 out3; ERROR 21000: Subquery returns more than 1 row drop table t1, t2, t3; +CREATE TABLE t1( +q11 int, q12 int, q13 int, q14 int, q15 int, q16 int, q17 int, q18 int, q19 int, +q21 int, q22 int, q23 int, q24 int, q25 int, q26 int, q27 int, q28 int, q29 int, +f1 int +); +CREATE TABLE t2(f2 int, f21 int, f3 timestamp, f4 int, f5 int, f6 int); +INSERT INTO t1 (f1) VALUES (1),(1),(2),(2); +INSERT INTO t2 VALUES (1,1,"2004-02-29 11:11:11",0,0,0), (2,2,"2004-02-29 11:11:11",0,0,0); +SELECT f1, +(SELECT t.f21 from t2 t where max( +q11+q12+q13+q14+q15+q16+q17+q18+q19+ +q21+q22+q23+q24+q25+q26+q27+q28+q29) = t.f2 UNION +SELECT t.f3 FROM t2 AS t WHERE t1.f1=t.f2 AND t.f3=MAX(t1.f1) UNION +SELECT 1 LIMIT 1) AS test +FROM t1 GROUP BY f1; +f1 test +1 1 +2 1 +Warnings: +Warning 1292 Incorrect datetime value: '1' +Warning 1292 Incorrect datetime value: '2' +DROP TABLE t1,t2; diff --git a/mysql-test/t/subselect2.test b/mysql-test/t/subselect2.test index ae210b865a2..73b0e77ade6 100644 --- a/mysql-test/t/subselect2.test +++ b/mysql-test/t/subselect2.test @@ -411,3 +411,23 @@ insert into t3 select a from t1; select null in (select a from t1 where a < out3.a union select a from t2 where (select a from t3) +1 < out3.a+1) from t3 out3; drop table t1, t2, t3; + +# +# Bug #28499924: INCORRECT BEHAVIOR WITH UNION IN SUBQUERY +# +CREATE TABLE t1( + q11 int, q12 int, q13 int, q14 int, q15 int, q16 int, q17 int, q18 int, q19 int, + q21 int, q22 int, q23 int, q24 int, q25 int, q26 int, q27 int, q28 int, q29 int, + f1 int +); +CREATE TABLE t2(f2 int, f21 int, f3 timestamp, f4 int, f5 int, f6 int); +INSERT INTO t1 (f1) VALUES (1),(1),(2),(2); +INSERT INTO t2 VALUES (1,1,"2004-02-29 11:11:11",0,0,0), (2,2,"2004-02-29 11:11:11",0,0,0); +SELECT f1, + (SELECT t.f21 from t2 t where max( + q11+q12+q13+q14+q15+q16+q17+q18+q19+ + q21+q22+q23+q24+q25+q26+q27+q28+q29) = t.f2 UNION + SELECT t.f3 FROM t2 AS t WHERE t1.f1=t.f2 AND t.f3=MAX(t1.f1) UNION + SELECT 1 LIMIT 1) AS test + FROM t1 GROUP BY f1; +DROP TABLE t1,t2; From 949559285efff44ba49b478ee766e0fe0a5a9b79 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 23 Jan 2019 10:09:49 +0100 Subject: [PATCH 030/106] MDEV-18059 `support-files/mysql.server.sh stop` must run as root don't run `su - mysql` is $USER is already mysql --- support-files/mysql.server.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/support-files/mysql.server.sh b/support-files/mysql.server.sh index c1d85ba2664..f3990967b87 100644 --- a/support-files/mysql.server.sh +++ b/support-files/mysql.server.sh @@ -187,7 +187,11 @@ fi user='@MYSQLD_USER@' su_kill() { - su - $user -s /bin/sh -c "kill $*" >/dev/null 2>&1 + if test "$USER" = "$user"; then + kill $* >/dev/null 2>&1 + else + su - $user -s /bin/sh -c "kill $*" >/dev/null 2>&1 + fi } # From ad220b96fb01dbb6acf7e51bdd8d4d6362d96ea7 Mon Sep 17 00:00:00 2001 From: Eugene Kosov Date: Mon, 2 Jul 2018 12:26:22 +0300 Subject: [PATCH 031/106] MDEV-16658 Memory leak in mysqltest on connect failure Close connection handler on connection failure. This fixes 14 failing tests in main suite under clang+ASAN build. ASAN report for main.connect looks like this: ================================================================= ==25495==ERROR: LeakSanitizer: detected memory leaks Direct leak of 146280 byte(s) in 115 object(s) allocated from: #0 0x4fba47 in calloc /fun/cpp_projects/llvm_toolchain/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:138 #1 0x5a7a02 in mysql_init /work/mariadb/libmariadb/libmariadb/mariadb_lib.c:977:26 #2 0x570a7a in do_connect(st_command*) /work/mariadb/client/mysqltest.cc:6096:26 #3 0x584c39 in main /work/mariadb/client/mysqltest.cc:9321:9 #4 0x7fd15514db96 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:310 Indirect leak of 7065600 byte(s) in 115 object(s) allocated from: #0 0x4fb80f in __interceptor_malloc /fun/cpp_projects/llvm_toolchain/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:129 #1 0x637a83 in my_context_init /work/mariadb/libmariadb/libmariadb/ma_context.c:367:23 #2 0x59fd16 in mysql_optionsv /work/mariadb/libmariadb/libmariadb/mariadb_lib.c:2738:9 #3 0x5bc1d4 in mysql_options /work/mariadb/libmariadb/libmariadb/mariadb_lib.c:3242:10 #4 0x570b94 in do_connect(st_command*) /work/mariadb/client/mysqltest.cc:6103:7 #5 0x584c39 in main /work/mariadb/client/mysqltest.cc:9321:9 #6 0x7fd15514db96 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:310 Indirect leak of 940240 byte(s) in 115 object(s) allocated from: #0 0x4fb80f in __interceptor_malloc /fun/cpp_projects/llvm_toolchain/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:129 #1 0x64386e in ma_init_dynamic_array /work/mariadb/libmariadb/libmariadb/ma_array.c:49:31 #2 0x649ead in _hash_init /work/mariadb/libmariadb/libmariadb/ma_hash.c:52:7 #3 0x5a3080 in mysql_optionsv /work/mariadb/libmariadb/libmariadb/mariadb_lib.c:2938:13 #4 0x5bc20c in mysql_options4 /work/mariadb/libmariadb/libmariadb/mariadb_lib.c:3248:10 #5 0x56f63b in connect_n_handle_errors(st_command*, st_mysql*, char const*, char const*, char const*, char const*, int, char const*) /work/mariadb/client/mysqltest.cc:5874:3 #6 0x57146b in do_connect(st_command*) /work/mariadb/client/mysqltest.cc:6193:7 #7 0x584c39 in main /work/mariadb/client/mysqltest.cc:9321:9 #8 0x7fd15514db96 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:310 ... Closes #809 --- client/mysqltest.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 088afed41b2..2b7401878ef 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -6129,6 +6129,11 @@ void do_connect(struct st_command *command) if (con_slot == next_con) next_con++; /* if we used the next_con slot, advance the pointer */ } + else // Failed to connect. Free the memory. + { + mysql_close(con_slot->mysql); + con_slot->mysql= NULL; + } dynstr_free(&ds_connection_name); dynstr_free(&ds_host); From f17c284c5745f34de230af8a339eabb11bc0d5ee Mon Sep 17 00:00:00 2001 From: Geoff Montee Date: Wed, 23 Jan 2019 21:59:16 -0500 Subject: [PATCH 032/106] MDEV-18347: mariabackup doesn't read all server option groups from configuration files --- extra/mariabackup/xtrabackup.cc | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index ef75797d1a4..338b70dc874 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -1234,11 +1234,23 @@ debug_sync_point(const char *name) #endif } -static const char *xb_client_default_groups[]= - { "xtrabackup", "mariabackup", "client", 0, 0, 0 }; +static const char *xb_client_default_groups[]={ + "xtrabackup", "mariabackup", + "client", "client-server", + "client-mariadb", + 0, 0, 0 +}; -static const char *xb_server_default_groups[]= - { "xtrabackup", "mariabackup", "mysqld", 0, 0, 0 }; +static const char *xb_server_default_groups[]={ + "xtrabackup", "mariabackup", + "mysqld", "server", MYSQL_BASE_VERSION, + "mariadb", MARIADB_BASE_VERSION, + "client-server", + #ifdef WITH_WSREP + "galera", + #endif + 0, 0, 0 +}; static void print_version(void) { From 17c75bd272f620a11dbb9fe0517b41da03d081f3 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Thu, 17 Jan 2019 16:37:57 +0400 Subject: [PATCH 033/106] MDEV-18195 ASAN use-after-poison in my_strcasecmp_utf8 / Item::eq upon prepared statement with ORDER BY NAME_CONST ASAN noticed a freed memory access during EXECUTE in this script: PREPARE stmt FROM "SELECT 'x' ORDER BY NAME_CONST( 'f', 'foo' )"; EXECUTE stmt; In case of a PREPARE statement, all Items, including Item_name_const, are created on Prepared_statement::main_mem_root. Item_name_const::fix_fields() did not take this into account and could allocate the value of Item::name on a wrong memory root, in this code: if (is_autogenerated_name) { set_name(thd, item_name->c_ptr(), (uint) item_name->length(), system_charset_info); } When fix_fields() is called in the reported SQL script, THD's arena already points to THD::main_mem_root rather than to Prepared_statement::main_mem_root, so Item::name was allocated on THD::main_mem_root. Then, at the end of the dispatch_command() for the PREPARE statement, THD::main_mem_root got cleared. So during EXECUTE, Item::name pointed to an already freed memory. This patch changes the code to set the implicit name for Item_name_const at the constructor time rather than at fix_fields time. This guarantees that Item_name_const and its Item::name always reside on the same memory root. Note, this change makes the code for Item_name_const symmetric with other constant-alike items that set their default implicit names at the constructor call time rather than at fix_fields() time: - Item_string - Item_int - Item_real - Item_decimal - Item_null - Item_param --- mysql-test/r/func_misc.result | 8 ++++++++ mysql-test/t/func_misc.test | 9 +++++++++ sql/item.cc | 18 ++++++------------ 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result index 1f9aa212740..287a70f1f73 100644 --- a/mysql-test/r/func_misc.result +++ b/mysql-test/r/func_misc.result @@ -1471,3 +1471,11 @@ CALL p1(); ip_full_addr 2000:: DROP PROCEDURE p1; +# +# MDEV-18195 ASAN use-after-poison in my_strcasecmp_utf8 / Item::eq upon prepared statement with ORDER BY NAME_CONST +# +PREPARE stmt FROM "SELECT 'x' ORDER BY NAME_CONST( 'f', 'foo' )"; +EXECUTE stmt; +x +x +DEALLOCATE PREPARE stmt; diff --git a/mysql-test/t/func_misc.test b/mysql-test/t/func_misc.test index 2509f55ccbb..a8da9068ab8 100644 --- a/mysql-test/t/func_misc.test +++ b/mysql-test/t/func_misc.test @@ -1145,3 +1145,12 @@ $$ DELIMITER ;$$ CALL p1(); DROP PROCEDURE p1; + + +--echo # +--echo # MDEV-18195 ASAN use-after-poison in my_strcasecmp_utf8 / Item::eq upon prepared statement with ORDER BY NAME_CONST +--echo # + +PREPARE stmt FROM "SELECT 'x' ORDER BY NAME_CONST( 'f', 'foo' )"; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; diff --git a/sql/item.cc b/sql/item.cc index 1a2c4eba5fb..d8f27bdb30e 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1672,10 +1672,14 @@ bool Item_name_const::is_null() Item_name_const::Item_name_const(THD *thd, Item *name_arg, Item *val): Item(thd), value_item(val), name_item(name_arg) { + StringBuffer<128> name_buffer; + String *name_str; Item::maybe_null= TRUE; valid_args= true; - if (!name_item->basic_const_item()) + if (!name_item->basic_const_item() || + !(name_str= name_item->val_str(&name_buffer))) // Can't have a NULL name goto err; + set_name(name_str->ptr(), name_str->length(), name_str->charset()); if (value_item->basic_const_item()) return; // ok @@ -1737,24 +1741,14 @@ Item::Type Item_name_const::type() const bool Item_name_const::fix_fields(THD *thd, Item **ref) { - char buf[128]; - String *item_name; - String s(buf, sizeof(buf), &my_charset_bin); - s.length(0); - if (value_item->fix_fields(thd, &value_item) || name_item->fix_fields(thd, &name_item) || !value_item->const_item() || - !name_item->const_item() || - !(item_name= name_item->val_str(&s))) // Can't have a NULL name + !name_item->const_item()) { my_error(ER_RESERVED_SYNTAX, MYF(0), "NAME_CONST"); return TRUE; } - if (is_autogenerated_name) - { - set_name(item_name->ptr(), (uint) item_name->length(), system_charset_info); - } if (value_item->collation.derivation == DERIVATION_NUMERIC) collation.set_numeric(); else From 1abdc0e435e4e7e71257e246972a3b3015df287c Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Thu, 24 Jan 2019 15:47:27 +0100 Subject: [PATCH 034/106] 5.6.43 --- mysql-test/suite/perfschema/r/dml_setup_instruments.result | 4 +++- mysql-test/suite/perfschema/t/dml_setup_instruments.test | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/perfschema/r/dml_setup_instruments.result b/mysql-test/suite/perfschema/r/dml_setup_instruments.result index 310ff60aa5b..7bc7ca785d6 100644 --- a/mysql-test/suite/perfschema/r/dml_setup_instruments.result +++ b/mysql-test/suite/perfschema/r/dml_setup_instruments.result @@ -16,7 +16,9 @@ wait/synch/mutex/sql/LOCK_crypt YES YES wait/synch/mutex/sql/LOCK_delayed_create YES YES select * from performance_schema.setup_instruments where name like 'Wait/Synch/Rwlock/sql/%' - and name not in ('wait/synch/rwlock/sql/CRYPTO_dynlock_value::lock') + and name not in ( +'wait/synch/rwlock/sql/CRYPTO_dynlock_value::lock', +'wait/synch/rwlock/sql/LOCK_named_pipe_full_access_group') order by name limit 10; NAME ENABLED TIMED wait/synch/rwlock/sql/Binlog_relay_IO_delegate::lock YES YES diff --git a/mysql-test/suite/perfschema/t/dml_setup_instruments.test b/mysql-test/suite/perfschema/t/dml_setup_instruments.test index 8a4f11ba51f..18c260e1555 100644 --- a/mysql-test/suite/perfschema/t/dml_setup_instruments.test +++ b/mysql-test/suite/perfschema/t/dml_setup_instruments.test @@ -22,10 +22,13 @@ select * from performance_schema.setup_instruments order by name limit 10; # CRYPTO_dynlock_value::lock is dependent on the build (SSL) +# LOCK_named_pipe_full_access_group is dependent on the build (Windows) select * from performance_schema.setup_instruments where name like 'Wait/Synch/Rwlock/sql/%' - and name not in ('wait/synch/rwlock/sql/CRYPTO_dynlock_value::lock') + and name not in ( + 'wait/synch/rwlock/sql/CRYPTO_dynlock_value::lock', + 'wait/synch/rwlock/sql/LOCK_named_pipe_full_access_group') order by name limit 10; # COND_handler_count is dependent on the build (Windows only) From 036ca990abddbc9b93f45904ccabd5ec4bd5b396 Mon Sep 17 00:00:00 2001 From: Varun Gupta Date: Thu, 24 Jan 2019 20:47:46 +0530 Subject: [PATCH 035/106] MDEV-18255: Server crashes in Bitmap<64u>::intersect Calling st_select_lex::update_used_tables in JOIN::optimize_unflattened_subqueries only when we are sure that the join have not been cleaned up. This can happen for a case when we have a non-merged semi-join and an impossible where which would lead to the cleanup of the join which has the non-merged semi-join --- mysql-test/r/subselect_mat.result | 16 ++++++++++++++++ mysql-test/t/subselect_mat.test | 13 +++++++++++++ sql/sql_lex.cc | 3 ++- 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/subselect_mat.result b/mysql-test/r/subselect_mat.result index aa0ac73abd2..7907b86135e 100644 --- a/mysql-test/r/subselect_mat.result +++ b/mysql-test/r/subselect_mat.result @@ -2822,3 +2822,19 @@ id select_type table type possible_keys key key_len ref rows Extra SELECT * FROM t2 WHERE f IN ( SELECT LEFT('foo',0) FROM t1 ORDER BY 1 ); f DROP TABLE t1, t2; +# +# MDEV-18255: Server crashes in Bitmap<64u>::intersect +# +create table t1 (v1 varchar(1)) engine=myisam ; +create table t2 (v1 varchar(1)) engine=myisam ; +explain +select 1 from t1 where exists +(select 1 from t1 where t1.v1 in (select t2.v1 from t2 having t2.v1 < 'j')) ; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table +3 MATERIALIZED NULL NULL NULL NULL NULL NULL NULL no matching row in const table +select 1 from t1 where exists +(select 1 from t1 where t1.v1 in (select t2.v1 from t2 having t2.v1 < 'j')) ; +1 +drop table t1,t2; diff --git a/mysql-test/t/subselect_mat.test b/mysql-test/t/subselect_mat.test index 5211f35b48b..66a6cc97acb 100644 --- a/mysql-test/t/subselect_mat.test +++ b/mysql-test/t/subselect_mat.test @@ -267,3 +267,16 @@ explain SELECT * FROM t2 WHERE f IN ( SELECT LEFT('foo',0) FROM t1 ORDER BY 1 ); SELECT * FROM t2 WHERE f IN ( SELECT LEFT('foo',0) FROM t1 ORDER BY 1 ); DROP TABLE t1, t2; + +--echo # +--echo # MDEV-18255: Server crashes in Bitmap<64u>::intersect +--echo # +create table t1 (v1 varchar(1)) engine=myisam ; +create table t2 (v1 varchar(1)) engine=myisam ; + +explain +select 1 from t1 where exists + (select 1 from t1 where t1.v1 in (select t2.v1 from t2 having t2.v1 < 'j')) ; +select 1 from t1 where exists + (select 1 from t1 where t1.v1 in (select t2.v1 from t2 having t2.v1 < 'j')) ; +drop table t1,t2; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 08c169c5999..2fb239ed498 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -3551,7 +3551,8 @@ bool st_select_lex::optimize_unflattened_subqueries(bool const_only) inner_join->select_options|= SELECT_DESCRIBE; } res= inner_join->optimize(); - sl->update_used_tables(); + if (!inner_join->cleaned) + sl->update_used_tables(); sl->update_correlated_cache(); is_correlated_unit|= sl->is_correlated; inner_join->select_options= save_options; From 3262afc6c50bdee489dd35feb8c5254dbc93494b Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Thu, 24 Jan 2019 16:48:39 +0100 Subject: [PATCH 036/106] 5.6.42-84.2 --- storage/xtradb/handler/ha_innodb.cc | 5 +++ storage/xtradb/handler/handler0alter.cc | 35 ++++++++++++++++----- storage/xtradb/include/os0file.h | 6 +++- storage/xtradb/include/univ.i | 2 +- storage/xtradb/log/log0online.cc | 41 ++++++++++++++++++++++++- storage/xtradb/row/row0merge.cc | 17 ++++++++-- storage/xtradb/row/row0mysql.cc | 15 ++------- storage/xtradb/row/row0sel.cc | 4 +-- 8 files changed, 99 insertions(+), 26 deletions(-) diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 053a181e26c..1ff50136859 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -2322,6 +2322,11 @@ innobase_get_lower_case_table_names(void) { return(lower_case_table_names); } +/** return one of the tmpdir path +@return tmpdir path*/ +UNIV_INTERN +char* +innobase_mysql_tmpdir(void) { return (mysql_tmpdir); } /** Create a temporary file in the location specified by the parameter path. If the path is null, then it will be created in tmpdir. diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc index 517dd30410b..856f8bac8de 100644 --- a/storage/xtradb/handler/handler0alter.cc +++ b/storage/xtradb/handler/handler0alter.cc @@ -4056,11 +4056,23 @@ oom: table. Either way, we should be seeing and reporting a bogus duplicate key error. */ dup_key = NULL; - } else { - DBUG_ASSERT(prebuilt->trx->error_key_num - < ha_alter_info->key_count); + } else if (prebuilt->trx->error_key_num == 0) { dup_key = &ha_alter_info->key_info_buffer[ prebuilt->trx->error_key_num]; + } else { + /* Check if there is generated cluster index column */ + if (ctx->num_to_add_index > ha_alter_info->key_count) { + DBUG_ASSERT(prebuilt->trx->error_key_num + <= ha_alter_info->key_count); + dup_key = &ha_alter_info->key_info_buffer[ + prebuilt->trx->error_key_num - 1]; + } + else { + DBUG_ASSERT(prebuilt->trx->error_key_num + < ha_alter_info->key_count); + dup_key = &ha_alter_info->key_info_buffer[ + prebuilt->trx->error_key_num]; + } } print_keydup_error(altered_table, dup_key, MYF(0)); break; @@ -4981,11 +4993,20 @@ commit_try_rebuild( FTS_DOC_ID. */ dup_key = NULL; } else { - DBUG_ASSERT(err_key < - ha_alter_info->key_count); - dup_key = &ha_alter_info - ->key_info_buffer[err_key]; + if (ctx->num_to_add_index > ha_alter_info->key_count) { + DBUG_ASSERT(err_key <= + ha_alter_info->key_count); + dup_key = &ha_alter_info + ->key_info_buffer[err_key - 1]; + } + else { + DBUG_ASSERT(err_key < + ha_alter_info->key_count); + dup_key = &ha_alter_info + ->key_info_buffer[err_key]; + } } + print_keydup_error(altered_table, dup_key, MYF(0)); DBUG_RETURN(true); case DB_ONLINE_LOG_TOO_BIG: diff --git a/storage/xtradb/include/os0file.h b/storage/xtradb/include/os0file.h index f7531d99f38..bc7e468b776 100644 --- a/storage/xtradb/include/os0file.h +++ b/storage/xtradb/include/os0file.h @@ -1,6 +1,6 @@ /*********************************************************************** -Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2018, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2009, Percona Inc. Portions of this file contain modifications contributed and copyrighted @@ -1531,6 +1531,10 @@ os_file_get_status( file can be opened in RW mode */ #if !defined(UNIV_HOTBACKUP) + +/** return one of the tmpdir path + @return tmpdir path*/ +char *innobase_mysql_tmpdir(void); /** Create a temporary file in the location specified by the parameter path. If the path is null, then it will be created in tmpdir. @param[in] path location for creating temporary file diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i index f625ea46433..4904e174b87 100644 --- a/storage/xtradb/include/univ.i +++ b/storage/xtradb/include/univ.i @@ -47,7 +47,7 @@ Created 1/20/1994 Heikki Tuuri #define INNODB_VERSION_BUGFIX MYSQL_VERSION_PATCH #ifndef PERCONA_INNODB_VERSION -#define PERCONA_INNODB_VERSION 84.1 +#define PERCONA_INNODB_VERSION 84.2 #endif /* Enable UNIV_LOG_ARCHIVE in XtraDB */ diff --git a/storage/xtradb/log/log0online.cc b/storage/xtradb/log/log0online.cc index e3cfbfc2088..a3d76e79b2a 100644 --- a/storage/xtradb/log/log0online.cc +++ b/storage/xtradb/log/log0online.cc @@ -1880,6 +1880,8 @@ log_online_purge_changed_page_bitmaps( for (i = 0; i < bitmap_files.count; i++) { + char full_bmp_file_name[2 * FN_REFLEN + 2]; + /* We consider the end LSN of the current bitmap, derived from the start LSN of the subsequent bitmap file, to determine whether to remove the current bitmap. Note that bitmap_files @@ -1895,8 +1897,45 @@ log_online_purge_changed_page_bitmaps( break; } + + /* In some non-trivial cases the sequence of .xdb files may + have gaps. For instance: + ib_modified_log_1_0.xdb + ib_modified_log_2_.xdb + ib_modified_log_4_.xdb + Adding this check as a safety precaution. */ + if (bitmap_files.files[i].name[0] == '\0') + continue; + + /* If redo log tracking is enabled, reuse 'bmp_file_home' + from 'log_bmp_sys'. Otherwise, compose the full '.xdb' file + path from 'srv_data_home', adding a path separator if + necessary. */ + if (log_bmp_sys != NULL) { + ut_snprintf(full_bmp_file_name, + sizeof(full_bmp_file_name), + "%s%s", log_bmp_sys->bmp_file_home, + bitmap_files.files[i].name); + } + else { + char separator[2] = {0, 0}; + const size_t srv_data_home_len = + strlen(srv_data_home); + + ut_a(srv_data_home_len < FN_REFLEN); + if (srv_data_home_len != 0 && + srv_data_home[srv_data_home_len - 1] != + SRV_PATH_SEPARATOR) { + separator[0] = SRV_PATH_SEPARATOR; + } + ut_snprintf(full_bmp_file_name, + sizeof(full_bmp_file_name), "%s%s%s", + srv_data_home, separator, + bitmap_files.files[i].name); + } + if (!os_file_delete_if_exists(innodb_file_bmp_key, - bitmap_files.files[i].name)) { + full_bmp_file_name)) { os_file_get_last_error(TRUE); result = TRUE; diff --git a/storage/xtradb/row/row0merge.cc b/storage/xtradb/row/row0merge.cc index b000f313d67..507709ce12b 100644 --- a/storage/xtradb/row/row0merge.cc +++ b/storage/xtradb/row/row0merge.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2005, 2017, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2005, 2018, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -3129,15 +3129,27 @@ row_merge_file_create_low( const char* path) { int fd; + char filename[] = "Innodb Merge Temp File\0"; + char* filepath = NULL; + int path_len; + if (path == NULL) { + path = innobase_mysql_tmpdir(); + } #ifdef UNIV_PFS_IO /* This temp file open does not go through normal file APIs, add instrumentation to register with performance schema */ + path_len = strlen(path) + sizeof "/" + strlen(filename)+1; + filepath = static_cast(mem_alloc(path_len)); + memcpy(filepath,path,strlen(path)); + ut_snprintf(filepath + strlen(path),path_len - strlen(path), + "%c%s",'/',filename); struct PSI_file_locker* locker = NULL; + PSI_file_locker_state state; locker = PSI_FILE_CALL(get_thread_file_name_locker)( &state, innodb_file_temp_key, PSI_FILE_OPEN, - "Innodb Merge Temp File", &locker); + filepath, &locker); if (locker != NULL) { PSI_FILE_CALL(start_file_open_wait)(locker, __FILE__, @@ -3150,6 +3162,7 @@ row_merge_file_create_low( PSI_FILE_CALL(end_file_open_wait_and_bind_to_descriptor)( locker, fd); } + mem_free(filepath); #endif if (fd < 0) { diff --git a/storage/xtradb/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc index ddde8b8f730..9fc5c669ba0 100644 --- a/storage/xtradb/row/row0mysql.cc +++ b/storage/xtradb/row/row0mysql.cc @@ -5500,18 +5500,6 @@ row_rename_table_for_mysql( goto funct_exit; } - /* Wait for background fts sync to finish */ - for (retry = 1; dict_fts_index_syncing(table); ++retry) { - DICT_BG_YIELD(trx); - if (retry % 100 == 0) { - ib_logf(IB_LOG_LEVEL_INFO, - "Unable to rename table %s to new name" - " %s because FTS sync is running on table." - " Retrying\n", - old_name, new_name); - } - } - /* We use the private SQL parser of Innobase to generate the query graphs needed in updating the dictionary data from system tables. */ @@ -5669,6 +5657,9 @@ row_rename_table_for_mysql( " = TO_BINARY(:old_table_name);\n" "END;\n" , FALSE, trx); + if (err != DB_SUCCESS) { + goto end; + } } else if (n_constraints_to_drop > 0) { /* Drop some constraints of tmp tables. */ diff --git a/storage/xtradb/row/row0sel.cc b/storage/xtradb/row/row0sel.cc index 5db61ecdd56..0edad710d79 100644 --- a/storage/xtradb/row/row0sel.cc +++ b/storage/xtradb/row/row0sel.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1997, 2018, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. Portions of this file contain modifications contributed and copyrighted by @@ -4416,7 +4416,7 @@ rec_loop: passed to InnoDB when there is no ICP and number of loops in row_search_for_mysql for rows found but not reporting due to search views etc. */ - if (prev_rec != NULL + if (prev_rec != NULL && !prebuilt->innodb_api && prebuilt->mysql_handler->end_range != NULL && prebuilt->idx_cond == NULL && end_loop >= 100) { From 13802fef831790c4b63a3ddbf96e516eff422464 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Thu, 24 Jan 2019 17:31:13 +0100 Subject: [PATCH 037/106] 5.6.42-84.2 --- storage/tokudb/PerconaFT/COPYING.APACHEv2 | 174 ++ storage/tokudb/PerconaFT/README.md | 5 +- storage/tokudb/PerconaFT/ft/txn/txn_manager.h | 4 +- .../PerconaFT/locktree/concurrent_tree.cc | 14 + .../PerconaFT/locktree/concurrent_tree.h | 14 + storage/tokudb/PerconaFT/locktree/keyrange.cc | 13 + storage/tokudb/PerconaFT/locktree/keyrange.h | 13 + .../tokudb/PerconaFT/locktree/lock_request.cc | 13 + .../tokudb/PerconaFT/locktree/lock_request.h | 13 + storage/tokudb/PerconaFT/locktree/locktree.cc | 13 + storage/tokudb/PerconaFT/locktree/locktree.h | 13 + storage/tokudb/PerconaFT/locktree/manager.cc | 13 + .../tokudb/PerconaFT/locktree/range_buffer.cc | 13 + .../tokudb/PerconaFT/locktree/range_buffer.h | 13 + storage/tokudb/PerconaFT/locktree/treenode.cc | 13 + storage/tokudb/PerconaFT/locktree/treenode.h | 13 + .../tokudb/PerconaFT/locktree/txnid_set.cc | 13 + storage/tokudb/PerconaFT/locktree/txnid_set.h | 13 + storage/tokudb/PerconaFT/locktree/wfg.cc | 13 + storage/tokudb/PerconaFT/locktree/wfg.h | 13 + .../PerconaFT/portability/toku_instr_mysql.cc | 12 +- .../PerconaFT/portability/toku_instr_mysql.h | 11 +- .../PerconaFT/portability/toku_pthread.h | 78 +- storage/tokudb/PerconaFT/tools/CMakeLists.txt | 8 +- .../tokudb/PerconaFT/util/growable_array.h | 13 + storage/tokudb/PerconaFT/util/omt.cc | 2373 +++++++++-------- storage/tokudb/PerconaFT/util/omt.h | 13 + storage/tokudb/ha_tokudb.cc | 10 + storage/tokudb/hatoku_hton.cc | 4 +- storage/tokudb/hatoku_hton.h | 1 - .../mysql-test/tokudb_bugs/r/PS-4979.result | 2 + .../mysql-test/tokudb_bugs/t/PS-4979.test | 12 + storage/tokudb/tokudb_background.cc | 4 +- storage/tokudb/tokudb_sysvars.cc | 14 +- storage/tokudb/tokudb_sysvars.h | 4 +- 35 files changed, 1834 insertions(+), 1131 deletions(-) create mode 100644 storage/tokudb/PerconaFT/COPYING.APACHEv2 create mode 100644 storage/tokudb/mysql-test/tokudb_bugs/r/PS-4979.result create mode 100644 storage/tokudb/mysql-test/tokudb_bugs/t/PS-4979.test diff --git a/storage/tokudb/PerconaFT/COPYING.APACHEv2 b/storage/tokudb/PerconaFT/COPYING.APACHEv2 new file mode 100644 index 00000000000..ecbfc770fa9 --- /dev/null +++ b/storage/tokudb/PerconaFT/COPYING.APACHEv2 @@ -0,0 +1,174 @@ +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. diff --git a/storage/tokudb/PerconaFT/README.md b/storage/tokudb/PerconaFT/README.md index ffb646b67af..26333df877e 100644 --- a/storage/tokudb/PerconaFT/README.md +++ b/storage/tokudb/PerconaFT/README.md @@ -104,11 +104,14 @@ All source code and test contributions must be provided under a [BSD 2-Clause][b License ------- +Portions of the PerconaFT library (the 'locktree' and 'omt') are available under the Apache version 2 license. PerconaFT is available under the GPL version 2, and AGPL version 3. -See [COPYING.AGPLv3][agpllicense], +See [COPYING.APACHEv2][apachelicense], +[COPYING.AGPLv3][agpllicense], [COPYING.GPLv2][gpllicense], and [PATENTS][patents]. +[apachelicense]: http://github.com/Percona/PerconaFT/blob/master/COPYING.APACHEv2 [agpllicense]: http://github.com/Percona/PerconaFT/blob/master/COPYING.AGPLv3 [gpllicense]: http://github.com/Percona/PerconaFT/blob/master/COPYING.GPLv2 [patents]: http://github.com/Percona/PerconaFT/blob/master/PATENTS diff --git a/storage/tokudb/PerconaFT/ft/txn/txn_manager.h b/storage/tokudb/PerconaFT/ft/txn/txn_manager.h index 7cdc52c4f43..25fa6032112 100644 --- a/storage/tokudb/PerconaFT/ft/txn/txn_manager.h +++ b/storage/tokudb/PerconaFT/ft/txn/txn_manager.h @@ -46,11 +46,11 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. void set_test_txn_sync_callback(void (*) (pthread_t, void*), void*); #define toku_test_txn_sync_callback(a) ((test_txn_sync_callback)? test_txn_sync_callback( a,test_txn_sync_callback_extra) : (void) 0) -#if TOKU_DEBUG_TXN_SYNC +#if defined(TOKU_DEBUG_TXN_SYNC) #define toku_debug_txn_sync(a) toku_test_txn_sync_callback(a) #else #define toku_debug_txn_sync(a) ((void) 0) -#endif +#endif // defined(TOKU_DEBUG_TXN_SYNC) typedef struct txn_manager *TXN_MANAGER; diff --git a/storage/tokudb/PerconaFT/locktree/concurrent_tree.cc b/storage/tokudb/PerconaFT/locktree/concurrent_tree.cc index 9347267db49..e07f32c98fb 100644 --- a/storage/tokudb/PerconaFT/locktree/concurrent_tree.cc +++ b/storage/tokudb/PerconaFT/locktree/concurrent_tree.cc @@ -32,6 +32,20 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. You should have received a copy of the GNU Affero General Public License along with PerconaFT. If not, see . + +---------------------------------------- + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. ======= */ #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." diff --git a/storage/tokudb/PerconaFT/locktree/concurrent_tree.h b/storage/tokudb/PerconaFT/locktree/concurrent_tree.h index 1eb339b7317..66a7ff176bb 100644 --- a/storage/tokudb/PerconaFT/locktree/concurrent_tree.h +++ b/storage/tokudb/PerconaFT/locktree/concurrent_tree.h @@ -32,6 +32,20 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. You should have received a copy of the GNU Affero General Public License along with PerconaFT. If not, see . + +---------------------------------------- + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. ======= */ #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." diff --git a/storage/tokudb/PerconaFT/locktree/keyrange.cc b/storage/tokudb/PerconaFT/locktree/keyrange.cc index 8c2a69d4703..2b4b3bbd4fd 100644 --- a/storage/tokudb/PerconaFT/locktree/keyrange.cc +++ b/storage/tokudb/PerconaFT/locktree/keyrange.cc @@ -32,6 +32,19 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. You should have received a copy of the GNU Affero General Public License along with PerconaFT. If not, see . + +---------------------------------------- + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and ======= */ #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." diff --git a/storage/tokudb/PerconaFT/locktree/keyrange.h b/storage/tokudb/PerconaFT/locktree/keyrange.h index 079ac3d7a80..a454287cbc8 100644 --- a/storage/tokudb/PerconaFT/locktree/keyrange.h +++ b/storage/tokudb/PerconaFT/locktree/keyrange.h @@ -32,6 +32,19 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. You should have received a copy of the GNU Affero General Public License along with PerconaFT. If not, see . + +---------------------------------------- + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and ======= */ #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." diff --git a/storage/tokudb/PerconaFT/locktree/lock_request.cc b/storage/tokudb/PerconaFT/locktree/lock_request.cc index 8d49ccf8a1f..3d4d43b9e25 100644 --- a/storage/tokudb/PerconaFT/locktree/lock_request.cc +++ b/storage/tokudb/PerconaFT/locktree/lock_request.cc @@ -32,6 +32,19 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. You should have received a copy of the GNU Affero General Public License along with PerconaFT. If not, see . + +---------------------------------------- + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and ======= */ #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." diff --git a/storage/tokudb/PerconaFT/locktree/lock_request.h b/storage/tokudb/PerconaFT/locktree/lock_request.h index a8d8cb7785b..91a6ff12b52 100644 --- a/storage/tokudb/PerconaFT/locktree/lock_request.h +++ b/storage/tokudb/PerconaFT/locktree/lock_request.h @@ -32,6 +32,19 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. You should have received a copy of the GNU Affero General Public License along with PerconaFT. If not, see . + +---------------------------------------- + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and ======= */ #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." diff --git a/storage/tokudb/PerconaFT/locktree/locktree.cc b/storage/tokudb/PerconaFT/locktree/locktree.cc index 069aae26f66..8ba3f0f00ae 100644 --- a/storage/tokudb/PerconaFT/locktree/locktree.cc +++ b/storage/tokudb/PerconaFT/locktree/locktree.cc @@ -32,6 +32,19 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. You should have received a copy of the GNU Affero General Public License along with PerconaFT. If not, see . + +---------------------------------------- + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and ======= */ #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." diff --git a/storage/tokudb/PerconaFT/locktree/locktree.h b/storage/tokudb/PerconaFT/locktree/locktree.h index 1ba7a51b124..7006b6fb01d 100644 --- a/storage/tokudb/PerconaFT/locktree/locktree.h +++ b/storage/tokudb/PerconaFT/locktree/locktree.h @@ -32,6 +32,19 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. You should have received a copy of the GNU Affero General Public License along with PerconaFT. If not, see . + +---------------------------------------- + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and ======= */ #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." diff --git a/storage/tokudb/PerconaFT/locktree/manager.cc b/storage/tokudb/PerconaFT/locktree/manager.cc index 6bb5c77bf32..21f8dc6cf01 100644 --- a/storage/tokudb/PerconaFT/locktree/manager.cc +++ b/storage/tokudb/PerconaFT/locktree/manager.cc @@ -32,6 +32,19 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. You should have received a copy of the GNU Affero General Public License along with PerconaFT. If not, see . + +---------------------------------------- + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and ======= */ #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." diff --git a/storage/tokudb/PerconaFT/locktree/range_buffer.cc b/storage/tokudb/PerconaFT/locktree/range_buffer.cc index 3ddfd0faf97..d1f14fc4a52 100644 --- a/storage/tokudb/PerconaFT/locktree/range_buffer.cc +++ b/storage/tokudb/PerconaFT/locktree/range_buffer.cc @@ -32,6 +32,19 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. You should have received a copy of the GNU Affero General Public License along with PerconaFT. If not, see . + +---------------------------------------- + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and ======= */ #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." diff --git a/storage/tokudb/PerconaFT/locktree/range_buffer.h b/storage/tokudb/PerconaFT/locktree/range_buffer.h index b0e36968e73..811b0f85e69 100644 --- a/storage/tokudb/PerconaFT/locktree/range_buffer.h +++ b/storage/tokudb/PerconaFT/locktree/range_buffer.h @@ -32,6 +32,19 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. You should have received a copy of the GNU Affero General Public License along with PerconaFT. If not, see . + +---------------------------------------- + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and ======= */ #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." diff --git a/storage/tokudb/PerconaFT/locktree/treenode.cc b/storage/tokudb/PerconaFT/locktree/treenode.cc index cc3a4969643..0247242f975 100644 --- a/storage/tokudb/PerconaFT/locktree/treenode.cc +++ b/storage/tokudb/PerconaFT/locktree/treenode.cc @@ -32,6 +32,19 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. You should have received a copy of the GNU Affero General Public License along with PerconaFT. If not, see . + +---------------------------------------- + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and ======= */ #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." diff --git a/storage/tokudb/PerconaFT/locktree/treenode.h b/storage/tokudb/PerconaFT/locktree/treenode.h index 08aad2b6636..981e8b5a9cf 100644 --- a/storage/tokudb/PerconaFT/locktree/treenode.h +++ b/storage/tokudb/PerconaFT/locktree/treenode.h @@ -32,6 +32,19 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. You should have received a copy of the GNU Affero General Public License along with PerconaFT. If not, see . + +---------------------------------------- + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and ======= */ #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." diff --git a/storage/tokudb/PerconaFT/locktree/txnid_set.cc b/storage/tokudb/PerconaFT/locktree/txnid_set.cc index 82b59453156..bd4e9723155 100644 --- a/storage/tokudb/PerconaFT/locktree/txnid_set.cc +++ b/storage/tokudb/PerconaFT/locktree/txnid_set.cc @@ -32,6 +32,19 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. You should have received a copy of the GNU Affero General Public License along with PerconaFT. If not, see . + +---------------------------------------- + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and ======= */ #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." diff --git a/storage/tokudb/PerconaFT/locktree/txnid_set.h b/storage/tokudb/PerconaFT/locktree/txnid_set.h index 109d7f798e4..81fd45b6dde 100644 --- a/storage/tokudb/PerconaFT/locktree/txnid_set.h +++ b/storage/tokudb/PerconaFT/locktree/txnid_set.h @@ -32,6 +32,19 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. You should have received a copy of the GNU Affero General Public License along with PerconaFT. If not, see . + +---------------------------------------- + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and ======= */ #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." diff --git a/storage/tokudb/PerconaFT/locktree/wfg.cc b/storage/tokudb/PerconaFT/locktree/wfg.cc index 9a234f50060..26b7a3b5295 100644 --- a/storage/tokudb/PerconaFT/locktree/wfg.cc +++ b/storage/tokudb/PerconaFT/locktree/wfg.cc @@ -32,6 +32,19 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. You should have received a copy of the GNU Affero General Public License along with PerconaFT. If not, see . + +---------------------------------------- + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and ======= */ #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." diff --git a/storage/tokudb/PerconaFT/locktree/wfg.h b/storage/tokudb/PerconaFT/locktree/wfg.h index c56886e1362..5c1599592e6 100644 --- a/storage/tokudb/PerconaFT/locktree/wfg.h +++ b/storage/tokudb/PerconaFT/locktree/wfg.h @@ -32,6 +32,19 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. You should have received a copy of the GNU Affero General Public License along with PerconaFT. If not, see . + +---------------------------------------- + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and ======= */ #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." diff --git a/storage/tokudb/PerconaFT/portability/toku_instr_mysql.cc b/storage/tokudb/PerconaFT/portability/toku_instr_mysql.cc index 6f69c3c31b9..b5305ffaff4 100644 --- a/storage/tokudb/PerconaFT/portability/toku_instr_mysql.cc +++ b/storage/tokudb/PerconaFT/portability/toku_instr_mysql.cc @@ -184,9 +184,9 @@ void toku_instr_file_io_end(toku_io_instrumentation &io_instr, ssize_t count) { void toku_instr_mutex_init(const toku_instr_key &key, toku_mutex_t &mutex) { mutex.psi_mutex = PSI_MUTEX_CALL(init_mutex)(key.id(), &mutex.pmutex); -#if TOKU_PTHREAD_DEBUG +#if defined(TOKU_PTHREAD_DEBUG) mutex.instr_key_id = key.id(); -#endif +#endif // defined(TOKU_PTHREAD_DEBUG) } void toku_instr_mutex_destroy(PSI_mutex *&mutex_instr) { @@ -242,9 +242,9 @@ void toku_instr_mutex_unlock(PSI_mutex *mutex_instr) { void toku_instr_cond_init(const toku_instr_key &key, toku_cond_t &cond) { cond.psi_cond = PSI_COND_CALL(init_cond)(key.id(), &cond.pcond); -#if TOKU_PTHREAD_DEBUG +#if defined(TOKU_PTHREAD_DEBUG) cond.instr_key_id = key.id(); -#endif +#endif // // defined(TOKU_PTHREAD_DEBUG) } void toku_instr_cond_destroy(PSI_cond *&cond_instr) { @@ -295,9 +295,9 @@ void toku_instr_cond_broadcast(const toku_cond_t &cond) { void toku_instr_rwlock_init(const toku_instr_key &key, toku_pthread_rwlock_t &rwlock) { rwlock.psi_rwlock = PSI_RWLOCK_CALL(init_rwlock)(key.id(), &rwlock.rwlock); -#if TOKU_PTHREAD_DEBUG +#if defined(TOKU_PTHREAD_DEBUG) rwlock.instr_key_id = key.id(); -#endif +#endif // defined(TOKU_PTHREAD_DEBUG) } void toku_instr_rwlock_destroy(PSI_rwlock *&rwlock_instr) { diff --git a/storage/tokudb/PerconaFT/portability/toku_instr_mysql.h b/storage/tokudb/PerconaFT/portability/toku_instr_mysql.h index d6b0ed35ce9..695624acd6d 100644 --- a/storage/tokudb/PerconaFT/portability/toku_instr_mysql.h +++ b/storage/tokudb/PerconaFT/portability/toku_instr_mysql.h @@ -12,8 +12,15 @@ // undefine them here to avoid compilation errors. #undef __STDC_FORMAT_MACROS #undef __STDC_LIMIT_MACROS -#include // PSI_file -#include // PSI_mutex +#include "mysql/psi/mysql_file.h" // PSI_file +#include "mysql/psi/mysql_thread.h" // PSI_mutex +#include "mysql/psi/mysql_stage.h" // PSI_stage + +#if (MYSQL_VERSION_ID >= 80000) +#include "mysql/psi/mysql_cond.h" +#include "mysql/psi/mysql_mutex.h" +#include "mysql/psi/mysql_rwlock.h" +#endif // (MYSQL_VERSION_ID >= nn) #ifndef HAVE_PSI_MUTEX_INTERFACE #error HAVE_PSI_MUTEX_INTERFACE required diff --git a/storage/tokudb/PerconaFT/portability/toku_pthread.h b/storage/tokudb/PerconaFT/portability/toku_pthread.h index e3bd3bce598..da956097d05 100644 --- a/storage/tokudb/PerconaFT/portability/toku_pthread.h +++ b/storage/tokudb/PerconaFT/portability/toku_pthread.h @@ -64,23 +64,23 @@ struct toku_mutex_t { pthread_mutex_t pmutex; struct PSI_mutex *psi_mutex; /* The performance schema instrumentation hook */ -#if TOKU_PTHREAD_DEBUG +#if defined(TOKU_PTHREAD_DEBUG) pthread_t owner; // = pthread_self(); // for debugging bool locked; bool valid; pfs_key_t instr_key_id; -#endif +#endif // defined(TOKU_PTHREAD_DEBUG) }; struct toku_cond_t { pthread_cond_t pcond; struct PSI_cond *psi_cond; -#if TOKU_PTHREAD_DEBUG +#if defined(TOKU_PTHREAD_DEBUG) pfs_key_t instr_key_id; -#endif +#endif // defined(TOKU_PTHREAD_DEBUG) }; -#ifdef TOKU_PTHREAD_DEBUG +#if defined(TOKU_PTHREAD_DEBUG) #define TOKU_COND_INITIALIZER \ { \ .pcond = PTHREAD_COND_INITIALIZER, .psi_cond = nullptr, \ @@ -89,14 +89,14 @@ struct toku_cond_t { #else #define TOKU_COND_INITIALIZER \ { .pcond = PTHREAD_COND_INITIALIZER, .psi_cond = nullptr } -#endif +#endif // defined(TOKU_PTHREAD_DEBUG) struct toku_pthread_rwlock_t { pthread_rwlock_t rwlock; struct PSI_rwlock *psi_rwlock; -#if TOKU_PTHREAD_DEBUG +#if defined(TOKU_PTHREAD_DEBUG) pfs_key_t instr_key_id; -#endif +#endif // defined(TOKU_PTHREAD_DEBUG) }; typedef struct toku_mutex_aligned { @@ -117,7 +117,7 @@ typedef struct toku_mutex_aligned { #define ZERO_MUTEX_INITIALIZER \ {} -#if TOKU_PTHREAD_DEBUG +#if defined(TOKU_PTHREAD_DEBUG) #define TOKU_MUTEX_INITIALIZER \ { \ .pmutex = PTHREAD_MUTEX_INITIALIZER, .psi_mutex = nullptr, .owner = 0, \ @@ -126,12 +126,12 @@ typedef struct toku_mutex_aligned { #else #define TOKU_MUTEX_INITIALIZER \ { .pmutex = PTHREAD_MUTEX_INITIALIZER, .psi_mutex = nullptr } -#endif +#endif // defined(TOKU_PTHREAD_DEBUG) // Darwin doesn't provide adaptive mutexes #if defined(__APPLE__) #define TOKU_MUTEX_ADAPTIVE PTHREAD_MUTEX_DEFAULT -#if TOKU_PTHREAD_DEBUG +#if defined(TOKU_PTHREAD_DEBUG) #define TOKU_ADAPTIVE_MUTEX_INITIALIZER \ { \ .pmutex = PTHREAD_MUTEX_INITIALIZER, .psi_mutex = nullptr, .owner = 0, \ @@ -140,10 +140,10 @@ typedef struct toku_mutex_aligned { #else #define TOKU_ADAPTIVE_MUTEX_INITIALIZER \ { .pmutex = PTHREAD_MUTEX_INITIALIZER, .psi_mutex = nullptr } -#endif +#endif // defined(TOKU_PTHREAD_DEBUG) #else // __FreeBSD__, __linux__, at least #define TOKU_MUTEX_ADAPTIVE PTHREAD_MUTEX_ADAPTIVE_NP -#if TOKU_PTHREAD_DEBUG +#if defined(TOKU_PTHREAD_DEBUG) #define TOKU_ADAPTIVE_MUTEX_INITIALIZER \ { \ .pmutex = PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP, .psi_mutex = nullptr, \ @@ -152,8 +152,8 @@ typedef struct toku_mutex_aligned { #else #define TOKU_ADAPTIVE_MUTEX_INITIALIZER \ { .pmutex = PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP, .psi_mutex = nullptr } -#endif -#endif +#endif // defined(TOKU_PTHREAD_DEBUG) +#endif // defined(__APPLE__) // Different OSes implement mutexes as different amounts of nested structs. // C++ will fill out all missing values with zeroes if you provide at least one @@ -188,7 +188,7 @@ toku_mutexattr_destroy(toku_pthread_mutexattr_t *attr) { assert_zero(r); } -#if TOKU_PTHREAD_DEBUG +#if defined(TOKU_PTHREAD_DEBUG) static inline void toku_mutex_assert_locked(const toku_mutex_t *mutex) { invariant(mutex->locked); invariant(mutex->owner == pthread_self()); @@ -197,7 +197,7 @@ static inline void toku_mutex_assert_locked(const toku_mutex_t *mutex) { static inline void toku_mutex_assert_locked(const toku_mutex_t *mutex __attribute__((unused))) { } -#endif +#endif // defined(TOKU_PTHREAD_DEBUG) // asserting that a mutex is unlocked only makes sense // if the calling thread can guaruntee that no other threads @@ -207,7 +207,7 @@ toku_mutex_assert_locked(const toku_mutex_t *mutex __attribute__((unused))) { // when a node is locked the caller knows that no other threads // can be trying to lock its childrens' mutexes. the children // are in one of two fixed states: locked or unlocked. -#if TOKU_PTHREAD_DEBUG +#if defined(TOKU_PTHREAD_DEBUG) static inline void toku_mutex_assert_unlocked(toku_mutex_t *mutex) { invariant(mutex->owner == 0); @@ -216,7 +216,7 @@ toku_mutex_assert_unlocked(toku_mutex_t *mutex) { #else static inline void toku_mutex_assert_unlocked(toku_mutex_t *mutex __attribute__((unused))) {} -#endif +#endif // defined(TOKU_PTHREAD_DEBUG) #define toku_mutex_lock(M) \ toku_mutex_lock_with_source_location(M, __FILE__, __LINE__) @@ -231,13 +231,13 @@ static inline void toku_cond_init(toku_cond_t *cond, toku_mutex_trylock_with_source_location(M, __FILE__, __LINE__) inline void toku_mutex_unlock(toku_mutex_t *mutex) { -#if TOKU_PTHREAD_DEBUG +#if defined(TOKU_PTHREAD_DEBUG) invariant(mutex->owner == pthread_self()); invariant(mutex->valid); invariant(mutex->locked); mutex->locked = false; mutex->owner = 0; -#endif +#endif // defined(TOKU_PTHREAD_DEBUG) toku_instr_mutex_unlock(mutex->psi_mutex); int r = pthread_mutex_unlock(&mutex->pmutex); assert_zero(r); @@ -254,13 +254,13 @@ inline void toku_mutex_lock_with_source_location(toku_mutex_t *mutex, toku_instr_mutex_lock_end(mutex_instr, r); assert_zero(r); -#if TOKU_PTHREAD_DEBUG +#if defined(TOKU_PTHREAD_DEBUG) invariant(mutex->valid); invariant(!mutex->locked); invariant(mutex->owner == 0); mutex->locked = true; mutex->owner = pthread_self(); -#endif +#endif // defined(TOKU_PTHREAD_DEBUG) } inline int toku_mutex_trylock_with_source_location(toku_mutex_t *mutex, @@ -273,7 +273,7 @@ inline int toku_mutex_trylock_with_source_location(toku_mutex_t *mutex, const int r = pthread_mutex_lock(&mutex->pmutex); toku_instr_mutex_lock_end(mutex_instr, r); -#if TOKU_PTHREAD_DEBUG +#if defined(TOKU_PTHREAD_DEBUG) if (r == 0) { invariant(mutex->valid); invariant(!mutex->locked); @@ -281,7 +281,7 @@ inline int toku_mutex_trylock_with_source_location(toku_mutex_t *mutex, mutex->locked = true; mutex->owner = pthread_self(); } -#endif +#endif // defined(TOKU_PTHREAD_DEBUG) return r; } @@ -310,11 +310,11 @@ inline void toku_cond_wait_with_source_location(toku_cond_t *cond, const char *src_file, uint src_line) { -#if TOKU_PTHREAD_DEBUG +#if defined(TOKU_PTHREAD_DEBUG) invariant(mutex->locked); mutex->locked = false; mutex->owner = 0; -#endif +#endif // defined(TOKU_PTHREAD_DEBUG) /* Instrumentation start */ toku_cond_instrumentation cond_instr; @@ -332,11 +332,11 @@ inline void toku_cond_wait_with_source_location(toku_cond_t *cond, toku_instr_cond_wait_end(cond_instr, r); assert_zero(r); -#if TOKU_PTHREAD_DEBUG +#if defined(TOKU_PTHREAD_DEBUG) invariant(!mutex->locked); mutex->locked = true; mutex->owner = pthread_self(); -#endif +#endif // defined(TOKU_PTHREAD_DEBUG) } inline int toku_cond_timedwait_with_source_location(toku_cond_t *cond, @@ -344,11 +344,11 @@ inline int toku_cond_timedwait_with_source_location(toku_cond_t *cond, toku_timespec_t *wakeup_at, const char *src_file, uint src_line) { -#if TOKU_PTHREAD_DEBUG +#if defined(TOKU_PTHREAD_DEBUG) invariant(mutex->locked); mutex->locked = false; mutex->owner = 0; -#endif +#endif // defined(TOKU_PTHREAD_DEBUG) /* Instrumentation start */ toku_cond_instrumentation cond_instr; @@ -366,11 +366,11 @@ inline int toku_cond_timedwait_with_source_location(toku_cond_t *cond, /* Instrumentation end */ toku_instr_cond_wait_end(cond_instr, r); -#if TOKU_PTHREAD_DEBUG +#if defined(TOKU_PTHREAD_DEBUG) invariant(!mutex->locked); mutex->locked = true; mutex->owner = pthread_self(); -#endif +#endif // defined(TOKU_PTHREAD_DEBUG) return r; } @@ -389,26 +389,26 @@ inline void toku_cond_broadcast(toku_cond_t *cond) { inline void toku_mutex_init(const toku_instr_key &key, toku_mutex_t *mutex, const toku_pthread_mutexattr_t *attr) { -#if TOKU_PTHREAD_DEBUG +#if defined(TOKU_PTHREAD_DEBUG) mutex->valid = true; -#endif +#endif // defined(TOKU_PTHREAD_DEBUG) toku_instr_mutex_init(key, *mutex); const int r = pthread_mutex_init(&mutex->pmutex, attr); assert_zero(r); -#if TOKU_PTHREAD_DEBUG +#if defined(TOKU_PTHREAD_DEBUG) mutex->locked = false; invariant(mutex->valid); mutex->valid = true; mutex->owner = 0; -#endif +#endif // defined(TOKU_PTHREAD_DEBUG) } inline void toku_mutex_destroy(toku_mutex_t *mutex) { -#if TOKU_PTHREAD_DEBUG +#if defined(TOKU_PTHREAD_DEBUG) invariant(mutex->valid); mutex->valid = false; invariant(!mutex->locked); -#endif +#endif // defined(TOKU_PTHREAD_DEBUG) toku_instr_mutex_destroy(mutex->psi_mutex); int r = pthread_mutex_destroy(&mutex->pmutex); assert_zero(r); diff --git a/storage/tokudb/PerconaFT/tools/CMakeLists.txt b/storage/tokudb/PerconaFT/tools/CMakeLists.txt index d54c2c21827..710a55a5957 100644 --- a/storage/tokudb/PerconaFT/tools/CMakeLists.txt +++ b/storage/tokudb/PerconaFT/tools/CMakeLists.txt @@ -15,16 +15,12 @@ foreach(tool ${tools}) if ((CMAKE_BUILD_TYPE MATCHES "Debug") AND (CMAKE_CXX_FLAGS_DEBUG MATCHES " -DENABLED_DEBUG_SYNC")) if (MYSQL_BASE_VERSION VERSION_EQUAL "8.0") - target_link_libraries(${tool} sql_main sql_gis sql_main binlog rpl master slave ${ICU_LIBRARIES}) + target_link_libraries(${tool} sql_main sql_gis sql_main sql_dd sql_gis binlog rpl master slave ${ICU_LIBRARIES}) else () target_link_libraries(${tool} sql binlog rpl master slave) endif () else () - if (MYSQL_BASE_VERSION VERSION_EQUAL "8.0") - target_link_libraries(${tool} mysqlclient) - else () - target_link_libraries(${tool} perconaserverclient) - endif () + target_link_libraries(${tool} perconaserverclient) endif () endif () diff --git a/storage/tokudb/PerconaFT/util/growable_array.h b/storage/tokudb/PerconaFT/util/growable_array.h index e8873ae4abd..ad60ea6395b 100644 --- a/storage/tokudb/PerconaFT/util/growable_array.h +++ b/storage/tokudb/PerconaFT/util/growable_array.h @@ -32,6 +32,19 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. You should have received a copy of the GNU Affero General Public License along with PerconaFT. If not, see . + +---------------------------------------- + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and ======= */ #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." diff --git a/storage/tokudb/PerconaFT/util/omt.cc b/storage/tokudb/PerconaFT/util/omt.cc index 1fae0712c77..846c4df7f54 100644 --- a/storage/tokudb/PerconaFT/util/omt.cc +++ b/storage/tokudb/PerconaFT/util/omt.cc @@ -32,1105 +32,1356 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. You should have received a copy of the GNU Affero General Public License along with PerconaFT. If not, see . + +---------------------------------------- + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and ======= */ -#ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." +#ident \ + "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." -#include #include +#include #include namespace toku { -template -void omt::create(void) { - this->create_internal(2); - if (supports_marks) { - this->convert_to_tree(); - } -} - -template -void omt::create_no_array(void) { - if (!supports_marks) { - this->create_internal_no_array(0); - } else { - this->is_array = false; - this->capacity = 0; - this->d.t.nodes = nullptr; - this->d.t.root.set_to_null(); - this->d.t.free_idx = 0; - } -} - -template -void omt::create_from_sorted_array(const omtdata_t *const values, const uint32_t numvalues) { - this->create_internal(numvalues); - memcpy(this->d.a.values, values, numvalues * (sizeof values[0])); - this->d.a.num_values = numvalues; - if (supports_marks) { - this->convert_to_tree(); - } -} - -template -void omt::create_steal_sorted_array(omtdata_t **const values, const uint32_t numvalues, const uint32_t new_capacity) { - paranoid_invariant_notnull(values); - this->create_internal_no_array(new_capacity); - this->d.a.num_values = numvalues; - this->d.a.values = *values; - *values = nullptr; - if (supports_marks) { - this->convert_to_tree(); - } -} - -template -int omt::split_at(omt *const newomt, const uint32_t idx) { - barf_if_marked(*this); - paranoid_invariant_notnull(newomt); - if (idx > this->size()) { return EINVAL; } - this->convert_to_array(); - const uint32_t newsize = this->size() - idx; - newomt->create_from_sorted_array(&this->d.a.values[this->d.a.start_idx + idx], newsize); - this->d.a.num_values = idx; - this->maybe_resize_array(idx); - if (supports_marks) { - this->convert_to_tree(); - } - return 0; -} - -template -void omt::merge(omt *const leftomt, omt *const rightomt) { - barf_if_marked(*this); - paranoid_invariant_notnull(leftomt); - paranoid_invariant_notnull(rightomt); - const uint32_t leftsize = leftomt->size(); - const uint32_t rightsize = rightomt->size(); - const uint32_t newsize = leftsize + rightsize; - - if (leftomt->is_array) { - if (leftomt->capacity - (leftomt->d.a.start_idx + leftomt->d.a.num_values) >= rightsize) { - this->create_steal_sorted_array(&leftomt->d.a.values, leftomt->d.a.num_values, leftomt->capacity); - this->d.a.start_idx = leftomt->d.a.start_idx; - } else { - this->create_internal(newsize); - memcpy(&this->d.a.values[0], - &leftomt->d.a.values[leftomt->d.a.start_idx], - leftomt->d.a.num_values * (sizeof this->d.a.values[0])); - } - } else { - this->create_internal(newsize); - leftomt->fill_array_with_subtree_values(&this->d.a.values[0], leftomt->d.t.root); - } - leftomt->destroy(); - this->d.a.num_values = leftsize; - - if (rightomt->is_array) { - memcpy(&this->d.a.values[this->d.a.start_idx + this->d.a.num_values], - &rightomt->d.a.values[rightomt->d.a.start_idx], - rightomt->d.a.num_values * (sizeof this->d.a.values[0])); - } else { - rightomt->fill_array_with_subtree_values(&this->d.a.values[this->d.a.start_idx + this->d.a.num_values], - rightomt->d.t.root); - } - rightomt->destroy(); - this->d.a.num_values += rightsize; - paranoid_invariant(this->size() == newsize); - if (supports_marks) { - this->convert_to_tree(); - } -} - -template -void omt::clone(const omt &src) { - barf_if_marked(*this); - this->create_internal(src.size()); - if (src.is_array) { - memcpy(&this->d.a.values[0], &src.d.a.values[src.d.a.start_idx], src.d.a.num_values * (sizeof this->d.a.values[0])); - } else { - src.fill_array_with_subtree_values(&this->d.a.values[0], src.d.t.root); - } - this->d.a.num_values = src.size(); - if (supports_marks) { - this->convert_to_tree(); - } -} - -template -void omt::clear(void) { - if (this->is_array) { - this->d.a.start_idx = 0; - this->d.a.num_values = 0; - } else { - this->d.t.root.set_to_null(); - this->d.t.free_idx = 0; - } -} - -template -void omt::destroy(void) { - this->clear(); - this->capacity = 0; - if (this->is_array) { - if (this->d.a.values != nullptr) { - toku_free(this->d.a.values); - } - this->d.a.values = nullptr; - } else { - if (this->d.t.nodes != nullptr) { - toku_free(this->d.t.nodes); - } - this->d.t.nodes = nullptr; - } -} - -template -uint32_t omt::size(void) const { - if (this->is_array) { - return this->d.a.num_values; - } else { - return this->nweight(this->d.t.root); - } -} - - -template -template -int omt::insert(const omtdata_t &value, const omtcmp_t &v, uint32_t *const idx) { - int r; - uint32_t insert_idx; - - r = this->find_zero(v, nullptr, &insert_idx); - if (r==0) { - if (idx) *idx = insert_idx; - return DB_KEYEXIST; - } - if (r != DB_NOTFOUND) return r; - - if ((r = this->insert_at(value, insert_idx))) return r; - if (idx) *idx = insert_idx; - - return 0; -} - -// The following 3 functions implement a static if for us. -template -static void barf_if_marked(const omt &UU(omt)) { -} - -template -static void barf_if_marked(const omt &omt) { - invariant(!omt.has_marks()); -} - -template -bool omt::has_marks(void) const { - static_assert(supports_marks, "Does not support marks"); - if (this->d.t.root.is_null()) { - return false; - } - const omt_node &node = this->d.t.nodes[this->d.t.root.get_index()]; - return node.get_marks_below() || node.get_marked(); -} - -template -int omt::insert_at(const omtdata_t &value, const uint32_t idx) { - barf_if_marked(*this); - if (idx > this->size()) { return EINVAL; } - - this->maybe_resize_or_convert(this->size() + 1); - if (this->is_array && idx != this->d.a.num_values && - (idx != 0 || this->d.a.start_idx == 0)) { - this->convert_to_tree(); - } - if (this->is_array) { - if (idx == this->d.a.num_values) { - this->d.a.values[this->d.a.start_idx + this->d.a.num_values] = value; - } - else { - this->d.a.values[--this->d.a.start_idx] = value; - } - this->d.a.num_values++; - } - else { - subtree *rebalance_subtree = nullptr; - this->insert_internal(&this->d.t.root, value, idx, &rebalance_subtree); - if (rebalance_subtree != nullptr) { - this->rebalance(rebalance_subtree); - } - } - return 0; -} - -template -int omt::set_at(const omtdata_t &value, const uint32_t idx) { - barf_if_marked(*this); - if (idx >= this->size()) { return EINVAL; } - - if (this->is_array) { - this->set_at_internal_array(value, idx); - } else { - this->set_at_internal(this->d.t.root, value, idx); - } - return 0; -} - -template -int omt::delete_at(const uint32_t idx) { - barf_if_marked(*this); - if (idx >= this->size()) { return EINVAL; } - - this->maybe_resize_or_convert(this->size() - 1); - if (this->is_array && idx != 0 && idx != this->d.a.num_values - 1) { - this->convert_to_tree(); - } - if (this->is_array) { - //Testing for 0 does not rule out it being the last entry. - //Test explicitly for num_values-1 - if (idx != this->d.a.num_values - 1) { - this->d.a.start_idx++; - } - this->d.a.num_values--; - } else { - subtree *rebalance_subtree = nullptr; - this->delete_internal(&this->d.t.root, idx, nullptr, &rebalance_subtree); - if (rebalance_subtree != nullptr) { - this->rebalance(rebalance_subtree); - } - } - return 0; -} - -template -template -int omt::iterate(iterate_extra_t *const iterate_extra) const { - return this->iterate_on_range(0, this->size(), iterate_extra); -} - -template -template -int omt::iterate_on_range(const uint32_t left, const uint32_t right, iterate_extra_t *const iterate_extra) const { - if (right > this->size()) { return EINVAL; } - if (left == right) { return 0; } - if (this->is_array) { - return this->iterate_internal_array(left, right, iterate_extra); - } - return this->iterate_internal(left, right, this->d.t.root, 0, iterate_extra); -} - -template -template -int omt::iterate_and_mark_range(const uint32_t left, const uint32_t right, iterate_extra_t *const iterate_extra) { - static_assert(supports_marks, "does not support marks"); - if (right > this->size()) { return EINVAL; } - if (left == right) { return 0; } - paranoid_invariant(!this->is_array); - return this->iterate_and_mark_range_internal(left, right, this->d.t.root, 0, iterate_extra); -} - -//TODO: We can optimize this if we steal 3 bits. 1 bit: this node is marked. 1 bit: left subtree has marks. 1 bit: right subtree has marks. -template -template -int omt::iterate_over_marked(iterate_extra_t *const iterate_extra) const { - static_assert(supports_marks, "does not support marks"); - paranoid_invariant(!this->is_array); - return this->iterate_over_marked_internal(this->d.t.root, 0, iterate_extra); -} - -template -void omt::unmark(const subtree &subtree, const uint32_t index, GrowableArray *const indexes) { - if (subtree.is_null()) { return; } - omt_node &n = this->d.t.nodes[subtree.get_index()]; - const uint32_t index_root = index + this->nweight(n.left); - - const bool below = n.get_marks_below(); - if (below) { - this->unmark(n.left, index, indexes); - } - if (n.get_marked()) { - indexes->push(index_root); - } - n.clear_stolen_bits(); - if (below) { - this->unmark(n.right, index_root + 1, indexes); - } -} - -template -void omt::delete_all_marked(void) { - static_assert(supports_marks, "does not support marks"); - if (!this->has_marks()) { - return; - } - paranoid_invariant(!this->is_array); - GrowableArray marked_indexes; - marked_indexes.init(); - - // Remove all marks. - // We need to delete all the stolen bits before calling delete_at to prevent barfing. - this->unmark(this->d.t.root, 0, &marked_indexes); - - for (uint32_t i = 0; i < marked_indexes.get_size(); i++) { - // Delete from left to right, shift by number already deleted. - // Alternative is delete from right to left. - int r = this->delete_at(marked_indexes.fetch_unchecked(i) - i); - lazy_assert_zero(r); - } - marked_indexes.deinit(); - barf_if_marked(*this); -} - -template -uint32_t omt::verify_marks_consistent_internal(const subtree &subtree, const bool UU(allow_marks)) const { - if (subtree.is_null()) { - return 0; - } - const omt_node &node = this->d.t.nodes[subtree.get_index()]; - uint32_t num_marks = verify_marks_consistent_internal(node.left, node.get_marks_below()); - num_marks += verify_marks_consistent_internal(node.right, node.get_marks_below()); - if (node.get_marks_below()) { - paranoid_invariant(allow_marks); - paranoid_invariant(num_marks > 0); - } else { - // redundant with invariant below, but nice to have explicitly - paranoid_invariant(num_marks == 0); - } - if (node.get_marked()) { - paranoid_invariant(allow_marks); - ++num_marks; - } - return num_marks; -} - -template -void omt::verify_marks_consistent(void) const { - static_assert(supports_marks, "does not support marks"); - paranoid_invariant(!this->is_array); - this->verify_marks_consistent_internal(this->d.t.root, true); -} - -template -template -void omt::iterate_ptr(iterate_extra_t *const iterate_extra) { - if (this->is_array) { - this->iterate_ptr_internal_array(0, this->size(), iterate_extra); - } else { - this->iterate_ptr_internal(0, this->size(), this->d.t.root, 0, iterate_extra); - } -} - -template -int omt::fetch(const uint32_t idx, omtdataout_t *const value) const { - if (idx >= this->size()) { return EINVAL; } - if (this->is_array) { - this->fetch_internal_array(idx, value); - } else { - this->fetch_internal(this->d.t.root, idx, value); - } - return 0; -} - -template -template -int omt::find_zero(const omtcmp_t &extra, omtdataout_t *const value, uint32_t *const idxp) const { - uint32_t tmp_index; - uint32_t *const child_idxp = (idxp != nullptr) ? idxp : &tmp_index; - int r; - if (this->is_array) { - r = this->find_internal_zero_array(extra, value, child_idxp); - } - else { - r = this->find_internal_zero(this->d.t.root, extra, value, child_idxp); - } - return r; -} - -template -template -int omt::find(const omtcmp_t &extra, int direction, omtdataout_t *const value, uint32_t *const idxp) const { - uint32_t tmp_index; - uint32_t *const child_idxp = (idxp != nullptr) ? idxp : &tmp_index; - paranoid_invariant(direction != 0); - if (direction < 0) { - if (this->is_array) { - return this->find_internal_minus_array(extra, value, child_idxp); - } else { - return this->find_internal_minus(this->d.t.root, extra, value, child_idxp); - } - } else { - if (this->is_array) { - return this->find_internal_plus_array(extra, value, child_idxp); - } else { - return this->find_internal_plus(this->d.t.root, extra, value, child_idxp); - } - } -} - -template -size_t omt::memory_size(void) { - if (this->is_array) { - return (sizeof *this) + this->capacity * (sizeof this->d.a.values[0]); - } - return (sizeof *this) + this->capacity * (sizeof this->d.t.nodes[0]); -} - - -template -void omt::create_internal_no_array(const uint32_t new_capacity) { - this->is_array = true; - this->d.a.start_idx = 0; - this->d.a.num_values = 0; - this->d.a.values = nullptr; - this->capacity = new_capacity; -} - -template -void omt::create_internal(const uint32_t new_capacity) { - this->create_internal_no_array(new_capacity); - XMALLOC_N(this->capacity, this->d.a.values); -} - -template -uint32_t omt::nweight(const subtree &subtree) const { - if (subtree.is_null()) { - return 0; - } else { - return this->d.t.nodes[subtree.get_index()].weight; - } -} - -template -typename omt::node_idx omt::node_malloc(void) { - paranoid_invariant(this->d.t.free_idx < this->capacity); - omt_node &n = this->d.t.nodes[this->d.t.free_idx]; - n.clear_stolen_bits(); - return this->d.t.free_idx++; -} - -template -void omt::node_free(const node_idx UU(idx)) { - paranoid_invariant(idx < this->capacity); -} - -template -void omt::maybe_resize_array(const uint32_t n) { - const uint32_t new_size = n<=2 ? 4 : 2*n; - const uint32_t room = this->capacity - this->d.a.start_idx; - - if (room < n || this->capacity / 2 >= new_size) { - omtdata_t *XMALLOC_N(new_size, tmp_values); - memcpy(tmp_values, &this->d.a.values[this->d.a.start_idx], - this->d.a.num_values * (sizeof tmp_values[0])); - this->d.a.start_idx = 0; - this->capacity = new_size; - toku_free(this->d.a.values); - this->d.a.values = tmp_values; - } -} - -template -void omt::fill_array_with_subtree_values(omtdata_t *const array, const subtree &subtree) const { - if (subtree.is_null()) return; - const omt_node &tree = this->d.t.nodes[subtree.get_index()]; - this->fill_array_with_subtree_values(&array[0], tree.left); - array[this->nweight(tree.left)] = tree.value; - this->fill_array_with_subtree_values(&array[this->nweight(tree.left) + 1], tree.right); -} - -template -void omt::convert_to_array(void) { - if (!this->is_array) { - const uint32_t num_values = this->size(); - uint32_t new_size = 2*num_values; - new_size = new_size < 4 ? 4 : new_size; - - omtdata_t *XMALLOC_N(new_size, tmp_values); - this->fill_array_with_subtree_values(tmp_values, this->d.t.root); - toku_free(this->d.t.nodes); - this->is_array = true; - this->capacity = new_size; - this->d.a.num_values = num_values; - this->d.a.values = tmp_values; - this->d.a.start_idx = 0; - } -} - -template -void omt::rebuild_from_sorted_array(subtree *const subtree, const omtdata_t *const values, const uint32_t numvalues) { - if (numvalues==0) { - subtree->set_to_null(); - } else { - const uint32_t halfway = numvalues/2; - const node_idx newidx = this->node_malloc(); - omt_node *const newnode = &this->d.t.nodes[newidx]; - newnode->weight = numvalues; - newnode->value = values[halfway]; - subtree->set_index(newidx); - // update everything before the recursive calls so the second call can be a tail call. - this->rebuild_from_sorted_array(&newnode->left, &values[0], halfway); - this->rebuild_from_sorted_array(&newnode->right, &values[halfway+1], numvalues - (halfway+1)); - } -} - -template -void omt::convert_to_tree(void) { - if (this->is_array) { - const uint32_t num_nodes = this->size(); - uint32_t new_size = num_nodes*2; - new_size = new_size < 4 ? 4 : new_size; - - omt_node *XMALLOC_N(new_size, new_nodes); - omtdata_t *const values = this->d.a.values; - omtdata_t *const tmp_values = &values[this->d.a.start_idx]; - this->is_array = false; - this->d.t.nodes = new_nodes; - this->capacity = new_size; - this->d.t.free_idx = 0; - this->d.t.root.set_to_null(); - this->rebuild_from_sorted_array(&this->d.t.root, tmp_values, num_nodes); - toku_free(values); - } -} - -template -void omt::maybe_resize_or_convert(const uint32_t n) { - if (this->is_array) { - this->maybe_resize_array(n); - } else { - const uint32_t new_size = n<=2 ? 4 : 2*n; - const uint32_t num_nodes = this->nweight(this->d.t.root); - if ((this->capacity/2 >= new_size) || - (this->d.t.free_idx >= this->capacity && num_nodes < n) || - (this->capacityconvert_to_array(); - // if we had a free list, the "supports_marks" version could - // just resize, as it is now, we have to convert to and back - // from an array. - if (supports_marks) { - this->convert_to_tree(); - } - } - } -} - -template -bool omt::will_need_rebalance(const subtree &subtree, const int leftmod, const int rightmod) const { - if (subtree.is_null()) { return false; } - const omt_node &n = this->d.t.nodes[subtree.get_index()]; - // one of the 1's is for the root. - // the other is to take ceil(n/2) - const uint32_t weight_left = this->nweight(n.left) + leftmod; - const uint32_t weight_right = this->nweight(n.right) + rightmod; - return ((1+weight_left < (1+1+weight_right)/2) - || - (1+weight_right < (1+1+weight_left)/2)); -} - -template -void omt::insert_internal(subtree *const subtreep, const omtdata_t &value, const uint32_t idx, subtree **const rebalance_subtree) { - if (subtreep->is_null()) { - paranoid_invariant_zero(idx); - const node_idx newidx = this->node_malloc(); - omt_node *const newnode = &this->d.t.nodes[newidx]; - newnode->weight = 1; - newnode->left.set_to_null(); - newnode->right.set_to_null(); - newnode->value = value; - subtreep->set_index(newidx); - } else { - omt_node &n = this->d.t.nodes[subtreep->get_index()]; - n.weight++; - if (idx <= this->nweight(n.left)) { - if (*rebalance_subtree == nullptr && this->will_need_rebalance(*subtreep, 1, 0)) { - *rebalance_subtree = subtreep; - } - this->insert_internal(&n.left, value, idx, rebalance_subtree); - } else { - if (*rebalance_subtree == nullptr && this->will_need_rebalance(*subtreep, 0, 1)) { - *rebalance_subtree = subtreep; - } - const uint32_t sub_index = idx - this->nweight(n.left) - 1; - this->insert_internal(&n.right, value, sub_index, rebalance_subtree); - } - } -} - -template -void omt::set_at_internal_array(const omtdata_t &value, const uint32_t idx) { - this->d.a.values[this->d.a.start_idx + idx] = value; -} - -template -void omt::set_at_internal(const subtree &subtree, const omtdata_t &value, const uint32_t idx) { - paranoid_invariant(!subtree.is_null()); - omt_node &n = this->d.t.nodes[subtree.get_index()]; - const uint32_t leftweight = this->nweight(n.left); - if (idx < leftweight) { - this->set_at_internal(n.left, value, idx); - } else if (idx == leftweight) { - n.value = value; - } else { - this->set_at_internal(n.right, value, idx - leftweight - 1); - } -} - -template -void omt::delete_internal(subtree *const subtreep, const uint32_t idx, omt_node *const copyn, subtree **const rebalance_subtree) { - paranoid_invariant_notnull(subtreep); - paranoid_invariant_notnull(rebalance_subtree); - paranoid_invariant(!subtreep->is_null()); - omt_node &n = this->d.t.nodes[subtreep->get_index()]; - const uint32_t leftweight = this->nweight(n.left); - if (idx < leftweight) { - n.weight--; - if (*rebalance_subtree == nullptr && this->will_need_rebalance(*subtreep, -1, 0)) { - *rebalance_subtree = subtreep; - } - this->delete_internal(&n.left, idx, copyn, rebalance_subtree); - } else if (idx == leftweight) { - if (n.left.is_null()) { - const uint32_t oldidx = subtreep->get_index(); - *subtreep = n.right; - if (copyn != nullptr) { - copyn->value = n.value; - } - this->node_free(oldidx); - } else if (n.right.is_null()) { - const uint32_t oldidx = subtreep->get_index(); - *subtreep = n.left; - if (copyn != nullptr) { - copyn->value = n.value; - } - this->node_free(oldidx); - } else { - if (*rebalance_subtree == nullptr && this->will_need_rebalance(*subtreep, 0, -1)) { - *rebalance_subtree = subtreep; - } - // don't need to copy up value, it's only used by this - // next call, and when that gets to the bottom there - // won't be any more recursion - n.weight--; - this->delete_internal(&n.right, 0, &n, rebalance_subtree); - } - } else { - n.weight--; - if (*rebalance_subtree == nullptr && this->will_need_rebalance(*subtreep, 0, -1)) { - *rebalance_subtree = subtreep; - } - this->delete_internal(&n.right, idx - leftweight - 1, copyn, rebalance_subtree); - } -} - -template -template -int omt::iterate_internal_array(const uint32_t left, const uint32_t right, - iterate_extra_t *const iterate_extra) const { - int r; - for (uint32_t i = left; i < right; ++i) { - r = f(this->d.a.values[this->d.a.start_idx + i], i, iterate_extra); - if (r != 0) { - return r; - } - } - return 0; -} - -template -template -void omt::iterate_ptr_internal(const uint32_t left, const uint32_t right, - const subtree &subtree, const uint32_t idx, - iterate_extra_t *const iterate_extra) { - if (!subtree.is_null()) { - omt_node &n = this->d.t.nodes[subtree.get_index()]; - const uint32_t idx_root = idx + this->nweight(n.left); - if (left < idx_root) { - this->iterate_ptr_internal(left, right, n.left, idx, iterate_extra); - } - if (left <= idx_root && idx_root < right) { - int r = f(&n.value, idx_root, iterate_extra); - lazy_assert_zero(r); - } - if (idx_root + 1 < right) { - this->iterate_ptr_internal(left, right, n.right, idx_root + 1, iterate_extra); - } - } -} - -template -template -void omt::iterate_ptr_internal_array(const uint32_t left, const uint32_t right, - iterate_extra_t *const iterate_extra) { - for (uint32_t i = left; i < right; ++i) { - int r = f(&this->d.a.values[this->d.a.start_idx + i], i, iterate_extra); - lazy_assert_zero(r); - } -} - -template -template -int omt::iterate_internal(const uint32_t left, const uint32_t right, - const subtree &subtree, const uint32_t idx, - iterate_extra_t *const iterate_extra) const { - if (subtree.is_null()) { return 0; } - int r; - const omt_node &n = this->d.t.nodes[subtree.get_index()]; - const uint32_t idx_root = idx + this->nweight(n.left); - if (left < idx_root) { - r = this->iterate_internal(left, right, n.left, idx, iterate_extra); - if (r != 0) { return r; } - } - if (left <= idx_root && idx_root < right) { - r = f(n.value, idx_root, iterate_extra); - if (r != 0) { return r; } - } - if (idx_root + 1 < right) { - return this->iterate_internal(left, right, n.right, idx_root + 1, iterate_extra); - } - return 0; -} - -template -template -int omt::iterate_and_mark_range_internal(const uint32_t left, const uint32_t right, - const subtree &subtree, const uint32_t idx, - iterate_extra_t *const iterate_extra) { - paranoid_invariant(!subtree.is_null()); - int r; - omt_node &n = this->d.t.nodes[subtree.get_index()]; - const uint32_t idx_root = idx + this->nweight(n.left); - if (left < idx_root && !n.left.is_null()) { - n.set_marks_below_bit(); - r = this->iterate_and_mark_range_internal(left, right, n.left, idx, iterate_extra); - if (r != 0) { return r; } - } - if (left <= idx_root && idx_root < right) { - n.set_marked_bit(); - r = f(n.value, idx_root, iterate_extra); - if (r != 0) { return r; } - } - if (idx_root + 1 < right && !n.right.is_null()) { - n.set_marks_below_bit(); - return this->iterate_and_mark_range_internal(left, right, n.right, idx_root + 1, iterate_extra); - } - return 0; -} - -template -template -int omt::iterate_over_marked_internal(const subtree &subtree, const uint32_t idx, - iterate_extra_t *const iterate_extra) const { - if (subtree.is_null()) { return 0; } - int r; - const omt_node &n = this->d.t.nodes[subtree.get_index()]; - const uint32_t idx_root = idx + this->nweight(n.left); - if (n.get_marks_below()) { - r = this->iterate_over_marked_internal(n.left, idx, iterate_extra); - if (r != 0) { return r; } - } - if (n.get_marked()) { - r = f(n.value, idx_root, iterate_extra); - if (r != 0) { return r; } - } - if (n.get_marks_below()) { - return this->iterate_over_marked_internal(n.right, idx_root + 1, iterate_extra); - } - return 0; -} - -template -void omt::fetch_internal_array(const uint32_t i, omtdataout_t *const value) const { - if (value != nullptr) { - copyout(value, &this->d.a.values[this->d.a.start_idx + i]); - } -} - -template -void omt::fetch_internal(const subtree &subtree, const uint32_t i, omtdataout_t *const value) const { - omt_node &n = this->d.t.nodes[subtree.get_index()]; - const uint32_t leftweight = this->nweight(n.left); - if (i < leftweight) { - this->fetch_internal(n.left, i, value); - } else if (i == leftweight) { - if (value != nullptr) { - copyout(value, &n); - } - } else { - this->fetch_internal(n.right, i - leftweight - 1, value); - } -} - -template -void omt::fill_array_with_subtree_idxs(node_idx *const array, const subtree &subtree) const { - if (!subtree.is_null()) { - const omt_node &tree = this->d.t.nodes[subtree.get_index()]; - this->fill_array_with_subtree_idxs(&array[0], tree.left); - array[this->nweight(tree.left)] = subtree.get_index(); - this->fill_array_with_subtree_idxs(&array[this->nweight(tree.left) + 1], tree.right); - } -} - -template -void omt::rebuild_subtree_from_idxs(subtree *const subtree, const node_idx *const idxs, const uint32_t numvalues) { - if (numvalues==0) { - subtree->set_to_null(); - } else { - uint32_t halfway = numvalues/2; - subtree->set_index(idxs[halfway]); - //node_idx newidx = idxs[halfway]; - omt_node &newnode = this->d.t.nodes[subtree->get_index()]; - newnode.weight = numvalues; - // value is already in there. - this->rebuild_subtree_from_idxs(&newnode.left, &idxs[0], halfway); - this->rebuild_subtree_from_idxs(&newnode.right, &idxs[halfway+1], numvalues-(halfway+1)); - //n_idx = newidx; - } -} - -template -void omt::rebalance(subtree *const subtree) { - node_idx idx = subtree->get_index(); - if (idx==this->d.t.root.get_index()) { - //Try to convert to an array. - //If this fails, (malloc) nothing will have changed. - //In the failure case we continue on to the standard rebalance - //algorithm. - this->convert_to_array(); + template + void omt::create(void) { + this->create_internal(2); if (supports_marks) { this->convert_to_tree(); } - } else { - const omt_node &n = this->d.t.nodes[idx]; - node_idx *tmp_array; - size_t mem_needed = n.weight * (sizeof tmp_array[0]); - size_t mem_free = (this->capacity - this->d.t.free_idx) * (sizeof this->d.t.nodes[0]); - bool malloced; - if (mem_needed<=mem_free) { - //There is sufficient free space at the end of the nodes array - //to hold enough node indexes to rebalance. - malloced = false; - tmp_array = reinterpret_cast(&this->d.t.nodes[this->d.t.free_idx]); - } - else { - malloced = true; - XMALLOC_N(n.weight, tmp_array); - } - this->fill_array_with_subtree_idxs(tmp_array, *subtree); - this->rebuild_subtree_from_idxs(subtree, tmp_array, n.weight); - if (malloced) toku_free(tmp_array); } -} -template -void omt::copyout(omtdata_t *const out, const omt_node *const n) { - *out = n->value; -} - -template -void omt::copyout(omtdata_t **const out, omt_node *const n) { - *out = &n->value; -} - -template -void omt::copyout(omtdata_t *const out, const omtdata_t *const stored_value_ptr) { - *out = *stored_value_ptr; -} - -template -void omt::copyout(omtdata_t **const out, omtdata_t *const stored_value_ptr) { - *out = stored_value_ptr; -} - -template -template -int omt::find_internal_zero_array(const omtcmp_t &extra, omtdataout_t *const value, uint32_t *const idxp) const { - paranoid_invariant_notnull(idxp); - uint32_t min = this->d.a.start_idx; - uint32_t limit = this->d.a.start_idx + this->d.a.num_values; - uint32_t best_pos = subtree::NODE_NULL; - uint32_t best_zero = subtree::NODE_NULL; - - while (min!=limit) { - uint32_t mid = (min + limit) / 2; - int hv = h(this->d.a.values[mid], extra); - if (hv<0) { - min = mid+1; - } - else if (hv>0) { - best_pos = mid; - limit = mid; - } - else { - best_zero = mid; - limit = mid; + template + void omt::create_no_array(void) { + if (!supports_marks) { + this->create_internal_no_array(0); + } else { + this->is_array = false; + this->capacity = 0; + this->d.t.nodes = nullptr; + this->d.t.root.set_to_null(); + this->d.t.free_idx = 0; } } - if (best_zero!=subtree::NODE_NULL) { - //Found a zero - if (value != nullptr) { - copyout(value, &this->d.a.values[best_zero]); + + template + void omt::create_from_sorted_array( + const omtdata_t *const values, + const uint32_t numvalues) { + this->create_internal(numvalues); + memcpy(this->d.a.values, values, numvalues * (sizeof values[0])); + this->d.a.num_values = numvalues; + if (supports_marks) { + this->convert_to_tree(); + } + } + + template + void + omt::create_steal_sorted_array( + omtdata_t **const values, + const uint32_t numvalues, + const uint32_t new_capacity) { + paranoid_invariant_notnull(values); + this->create_internal_no_array(new_capacity); + this->d.a.num_values = numvalues; + this->d.a.values = *values; + *values = nullptr; + if (supports_marks) { + this->convert_to_tree(); + } + } + + template + int omt::split_at( + omt *const newomt, + const uint32_t idx) { + barf_if_marked(*this); + paranoid_invariant_notnull(newomt); + if (idx > this->size()) { + return EINVAL; + } + this->convert_to_array(); + const uint32_t newsize = this->size() - idx; + newomt->create_from_sorted_array( + &this->d.a.values[this->d.a.start_idx + idx], newsize); + this->d.a.num_values = idx; + this->maybe_resize_array(idx); + if (supports_marks) { + this->convert_to_tree(); } - *idxp = best_zero - this->d.a.start_idx; return 0; } - if (best_pos!=subtree::NODE_NULL) *idxp = best_pos - this->d.a.start_idx; - else *idxp = this->d.a.num_values; - return DB_NOTFOUND; -} -template -template -int omt::find_internal_zero(const subtree &subtree, const omtcmp_t &extra, omtdataout_t *const value, uint32_t *const idxp) const { - paranoid_invariant_notnull(idxp); - if (subtree.is_null()) { - *idxp = 0; - return DB_NOTFOUND; + template + void omt::merge( + omt *const leftomt, + omt *const rightomt) { + barf_if_marked(*this); + paranoid_invariant_notnull(leftomt); + paranoid_invariant_notnull(rightomt); + const uint32_t leftsize = leftomt->size(); + const uint32_t rightsize = rightomt->size(); + const uint32_t newsize = leftsize + rightsize; + + if (leftomt->is_array) { + if (leftomt->capacity - + (leftomt->d.a.start_idx + leftomt->d.a.num_values) >= + rightsize) { + this->create_steal_sorted_array(&leftomt->d.a.values, + leftomt->d.a.num_values, + leftomt->capacity); + this->d.a.start_idx = leftomt->d.a.start_idx; + } else { + this->create_internal(newsize); + memcpy(&this->d.a.values[0], + &leftomt->d.a.values[leftomt->d.a.start_idx], + leftomt->d.a.num_values * (sizeof this->d.a.values[0])); + } + } else { + this->create_internal(newsize); + leftomt->fill_array_with_subtree_values(&this->d.a.values[0], + leftomt->d.t.root); + } + leftomt->destroy(); + this->d.a.num_values = leftsize; + + if (rightomt->is_array) { + memcpy( + &this->d.a.values[this->d.a.start_idx + this->d.a.num_values], + &rightomt->d.a.values[rightomt->d.a.start_idx], + rightomt->d.a.num_values * (sizeof this->d.a.values[0])); + } else { + rightomt->fill_array_with_subtree_values( + &this->d.a.values[this->d.a.start_idx + this->d.a.num_values], + rightomt->d.t.root); + } + rightomt->destroy(); + this->d.a.num_values += rightsize; + paranoid_invariant(this->size() == newsize); + if (supports_marks) { + this->convert_to_tree(); + } } - omt_node &n = this->d.t.nodes[subtree.get_index()]; - int hv = h(n.value, extra); - if (hv<0) { - int r = this->find_internal_zero(n.right, extra, value, idxp); - *idxp += this->nweight(n.left)+1; + + template + void omt::clone(const omt &src) { + barf_if_marked(*this); + this->create_internal(src.size()); + if (src.is_array) { + memcpy(&this->d.a.values[0], + &src.d.a.values[src.d.a.start_idx], + src.d.a.num_values * (sizeof this->d.a.values[0])); + } else { + src.fill_array_with_subtree_values(&this->d.a.values[0], + src.d.t.root); + } + this->d.a.num_values = src.size(); + if (supports_marks) { + this->convert_to_tree(); + } + } + + template + void omt::clear(void) { + if (this->is_array) { + this->d.a.start_idx = 0; + this->d.a.num_values = 0; + } else { + this->d.t.root.set_to_null(); + this->d.t.free_idx = 0; + } + } + + template + void omt::destroy(void) { + this->clear(); + this->capacity = 0; + if (this->is_array) { + if (this->d.a.values != nullptr) { + toku_free(this->d.a.values); + } + this->d.a.values = nullptr; + } else { + if (this->d.t.nodes != nullptr) { + toku_free(this->d.t.nodes); + } + this->d.t.nodes = nullptr; + } + } + + template + uint32_t omt::size(void) const { + if (this->is_array) { + return this->d.a.num_values; + } else { + return this->nweight(this->d.t.root); + } + } + + template + template + int omt::insert( + const omtdata_t &value, + const omtcmp_t &v, + uint32_t *const idx) { + int r; + uint32_t insert_idx; + + r = this->find_zero(v, nullptr, &insert_idx); + if (r == 0) { + if (idx) + *idx = insert_idx; + return DB_KEYEXIST; + } + if (r != DB_NOTFOUND) + return r; + + if ((r = this->insert_at(value, insert_idx))) + return r; + if (idx) + *idx = insert_idx; + + return 0; + } + + // The following 3 functions implement a static if for us. + template + static void barf_if_marked( + const omt &UU(omt)) {} + + template + static void barf_if_marked(const omt &omt) { + invariant(!omt.has_marks()); + } + + template + bool omt::has_marks(void) const { + static_assert(supports_marks, "Does not support marks"); + if (this->d.t.root.is_null()) { + return false; + } + const omt_node &node = this->d.t.nodes[this->d.t.root.get_index()]; + return node.get_marks_below() || node.get_marked(); + } + + template + int omt::insert_at( + const omtdata_t &value, + const uint32_t idx) { + barf_if_marked(*this); + if (idx > this->size()) { + return EINVAL; + } + + this->maybe_resize_or_convert(this->size() + 1); + if (this->is_array && idx != this->d.a.num_values && + (idx != 0 || this->d.a.start_idx == 0)) { + this->convert_to_tree(); + } + if (this->is_array) { + if (idx == this->d.a.num_values) { + this->d.a.values[this->d.a.start_idx + this->d.a.num_values] = + value; + } else { + this->d.a.values[--this->d.a.start_idx] = value; + } + this->d.a.num_values++; + } else { + subtree *rebalance_subtree = nullptr; + this->insert_internal( + &this->d.t.root, value, idx, &rebalance_subtree); + if (rebalance_subtree != nullptr) { + this->rebalance(rebalance_subtree); + } + } + return 0; + } + + template + int omt::set_at( + const omtdata_t &value, + const uint32_t idx) { + barf_if_marked(*this); + if (idx >= this->size()) { + return EINVAL; + } + + if (this->is_array) { + this->set_at_internal_array(value, idx); + } else { + this->set_at_internal(this->d.t.root, value, idx); + } + return 0; + } + + template + int omt::delete_at( + const uint32_t idx) { + barf_if_marked(*this); + if (idx >= this->size()) { + return EINVAL; + } + + this->maybe_resize_or_convert(this->size() - 1); + if (this->is_array && idx != 0 && idx != this->d.a.num_values - 1) { + this->convert_to_tree(); + } + if (this->is_array) { + // Testing for 0 does not rule out it being the last entry. + // Test explicitly for num_values-1 + if (idx != this->d.a.num_values - 1) { + this->d.a.start_idx++; + } + this->d.a.num_values--; + } else { + subtree *rebalance_subtree = nullptr; + this->delete_internal( + &this->d.t.root, idx, nullptr, &rebalance_subtree); + if (rebalance_subtree != nullptr) { + this->rebalance(rebalance_subtree); + } + } + return 0; + } + + template + template < + typename iterate_extra_t, + int (*f)(const omtdata_t &, const uint32_t, iterate_extra_t *const)> + int omt::iterate( + iterate_extra_t *const iterate_extra) const { + return this->iterate_on_range( + 0, this->size(), iterate_extra); + } + + template + template < + typename iterate_extra_t, + int (*f)(const omtdata_t &, const uint32_t, iterate_extra_t *const)> + int omt::iterate_on_range( + const uint32_t left, + const uint32_t right, + iterate_extra_t *const iterate_extra) const { + if (right > this->size()) { + return EINVAL; + } + if (left == right) { + return 0; + } + if (this->is_array) { + return this->iterate_internal_array( + left, right, iterate_extra); + } + return this->iterate_internal( + left, right, this->d.t.root, 0, iterate_extra); + } + + template + template < + typename iterate_extra_t, + int (*f)(const omtdata_t &, const uint32_t, iterate_extra_t *const)> + int omt::iterate_and_mark_range( + const uint32_t left, + const uint32_t right, + iterate_extra_t *const iterate_extra) { + static_assert(supports_marks, "does not support marks"); + if (right > this->size()) { + return EINVAL; + } + if (left == right) { + return 0; + } + paranoid_invariant(!this->is_array); + return this->iterate_and_mark_range_internal( + left, right, this->d.t.root, 0, iterate_extra); + } + + // TODO: We can optimize this if we steal 3 bits. 1 bit: this node is + // marked. 1 bit: left subtree has marks. 1 bit: right subtree has marks. + template + template < + typename iterate_extra_t, + int (*f)(const omtdata_t &, const uint32_t, iterate_extra_t *const)> + int omt::iterate_over_marked( + iterate_extra_t *const iterate_extra) const { + static_assert(supports_marks, "does not support marks"); + paranoid_invariant(!this->is_array); + return this->iterate_over_marked_internal( + this->d.t.root, 0, iterate_extra); + } + + template + void omt::unmark( + const subtree &st, + const uint32_t index, + GrowableArray *const indexes) { + if (st.is_null()) { + return; + } + omt_node &n = this->d.t.nodes[st.get_index()]; + const uint32_t index_root = index + this->nweight(n.left); + + const bool below = n.get_marks_below(); + if (below) { + this->unmark(n.left, index, indexes); + } + if (n.get_marked()) { + indexes->push(index_root); + } + n.clear_stolen_bits(); + if (below) { + this->unmark(n.right, index_root + 1, indexes); + } + } + + template + void omt::delete_all_marked(void) { + static_assert(supports_marks, "does not support marks"); + if (!this->has_marks()) { + return; + } + paranoid_invariant(!this->is_array); + GrowableArray marked_indexes; + marked_indexes.init(); + + // Remove all marks. + // We need to delete all the stolen bits before calling delete_at to + // prevent barfing. + this->unmark(this->d.t.root, 0, &marked_indexes); + + for (uint32_t i = 0; i < marked_indexes.get_size(); i++) { + // Delete from left to right, shift by number already deleted. + // Alternative is delete from right to left. + int r = this->delete_at(marked_indexes.fetch_unchecked(i) - i); + lazy_assert_zero(r); + } + marked_indexes.deinit(); + barf_if_marked(*this); + } + + template + uint32_t omt:: + verify_marks_consistent_internal(const subtree &st, + const bool UU(allow_marks)) const { + if (st.is_null()) { + return 0; + } + const omt_node &node = this->d.t.nodes[st.get_index()]; + uint32_t num_marks = + verify_marks_consistent_internal(node.left, node.get_marks_below()); + num_marks += verify_marks_consistent_internal(node.right, + node.get_marks_below()); + if (node.get_marks_below()) { + paranoid_invariant(allow_marks); + paranoid_invariant(num_marks > 0); + } else { + // redundant with invariant below, but nice to have explicitly + paranoid_invariant(num_marks == 0); + } + if (node.get_marked()) { + paranoid_invariant(allow_marks); + ++num_marks; + } + return num_marks; + } + + template + void omt::verify_marks_consistent( + void) const { + static_assert(supports_marks, "does not support marks"); + paranoid_invariant(!this->is_array); + this->verify_marks_consistent_internal(this->d.t.root, true); + } + + template + template + void omt::iterate_ptr( + iterate_extra_t *const iterate_extra) { + if (this->is_array) { + this->iterate_ptr_internal_array( + 0, this->size(), iterate_extra); + } else { + this->iterate_ptr_internal( + 0, this->size(), this->d.t.root, 0, iterate_extra); + } + } + + template + int omt::fetch( + const uint32_t idx, + omtdataout_t *const value) const { + if (idx >= this->size()) { + return EINVAL; + } + if (this->is_array) { + this->fetch_internal_array(idx, value); + } else { + this->fetch_internal(this->d.t.root, idx, value); + } + return 0; + } + + template + template + int omt::find_zero( + const omtcmp_t &extra, + omtdataout_t *const value, + uint32_t *const idxp) const { + uint32_t tmp_index; + uint32_t *const child_idxp = (idxp != nullptr) ? idxp : &tmp_index; + int r; + if (this->is_array) { + r = this->find_internal_zero_array( + extra, value, child_idxp); + } else { + r = this->find_internal_zero( + this->d.t.root, extra, value, child_idxp); + } return r; - } else if (hv>0) { - return this->find_internal_zero(n.left, extra, value, idxp); - } else { - int r = this->find_internal_zero(n.left, extra, value, idxp); - if (r==DB_NOTFOUND) { - *idxp = this->nweight(n.left); + } + + template + template + int omt::find( + const omtcmp_t &extra, + int direction, + omtdataout_t *const value, + uint32_t *const idxp) const { + uint32_t tmp_index; + uint32_t *const child_idxp = (idxp != nullptr) ? idxp : &tmp_index; + paranoid_invariant(direction != 0); + if (direction < 0) { + if (this->is_array) { + return this->find_internal_minus_array( + extra, value, child_idxp); + } else { + return this->find_internal_minus( + this->d.t.root, extra, value, child_idxp); + } + } else { + if (this->is_array) { + return this->find_internal_plus_array( + extra, value, child_idxp); + } else { + return this->find_internal_plus( + this->d.t.root, extra, value, child_idxp); + } + } + } + + template + size_t omt::memory_size(void) { + if (this->is_array) { + return (sizeof *this) + + this->capacity * (sizeof this->d.a.values[0]); + } + return (sizeof *this) + this->capacity * (sizeof this->d.t.nodes[0]); + } + + template + void omt::create_internal_no_array( + const uint32_t new_capacity) { + this->is_array = true; + this->d.a.start_idx = 0; + this->d.a.num_values = 0; + this->d.a.values = nullptr; + this->capacity = new_capacity; + } + + template + void omt::create_internal( + const uint32_t new_capacity) { + this->create_internal_no_array(new_capacity); + XMALLOC_N(this->capacity, this->d.a.values); + } + + template + uint32_t omt::nweight( + const subtree &st) const { + if (st.is_null()) { + return 0; + } else { + return this->d.t.nodes[st.get_index()].weight; + } + } + + template + typename omt::node_idx + omt::node_malloc(void) { + paranoid_invariant(this->d.t.free_idx < this->capacity); + omt_node &n = this->d.t.nodes[this->d.t.free_idx]; + n.clear_stolen_bits(); + return this->d.t.free_idx++; + } + + template + void omt::node_free( + const node_idx UU(idx)) { + paranoid_invariant(idx < this->capacity); + } + + template + void omt::maybe_resize_array( + const uint32_t n) { + const uint32_t new_size = n <= 2 ? 4 : 2 * n; + const uint32_t room = this->capacity - this->d.a.start_idx; + + if (room < n || this->capacity / 2 >= new_size) { + omtdata_t *XMALLOC_N(new_size, tmp_values); + memcpy(tmp_values, + &this->d.a.values[this->d.a.start_idx], + this->d.a.num_values * (sizeof tmp_values[0])); + this->d.a.start_idx = 0; + this->capacity = new_size; + toku_free(this->d.a.values); + this->d.a.values = tmp_values; + } + } + + template + void omt:: + fill_array_with_subtree_values(omtdata_t *const array, + const subtree &st) const { + if (st.is_null()) + return; + const omt_node &tree = this->d.t.nodes[st.get_index()]; + this->fill_array_with_subtree_values(&array[0], tree.left); + array[this->nweight(tree.left)] = tree.value; + this->fill_array_with_subtree_values( + &array[this->nweight(tree.left) + 1], tree.right); + } + + template + void omt::convert_to_array(void) { + if (!this->is_array) { + const uint32_t num_values = this->size(); + uint32_t new_size = 2 * num_values; + new_size = new_size < 4 ? 4 : new_size; + + omtdata_t *XMALLOC_N(new_size, tmp_values); + this->fill_array_with_subtree_values(tmp_values, this->d.t.root); + toku_free(this->d.t.nodes); + this->is_array = true; + this->capacity = new_size; + this->d.a.num_values = num_values; + this->d.a.values = tmp_values; + this->d.a.start_idx = 0; + } + } + + template + void + omt::rebuild_from_sorted_array( + subtree *const st, + const omtdata_t *const values, + const uint32_t numvalues) { + if (numvalues == 0) { + st->set_to_null(); + } else { + const uint32_t halfway = numvalues / 2; + const node_idx newidx = this->node_malloc(); + omt_node *const newnode = &this->d.t.nodes[newidx]; + newnode->weight = numvalues; + newnode->value = values[halfway]; + st->set_index(newidx); + // update everything before the recursive calls so the second call + // can be a tail call. + this->rebuild_from_sorted_array( + &newnode->left, &values[0], halfway); + this->rebuild_from_sorted_array(&newnode->right, + &values[halfway + 1], + numvalues - (halfway + 1)); + } + } + + template + void omt::convert_to_tree(void) { + if (this->is_array) { + const uint32_t num_nodes = this->size(); + uint32_t new_size = num_nodes * 2; + new_size = new_size < 4 ? 4 : new_size; + + omt_node *XMALLOC_N(new_size, new_nodes); + omtdata_t *const values = this->d.a.values; + omtdata_t *const tmp_values = &values[this->d.a.start_idx]; + this->is_array = false; + this->d.t.nodes = new_nodes; + this->capacity = new_size; + this->d.t.free_idx = 0; + this->d.t.root.set_to_null(); + this->rebuild_from_sorted_array( + &this->d.t.root, tmp_values, num_nodes); + toku_free(values); + } + } + + template + void omt::maybe_resize_or_convert( + const uint32_t n) { + if (this->is_array) { + this->maybe_resize_array(n); + } else { + const uint32_t new_size = n <= 2 ? 4 : 2 * n; + const uint32_t num_nodes = this->nweight(this->d.t.root); + if ((this->capacity / 2 >= new_size) || + (this->d.t.free_idx >= this->capacity && num_nodes < n) || + (this->capacity < n)) { + this->convert_to_array(); + // if we had a free list, the "supports_marks" version could + // just resize, as it is now, we have to convert to and back + // from an array. + if (supports_marks) { + this->convert_to_tree(); + } + } + } + } + + template + bool omt::will_need_rebalance( + const subtree &st, + const int leftmod, + const int rightmod) const { + if (st.is_null()) { + return false; + } + const omt_node &n = this->d.t.nodes[st.get_index()]; + // one of the 1's is for the root. + // the other is to take ceil(n/2) + const uint32_t weight_left = this->nweight(n.left) + leftmod; + const uint32_t weight_right = this->nweight(n.right) + rightmod; + return ((1 + weight_left < (1 + 1 + weight_right) / 2) || + (1 + weight_right < (1 + 1 + weight_left) / 2)); + } + + template + void omt::insert_internal( + subtree *const subtreep, + const omtdata_t &value, + const uint32_t idx, + subtree **const rebalance_subtree) { + if (subtreep->is_null()) { + paranoid_invariant_zero(idx); + const node_idx newidx = this->node_malloc(); + omt_node *const newnode = &this->d.t.nodes[newidx]; + newnode->weight = 1; + newnode->left.set_to_null(); + newnode->right.set_to_null(); + newnode->value = value; + subtreep->set_index(newidx); + } else { + omt_node &n = this->d.t.nodes[subtreep->get_index()]; + n.weight++; + if (idx <= this->nweight(n.left)) { + if (*rebalance_subtree == nullptr && + this->will_need_rebalance(*subtreep, 1, 0)) { + *rebalance_subtree = subtreep; + } + this->insert_internal(&n.left, value, idx, rebalance_subtree); + } else { + if (*rebalance_subtree == nullptr && + this->will_need_rebalance(*subtreep, 0, 1)) { + *rebalance_subtree = subtreep; + } + const uint32_t sub_index = idx - this->nweight(n.left) - 1; + this->insert_internal( + &n.right, value, sub_index, rebalance_subtree); + } + } + } + + template + void omt::set_at_internal_array( + const omtdata_t &value, + const uint32_t idx) { + this->d.a.values[this->d.a.start_idx + idx] = value; + } + + template + void omt::set_at_internal( + const subtree &st, + const omtdata_t &value, + const uint32_t idx) { + paranoid_invariant(!st.is_null()); + omt_node &n = this->d.t.nodes[st.get_index()]; + const uint32_t leftweight = this->nweight(n.left); + if (idx < leftweight) { + this->set_at_internal(n.left, value, idx); + } else if (idx == leftweight) { + n.value = value; + } else { + this->set_at_internal(n.right, value, idx - leftweight - 1); + } + } + + template + void omt::delete_internal( + subtree *const subtreep, + const uint32_t idx, + omt_node *const copyn, + subtree **const rebalance_subtree) { + paranoid_invariant_notnull(subtreep); + paranoid_invariant_notnull(rebalance_subtree); + paranoid_invariant(!subtreep->is_null()); + omt_node &n = this->d.t.nodes[subtreep->get_index()]; + const uint32_t leftweight = this->nweight(n.left); + if (idx < leftweight) { + n.weight--; + if (*rebalance_subtree == nullptr && + this->will_need_rebalance(*subtreep, -1, 0)) { + *rebalance_subtree = subtreep; + } + this->delete_internal(&n.left, idx, copyn, rebalance_subtree); + } else if (idx == leftweight) { + if (n.left.is_null()) { + const uint32_t oldidx = subtreep->get_index(); + *subtreep = n.right; + if (copyn != nullptr) { + copyn->value = n.value; + } + this->node_free(oldidx); + } else if (n.right.is_null()) { + const uint32_t oldidx = subtreep->get_index(); + *subtreep = n.left; + if (copyn != nullptr) { + copyn->value = n.value; + } + this->node_free(oldidx); + } else { + if (*rebalance_subtree == nullptr && + this->will_need_rebalance(*subtreep, 0, -1)) { + *rebalance_subtree = subtreep; + } + // don't need to copy up value, it's only used by this + // next call, and when that gets to the bottom there + // won't be any more recursion + n.weight--; + this->delete_internal(&n.right, 0, &n, rebalance_subtree); + } + } else { + n.weight--; + if (*rebalance_subtree == nullptr && + this->will_need_rebalance(*subtreep, 0, -1)) { + *rebalance_subtree = subtreep; + } + this->delete_internal( + &n.right, idx - leftweight - 1, copyn, rebalance_subtree); + } + } + + template + template < + typename iterate_extra_t, + int (*f)(const omtdata_t &, const uint32_t, iterate_extra_t *const)> + int omt::iterate_internal_array( + const uint32_t left, + const uint32_t right, + iterate_extra_t *const iterate_extra) const { + int r; + for (uint32_t i = left; i < right; ++i) { + r = f(this->d.a.values[this->d.a.start_idx + i], i, iterate_extra); + if (r != 0) { + return r; + } + } + return 0; + } + + template + template + void omt::iterate_ptr_internal( + const uint32_t left, + const uint32_t right, + const subtree &st, + const uint32_t idx, + iterate_extra_t *const iterate_extra) { + if (!st.is_null()) { + omt_node &n = this->d.t.nodes[st.get_index()]; + const uint32_t idx_root = idx + this->nweight(n.left); + if (left < idx_root) { + this->iterate_ptr_internal( + left, right, n.left, idx, iterate_extra); + } + if (left <= idx_root && idx_root < right) { + int r = f(&n.value, idx_root, iterate_extra); + lazy_assert_zero(r); + } + if (idx_root + 1 < right) { + this->iterate_ptr_internal( + left, right, n.right, idx_root + 1, iterate_extra); + } + } + } + + template + template + void + omt::iterate_ptr_internal_array( + const uint32_t left, + const uint32_t right, + iterate_extra_t *const iterate_extra) { + for (uint32_t i = left; i < right; ++i) { + int r = + f(&this->d.a.values[this->d.a.start_idx + i], i, iterate_extra); + lazy_assert_zero(r); + } + } + + template + template < + typename iterate_extra_t, + int (*f)(const omtdata_t &, const uint32_t, iterate_extra_t *const)> + int omt::iterate_internal( + const uint32_t left, + const uint32_t right, + const subtree &st, + const uint32_t idx, + iterate_extra_t *const iterate_extra) const { + if (st.is_null()) { + return 0; + } + int r; + const omt_node &n = this->d.t.nodes[st.get_index()]; + const uint32_t idx_root = idx + this->nweight(n.left); + if (left < idx_root) { + r = this->iterate_internal( + left, right, n.left, idx, iterate_extra); + if (r != 0) { + return r; + } + } + if (left <= idx_root && idx_root < right) { + r = f(n.value, idx_root, iterate_extra); + if (r != 0) { + return r; + } + } + if (idx_root + 1 < right) { + return this->iterate_internal( + left, right, n.right, idx_root + 1, iterate_extra); + } + return 0; + } + + template + template < + typename iterate_extra_t, + int (*f)(const omtdata_t &, const uint32_t, iterate_extra_t *const)> + int omt:: + iterate_and_mark_range_internal(const uint32_t left, + const uint32_t right, + const subtree &st, + const uint32_t idx, + iterate_extra_t *const iterate_extra) { + paranoid_invariant(!st.is_null()); + int r; + omt_node &n = this->d.t.nodes[st.get_index()]; + const uint32_t idx_root = idx + this->nweight(n.left); + if (left < idx_root && !n.left.is_null()) { + n.set_marks_below_bit(); + r = this->iterate_and_mark_range_internal( + left, right, n.left, idx, iterate_extra); + if (r != 0) { + return r; + } + } + if (left <= idx_root && idx_root < right) { + n.set_marked_bit(); + r = f(n.value, idx_root, iterate_extra); + if (r != 0) { + return r; + } + } + if (idx_root + 1 < right && !n.right.is_null()) { + n.set_marks_below_bit(); + return this->iterate_and_mark_range_internal( + left, right, n.right, idx_root + 1, iterate_extra); + } + return 0; + } + + template + template < + typename iterate_extra_t, + int (*f)(const omtdata_t &, const uint32_t, iterate_extra_t *const)> + int + omt::iterate_over_marked_internal( + const subtree &st, + const uint32_t idx, + iterate_extra_t *const iterate_extra) const { + if (st.is_null()) { + return 0; + } + int r; + const omt_node &n = this->d.t.nodes[st.get_index()]; + const uint32_t idx_root = idx + this->nweight(n.left); + if (n.get_marks_below()) { + r = this->iterate_over_marked_internal( + n.left, idx, iterate_extra); + if (r != 0) { + return r; + } + } + if (n.get_marked()) { + r = f(n.value, idx_root, iterate_extra); + if (r != 0) { + return r; + } + } + if (n.get_marks_below()) { + return this->iterate_over_marked_internal( + n.right, idx_root + 1, iterate_extra); + } + return 0; + } + + template + void omt::fetch_internal_array( + const uint32_t i, + omtdataout_t *const value) const { + if (value != nullptr) { + copyout(value, &this->d.a.values[this->d.a.start_idx + i]); + } + } + + template + void omt::fetch_internal( + const subtree &st, + const uint32_t i, + omtdataout_t *const value) const { + omt_node &n = this->d.t.nodes[st.get_index()]; + const uint32_t leftweight = this->nweight(n.left); + if (i < leftweight) { + this->fetch_internal(n.left, i, value); + } else if (i == leftweight) { if (value != nullptr) { copyout(value, &n); } - r = 0; - } - return r; - } -} - -template -template -int omt::find_internal_plus_array(const omtcmp_t &extra, omtdataout_t *const value, uint32_t *const idxp) const { - paranoid_invariant_notnull(idxp); - uint32_t min = this->d.a.start_idx; - uint32_t limit = this->d.a.start_idx + this->d.a.num_values; - uint32_t best = subtree::NODE_NULL; - - while (min != limit) { - const uint32_t mid = (min + limit) / 2; - const int hv = h(this->d.a.values[mid], extra); - if (hv > 0) { - best = mid; - limit = mid; } else { - min = mid + 1; + this->fetch_internal(n.right, i - leftweight - 1, value); } } - if (best == subtree::NODE_NULL) { return DB_NOTFOUND; } - if (value != nullptr) { - copyout(value, &this->d.a.values[best]); - } - *idxp = best - this->d.a.start_idx; - return 0; -} -template -template -int omt::find_internal_plus(const subtree &subtree, const omtcmp_t &extra, omtdataout_t *const value, uint32_t *const idxp) const { - paranoid_invariant_notnull(idxp); - if (subtree.is_null()) { + template + void + omt::fill_array_with_subtree_idxs( + node_idx *const array, + const subtree &st) const { + if (!st.is_null()) { + const omt_node &tree = this->d.t.nodes[st.get_index()]; + this->fill_array_with_subtree_idxs(&array[0], tree.left); + array[this->nweight(tree.left)] = st.get_index(); + this->fill_array_with_subtree_idxs( + &array[this->nweight(tree.left) + 1], tree.right); + } + } + + template + void + omt::rebuild_subtree_from_idxs( + subtree *const st, + const node_idx *const idxs, + const uint32_t numvalues) { + if (numvalues == 0) { + st->set_to_null(); + } else { + uint32_t halfway = numvalues / 2; + st->set_index(idxs[halfway]); + // node_idx newidx = idxs[halfway]; + omt_node &newnode = this->d.t.nodes[st->get_index()]; + newnode.weight = numvalues; + // value is already in there. + this->rebuild_subtree_from_idxs(&newnode.left, &idxs[0], halfway); + this->rebuild_subtree_from_idxs( + &newnode.right, &idxs[halfway + 1], numvalues - (halfway + 1)); + // n_idx = newidx; + } + } + + template + void omt::rebalance( + subtree *const st) { + node_idx idx = st->get_index(); + if (idx == this->d.t.root.get_index()) { + // Try to convert to an array. + // If this fails, (malloc) nothing will have changed. + // In the failure case we continue on to the standard rebalance + // algorithm. + this->convert_to_array(); + if (supports_marks) { + this->convert_to_tree(); + } + } else { + const omt_node &n = this->d.t.nodes[idx]; + node_idx *tmp_array; + size_t mem_needed = n.weight * (sizeof tmp_array[0]); + size_t mem_free = (this->capacity - this->d.t.free_idx) * + (sizeof this->d.t.nodes[0]); + bool malloced; + if (mem_needed <= mem_free) { + // There is sufficient free space at the end of the nodes array + // to hold enough node indexes to rebalance. + malloced = false; + tmp_array = reinterpret_cast( + &this->d.t.nodes[this->d.t.free_idx]); + } else { + malloced = true; + XMALLOC_N(n.weight, tmp_array); + } + this->fill_array_with_subtree_idxs(tmp_array, *st); + this->rebuild_subtree_from_idxs(st, tmp_array, n.weight); + if (malloced) + toku_free(tmp_array); + } + } + + template + void omt::copyout( + omtdata_t *const out, + const omt_node *const n) { + *out = n->value; + } + + template + void omt::copyout( + omtdata_t **const out, + omt_node *const n) { + *out = &n->value; + } + + template + void omt::copyout( + omtdata_t *const out, + const omtdata_t *const stored_value_ptr) { + *out = *stored_value_ptr; + } + + template + void omt::copyout( + omtdata_t **const out, + omtdata_t *const stored_value_ptr) { + *out = stored_value_ptr; + } + + template + template + int omt::find_internal_zero_array( + const omtcmp_t &extra, + omtdataout_t *const value, + uint32_t *const idxp) const { + paranoid_invariant_notnull(idxp); + uint32_t min = this->d.a.start_idx; + uint32_t limit = this->d.a.start_idx + this->d.a.num_values; + uint32_t best_pos = subtree::NODE_NULL; + uint32_t best_zero = subtree::NODE_NULL; + + while (min != limit) { + uint32_t mid = (min + limit) / 2; + int hv = h(this->d.a.values[mid], extra); + if (hv < 0) { + min = mid + 1; + } else if (hv > 0) { + best_pos = mid; + limit = mid; + } else { + best_zero = mid; + limit = mid; + } + } + if (best_zero != subtree::NODE_NULL) { + // Found a zero + if (value != nullptr) { + copyout(value, &this->d.a.values[best_zero]); + } + *idxp = best_zero - this->d.a.start_idx; + return 0; + } + if (best_pos != subtree::NODE_NULL) + *idxp = best_pos - this->d.a.start_idx; + else + *idxp = this->d.a.num_values; return DB_NOTFOUND; } - omt_node *const n = &this->d.t.nodes[subtree.get_index()]; - int hv = h(n->value, extra); - int r; - if (hv > 0) { - r = this->find_internal_plus(n->left, extra, value, idxp); - if (r == DB_NOTFOUND) { - *idxp = this->nweight(n->left); - if (value != nullptr) { - copyout(value, n); - } - r = 0; - } - } else { - r = this->find_internal_plus(n->right, extra, value, idxp); - if (r == 0) { - *idxp += this->nweight(n->left) + 1; - } - } - return r; -} -template -template -int omt::find_internal_minus_array(const omtcmp_t &extra, omtdataout_t *const value, uint32_t *const idxp) const { - paranoid_invariant_notnull(idxp); - uint32_t min = this->d.a.start_idx; - uint32_t limit = this->d.a.start_idx + this->d.a.num_values; - uint32_t best = subtree::NODE_NULL; - - while (min != limit) { - const uint32_t mid = (min + limit) / 2; - const int hv = h(this->d.a.values[mid], extra); + template + template + int omt::find_internal_zero( + const subtree &st, + const omtcmp_t &extra, + omtdataout_t *const value, + uint32_t *const idxp) const { + paranoid_invariant_notnull(idxp); + if (st.is_null()) { + *idxp = 0; + return DB_NOTFOUND; + } + omt_node &n = this->d.t.nodes[st.get_index()]; + int hv = h(n.value, extra); if (hv < 0) { - best = mid; - min = mid + 1; + int r = this->find_internal_zero( + n.right, extra, value, idxp); + *idxp += this->nweight(n.left) + 1; + return r; + } else if (hv > 0) { + return this->find_internal_zero( + n.left, extra, value, idxp); } else { - limit = mid; + int r = this->find_internal_zero( + n.left, extra, value, idxp); + if (r == DB_NOTFOUND) { + *idxp = this->nweight(n.left); + if (value != nullptr) { + copyout(value, &n); + } + r = 0; + } + return r; } } - if (best == subtree::NODE_NULL) { return DB_NOTFOUND; } - if (value != nullptr) { - copyout(value, &this->d.a.values[best]); - } - *idxp = best - this->d.a.start_idx; - return 0; -} -template -template -int omt::find_internal_minus(const subtree &subtree, const omtcmp_t &extra, omtdataout_t *const value, uint32_t *const idxp) const { - paranoid_invariant_notnull(idxp); - if (subtree.is_null()) { - return DB_NOTFOUND; - } - omt_node *const n = &this->d.t.nodes[subtree.get_index()]; - int hv = h(n->value, extra); - if (hv < 0) { - int r = this->find_internal_minus(n->right, extra, value, idxp); - if (r == 0) { - *idxp += this->nweight(n->left) + 1; - } else if (r == DB_NOTFOUND) { - *idxp = this->nweight(n->left); - if (value != nullptr) { - copyout(value, n); + template + template + int omt::find_internal_plus_array( + const omtcmp_t &extra, + omtdataout_t *const value, + uint32_t *const idxp) const { + paranoid_invariant_notnull(idxp); + uint32_t min = this->d.a.start_idx; + uint32_t limit = this->d.a.start_idx + this->d.a.num_values; + uint32_t best = subtree::NODE_NULL; + + while (min != limit) { + const uint32_t mid = (min + limit) / 2; + const int hv = h(this->d.a.values[mid], extra); + if (hv > 0) { + best = mid; + limit = mid; + } else { + min = mid + 1; + } + } + if (best == subtree::NODE_NULL) { + return DB_NOTFOUND; + } + if (value != nullptr) { + copyout(value, &this->d.a.values[best]); + } + *idxp = best - this->d.a.start_idx; + return 0; + } + + template + template + int omt::find_internal_plus( + const subtree &st, + const omtcmp_t &extra, + omtdataout_t *const value, + uint32_t *const idxp) const { + paranoid_invariant_notnull(idxp); + if (st.is_null()) { + return DB_NOTFOUND; + } + omt_node *const n = &this->d.t.nodes[st.get_index()]; + int hv = h(n->value, extra); + int r; + if (hv > 0) { + r = this->find_internal_plus( + n->left, extra, value, idxp); + if (r == DB_NOTFOUND) { + *idxp = this->nweight(n->left); + if (value != nullptr) { + copyout(value, n); + } + r = 0; + } + } else { + r = this->find_internal_plus( + n->right, extra, value, idxp); + if (r == 0) { + *idxp += this->nweight(n->left) + 1; } - r = 0; } return r; - } else { - return this->find_internal_minus(n->left, extra, value, idxp); } -} -} // namespace toku + + template + template + int omt::find_internal_minus_array( + const omtcmp_t &extra, + omtdataout_t *const value, + uint32_t *const idxp) const { + paranoid_invariant_notnull(idxp); + uint32_t min = this->d.a.start_idx; + uint32_t limit = this->d.a.start_idx + this->d.a.num_values; + uint32_t best = subtree::NODE_NULL; + + while (min != limit) { + const uint32_t mid = (min + limit) / 2; + const int hv = h(this->d.a.values[mid], extra); + if (hv < 0) { + best = mid; + min = mid + 1; + } else { + limit = mid; + } + } + if (best == subtree::NODE_NULL) { + return DB_NOTFOUND; + } + if (value != nullptr) { + copyout(value, &this->d.a.values[best]); + } + *idxp = best - this->d.a.start_idx; + return 0; + } + + template + template + int omt::find_internal_minus( + const subtree &st, + const omtcmp_t &extra, + omtdataout_t *const value, + uint32_t *const idxp) const { + paranoid_invariant_notnull(idxp); + if (st.is_null()) { + return DB_NOTFOUND; + } + omt_node *const n = &this->d.t.nodes[st.get_index()]; + int hv = h(n->value, extra); + if (hv < 0) { + int r = this->find_internal_minus( + n->right, extra, value, idxp); + if (r == 0) { + *idxp += this->nweight(n->left) + 1; + } else if (r == DB_NOTFOUND) { + *idxp = this->nweight(n->left); + if (value != nullptr) { + copyout(value, n); + } + r = 0; + } + return r; + } else { + return this->find_internal_minus( + n->left, extra, value, idxp); + } + } +} // namespace toku diff --git a/storage/tokudb/PerconaFT/util/omt.h b/storage/tokudb/PerconaFT/util/omt.h index c7ed2ca546f..dc2fd9b7162 100644 --- a/storage/tokudb/PerconaFT/util/omt.h +++ b/storage/tokudb/PerconaFT/util/omt.h @@ -32,6 +32,19 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. You should have received a copy of the GNU Affero General Public License along with PerconaFT. If not, see . + +---------------------------------------- + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and ======= */ #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." diff --git a/storage/tokudb/ha_tokudb.cc b/storage/tokudb/ha_tokudb.cc index 548ac5c7b09..babbe825f2e 100644 --- a/storage/tokudb/ha_tokudb.cc +++ b/storage/tokudb/ha_tokudb.cc @@ -7252,6 +7252,16 @@ int ha_tokudb::create( tokudb_trx_data *trx = NULL; THD* thd = ha_thd(); + String database_name, table_name, dictionary_name; + tokudb_split_dname(name, database_name, table_name, dictionary_name); + if (database_name.is_empty() || table_name.is_empty()) { + push_warning_printf(thd, + Sql_condition::WARN_LEVEL_WARN, + ER_TABLE_NAME, + "TokuDB: Table Name or Database Name is empty"); + DBUG_RETURN(ER_TABLE_NAME); + } + memset(&kc_info, 0, sizeof(kc_info)); #if 100000 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 100999 diff --git a/storage/tokudb/hatoku_hton.cc b/storage/tokudb/hatoku_hton.cc index 610c9e07be0..a1d6597e33a 100644 --- a/storage/tokudb/hatoku_hton.cc +++ b/storage/tokudb/hatoku_hton.cc @@ -575,10 +575,10 @@ static int tokudb_init_func(void *p) { db_env->set_update(db_env, tokudb_update_fun); - db_env_set_direct_io(tokudb::sysvars::directio == TRUE); + db_env_set_direct_io(tokudb::sysvars::directio); db_env_set_compress_buffers_before_eviction( - tokudb::sysvars::compress_buffers_before_eviction == TRUE); + tokudb::sysvars::compress_buffers_before_eviction); db_env->change_fsync_log_period(db_env, tokudb::sysvars::fsync_log_period); diff --git a/storage/tokudb/hatoku_hton.h b/storage/tokudb/hatoku_hton.h index c5b6aab1769..e90af067b00 100644 --- a/storage/tokudb/hatoku_hton.h +++ b/storage/tokudb/hatoku_hton.h @@ -190,7 +190,6 @@ inline bool tokudb_killed_thd_callback(void* extra, return thd_killed(thd) != 0; } -extern HASH tokudb_open_tables; extern const char* tokudb_hton_name; extern int tokudb_hton_initialized; extern tokudb::thread::rwlock_t tokudb_hton_initialized_lock; diff --git a/storage/tokudb/mysql-test/tokudb_bugs/r/PS-4979.result b/storage/tokudb/mysql-test/tokudb_bugs/r/PS-4979.result new file mode 100644 index 00000000000..f0d2f93f630 --- /dev/null +++ b/storage/tokudb/mysql-test/tokudb_bugs/r/PS-4979.result @@ -0,0 +1,2 @@ +CREATE TABLE `#mysql50#q.q`(f1 INT KEY) ENGINE=TOKUDB; +ERROR HY000: Got error 1632 from storage engine diff --git a/storage/tokudb/mysql-test/tokudb_bugs/t/PS-4979.test b/storage/tokudb/mysql-test/tokudb_bugs/t/PS-4979.test new file mode 100644 index 00000000000..1e4b5d11922 --- /dev/null +++ b/storage/tokudb/mysql-test/tokudb_bugs/t/PS-4979.test @@ -0,0 +1,12 @@ +--source include/have_tokudb.inc +# PS-4979 : Dropping TokuDB table with non-alphanumeric characters could lead +# to a crash +# +# `#mysql50#q.q` is an invalid table name, but the server side doesn't detect it +# and complain. Instead it passes in an empty table name to the engine. The +# engine expects a table name in the form of a relative path like +# "./databasename/tablename". InnoDB detects this in parsing the table name +# during the creation and returns an error. + +--error ER_GET_ERRNO +CREATE TABLE `#mysql50#q.q`(f1 INT KEY) ENGINE=TOKUDB; diff --git a/storage/tokudb/tokudb_background.cc b/storage/tokudb/tokudb_background.cc index 13e0e9321cc..19f03dbca65 100644 --- a/storage/tokudb/tokudb_background.cc +++ b/storage/tokudb/tokudb_background.cc @@ -182,14 +182,14 @@ void* job_manager_t::real_thread_func() { if (res == tokudb::thread::semaphore_t::E_INTERRUPTED || _shutdown) { break; } else if (res == tokudb::thread::semaphore_t::E_SIGNALLED) { -#if TOKUDB_DEBUG +#if defined(TOKUDB_DEBUG) if (TOKUDB_UNLIKELY( tokudb::sysvars::debug_pause_background_job_manager)) { _sem.signal(); tokudb::time::sleep_microsec(250000); continue; } -#endif // TOKUDB_DEBUG +#endif // defined(TOKUDB_DEBUG) mutex_t_lock(_mutex); assert_debug(_background_jobs.size() > 0); diff --git a/storage/tokudb/tokudb_sysvars.cc b/storage/tokudb/tokudb_sysvars.cc index e8e9f908275..d1f58d012ec 100644 --- a/storage/tokudb/tokudb_sysvars.cc +++ b/storage/tokudb/tokudb_sysvars.cc @@ -662,13 +662,13 @@ static MYSQL_THDVAR_ULONGLONG( ~0ULL, 1); -static MYSQL_THDVAR_STR( - last_lock_timeout, - PLUGIN_VAR_MEMALLOC, - "last lock timeout", - NULL, - NULL, - NULL); +static MYSQL_THDVAR_STR(last_lock_timeout, + PLUGIN_VAR_MEMALLOC | PLUGIN_VAR_NOCMDOPT | + PLUGIN_VAR_READONLY, + "last lock timeout", + NULL, + NULL, + NULL); static MYSQL_THDVAR_BOOL( load_save_space, diff --git a/storage/tokudb/tokudb_sysvars.h b/storage/tokudb/tokudb_sysvars.h index d81d5fd7999..6f09f296a80 100644 --- a/storage/tokudb/tokudb_sysvars.h +++ b/storage/tokudb/tokudb_sysvars.h @@ -93,10 +93,10 @@ extern my_bool gdb_on_fatal; extern my_bool check_jemalloc; -#if TOKUDB_DEBUG +#if defined(TOKUDB_DEBUG) // used to control background job manager extern my_bool debug_pause_background_job_manager; -#endif // TOKUDB_DEBUG +#endif // defined(TOKUDB_DEBUG) // session/thread my_bool alter_print_error(THD* thd); From f9ac7032cbc4b7b9af9c8122e6ebfd91af9fbaf9 Mon Sep 17 00:00:00 2001 From: Andrei Elkin Date: Sun, 20 Jan 2019 19:00:16 +0200 Subject: [PATCH 038/106] MDEV-14605 Changes to "ON UPDATE CURRENT_TIMESTAMP" fields are not always logged properly with binlog_row_image=MINIMAL There are two issues fixed in this commit. The first is an observation of a multi-table UPDATE binlogged in row-format in binlog_row_image=MINIMAL mode. While the UPDATE aims at a table with an ON-UPDATE attribute its binlog after-image misses to record also installed default value. The reason for that turns out missed marking of default-capable fields in TABLE::write_set. This is fixed to mark such fields similarly to 10.2's MDEV-10134 patch (db7edfed17efe6) that introduced it. The marking follows up 93d1e5ce0b841bed's idea to exploit TABLE:rpl_write_set introduced there though, and thus does not mess (in 10.1) with the actual MDEV-10134 agenda. The patch makes formerly arg-less TABLE::mark_default_fields_for_write() to accept an argument which would be TABLE:rpl_write_set. The 2nd issue is extra columns in in binlog_row_image=MINIMAL before-image while merely a packed primary key is enough. The test main.mysqlbinlog_row_minimal always had a wrong result recorded. This is fixed to invoke a function that intended for read_set possible filtering and which is called (supposed to) in all type of MDL, UPDATE including; the test results have gotten corrected. At *merging* from 10.1->10.2 the 1st "main" part of the patch is unnecessary since the bug is not observed in 10.2, so only hunks from sql/sql_class.cc are required. --- mysql-test/r/mysqlbinlog_row_minimal.result | 108 +++++++++++++++----- mysql-test/t/mysqlbinlog_row_minimal.test | 41 ++++++++ sql/sql_class.cc | 23 ++++- sql/table.cc | 6 +- sql/table.h | 6 +- 5 files changed, 155 insertions(+), 29 deletions(-) diff --git a/mysql-test/r/mysqlbinlog_row_minimal.result b/mysql-test/r/mysqlbinlog_row_minimal.result index 34bafd6301a..2e34b2885ca 100644 --- a/mysql-test/r/mysqlbinlog_row_minimal.result +++ b/mysql-test/r/mysqlbinlog_row_minimal.result @@ -214,39 +214,36 @@ BEGIN # at 1997 # server id 1 end_log_pos 2049 Table_map: `test`.`t2` mapped to number 32 # at 2049 -# server id 1 end_log_pos 2119 Update_rows: table id 32 flags: STMT_END_F +# server id 1 end_log_pos 2111 Update_rows: table id 32 flags: STMT_END_F ### UPDATE `test`.`t2` ### WHERE ### @1=10 /* INT meta=0 nullable=0 is_null=0 */ -### @5=4 /* INT meta=0 nullable=1 is_null=0 */ ### SET ### @5=5 /* INT meta=0 nullable=1 is_null=0 */ ### UPDATE `test`.`t2` ### WHERE ### @1=11 /* INT meta=0 nullable=0 is_null=0 */ -### @5=4 /* INT meta=0 nullable=1 is_null=0 */ ### SET ### @5=5 /* INT meta=0 nullable=1 is_null=0 */ ### UPDATE `test`.`t2` ### WHERE ### @1=12 /* INT meta=0 nullable=0 is_null=0 */ -### @5=NULL /* INT meta=0 nullable=1 is_null=1 */ ### SET ### @5=5 /* INT meta=0 nullable=1 is_null=0 */ -# at 2119 -# server id 1 end_log_pos 2188 Query thread_id=4 exec_time=x error_code=0 +# at 2111 +# server id 1 end_log_pos 2180 Query thread_id=4 exec_time=x error_code=0 SET TIMESTAMP=X/*!*/; COMMIT /*!*/; -# at 2188 -# server id 1 end_log_pos 2226 GTID 0-1-9 +# at 2180 +# server id 1 end_log_pos 2218 GTID 0-1-9 /*!100001 SET @@session.gtid_seq_no=9*//*!*/; BEGIN /*!*/; -# at 2226 -# server id 1 end_log_pos 2278 Table_map: `test`.`t1` mapped to number 31 -# at 2278 -# server id 1 end_log_pos 2328 Delete_rows: table id 31 flags: STMT_END_F +# at 2218 +# server id 1 end_log_pos 2270 Table_map: `test`.`t1` mapped to number 31 +# at 2270 +# server id 1 end_log_pos 2320 Delete_rows: table id 31 flags: STMT_END_F ### DELETE FROM `test`.`t1` ### WHERE ### @1=10 /* INT meta=0 nullable=0 is_null=0 */ @@ -259,20 +256,20 @@ BEGIN ### DELETE FROM `test`.`t1` ### WHERE ### @1=13 /* INT meta=0 nullable=0 is_null=0 */ -# at 2328 -# server id 1 end_log_pos 2397 Query thread_id=4 exec_time=x error_code=0 +# at 2320 +# server id 1 end_log_pos 2389 Query thread_id=4 exec_time=x error_code=0 SET TIMESTAMP=X/*!*/; COMMIT /*!*/; -# at 2397 -# server id 1 end_log_pos 2435 GTID 0-1-10 +# at 2389 +# server id 1 end_log_pos 2427 GTID 0-1-10 /*!100001 SET @@session.gtid_seq_no=10*//*!*/; BEGIN /*!*/; -# at 2435 -# server id 1 end_log_pos 2487 Table_map: `test`.`t2` mapped to number 32 -# at 2487 -# server id 1 end_log_pos 2537 Delete_rows: table id 32 flags: STMT_END_F +# at 2427 +# server id 1 end_log_pos 2479 Table_map: `test`.`t2` mapped to number 32 +# at 2479 +# server id 1 end_log_pos 2529 Delete_rows: table id 32 flags: STMT_END_F ### DELETE FROM `test`.`t2` ### WHERE ### @1=10 /* INT meta=0 nullable=0 is_null=0 */ @@ -285,13 +282,76 @@ BEGIN ### DELETE FROM `test`.`t2` ### WHERE ### @1=13 /* INT meta=0 nullable=0 is_null=0 */ -# at 2537 -# server id 1 end_log_pos 2606 Query thread_id=4 exec_time=x error_code=0 +# at 2529 +# server id 1 end_log_pos 2598 Query thread_id=4 exec_time=x error_code=0 SET TIMESTAMP=X/*!*/; COMMIT /*!*/; -# at 2606 -# server id 1 end_log_pos 2650 Rotate to master-bin.000002 pos: 4 +# at 2598 +# server id 1 end_log_pos 2642 Rotate to master-bin.000002 pos: 4 +DELIMITER ; +# End of log file +ROLLBACK /* added by mysqlbinlog */; +/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; +DROP TABLE t1,t2; +CREATE TABLE `t1` ( +`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, +`is_deleted` BIT(1) DEFAULT b'0', +`last_updated` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, +`ref_id` BIGINT(20) UNSIGNED NOT NULL, +PRIMARY KEY (`id`), +KEY `last_updated_KEY` (`last_updated`) +); +CREATE TABLE `t2` ( +`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, +`short_desc` VARCHAR(50) NOT NULL, +PRIMARY KEY (`id`) +); +INSERT INTO t2 (id, short_desc) VALUES (1, 'test'); +INSERT INTO t1 (id, is_deleted, ref_id) VALUES (1, b'0', 1); +FLUSH BINARY LOGS; +UPDATE t1 t1 INNER JOIN t2 t2 ON t1.ref_id = t2.id +SET t1.is_deleted = TRUE +WHERE t1.id = 1; +FLUSH BINARY LOGS; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; +/*!40019 SET @@session.max_insert_delayed_threads=0*/; +/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; +DELIMITER /*!*/; +# at 368 +# server id 1 end_log_pos 406 GTID 0-1-16 +/*!100101 SET @@session.skip_parallel_replication=0*//*!*/; +/*!100001 SET @@session.gtid_domain_id=0*//*!*/; +/*!100001 SET @@session.server_id=1*//*!*/; +/*!100001 SET @@session.gtid_seq_no=16*//*!*/; +BEGIN +/*!*/; +# at 406 +# server id 1 end_log_pos 453 Table_map: `test`.`t1` mapped to number 34 +# at 453 +# server id 1 end_log_pos 498 Update_rows: table id 34 flags: STMT_END_F +### UPDATE `test`.`t1` +### WHERE +### @1=1 /* LONGINT meta=0 nullable=0 is_null=0 */ +### SET +### @2=b'1' /* BIT(1) meta=1 nullable=1 is_null=0 */ +### @3=X /* TIMESTAMP(0) meta=0 nullable=0 is_null=0 */ +# at 498 +# server id 1 end_log_pos 576 Query thread_id=4 exec_time=x error_code=0 +SET TIMESTAMP=X/*!*/; +SET @@session.pseudo_thread_id=4/*!*/; +SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/; +SET @@session.sql_mode=1342177280/*!*/; +SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; +/*!\C latin1 *//*!*/; +SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; +SET @@session.lc_time_names=0/*!*/; +SET @@session.collation_database=DEFAULT/*!*/; +COMMIT +/*!*/; +# at 576 +# server id 1 end_log_pos 620 Rotate to master-bin.000004 pos: 4 DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; diff --git a/mysql-test/t/mysqlbinlog_row_minimal.test b/mysql-test/t/mysqlbinlog_row_minimal.test index 216cb43eb6f..39cae408d4e 100644 --- a/mysql-test/t/mysqlbinlog_row_minimal.test +++ b/mysql-test/t/mysqlbinlog_row_minimal.test @@ -26,8 +26,49 @@ DELETE FROM t2; --let $datadir = `SELECT @@datadir` FLUSH BINARY LOGS; + --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --replace_regex /\d{6} *\d*:\d\d:\d\d// /Start:.*at startup/Start: xxx/ /SET TIMESTAMP=\d*/SET TIMESTAMP=X/ /exec_time=\d*/exec_time=x/ --exec $MYSQL_BINLOG --verbose --verbose --base64-output=DECODE-ROWS $datadir/$binlog DROP TABLE t1,t2; + +# +# MDEV-14605 ON UPDATE CURRENT_TIMESTAMP fields by multi-table UPDATE are not logged with binlog_row_image=MINIMAL +# + +CREATE TABLE `t1` ( + + `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, + `is_deleted` BIT(1) DEFAULT b'0', + `last_updated` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `ref_id` BIGINT(20) UNSIGNED NOT NULL, + PRIMARY KEY (`id`), + KEY `last_updated_KEY` (`last_updated`) +); + +CREATE TABLE `t2` ( + `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, + `short_desc` VARCHAR(50) NOT NULL, + PRIMARY KEY (`id`) +); + + +INSERT INTO t2 (id, short_desc) VALUES (1, 'test'); +INSERT INTO t1 (id, is_deleted, ref_id) VALUES (1, b'0', 1); +FLUSH BINARY LOGS; +--let $binlog_pos= query_get_value(SHOW MASTER STATUS, Position, 1) + +UPDATE t1 t1 INNER JOIN t2 t2 ON t1.ref_id = t2.id + SET t1.is_deleted = TRUE + WHERE t1.id = 1; + +--let $binlog = query_get_value(SHOW MASTER STATUS, File, 1) + +FLUSH BINARY LOGS; +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +--replace_regex /\d{6} *\d*:\d\d:\d\d// /SET TIMESTAMP=\d*/SET TIMESTAMP=X/ /exec_time=\d*/exec_time=x/ /@3=\d*/@3=X/ /CRC32 0x[0-9a-f]+/CRC32 XXX/ +--exec $MYSQL_BINLOG --verbose --verbose --base64-output=DECODE-ROWS $datadir/$binlog --start-position=$binlog_pos + +DROP TABLE t1,t2; + diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 8424b4477c3..0971d4fdaaa 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -6390,6 +6390,22 @@ int THD::binlog_update_row(TABLE* table, bool is_trans, DBUG_ASSERT(is_current_stmt_binlog_format_row() && ((WSREP(this) && wsrep_emulate_bin_log) || mysql_bin_log.is_open())); + /** + Save a reference to the original read bitmaps + We will need this to restore the bitmaps at the end as + binlog_prepare_row_images() may change table->read_set. + table->read_set is used by pack_row and deep in + binlog_prepare_pending_events(). + */ + MY_BITMAP *old_read_set= table->read_set; + + /** + This will remove spurious fields required during execution but + not needed for binlogging. This is done according to the: + binlog-row-image option. + */ + binlog_prepare_row_images(table); + size_t const before_maxlen = max_row_length(table, before_record); size_t const after_maxlen = max_row_length(table, after_record); @@ -6401,9 +6417,9 @@ int THD::binlog_update_row(TABLE* table, bool is_trans, uchar *after_row= row_data.slot(1); size_t const before_size= pack_row(table, table->read_set, before_row, - before_record); + before_record); size_t const after_size= pack_row(table, table->rpl_write_set, after_row, - after_record); + after_record); /* Ensure that all events in a GTID group are in the same cache */ if (variables.option_bits & OPTION_GTID_BEGIN) @@ -6431,6 +6447,9 @@ int THD::binlog_update_row(TABLE* table, bool is_trans, int error= ev->add_row_data(before_row, before_size) || ev->add_row_data(after_row, after_size); + /* restore read set for the rest of execution */ + table->column_bitmaps_set_no_signal(old_read_set, + table->write_set); return error; } diff --git a/sql/table.cc b/sql/table.cc index ca06eee077c..31f0d255847 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -6137,6 +6137,8 @@ void TABLE::mark_columns_per_binlog_row_image() mark_columns_used_by_index_no_reset(s->primary_key, read_set); /* Only write columns that have changed */ rpl_write_set= write_set; + if (default_field) + mark_default_fields_for_write(rpl_write_set); break; default: @@ -6283,7 +6285,7 @@ bool TABLE::has_default_function(bool is_update) Add all fields that have a default function to the table write set. */ -void TABLE::mark_default_fields_for_write() +void TABLE::mark_default_fields_for_write(MY_BITMAP* bset) { Field **dfield_ptr, *dfield; enum_sql_command cmd= in_use->lex->sql_command; @@ -6294,7 +6296,7 @@ void TABLE::mark_default_fields_for_write() dfield->has_insert_default_function()) || ((sql_command_flags[cmd] & CF_UPDATES_DATA) && dfield->has_update_default_function())) - bitmap_set_bit(write_set, dfield->field_index); + bitmap_set_bit(bset, dfield->field_index); } } diff --git a/sql/table.h b/sql/table.h index 1a24d786d82..de10a966d1b 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1353,7 +1353,11 @@ public: void mark_columns_per_binlog_row_image(void); bool mark_virtual_col(Field *field); void mark_virtual_columns_for_write(bool insert_fl); - void mark_default_fields_for_write(); + void mark_default_fields_for_write(MY_BITMAP* bset); + inline void mark_default_fields_for_write() + { + mark_default_fields_for_write(write_set); + } bool has_default_function(bool is_update); inline void column_bitmaps_set(MY_BITMAP *read_set_arg, MY_BITMAP *write_set_arg) From 5d48ea7d07b481ae3930486b4b039e1454273190 Mon Sep 17 00:00:00 2001 From: Andrei Elkin Date: Fri, 27 Jul 2018 22:55:18 +0300 Subject: [PATCH 039/106] MDEV-10963 Fragmented BINLOG query The problem was originally stated in http://bugs.mysql.com/bug.php?id=82212 The size of an base64-encoded Rows_log_event exceeds its vanilla byte representation in 4/3 times. When a binlogged event size is about 1GB mysqlbinlog generates a BINLOG query that can't be send out due to its size. It is fixed with fragmenting the BINLOG argument C-string into (approximate) halves when the base64 encoded event is over 1GB size. The mysqlbinlog in such case puts out SET @binlog_fragment_0='base64-encoded-fragment_0'; SET @binlog_fragment_1='base64-encoded-fragment_1'; BINLOG @binlog_fragment_0, @binlog_fragment_1; to represent a big BINLOG. For prompt memory release BINLOG handler is made to reset the BINLOG argument user variables in the middle of processing, as if @binlog_fragment_{0,1} = NULL is assigned. Notice the 2 fragments are enough, though the client and server still may need to tweak their @@max_allowed_packet to satisfy to the fragment size (which they would have to do anyway with greater number of fragments, should that be desired). On the lower level the following changes are made: Log_event::print_base64() remains to call encoder and store the encoded data into a cache but now *without* doing any formatting. The latter is left for time when the cache is copied to an output file (e.g mysqlbinlog output). No formatting behavior is also reflected by the change in the meaning of the last argument which specifies whether to cache the encoded data. Rows_log_event::print_helper() is made to invoke a specialized fragmented cache-to-file copying function which is copy_cache_to_file_wrapped() that takes care of fragmenting also optionally wraps encoded strings (fragments) into SQL stanzas. my_b_copy_to_file() is refactored to into my_b_copy_all_to_file(). The former function is generalized to accepts more a limit argument to constraint the copying and does not reinitialize anymore the cache into reading mode. The limit does not do any effect on the fully read cache. --- client/mysqlbinlog.cc | 21 ++- include/my_sys.h | 4 +- .../suite/binlog/r/binlog_base64_flag.result | 19 ++ .../r/binlog_mysqlbinlog_row_frag.result | 24 +++ .../suite/binlog/t/binlog_base64_flag.test | 22 +++ .../binlog/t/binlog_mysqlbinlog_row_frag.test | 45 +++++ mysys/mf_iocache2.c | 59 +++--- sql/item_func.cc | 2 +- sql/item_func.h | 4 + sql/log_event.cc | 169 ++++++++++++++++-- sql/log_event.h | 13 +- sql/log_event_old.cc | 16 +- sql/sql_binlog.cc | 94 ++++++++-- sql/sql_lex.h | 4 + sql/sql_yacc.yy | 11 +- unittest/sql/mf_iocache-t.cc | 70 +++++++- 16 files changed, 510 insertions(+), 67 deletions(-) create mode 100644 mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_frag.result create mode 100644 mysql-test/suite/binlog/t/binlog_mysqlbinlog_row_frag.test diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index bc13aa6c2cc..2c05bb806a9 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -72,6 +72,7 @@ ulong mysqld_net_retry_count = 10L; ulong open_files_limit; ulong opt_binlog_rows_event_max_size; ulonglong test_flags = 0; +ulong opt_binlog_rows_event_max_encoded_size= MAX_MAX_ALLOWED_PACKET; static uint opt_protocol= 0; static FILE *result_file; static char *result_file_name= 0; @@ -813,7 +814,12 @@ write_event_header_and_base64(Log_event *ev, FILE *result_file, /* Write header and base64 output to cache */ ev->print_header(head, print_event_info, FALSE); - ev->print_base64(body, print_event_info, FALSE); + + DBUG_ASSERT(print_event_info->base64_output_mode == BASE64_OUTPUT_ALWAYS); + + ev->print_base64(body, print_event_info, + print_event_info->base64_output_mode != + BASE64_OUTPUT_DECODE_ROWS); /* Read data from cache and write to result file */ if (copy_event_cache_to_file_and_reinit(head, result_file) || @@ -852,7 +858,9 @@ static bool print_base64(PRINT_EVENT_INFO *print_event_info, Log_event *ev) return 1; } ev->print(result_file, print_event_info); - return print_event_info->head_cache.error == -1; + return + print_event_info->head_cache.error == -1 || + print_event_info->body_cache.error == -1; } @@ -1472,6 +1480,15 @@ that may lead to an endless loop.", "This value must be a multiple of 256.", &opt_binlog_rows_event_max_size, &opt_binlog_rows_event_max_size, 0, GET_ULONG, REQUIRED_ARG, UINT_MAX, 256, ULONG_MAX, 0, 256, 0}, +#ifndef DBUG_OFF + {"debug-binlog-row-event-max-encoded-size", 0, + "The maximum size of base64-encoded rows-event in one BINLOG pseudo-query " + "instance. When the computed actual size exceeds the limit " + "the BINLOG's argument string is fragmented in two.", + &opt_binlog_rows_event_max_encoded_size, + &opt_binlog_rows_event_max_encoded_size, 0, + GET_ULONG, REQUIRED_ARG, UINT_MAX/4, 256, ULONG_MAX, 0, 256, 0}, +#endif {"verify-binlog-checksum", 'c', "Verify checksum binlog events.", (uchar**) &opt_verify_binlog_checksum, (uchar**) &opt_verify_binlog_checksum, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, diff --git a/include/my_sys.h b/include/my_sys.h index 110a2ee9af3..c30580a8c06 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -602,7 +602,9 @@ static inline size_t my_b_bytes_in_cache(const IO_CACHE *info) return *info->current_end - *info->current_pos; } -int my_b_copy_to_file(IO_CACHE *cache, FILE *file); +int my_b_copy_to_file (IO_CACHE *cache, FILE *file, size_t count); +int my_b_copy_all_to_file(IO_CACHE *cache, FILE *file); + my_off_t my_b_append_tell(IO_CACHE* info); my_off_t my_b_safe_tell(IO_CACHE* info); /* picks the correct tell() */ int my_b_pread(IO_CACHE *info, uchar *Buffer, size_t Count, my_off_t pos); diff --git a/mysql-test/suite/binlog/r/binlog_base64_flag.result b/mysql-test/suite/binlog/r/binlog_base64_flag.result index d13e13c97b0..b97cf9072fa 100644 --- a/mysql-test/suite/binlog/r/binlog_base64_flag.result +++ b/mysql-test/suite/binlog/r/binlog_base64_flag.result @@ -28,6 +28,25 @@ a 1 1 3 +DELETE FROM t1 WHERE a=3; +BINLOG ' +ODdYRw8BAAAAZgAAAGoAAAABAAQANS4xLjIzLXJjLWRlYnVnLWxvZwAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAA4N1hHEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC +'; +SET @binlog_fragment_0=' +TFtYRxMBAAAAKQAAAH8BAAAAABAAAAAAAAAABHRlc3QAAnQxAAEDAAE= +TFtYRxcBAAAAIgAAAKEBAAAQABAAAAAAAAEAAf/+AwAAAA== +'; +SET @binlog_fragment_1=''; +BINLOG @binlog_fragment_0, @binlog_fragment_1; +select * from t1; +a +1 +1 +3 +SELECT @binlog_fragment_0, @binlog_fragment_1 as 'NULL','NULL'; +@binlog_fragment_0 NULL NULL +NULL NULL NULL ==== Test --base64-output=never on a binlog with row events ==== /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; diff --git a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_frag.result b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_frag.result new file mode 100644 index 00000000000..041be5ed09f --- /dev/null +++ b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_frag.result @@ -0,0 +1,24 @@ +CREATE TABLE t (a TEXT); +RESET MASTER; +INSERT INTO t SET a=repeat('a', 1024); +SELECT a from t into @a; +FLUSH LOGS; +DELETE FROM t; +FOUND /BINLOG @binlog_fragment_0, @binlog_fragment_1/ in mysqlbinlog.sql +SELECT a LIKE @a as 'true' FROM t; +true +1 +BINLOG number-of-fragments must be exactly two +BINLOG @binlog_fragment; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1 +BINLOG @binlog_fragment, @binlog_fragment, @binlog_fragment; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ' @binlog_fragment' at line 1 +SET @binlog_fragment_0='012345'; +SET @binlog_fragment_1='012345'; +BINLOG @binlog_fragment_0, @binlog_fragment_1; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use +SET @binlog_fragment_0='012345'; +BINLOG @binlog_fragment_0, @binlog_fragment_not_exist; +ERROR 42000: Incorrect argument type to variable 'binlog_fragment_not_exist' +# Cleanup +DROP TABLE t; diff --git a/mysql-test/suite/binlog/t/binlog_base64_flag.test b/mysql-test/suite/binlog/t/binlog_base64_flag.test index f8333315088..575a7307665 100644 --- a/mysql-test/suite/binlog/t/binlog_base64_flag.test +++ b/mysql-test/suite/binlog/t/binlog_base64_flag.test @@ -67,6 +67,28 @@ TFtYRxcBAAAAIgAAAKEBAAAQABAAAAAAAAEAAf/+AwAAAA== # The above line should succeed and 3 should be in the table select * from t1; +# The same as above with one-fragment BINLOG to prove +# equivalency with the fragmented BINLOG @frag_0, @frag_1. +DELETE FROM t1 WHERE a=3; +# This is a binlog statement containing a Format_description_log_event +# from the same version as the Table_map and Write_rows_log_event. +BINLOG ' +ODdYRw8BAAAAZgAAAGoAAAABAAQANS4xLjIzLXJjLWRlYnVnLWxvZwAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAA4N1hHEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC +'; + +# This is a Table_map_log_event+Write_rows_log_event corresponding to: +# INSERT INTO TABLE test.t1 VALUES (3) +SET @binlog_fragment_0=' +TFtYRxMBAAAAKQAAAH8BAAAAABAAAAAAAAAABHRlc3QAAnQxAAEDAAE= +TFtYRxcBAAAAIgAAAKEBAAAQABAAAAAAAAEAAf/+AwAAAA== +'; +SET @binlog_fragment_1=''; +BINLOG @binlog_fragment_0, @binlog_fragment_1; +# The above line should succeed and 3 should be in the table: +select * from t1; +# show "one-shot" feature of binlog_fragment variables +SELECT @binlog_fragment_0, @binlog_fragment_1 as 'NULL','NULL'; # Test that mysqlbinlog stops with an error message when the # --base64-output=never flag is used on a binlog with base64 events. diff --git a/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row_frag.test b/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row_frag.test new file mode 100644 index 00000000000..f0317ef1219 --- /dev/null +++ b/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row_frag.test @@ -0,0 +1,45 @@ +--source include/have_debug.inc +--source include/have_binlog_format_row.inc + +--let $MYSQLD_DATADIR= `select @@datadir` + +CREATE TABLE t (a TEXT); +# events of interest are guaranteed to stay in 000001 log +RESET MASTER; +--eval INSERT INTO t SET a=repeat('a', 1024) +SELECT a from t into @a; +FLUSH LOGS; +DELETE FROM t; + +--exec $MYSQL_BINLOG --debug-binlog-row-event-max-encoded-size=256 $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog.sql + +--let SEARCH_PATTERN= BINLOG @binlog_fragment_0, @binlog_fragment_1 +--let SEARCH_FILE= $MYSQLTEST_VARDIR/tmp/mysqlbinlog.sql +--source include/search_pattern_in_file.inc + +--exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/mysqlbinlog.sql + +SELECT a LIKE @a as 'true' FROM t; + +# improper syntax error +--echo BINLOG number-of-fragments must be exactly two +--error ER_PARSE_ERROR +BINLOG @binlog_fragment; +--error ER_PARSE_ERROR +BINLOG @binlog_fragment, @binlog_fragment, @binlog_fragment; + +# corrupted fragments error check (to the expected error code notice, +# the same error code occurs in a similar unfragmented case) +SET @binlog_fragment_0='012345'; +SET @binlog_fragment_1='012345'; +--error ER_SYNTAX_ERROR +BINLOG @binlog_fragment_0, @binlog_fragment_1; + +# Not existing fragment is not allowed +SET @binlog_fragment_0='012345'; +--error ER_WRONG_TYPE_FOR_VAR +BINLOG @binlog_fragment_0, @binlog_fragment_not_exist; + +--echo # Cleanup +--remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog.sql +DROP TABLE t; diff --git a/mysys/mf_iocache2.c b/mysys/mf_iocache2.c index fa3b6e672d7..f3877331664 100644 --- a/mysys/mf_iocache2.c +++ b/mysys/mf_iocache2.c @@ -23,51 +23,56 @@ #include #include -/* - Copy contents of an IO_CACHE to a file. - - SYNOPSIS - my_b_copy_to_file() - cache IO_CACHE to copy from - file File to copy to - - DESCRIPTION - Copy the contents of the cache to the file. The cache will be - re-inited to a read cache and will read from the beginning of the - cache. - - If a failure to write fully occurs, the cache is only copied - partially. +/** + Copy the cache to the file. Copying can be constrained to @c count + number of bytes when the parameter is less than SIZE_T_MAX. The + cache will be optionally re-inited to a read cache and will read + from the beginning of the cache. If a failure to write fully + occurs, the cache is only copied partially. TODO - Make this function solid by handling partial reads from the cache - in a correct manner: it should be atomic. + Make this function solid by handling partial reads from the cache + in a correct manner: it should be atomic. - RETURN VALUE - 0 All OK - 1 An error occurred + @param cache IO_CACHE to copy from + @param file File to copy to + @param count the copied size or the max of the type + when the whole cache is to be copied. + @return + 0 All OK + 1 An error occurred */ int -my_b_copy_to_file(IO_CACHE *cache, FILE *file) +my_b_copy_to_file(IO_CACHE *cache, FILE *file, + size_t count) { - size_t bytes_in_cache; + size_t curr_write, bytes_in_cache; DBUG_ENTER("my_b_copy_to_file"); - /* Reinit the cache to read from the beginning of the cache */ - if (reinit_io_cache(cache, READ_CACHE, 0L, FALSE, FALSE)) - DBUG_RETURN(1); bytes_in_cache= my_b_bytes_in_cache(cache); do { - if (my_fwrite(file, cache->read_pos, bytes_in_cache, + curr_write= MY_MIN(bytes_in_cache, count); + if (my_fwrite(file, cache->read_pos, curr_write, MYF(MY_WME | MY_NABP)) == (size_t) -1) DBUG_RETURN(1); - } while ((bytes_in_cache= my_b_fill(cache))); + + cache->read_pos += curr_write; + count -= curr_write; + } while (count && (bytes_in_cache= my_b_fill(cache))); if(cache->error == -1) DBUG_RETURN(1); DBUG_RETURN(0); } +int my_b_copy_all_to_file(IO_CACHE *cache, FILE *file) +{ + DBUG_ENTER("my_b_copy_all_to_file"); + /* Reinit the cache to read from the beginning of the cache */ + if (reinit_io_cache(cache, READ_CACHE, 0L, FALSE, FALSE)) + DBUG_RETURN(1); + DBUG_RETURN(my_b_copy_to_file(cache, file, SIZE_T_MAX)); +} my_off_t my_b_append_tell(IO_CACHE* info) { diff --git a/sql/item_func.cc b/sql/item_func.cc index 8b1c7b3bc61..169eb76d802 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -4828,7 +4828,7 @@ bool Item_func_set_user_var::register_field_in_bitmap(uchar *arg) true failure */ -static bool +bool update_hash(user_var_entry *entry, bool set_null, void *ptr, uint length, Item_result type, CHARSET_INFO *cs, bool unsigned_arg) diff --git a/sql/item_func.h b/sql/item_func.h index 2c0e3a62f6a..e3eab02f213 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -2283,4 +2283,8 @@ bool eval_const_cond(COND *cond); extern bool volatile mqh_used; +bool update_hash(user_var_entry *entry, bool set_null, void *ptr, uint length, + Item_result type, CHARSET_INFO *cs, + bool unsigned_arg); + #endif /* ITEM_FUNC_INCLUDED */ diff --git a/sql/log_event.cc b/sql/log_event.cc index 883f1863ac4..1369ba2d687 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2783,9 +2783,23 @@ void free_table_map_log_event(Table_map_log_event *event) delete event; } +/** + Encode the event, optionally per 'do_print_encoded' arg store the + result into the argument cache; optionally per event_info's + 'verbose' print into the cache a verbose representation of the event. + Note, no extra wrapping is done to the being io-cached data, like + to producing a BINLOG query. It's left for a routine that extracts from + the cache. + + @param file pointer to IO_CACHE + @param print_event_info pointer to print_event_info specializing + what out of and how to print the event + @param do_print_encoded whether to store base64-encoded event + into @file. +*/ void Log_event::print_base64(IO_CACHE* file, PRINT_EVENT_INFO* print_event_info, - bool more) + bool do_print_encoded) { const uchar *ptr= (const uchar *)temp_buf; uint32 size= uint4korr(ptr + EVENT_LEN_OFFSET); @@ -2804,17 +2818,9 @@ void Log_event::print_base64(IO_CACHE* file, DBUG_ASSERT(0); } - if (print_event_info->base64_output_mode != BASE64_OUTPUT_DECODE_ROWS) - { - if (my_b_tell(file) == 0) - my_b_write_string(file, "\nBINLOG '\n"); - + if (do_print_encoded) my_b_printf(file, "%s\n", tmp_str); - if (!more) - my_b_printf(file, "'%s\n", print_event_info->delimiter); - } - if (print_event_info->verbose) { Rows_log_event *ev= NULL; @@ -4851,9 +4857,17 @@ void Start_log_event_v3::print(FILE* file, PRINT_EVENT_INFO* print_event_info) print_event_info->base64_output_mode != BASE64_OUTPUT_NEVER && !print_event_info->short_form) { - if (print_event_info->base64_output_mode != BASE64_OUTPUT_DECODE_ROWS) + /* BINLOG is matched with the delimiter below on the same level */ + bool do_print_encoded= + print_event_info->base64_output_mode != BASE64_OUTPUT_DECODE_ROWS; + if (do_print_encoded) my_b_printf(&cache, "BINLOG '\n"); - print_base64(&cache, print_event_info, FALSE); + + print_base64(&cache, print_event_info, do_print_encoded); + + if (do_print_encoded) + my_b_printf(&cache, "'%s\n", print_event_info->delimiter); + print_event_info->printed_fd_event= TRUE; } DBUG_VOID_RETURN; @@ -10491,12 +10505,128 @@ void Rows_log_event::pack_info(Protocol *protocol) #endif #ifdef MYSQL_CLIENT +/** + Print an event "body" cache to @c file possibly in two fragments. + Each fragement is optionally per @c do_wrap to produce an SQL statement. + + @param file a file to print to + @param body the "body" IO_CACHE of event + @param do_wrap whether to wrap base64-encoded strings with + SQL cover. + @param delimiter delimiter string + + The function signals on any error through setting @c body->error to -1. +*/ +void copy_cache_to_file_wrapped(FILE *file, + IO_CACHE *body, + bool do_wrap, + const char *delimiter) +{ + const char str_binlog[]= "\nBINLOG '\n"; + const char fmt_delim[]= "'%s\n"; + const char fmt_n_delim[]= "\n'%s"; + const my_off_t cache_size= my_b_tell(body); + + if (reinit_io_cache(body, READ_CACHE, 0L, FALSE, FALSE)) + { + body->error= -1; + goto end; + } + + if (!do_wrap) + { + my_b_copy_to_file(body, file, SIZE_T_MAX); + } + else if (4 + sizeof(str_binlog) + cache_size + sizeof(fmt_delim) > + opt_binlog_rows_event_max_encoded_size) + { + /* + 2 fragments can always represent near 1GB row-based + base64-encoded event as two strings each of size less than + max(max_allowed_packet). Greater number of fragments does not + save from potential need to tweak (increase) @@max_allowed_packet + before to process the fragments. So 2 is safe and enough. + + Split the big query when its packet size's estimation exceeds a + limit. The estimate includes the maximum packet header + contribution of non-compressed packet. + */ + const char fmt_frag[]= "\nSET @binlog_fragment_%d ='\n"; + + my_fprintf(file, fmt_frag, 0); + if (my_b_copy_to_file(body, file, cache_size/2 + 1)) + { + body->error= -1; + goto end; + } + my_fprintf(file, fmt_n_delim, delimiter); + + my_fprintf(file, fmt_frag, 1); + if (my_b_copy_to_file(body, file, SIZE_T_MAX)) + { + body->error= -1; + goto end; + } + my_fprintf(file, fmt_delim, delimiter); + + my_fprintf(file, "BINLOG @binlog_fragment_0, @binlog_fragment_1%s\n", + delimiter); + } + else + { + my_fprintf(file, str_binlog); + if (my_b_copy_to_file(body, file, SIZE_T_MAX)) + { + body->error= -1; + goto end; + } + my_fprintf(file, fmt_delim, delimiter); + } + reinit_io_cache(body, WRITE_CACHE, 0, FALSE, TRUE); + +end: + return; +} + +/** + The function invokes base64 encoder to run on the current + event string and store the result into two caches. + When the event ends the current statement the caches are is copied into + the argument file. + Copying is also concerned how to wrap the event, specifically to produce + a valid SQL syntax. + When the encoded data size is within max(MAX_ALLOWED_PACKET) + a regular BINLOG query is composed. Otherwise it is build as fragmented + + SET @binlog_fragment_0='...'; + SET @binlog_fragment_1='...'; + BINLOG @binlog_fragment_0, @binlog_fragment_1; + + where fragments are represented by a pair of indexed user + "one shot" variables. + + @note + If any changes made don't forget to duplicate them to + Old_rows_log_event as long as it's supported. + + @param file pointer to IO_CACHE + @param print_event_info pointer to print_event_info specializing + what out of and how to print the event + @param name the name of a table that the event operates on + + The function signals on any error of cache access through setting + that cache's @c error to -1. +*/ void Rows_log_event::print_helper(FILE *file, PRINT_EVENT_INFO *print_event_info, char const *const name) { IO_CACHE *const head= &print_event_info->head_cache; IO_CACHE *const body= &print_event_info->body_cache; + bool do_print_encoded= + print_event_info->base64_output_mode != BASE64_OUTPUT_DECODE_ROWS && + !print_event_info->short_form; + if (!print_event_info->short_form) { bool const last_stmt_event= get_flags(STMT_END_F); @@ -10504,13 +10634,18 @@ void Rows_log_event::print_helper(FILE *file, my_b_printf(head, "\t%s: table id %lu%s\n", name, m_table_id, last_stmt_event ? " flags: STMT_END_F" : ""); - print_base64(body, print_event_info, !last_stmt_event); + print_base64(body, print_event_info, do_print_encoded); } if (get_flags(STMT_END_F)) { - copy_event_cache_to_file_and_reinit(head, file); - copy_event_cache_to_file_and_reinit(body, file); + if (copy_event_cache_to_file_and_reinit(head, file)) + { + head->error= -1; + return; + } + copy_cache_to_file_wrapped(file, body, do_print_encoded, + print_event_info->delimiter); } } #endif @@ -11379,7 +11514,9 @@ void Table_map_log_event::print(FILE *file, PRINT_EVENT_INFO *print_event_info) m_dbnam, m_tblnam, m_table_id, ((m_flags & TM_BIT_HAS_TRIGGERS_F) ? " (has triggers)" : "")); - print_base64(&print_event_info->body_cache, print_event_info, TRUE); + print_base64(&print_event_info->body_cache, print_event_info, + print_event_info->base64_output_mode != + BASE64_OUTPUT_DECODE_ROWS); copy_event_cache_to_file_and_reinit(&print_event_info->head_cache, file); } } diff --git a/sql/log_event.h b/sql/log_event.h index 90900f63533..446bd8cb827 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -1157,7 +1157,7 @@ public: void print_header(IO_CACHE* file, PRINT_EVENT_INFO* print_event_info, bool is_more); void print_base64(IO_CACHE* file, PRINT_EVENT_INFO* print_event_info, - bool is_more); + bool do_print_encoded); #endif /* read_log_event() functions read an event from a binlog or relay @@ -4891,15 +4891,22 @@ public: virtual int get_data_size() { return IGNORABLE_HEADER_LEN; } }; +#ifdef MYSQL_CLIENT +void copy_cache_to_file_wrapped(FILE *file, + PRINT_EVENT_INFO *print_event_info, + IO_CACHE *body, + bool do_wrap); +#endif static inline bool copy_event_cache_to_file_and_reinit(IO_CACHE *cache, FILE *file) { - return - my_b_copy_to_file(cache, file) || + return + my_b_copy_all_to_file(cache, file) || reinit_io_cache(cache, WRITE_CACHE, 0, FALSE, TRUE); } + #ifdef MYSQL_SERVER /***************************************************************************** diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc index d2b4470bbf9..a6f2ed3f416 100644 --- a/sql/log_event_old.cc +++ b/sql/log_event_old.cc @@ -1850,12 +1850,17 @@ void Old_rows_log_event::pack_info(Protocol *protocol) #ifdef MYSQL_CLIENT +/* Method duplicates Rows_log_event's one */ void Old_rows_log_event::print_helper(FILE *file, PRINT_EVENT_INFO *print_event_info, char const *const name) { IO_CACHE *const head= &print_event_info->head_cache; IO_CACHE *const body= &print_event_info->body_cache; + bool do_print_encoded= + print_event_info->base64_output_mode != BASE64_OUTPUT_DECODE_ROWS && + !print_event_info->short_form; + if (!print_event_info->short_form) { bool const last_stmt_event= get_flags(STMT_END_F); @@ -1863,13 +1868,18 @@ void Old_rows_log_event::print_helper(FILE *file, my_b_printf(head, "\t%s: table id %lu%s\n", name, m_table_id, last_stmt_event ? " flags: STMT_END_F" : ""); - print_base64(body, print_event_info, !last_stmt_event); + print_base64(body, print_event_info, do_print_encoded); } if (get_flags(STMT_END_F)) { - copy_event_cache_to_file_and_reinit(head, file); - copy_event_cache_to_file_and_reinit(body, file); + if (copy_event_cache_to_file_and_reinit(head, file)) + { + head->error= -1; + return; + } + copy_cache_to_file_wrapped(file, body, do_print_encoded, + print_event_info->delimiter); } } #endif diff --git a/sql/sql_binlog.cc b/sql/sql_binlog.cc index 91cf038907e..2e861d00f10 100644 --- a/sql/sql_binlog.cc +++ b/sql/sql_binlog.cc @@ -28,6 +28,65 @@ // START_EVENT_V3, // Log_event_type, // Log_event + +/** + Copy fragments into the standard placeholder thd->lex->comment.str. + + Compute the size of the (still) encoded total, + allocate and then copy fragments one after another. + The size can exceed max(max_allowed_packet) which is not a + problem as no String instance is created off this char array. + + @param thd THD handle + @return + 0 at success, + -1 otherwise. +*/ +int binlog_defragment(THD *thd) +{ + user_var_entry *entry[2]; + LEX_STRING name[2]= { thd->lex->comment, thd->lex->ident }; + + /* compute the total size */ + thd->lex->comment.str= NULL; + thd->lex->comment.length= 0; + for (uint k= 0; k < 2; k++) + { + entry[k]= + (user_var_entry*) my_hash_search(&thd->user_vars, (uchar*) name[k].str, + name[k].length); + if (!entry[k] || entry[k]->type != STRING_RESULT) + { + my_error(ER_WRONG_TYPE_FOR_VAR, MYF(0), name[k].str); + return -1; + } + thd->lex->comment.length += entry[k]->length; + } + + thd->lex->comment.str= // to be freed by the caller + (char *) my_malloc(thd->lex->comment.length, MYF(MY_WME)); + if (!thd->lex->comment.str) + { + my_error(ER_OUTOFMEMORY, MYF(ME_FATALERROR), 1); + return -1; + } + + /* fragments are merged into allocated buf while the user var:s get reset */ + size_t gathered_length= 0; + for (uint k=0; k < 2; k++) + { + memcpy(thd->lex->comment.str + gathered_length, entry[k]->value, + entry[k]->length); + gathered_length += entry[k]->length; + update_hash(entry[k], true, NULL, 0, STRING_RESULT, &my_charset_bin, 0); + } + + DBUG_ASSERT(gathered_length == thd->lex->comment.length); + + return 0; +} + + /** Execute a BINLOG statement. @@ -53,14 +112,6 @@ void mysql_client_binlog_statement(THD* thd) if (check_global_access(thd, SUPER_ACL)) DBUG_VOID_RETURN; - size_t coded_len= thd->lex->comment.length; - if (!coded_len) - { - my_error(ER_SYNTAX_ERROR, MYF(0)); - DBUG_VOID_RETURN; - } - size_t decoded_len= base64_needed_decoded_length(coded_len); - /* option_bits will be changed when applying the event. But we don't expect it be changed permanently after BINLOG statement, so backup it first. @@ -81,6 +132,8 @@ void mysql_client_binlog_statement(THD* thd) int err; Relay_log_info *rli; rpl_group_info *rgi; + char *buf= NULL; + size_t coded_len= 0, decoded_len= 0; rli= thd->rli_fake; if (!rli) @@ -102,15 +155,13 @@ void mysql_client_binlog_statement(THD* thd) rgi->thd= thd; const char *error= 0; - char *buf= (char *) my_malloc(decoded_len, MYF(MY_WME)); Log_event *ev = 0; + my_bool is_fragmented= FALSE; /* Out of memory check */ - if (!(rli && - rli->relay_log.description_event_for_exec && - buf)) + if (!(rli && rli->relay_log.description_event_for_exec)) { my_error(ER_OUTOFMEMORY, MYF(ME_FATALERROR), 1); /* needed 1 bytes */ goto end; @@ -119,6 +170,23 @@ void mysql_client_binlog_statement(THD* thd) rli->sql_driver_thd= thd; rli->no_storage= TRUE; + if (unlikely(is_fragmented= thd->lex->comment.str && thd->lex->ident.str)) + if (binlog_defragment(thd)) + goto end; + + if (!(coded_len= thd->lex->comment.length)) + { + my_error(ER_SYNTAX_ERROR, MYF(0)); + goto end; + } + + decoded_len= base64_needed_decoded_length(coded_len); + if (!(buf= (char *) my_malloc(decoded_len, MYF(MY_WME)))) + { + my_error(ER_OUTOFMEMORY, MYF(ME_FATALERROR), 1); + goto end; + } + for (char const *strptr= thd->lex->comment.str ; strptr < thd->lex->comment.str + thd->lex->comment.length ; ) { @@ -272,6 +340,8 @@ void mysql_client_binlog_statement(THD* thd) my_ok(thd); end: + if (unlikely(is_fragmented)) + my_free(thd->lex->comment.str); thd->variables.option_bits= thd_options; rgi->slave_close_thread_tables(thd); my_free(buf); diff --git a/sql/sql_lex.h b/sql/sql_lex.h index f1edc809579..edc647522d3 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -2459,6 +2459,10 @@ struct LEX: public Query_tables_list String *wild; /* Wildcard in SHOW {something} LIKE 'wild'*/ sql_exchange *exchange; select_result *result; + /** + @c the two may also hold BINLOG arguments: either comment holds a + base64-char string or both represent the BINLOG fragment user variables. + */ LEX_STRING comment, ident; LEX_USER *grant_user; XID *xid; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 0b85b597baf..bfaa0a60a24 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -7950,8 +7950,17 @@ binlog_base64_event: { Lex->sql_command = SQLCOM_BINLOG_BASE64_EVENT; Lex->comment= $2; + Lex->ident.str= NULL; + Lex->ident.length= 0; } - ; + | + BINLOG_SYM '@' ident_or_text ',' '@' ident_or_text + { + Lex->sql_command = SQLCOM_BINLOG_BASE64_EVENT; + Lex->comment= $3; + Lex->ident= $6; + } + ; check_view_or_table: table_or_tables table_list opt_mi_check_type diff --git a/unittest/sql/mf_iocache-t.cc b/unittest/sql/mf_iocache-t.cc index 1eef8365074..fca5ec5014d 100644 --- a/unittest/sql/mf_iocache-t.cc +++ b/unittest/sql/mf_iocache-t.cc @@ -370,10 +370,77 @@ void mdev17133() } +void mdev10963() +{ + int res; + uint n_checks= 8; + uchar buf[1024 * 512]; + uint n_frag= sizeof(buf)/(2 * CACHE_SIZE); + FILE *file; + myf my_flags= MYF(MY_WME); + const char *file_name="cache.log"; + + memset(buf, FILL, sizeof(buf)); + diag("MDEV-10963 Fragmented BINLOG query"); + + init_io_cache_encryption(); + srand((uint) time(NULL)); + + /* copying source */ + res= open_cached_file(&info, 0, 0, CACHE_SIZE, 0); + ok(res == 0, "open_cached_file" INFO_TAIL); + res= my_b_write(&info, buf, sizeof(buf)); + + ulong total_size= my_b_tell(&info); + ok(res == 0 && total_size == sizeof(buf), "cache is written"); + + /* destination */ + file= my_fopen(file_name, O_RDWR | O_TRUNC | O_CREAT, my_flags); + ok(my_fileno(file) > 0, "opened file fd = %d", my_fileno(file)); + + /* + For n_checks times verify a sequence of copying with random fragment + size ranging from zero to about the double of the cache read buffer size. + */ + for (; n_checks; n_checks--, rewind(file)) + { + // copied size is an estimate can be incremeneted to greater than total_size + ulong copied_size= 0; + + res= reinit_io_cache(&info, READ_CACHE, 0L, FALSE, FALSE); + ok(res == 0, "cache turned to read"); + + for (ulong i= 0, curr_size= 0; i < n_frag; i++, copied_size += curr_size) + { + curr_size= rand() % (2 * (total_size - copied_size) / (n_frag - i)); + + DBUG_ASSERT(curr_size <= total_size - copied_size || i == n_frag - 1); + + res= my_b_copy_to_file(&info, file, curr_size); + ok(res == 0, "%lu of the cache copied to file", curr_size); + } + /* + Regardless of total_size <> copied_size the function succeeds: + when total_size < copied_size the huge overflowed value of the last + argument is ignored because nothing already left uncopied in the cache. + */ + res= my_b_copy_to_file(&info, file, total_size - copied_size); + ok(res == 0, "%lu of the cache copied to file", total_size - copied_size); + ok(my_ftell(file, my_flags) == sizeof(buf), + "file written in %d fragments", n_frag+1); + + res= reinit_io_cache(&info, WRITE_CACHE, total_size, 0, 0); + ok(res == 0 && my_b_tell(&info) == sizeof(buf), "cache turned to write"); + } + close_cached_file(&info); + my_fclose(file, my_flags); + my_delete(file_name, MYF(MY_WME)); +} + int main(int argc __attribute__((unused)),char *argv[]) { MY_INIT(argv[0]); - plan(114); + plan(277); /* temp files with and without encryption */ encrypt_tmp_files= 1; @@ -391,6 +458,7 @@ int main(int argc __attribute__((unused)),char *argv[]) mdev14014(); mdev17133(); + mdev10963(); my_end(0); return exit_status(); From 013186eb968b4d8d0db661a6821c74193d40f43a Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 24 Jan 2019 10:51:40 +0100 Subject: [PATCH 040/106] compiler warning --- sql/log_event.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/log_event.cc b/sql/log_event.cc index 22638a1a44c..4a49a1ef740 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -11102,7 +11102,7 @@ int Table_map_log_event::do_apply_event(rpl_group_info *rgi) table_list->updating= 1; table_list->required_type= FRMTYPE_TABLE; - DBUG_PRINT("debug", ("table: %s is mapped to %u", table_list->table_name, + DBUG_PRINT("debug", ("table: %s is mapped to %llu", table_list->table_name, table_list->table_id)); #ifdef RBR_TRIGGERS table_list->master_had_triggers= ((m_flags & TM_BIT_HAS_TRIGGERS_F) ? 1 : 0); From 38ad46e0050939b0c4882eb0a339c84c4db8beb0 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 24 Jan 2019 13:31:05 +0100 Subject: [PATCH 041/106] cleanup: fill_alter_inplace_info remove attempts to track "candidate keys", use what was already decided in create_table_impl(). --- sql/sql_table.cc | 64 ++++++++++-------------------------------------- 1 file changed, 13 insertions(+), 51 deletions(-) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index df1ff8eaf5d..1b684cbd5db 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -5691,7 +5691,8 @@ static bool is_candidate_key(KEY *key) KEY_PART_INFO *key_part; KEY_PART_INFO *key_part_end= key->key_part + key->user_defined_key_parts; - if (!(key->flags & HA_NOSAME) || (key->flags & HA_NULL_PART_KEY)) + if (!(key->flags & HA_NOSAME) || (key->flags & HA_NULL_PART_KEY) || + (key->flags & HA_KEY_HAS_PART_KEY_SEG)) return false; for (key_part= key->key_part; key_part < key_part_end; key_part++) @@ -6157,9 +6158,7 @@ static int compare_uint(const uint *s, const uint *t) @retval false success */ -static bool fill_alter_inplace_info(THD *thd, - TABLE *table, - bool varchar, +static bool fill_alter_inplace_info(THD *thd, TABLE *table, bool varchar, Alter_inplace_info *ha_alter_info) { Field **f_ptr, *field; @@ -6167,7 +6166,6 @@ static bool fill_alter_inplace_info(THD *thd, Create_field *new_field; KEY_PART_INFO *key_part, *new_part; KEY_PART_INFO *end; - uint candidate_key_count= 0; Alter_info *alter_info= ha_alter_info->alter_info; DBUG_ENTER("fill_alter_inplace_info"); @@ -6443,8 +6441,13 @@ static bool fill_alter_inplace_info(THD *thd, Primary key index for the new table */ const KEY* const new_pk= (ha_alter_info->key_count > 0 && - is_candidate_key(ha_alter_info->key_info_buffer)) ? + (!my_strcasecmp(system_charset_info, + ha_alter_info->key_info_buffer->name, + primary_key_name) || + is_candidate_key(ha_alter_info->key_info_buffer))) ? ha_alter_info->key_info_buffer : NULL; + const KEY *const old_pk= table->s->primary_key == MAX_KEY ? NULL : + table->key_info + table->s->primary_key; DBUG_PRINT("info", ("index count old: %d new: %d", table->s->keys, ha_alter_info->key_count)); @@ -6526,8 +6529,7 @@ static bool fill_alter_inplace_info(THD *thd, (i) Old table doesn't have primary key, new table has it and vice-versa (ii) Primary key changed to another existing index */ - if ((new_key == new_pk) != - ((uint) (table_key - table->key_info) == table->s->primary_key)) + if ((new_key == new_pk) != (table_key == old_pk)) goto index_changed; continue; @@ -6581,22 +6583,6 @@ static bool fill_alter_inplace_info(THD *thd, /* Now let us calculate flags for storage engine API. */ - /* Count all existing candidate keys. */ - for (table_key= table->key_info; table_key < table_key_end; table_key++) - { - /* - Check if key is a candidate key, This key is either already primary key - or could be promoted to primary key if the original primary key is - dropped. - In MySQL one is allowed to create primary key with partial fields (i.e. - primary key which is not considered candidate). For simplicity we count - such key as a candidate key here. - */ - if (((uint) (table_key - table->key_info) == table->s->primary_key) || - is_candidate_key(table_key)) - candidate_key_count++; - } - /* Figure out what kind of indexes we are dropping. */ KEY **dropped_key; KEY **dropped_key_end= ha_alter_info->index_drop_buffer + @@ -6609,21 +6595,10 @@ static bool fill_alter_inplace_info(THD *thd, if (table_key->flags & HA_NOSAME) { - /* - Unique key. Check for PRIMARY KEY. Also see comment about primary - and candidate keys above. - */ - if ((uint) (table_key - table->key_info) == table->s->primary_key) - { + if (table_key == old_pk) ha_alter_info->handler_flags|= Alter_inplace_info::DROP_PK_INDEX; - candidate_key_count--; - } else - { ha_alter_info->handler_flags|= Alter_inplace_info::DROP_UNIQUE_INDEX; - if (is_candidate_key(table_key)) - candidate_key_count--; - } } else ha_alter_info->handler_flags|= Alter_inplace_info::DROP_INDEX; @@ -6636,23 +6611,10 @@ static bool fill_alter_inplace_info(THD *thd, if (new_key->flags & HA_NOSAME) { - bool is_pk= !my_strcasecmp(system_charset_info, new_key->name, primary_key_name); - - if ((!(new_key->flags & HA_KEY_HAS_PART_KEY_SEG) && - !(new_key->flags & HA_NULL_PART_KEY)) || - is_pk) - { - /* Candidate key or primary key! */ - if (candidate_key_count == 0 || is_pk) - ha_alter_info->handler_flags|= Alter_inplace_info::ADD_PK_INDEX; - else - ha_alter_info->handler_flags|= Alter_inplace_info::ADD_UNIQUE_INDEX; - candidate_key_count++; - } + if (new_key == new_pk) + ha_alter_info->handler_flags|= Alter_inplace_info::ADD_PK_INDEX; else - { ha_alter_info->handler_flags|= Alter_inplace_info::ADD_UNIQUE_INDEX; - } } else ha_alter_info->handler_flags|= Alter_inplace_info::ADD_INDEX; From e6fcd7230954c6111bba63e7f7201fc81e50178e Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Sun, 2 Dec 2018 00:25:05 +0100 Subject: [PATCH 042/106] Squashed commit of connect/10.0: commit 6a6a1f37798 Author: Olivier Bertrand Date: Fri Jan 4 12:31:52 2019 +0100 - Fix a few bug mainly concerning discovery and call from OEM (and prepare new table types) modified: storage/connect/tabjson.cpp modified: storage/connect/tabjson.h modified: storage/connect/tabxml.cpp modified: storage/connect/tabxml.h - Fix wrong line estimate modified: storage/connect/mysql-test/connect/r/part_table.result modified: storage/connect/mysql-test/connect/t/part_table.test commit bd7d2e912d9 Author: Olivier Bertrand Date: Tue Dec 4 23:35:09 2018 +0100 Fix wrong version number commit 4933680e7ab Author: Olivier Bertrand Date: Sun Dec 2 00:25:05 2018 +0100 - Make PlugSubAlloc to be exportable Suppress unused parameter from PlugSubSet modified: storage/connect/global.h modified: storage/connect/plugutil.cpp modified: storage/connect/jsonudf.cpp modified: storage/connect/tabjson.cpp modified: storage/connect/user_connect.cc - Fix a bug making column catalog XML tables fail modified: storage/connect/tabxml.cpp - Comment out wrong message modified: storage/connect/ha_connect.cc - Update error message when sorting an ODBC table fails modified: storage/connect/tabodbc.cpp - Add error message when gettting an address from an OEM fails. modified: storage/connect/reldef.cpp - Make some modifications useful for OEM module writting Export discovery functions for CSV, JDBC and XML Remove unuseful include from tabjson.h Move TDBXML::data_charset function from header file to source modified: storage/connect/tabfmt.h modified: storage/connect/tabjson.h modified: storage/connect/tabxml.cpp modified: storage/connect/tabxml.h - Update test result modified: storage/connect/mysql-test/connect/r/jdbc_oracle.result --- storage/connect/global.h | 6 +- storage/connect/ha_connect.cc | 4 +- storage/connect/jsonudf.cpp | 12 +- .../mysql-test/connect/r/jdbc_oracle.result | 18 +- .../connect/r/jdbc_postgresql.result | 10 +- .../mysql-test/connect/r/part_table.result | 4 +- .../mysql-test/connect/t/part_table.test | 2 +- storage/connect/plugutil.cpp | 28 +- storage/connect/reldef.cpp | 11 +- storage/connect/tabfmt.h | 2 +- storage/connect/tabjson.cpp | 52 +-- storage/connect/tabjson.h | 8 +- storage/connect/tabodbc.cpp | 305 +++++++++--------- storage/connect/tabxml.cpp | 248 ++++++++------ storage/connect/tabxml.h | 6 +- storage/connect/user_connect.cc | 4 +- 16 files changed, 398 insertions(+), 322 deletions(-) diff --git a/storage/connect/global.h b/storage/connect/global.h index 36e8a311124..dc1e149745f 100644 --- a/storage/connect/global.h +++ b/storage/connect/global.h @@ -219,11 +219,11 @@ DllExport LPCSTR PlugSetPath(LPSTR to, LPCSTR prefix, LPCSTR name, LPCSTR dir); DllExport BOOL PlugIsAbsolutePath(LPCSTR path); DllExport bool AllocSarea(PGLOBAL, uint); DllExport void FreeSarea(PGLOBAL); -DllExport BOOL PlugSubSet(PGLOBAL, void *, uint); +DllExport BOOL PlugSubSet(void *, uint); +DllExport void *PlugSubAlloc(PGLOBAL, void *, size_t); DllExport char *PlugDup(PGLOBAL g, const char *str); DllExport void *MakePtr(void *, OFFSET); DllExport void htrc(char const *fmt, ...); -//DllExport int GetTraceValue(void); DllExport uint GetTraceValue(void); #if defined(__cplusplus) @@ -233,6 +233,6 @@ DllExport uint GetTraceValue(void); /***********************************************************************/ /* Non exported routine declarations. */ /***********************************************************************/ -void *PlugSubAlloc(PGLOBAL, void *, size_t); // Does throw +//void *PlugSubAlloc(PGLOBAL, void *, size_t); // Does throw /*-------------------------- End of Global.H --------------------------*/ diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index bf890724d5e..1e826f67573 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -4191,7 +4191,7 @@ int ha_connect::rnd_pos(uchar *buf, uchar *pos) rc= rnd_next(buf); } else { PGLOBAL g = GetPlug((table) ? table->in_use : NULL, xp); - strcpy(g->Message, "Not supported by this table type"); +// strcpy(g->Message, "Not supported by this table type"); my_message(ER_ILLEGAL_HA, g->Message, MYF(0)); rc= HA_ERR_INTERNAL_ERROR; } // endif SetRecpos @@ -7307,7 +7307,7 @@ maria_declare_plugin(connect) PLUGIN_LICENSE_GPL, connect_init_func, /* Plugin Init */ connect_done_func, /* Plugin Deinit */ - 0x0107, /* version number (1.05) */ + 0x0106, /* version number (1.06) */ NULL, /* status variables */ connect_system_variables, /* system variables */ "1.06.0008", /* string version */ diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp index 26455d572b6..d5a3a840173 100644 --- a/storage/connect/jsonudf.cpp +++ b/storage/connect/jsonudf.cpp @@ -3055,7 +3055,7 @@ my_bool json_array_grp_init(UDF_INIT *initid, UDF_ARGS *args, char *message) PGLOBAL g = (PGLOBAL)initid->ptr; - PlugSubSet(g, g->Sarea, g->Sarea_Size); + PlugSubSet(g->Sarea, g->Sarea_Size); g->Activityp = (PACTIVITY)JsonNew(g, TYPE_JAR); g->N = (int)n; return false; @@ -3098,7 +3098,7 @@ void json_array_grp_clear(UDF_INIT *initid, char*, char*) { PGLOBAL g = (PGLOBAL)initid->ptr; - PlugSubSet(g, g->Sarea, g->Sarea_Size); + PlugSubSet(g->Sarea, g->Sarea_Size); g->Activityp = (PACTIVITY)JsonNew(g, TYPE_JAR); g->N = GetJsonGroupSize(); } // end of json_array_grp_clear @@ -3132,7 +3132,7 @@ my_bool json_object_grp_init(UDF_INIT *initid, UDF_ARGS *args, char *message) PGLOBAL g = (PGLOBAL)initid->ptr; - PlugSubSet(g, g->Sarea, g->Sarea_Size); + PlugSubSet(g->Sarea, g->Sarea_Size); g->Activityp = (PACTIVITY)JsonNew(g, TYPE_JOB); g->N = (int)n; return false; @@ -3169,7 +3169,7 @@ void json_object_grp_clear(UDF_INIT *initid, char*, char*) { PGLOBAL g = (PGLOBAL)initid->ptr; - PlugSubSet(g, g->Sarea, g->Sarea_Size); + PlugSubSet(g->Sarea, g->Sarea_Size); g->Activityp = (PACTIVITY)JsonNew(g, TYPE_JOB); g->N = GetJsonGroupSize(); } // end of json_object_grp_clear @@ -4418,7 +4418,7 @@ char *json_file(UDF_INIT *initid, UDF_ARGS *args, char *result, } else if (initid->const_item) g->N = 1; - PlugSubSet(g, g->Sarea, g->Sarea_Size); + PlugSubSet(g->Sarea, g->Sarea_Size); fn = MakePSZ(g, args, 0); if (args->arg_count > 1) { @@ -5662,7 +5662,7 @@ char *jbin_file(UDF_INIT *initid, UDF_ARGS *args, char *result, if (bsp && !bsp->Changed) goto fin; - PlugSubSet(g, g->Sarea, g->Sarea_Size); + PlugSubSet(g->Sarea, g->Sarea_Size); g->Xchk = NULL; fn = MakePSZ(g, args, 0); pretty = (args->arg_count > 2 && args->args[2]) ? (int)*(longlong*)args->args[2] : 3; diff --git a/storage/connect/mysql-test/connect/r/jdbc_oracle.result b/storage/connect/mysql-test/connect/r/jdbc_oracle.result index 2e36891a037..ec314c5f072 100644 --- a/storage/connect/mysql-test/connect/r/jdbc_oracle.result +++ b/storage/connect/mysql-test/connect/r/jdbc_oracle.result @@ -8,12 +8,19 @@ SELECT * FROM t2 WHERE command = 'drop table employee'; command number message drop table employee 0 Execute: java.sql.SQLSyntaxErrorException: ORA-00942: table or view does not exist +Warnings: +Warning 1105 Execute: java.sql.SQLSyntaxErrorException: ORA-00942: table or view does not exist + SELECT * FROM t2 WHERE command = 'create table employee (id int not null, name varchar(32), title char(16), salary number(8,2))'; command number message create table employee (id int not null, name varchar(32), title char(16), salary number(8,2)) 0 Affected rows +Warnings: +Warning 1105 Affected rows SELECT * FROM t2 WHERE command = "insert into employee values(4567,'Johnson', 'Engineer', 12560.50)"; command number message insert into employee values(4567,'Johnson', 'Engineer', 12560.50) 1 Affected rows +Warnings: +Warning 1105 Affected rows CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CATFUNC=tables CONNECTION='jdbc:oracle:thin:@localhost:1521:xe' OPTION_LIST='User=system,Password=manager'; @@ -27,8 +34,8 @@ OPTION_LIST='User=system,Password=manager'; SELECT * FROM t1; Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Radix Nullable Remarks NULL SYSTEM EMPLOYEE ID 3 NUMBER 38 0 0 10 0 NULL -NULL SYSTEM EMPLOYEE NAME 12 VARCHAR2 32 0 0 10 1 NULL -NULL SYSTEM EMPLOYEE TITLE 1 CHAR 16 0 0 10 1 NULL +NULL SYSTEM EMPLOYEE NAME 12 VARCHAR2 32 0 NULL 10 1 NULL +NULL SYSTEM EMPLOYEE TITLE 1 CHAR 16 0 NULL 10 1 NULL NULL SYSTEM EMPLOYEE SALARY 3 NUMBER 8 0 2 10 1 NULL DROP TABLE t1; CREATE SERVER 'oracle' FOREIGN DATA WRAPPER 'oracle.jdbc.driver.OracleDriver' OPTIONS ( @@ -52,7 +59,7 @@ Note 1105 EMPLOYEE: 1 affected rows SELECT * FROM t1; ID NAME TITLE SALARY 4567 Trump Engineer 12560.50 -6214 Clinton Retired 0.00 +6214 Clinton Retired NULL DELETE FROM t1 WHERE id = 6214; Warnings: Note 1105 EMPLOYEE: 1 affected rows @@ -63,8 +70,7 @@ DROP TABLE t1; SELECT * FROM t2 WHERE command = 'drop table employee'; command number message drop table employee 0 Affected rows +Warnings: +Warning 1105 Affected rows DROP TABLE t2; DROP SERVER 'oracle'; -SET GLOBAL connect_jvm_path=NULL; -SET GLOBAL connect_class_path=NULL; -SET GLOBAL time_zone = SYSTEM; diff --git a/storage/connect/mysql-test/connect/r/jdbc_postgresql.result b/storage/connect/mysql-test/connect/r/jdbc_postgresql.result index 7969672dd66..bec1dc8725b 100644 --- a/storage/connect/mysql-test/connect/r/jdbc_postgresql.result +++ b/storage/connect/mysql-test/connect/r/jdbc_postgresql.result @@ -1,4 +1,4 @@ -SET GLOBAL connect_class_path='C:/MariaDB-10.2/MariaDB/storage/connect/mysql-test/connect/std_data/JavaWrappers.jar;C:/Jconnectors/postgresql-42.2.1.jar'; +SET GLOBAL connect_class_path='C:/MariaDB-10.0/MariaDB/storage/connect/mysql-test/connect/std_data/JavaWrappers.jar;C:/Jconnectors/postgresql-42.2.1.jar'; CREATE TABLE t2 ( command varchar(128) not null, number int(5) not null flag=1, @@ -9,12 +9,18 @@ OPTION_LIST='Execsrc=1'; SELECT * FROM t2 WHERE command='drop table employee'; command number message drop table employee 0 Execute: org.postgresql.util.PSQLException: ERREUR: la table « employee » n'existe pas +Warnings: +Warning 1105 Execute: org.postgresql.util.PSQLException: ERREUR: la table employee n'existe pas SELECT * FROM t2 WHERE command = 'create table employee (id int not null, name varchar(32), title char(16), salary decimal(8,2))'; command number message create table employee (id int not null, name varchar(32), title char(16), salary decimal(8,2)) 0 Affected rows +Warnings: +Warning 1105 Affected rows SELECT * FROM t2 WHERE command = "insert into employee values(4567,'Johnson', 'Engineer', 12560.50)"; command number message insert into employee values(4567,'Johnson', 'Engineer', 12560.50) 1 Affected rows +Warnings: +Warning 1105 Affected rows CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CATFUNC=tables CONNECTION='jdbc:postgresql://localhost/test?user=postgres&password=tinono' OPTION_LIST='Tabtype=TABLE,Maxres=10'; @@ -63,4 +69,6 @@ DROP SERVER 'postgresql'; SELECT * FROM t2 WHERE command='drop table employee'; command number message drop table employee 0 Affected rows +Warnings: +Warning 1105 Affected rows DROP TABLE t2; diff --git a/storage/connect/mysql-test/connect/r/part_table.result b/storage/connect/mysql-test/connect/r/part_table.result index f3a556ae784..ee17a1d32b9 100644 --- a/storage/connect/mysql-test/connect/r/part_table.result +++ b/storage/connect/mysql-test/connect/r/part_table.result @@ -23,7 +23,7 @@ id msg CREATE TABLE xt3 ( id INT KEY NOT NULL, msg VARCHAR(32)) -ENGINE=CONNECT TABLE_TYPE=CSV AVG_ROW_LENGTH=10; +ENGINE=CONNECT TABLE_TYPE=CSV AVG_ROW_LENGTH=6; Warnings: Warning 1105 No file name. Table will use xt3.csv INSERT INTO xt3 VALUES(60,'sixty'),(81,'eighty one'),(72,'seventy two'); @@ -92,7 +92,7 @@ id msg EXPLAIN PARTITIONS SELECT * FROM t1 WHERE id = 81; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 3 ALL NULL NULL NULL NULL 4 Using where +1 SIMPLE t1 3 ALL NULL NULL NULL NULL 6 Using where DELETE FROM t1; Warnings: Note 1105 xt1: 4 affected rows diff --git a/storage/connect/mysql-test/connect/t/part_table.test b/storage/connect/mysql-test/connect/t/part_table.test index 5edd5766bd6..0fb2a11f0f9 100644 --- a/storage/connect/mysql-test/connect/t/part_table.test +++ b/storage/connect/mysql-test/connect/t/part_table.test @@ -22,7 +22,7 @@ SELECT * FROM xt2; CREATE TABLE xt3 ( id INT KEY NOT NULL, msg VARCHAR(32)) -ENGINE=CONNECT TABLE_TYPE=CSV AVG_ROW_LENGTH=10; +ENGINE=CONNECT TABLE_TYPE=CSV AVG_ROW_LENGTH=6; INSERT INTO xt3 VALUES(60,'sixty'),(81,'eighty one'),(72,'seventy two'); SELECT * FROM xt3; diff --git a/storage/connect/plugutil.cpp b/storage/connect/plugutil.cpp index 887527e38ab..048f00be75f 100644 --- a/storage/connect/plugutil.cpp +++ b/storage/connect/plugutil.cpp @@ -514,27 +514,31 @@ void FreeSarea(PGLOBAL g) /* Here there should be some verification done such as validity of */ /* the address and size not larger than memory size. */ /***********************************************************************/ -BOOL PlugSubSet(PGLOBAL g __attribute__((unused)), void *memp, uint size) +BOOL PlugSubSet(void *memp, uint size) { PPOOLHEADER pph = (PPOOLHEADER)memp; pph->To_Free = (OFFSET)sizeof(POOLHEADER); pph->FreeBlk = size - pph->To_Free; - return FALSE; } /* end of PlugSubSet */ +/***********************************************************************/ +/* Use it to export a function that do throwing. */ +/***********************************************************************/ +void *DoThrow(int n) +{ + throw n; +} /* end of DoThrow */ + /***********************************************************************/ /* Program for sub-allocating one item in a storage area. */ -/* Note: SubAlloc routines of OS/2 are no more used to increase the */ -/* code portability and avoid problems when a grammar compiled under */ -/* one version of OS/2 is used under another version. */ -/* The simple way things are done here is also based on the fact */ -/* that no freeing of suballocated blocks is permitted in Plug. */ +/* The simple way things are done here is based on the fact */ +/* that no freeing of suballocated blocks is permitted in CONNECT. */ /***********************************************************************/ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size) - { - PPOOLHEADER pph; /* Points on area header. */ +{ + PPOOLHEADER pph; /* Points on area header. */ if (!memp) /*******************************************************************/ @@ -559,8 +563,8 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size) if (trace(1)) htrc("PlugSubAlloc: %s\n", g->Message); - throw 1234; - } /* endif size OS32 code */ + DoThrow(1234); + } /* endif size OS32 code */ /*********************************************************************/ /* Do the suballocation the simplest way. */ @@ -574,7 +578,7 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size) memp, pph->To_Free, pph->FreeBlk); return (memp); - } /* end of PlugSubAlloc */ +} /* end of PlugSubAlloc */ /***********************************************************************/ /* Program for sub-allocating and copying a string in a storage area. */ diff --git a/storage/connect/reldef.cpp b/storage/connect/reldef.cpp index e4f169575f8..30d8063d1a6 100644 --- a/storage/connect/reldef.cpp +++ b/storage/connect/reldef.cpp @@ -522,8 +522,15 @@ PTABDEF OEMDEF::GetXdef(PGLOBAL g) // Get the function returning an instance of the external DEF class if (!(getdef = (XGETDEF)GetProcAddress((HINSTANCE)Hdll, getname))) { - sprintf(g->Message, MSG(PROCADD_ERROR), GetLastError(), getname); - FreeLibrary((HMODULE)Hdll); + char buf[256]; + DWORD rc = GetLastError(); + + sprintf(g->Message, MSG(PROCADD_ERROR), rc, getname); + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, NULL, rc, 0, + (LPTSTR)buf, sizeof(buf), NULL); + strcat(strcat(g->Message, ": "), buf); + FreeLibrary((HMODULE)Hdll); return NULL; } // endif getdef #else // !__WIN__ diff --git a/storage/connect/tabfmt.h b/storage/connect/tabfmt.h index 396bba568ff..10f0757c60b 100644 --- a/storage/connect/tabfmt.h +++ b/storage/connect/tabfmt.h @@ -13,7 +13,7 @@ typedef class TDBFMT *PTDBFMT; /***********************************************************************/ /* Functions used externally. */ /***********************************************************************/ -PQRYRES CSVColumns(PGLOBAL g, PCSZ dp, PTOS topt, bool info); +DllExport PQRYRES CSVColumns(PGLOBAL g, PCSZ dp, PTOS topt, bool info); /***********************************************************************/ /* CSV table. */ diff --git a/storage/connect/tabjson.cpp b/storage/connect/tabjson.cpp index 9e4f5ab987d..c0d36efcf42 100644 --- a/storage/connect/tabjson.cpp +++ b/storage/connect/tabjson.cpp @@ -1,6 +1,6 @@ /************* tabjson C++ Program Source Code File (.CPP) *************/ -/* PROGRAM NAME: tabjson Version 1.5 */ -/* (C) Copyright to the author Olivier BERTRAND 2014 - 2017 */ +/* PROGRAM NAME: tabjson Version 1.6 */ +/* (C) Copyright to the author Olivier BERTRAND 2014 - 2018 */ /* This program are the JSON class DB execution routines. */ /***********************************************************************/ @@ -173,6 +173,7 @@ JSONDISC::JSONDISC(PGLOBAL g, uint *lg) int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt) { + char filename[_MAX_PATH]; bool mgo = (GetTypeID(topt->type) == TAB_MONGO); PCSZ level = GetStringTableOption(g, topt, "Level", NULL); @@ -209,6 +210,12 @@ int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt) return 0; } // endif Fn + if (tdp->Fn) { + // We used the file name relative to recorded datapath + PlugSetPath(filename, tdp->Fn, tdp->GetPath()); + tdp->Fn = PlugDup(g, filename); + } // endif Fn + if (trace(1)) htrc("File %s objname=%s pretty=%d lvl=%d\n", tdp->Fn, tdp->Objname, tdp->Pretty, lvl); @@ -299,7 +306,7 @@ int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt) memset(G, 0, sizeof(GLOBAL)); G->Sarea_Size = tdp->Lrecl * 10; G->Sarea = PlugSubAlloc(g, NULL, G->Sarea_Size); - PlugSubSet(G, G->Sarea, G->Sarea_Size); + PlugSubSet(G->Sarea, G->Sarea_Size); G->jump_level = 0; tjnp->SetG(G); @@ -342,7 +349,7 @@ int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt) strncpy(colname, jpp->GetKey(), 64); fmt[bf] = 0; - if (Find(g, jpp->GetVal(), MY_MIN(lvl, 0))) + if (Find(g, jpp->GetVal(), colname, MY_MIN(lvl, 0))) goto err; } // endfor jpp @@ -385,7 +392,7 @@ err: return 0; } // end of GetColumns -bool JSONDISC::Find(PGLOBAL g, PJVAL jvp, int j) +bool JSONDISC::Find(PGLOBAL g, PJVAL jvp, PCSZ key, int j) { char *p, *pc = colname + strlen(colname); int ars; @@ -413,12 +420,14 @@ bool JSONDISC::Find(PGLOBAL g, PJVAL jvp, int j) job = (PJOB)jsp; for (PJPR jrp = job->GetFirst(); jrp; jrp = jrp->GetNext()) { - if (*jrp->GetKey() != '$') { - strncat(strncat(fmt, sep, 128), jrp->GetKey(), 128); - strncat(strncat(colname, "_", 64), jrp->GetKey(), 64); + PCSZ k = jrp->GetKey(); + + if (*k != '$') { + strncat(strncat(fmt, sep, 128), k, 128); + strncat(strncat(colname, "_", 64), k, 64); } // endif Key - if (Find(g, jrp->GetVal(), j + 1)) + if (Find(g, jrp->GetVal(), k, j + 1)) return true; *p = *pc = 0; @@ -428,13 +437,13 @@ bool JSONDISC::Find(PGLOBAL g, PJVAL jvp, int j) case TYPE_JAR: jar = (PJAR)jsp; - if (all || (tdp->Xcol && !stricmp(tdp->Xcol, colname))) + if (all || (tdp->Xcol && !stricmp(tdp->Xcol, key))) ars = jar->GetSize(false); else ars = MY_MIN(jar->GetSize(false), 1); for (int k = 0; k < ars; k++) { - if (!tdp->Xcol || stricmp(tdp->Xcol, colname)) { + if (!tdp->Xcol || stricmp(tdp->Xcol, key)) { sprintf(buf, "%d", k); if (tdp->Uri) @@ -448,7 +457,7 @@ bool JSONDISC::Find(PGLOBAL g, PJVAL jvp, int j) } else strncat(fmt, (tdp->Uri ? sep : "[*]"), 128); - if (Find(g, jar->GetValue(k), j)) + if (Find(g, jar->GetValue(k), "", j)) return true; *p = *pc = 0; @@ -522,7 +531,9 @@ void JSONDISC::AddColumn(PGLOBAL g) n++; } // endif jcp - pjcp = jcp; + if (jcp) + pjcp = jcp; + } // end of AddColumn @@ -549,7 +560,7 @@ JSONDEF::JSONDEF(void) /***********************************************************************/ /* DefineAM: define specific AM block values. */ /***********************************************************************/ -bool JSONDEF::DefineAM(PGLOBAL g, LPCSTR, int poff) +bool JSONDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) { Schema = GetStringCatInfo(g, "DBname", Schema); Jmode = (JMODE)GetIntCatInfo("Jmode", MODE_OBJECT); @@ -561,7 +572,8 @@ bool JSONDEF::DefineAM(PGLOBAL g, LPCSTR, int poff) Sep = *GetStringCatInfo(g, "Separator", "."); Accept = GetBoolCatInfo("Accept", false); - if (Uri = GetStringCatInfo(g, "Connect", NULL)) { + // Don't use url as uri when called from REST OEM module + if (stricmp(am, "REST") && (Uri = GetStringCatInfo(g, "Connect", NULL))) { #if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT) Collname = GetStringCatInfo(g, "Name", (Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name); @@ -670,7 +682,7 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m) memset(G, 0, sizeof(GLOBAL)); G->Sarea_Size = Lrecl * 10; G->Sarea = PlugSubAlloc(g, NULL, G->Sarea_Size); - PlugSubSet(G, G->Sarea, G->Sarea_Size); + PlugSubSet(G->Sarea, G->Sarea_Size); G->jump_level = 0; ((TDBJSN*)tdbp)->G = G; } else { @@ -963,7 +975,7 @@ int TDBJSN::ReadDB(PGLOBAL g) return rc; // Recover the memory used for parsing - PlugSubSet(G, G->Sarea, G->Sarea_Size); + PlugSubSet(G->Sarea, G->Sarea_Size); if ((Row = ParseJson(G, To_Line, strlen(To_Line), &Pretty, &Comma))) { Row = FindRow(g); @@ -1079,13 +1091,13 @@ int TDBJSN::MakeTopTree(PGLOBAL g, PJSON jsp) } // end of PrepareWriting /***********************************************************************/ -/* WriteDB: Data Base write routine for DOS access method. */ +/* WriteDB: Data Base write routine for JSON access method. */ /***********************************************************************/ int TDBJSN::WriteDB(PGLOBAL g) { int rc = TDBDOS::WriteDB(g); - PlugSubSet(G, G->Sarea, G->Sarea_Size); + PlugSubSet(G->Sarea, G->Sarea_Size); Row->Clear(); return rc; } // end of WriteDB @@ -2340,7 +2352,7 @@ void TDBJSON::CloseDB(PGLOBAL g) TDBJCL::TDBJCL(PJDEF tdp) : TDBCAT(tdp) { Topt = tdp->GetTopt(); - Db = tdp->Schema; + Db = tdp->Schema; Dsn = tdp->Uri; } // end of TDBJCL constructor diff --git a/storage/connect/tabjson.h b/storage/connect/tabjson.h index 2ff72905e86..8721a2a5ab7 100644 --- a/storage/connect/tabjson.h +++ b/storage/connect/tabjson.h @@ -1,11 +1,11 @@ /*************** tabjson H Declares Source Code File (.H) **************/ /* Name: tabjson.h Version 1.3 */ /* */ -/* (C) Copyright to the author Olivier BERTRAND 2014 - 2017 */ +/* (C) Copyright to the author Olivier BERTRAND 2014 - 2018 */ /* */ /* This file contains the JSON classes declares. */ /***********************************************************************/ -#include "osutil.h" +//#include "osutil.h" // Unuseful and bad for OEM #include "block.h" #include "colblk.h" #include "json.h" @@ -16,7 +16,7 @@ typedef class JSONDEF *PJDEF; typedef class TDBJSON *PJTDB; typedef class JSONCOL *PJCOL; class TDBJSN; -PQRYRES JSONColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt, bool info); +DllExport PQRYRES JSONColumns(PGLOBAL, PCSZ, PCSZ, PTOS, bool); /***********************************************************************/ /* The JSON tree node. Can be an Object or an Array. */ @@ -52,7 +52,7 @@ public: // Functions int GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt); - bool Find(PGLOBAL g, PJVAL jvp, int j); + bool Find(PGLOBAL g, PJVAL jvp, PCSZ key, int j); void AddColumn(PGLOBAL g); // Members diff --git a/storage/connect/tabodbc.cpp b/storage/connect/tabodbc.cpp index fddfb0c0420..0fa117c3d2f 100644 --- a/storage/connect/tabodbc.cpp +++ b/storage/connect/tabodbc.cpp @@ -5,7 +5,7 @@ /* */ /* COPYRIGHT: */ /* ---------- */ -/* (C) Copyright to the author Olivier BERTRAND 2000-2017 */ +/* (C) Copyright to the author Olivier BERTRAND 2000-2018 */ /* */ /* WHAT THIS PROGRAM DOES: */ /* ----------------------- */ @@ -95,23 +95,23 @@ bool ExactInfo(void); /* Constructor. */ /***********************************************************************/ ODBCDEF::ODBCDEF(void) - { +{ Connect = NULL; Catver = 0; UseCnc = false; - } // end of ODBCDEF constructor +} // end of ODBCDEF constructor /***********************************************************************/ /* DefineAM: define specific AM block values from XDB file. */ /***********************************************************************/ bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) - { +{ Desc = Connect = GetStringCatInfo(g, "Connect", NULL); if (!Connect && !Catfunc) { sprintf(g->Message, "Missing connection for ODBC table %s", Name); return true; - } // endif Connect + } // endif Connect if (EXTDEF::DefineAM(g, am, poff)) return true; @@ -123,13 +123,13 @@ bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) Qto= GetIntCatInfo("QueryTimeout", DEFAULT_QUERY_TIMEOUT); UseCnc = GetBoolCatInfo("UseDSN", false); return false; - } // end of DefineAM +} // end of DefineAM /***********************************************************************/ /* GetTable: makes a new Table Description Block. */ /***********************************************************************/ PTDB ODBCDEF::GetTable(PGLOBAL g, MODE m) - { +{ PTDB tdbp = NULL; /*********************************************************************/ @@ -158,10 +158,10 @@ PTDB ODBCDEF::GetTable(PGLOBAL g, MODE m) tdbp = new(g) TDBMUL(tdbp); else if (Multiple == 2) strcpy(g->Message, MSG(NO_ODBC_MUL)); - } // endswitch Catfunc + } // endswitch Catfunc return tdbp; - } // end of GetTable +} // end of GetTable /* -------------------------- Class TDBODBC -------------------------- */ @@ -169,7 +169,7 @@ PTDB ODBCDEF::GetTable(PGLOBAL g, MODE m) /* Implementation of the TDBODBC class. */ /***********************************************************************/ TDBODBC::TDBODBC(PODEF tdp) : TDBEXT(tdp) - { +{ Ocp = NULL; Cnp = NULL; @@ -191,19 +191,19 @@ TDBODBC::TDBODBC(PODEF tdp) : TDBEXT(tdp) Ops.UseCnc = false; } // endif tdp - } // end of TDBODBC standard constructor +} // end of TDBODBC standard constructor TDBODBC::TDBODBC(PTDBODBC tdbp) : TDBEXT(tdbp) - { +{ Ocp = tdbp->Ocp; // is that right ? Cnp = tdbp->Cnp; Connect = tdbp->Connect; Ops = tdbp->Ops; - } // end of TDBODBC copy constructor +} // end of TDBODBC copy constructor // Method PTDB TDBODBC::Clone(PTABS t) - { +{ PTDB tp; PODBCCOL cp1, cp2; PGLOBAL g = t->G; // Is this really useful ??? @@ -213,18 +213,18 @@ PTDB TDBODBC::Clone(PTABS t) for (cp1 = (PODBCCOL)Columns; cp1; cp1 = (PODBCCOL)cp1->GetNext()) { cp2 = new(g) ODBCCOL(cp1, tp); // Make a copy NewPointer(t, cp1, cp2); - } // endfor cp1 + } // endfor cp1 return tp; - } // end of CopyOne +} // end of CopyOne /***********************************************************************/ /* Allocate ODBC column description block. */ /***********************************************************************/ PCOL TDBODBC::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n) - { +{ return new(g) ODBCCOL(cdp, this, cprec, n); - } // end of MakeCol +} // end of MakeCol /***********************************************************************/ /* Extract the filename from connect string and return it. */ @@ -232,7 +232,7 @@ PCOL TDBODBC::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n) /* with a place holder to be used by SetFile. */ /***********************************************************************/ PCSZ TDBODBC::GetFile(PGLOBAL g) - { +{ if (Connect) { char *p1, *p2; int i; @@ -263,18 +263,18 @@ PCSZ TDBODBC::GetFile(PGLOBAL g) memcpy(MulConn, Connect, p1 - Connect); MulConn[p1 - Connect] = '\0'; strcat(strcat(MulConn, "%s"), (p2) ? p2 : ";"); - } // endif p1 + } // endif p1 - } // endif Connect + } // endif Connect return (DBQ) ? DBQ : (PSZ)"???"; - } // end of GetFile +} // end of GetFile /***********************************************************************/ /* Set DBQ and get the new file name into the connect string. */ /***********************************************************************/ void TDBODBC::SetFile(PGLOBAL g, PCSZ fn) - { +{ if (MulConn) { int n = strlen(MulConn) + strlen(fn) - 1; @@ -283,20 +283,20 @@ void TDBODBC::SetFile(PGLOBAL g, PCSZ fn) // of having to reallocate it is reduced. BufSize = n + 6; Connect = (char*)PlugSubAlloc(g, NULL, BufSize); - } // endif n + } // endif n // Make the complete connect string sprintf(Connect, MulConn, fn); - } // endif MultConn + } // endif MultConn DBQ = PlugDup(g, fn); - } // end of SetFile +} // end of SetFile /***********************************************************************/ /* MakeInsert: make the Insert statement used with ODBC connection. */ /***********************************************************************/ bool TDBODBC::MakeInsert(PGLOBAL g) - { +{ PCSZ schmp = NULL; char *catp = NULL, buf[NAM_LEN * 3]; int len = 0; @@ -377,7 +377,7 @@ bool TDBODBC::MakeInsert(PGLOBAL g) } else Query->Append(buf); - } // endfor colp + } // endfor colp Query->Append(") VALUES ("); @@ -390,32 +390,32 @@ bool TDBODBC::MakeInsert(PGLOBAL g) Query->RepLast(')'); return oom; - } // end of MakeInsert +} // end of MakeInsert /***********************************************************************/ /* ODBC Bind Parameter function. */ /***********************************************************************/ bool TDBODBC::BindParameters(PGLOBAL g) - { - PODBCCOL colp; +{ + PODBCCOL colp; - for (colp = (PODBCCOL)Columns; colp; colp = (PODBCCOL)colp->Next) { - colp->AllocateBuffers(g, 0); + for (colp = (PODBCCOL)Columns; colp; colp = (PODBCCOL)colp->Next) { + colp->AllocateBuffers(g, 0); - if (Ocp->BindParam(colp)) - return true; + if (Ocp->BindParam(colp)) + return true; - } // endfor colp + } // endfor colp - return false; - } // end of BindParameters + return false; +} // end of BindParameters #if 0 /***********************************************************************/ /* MakeUpdate: make the SQL statement to send to ODBC connection. */ /***********************************************************************/ char *TDBODBC::MakeUpdate(PGLOBAL g) - { +{ char *qc, *stmt = NULL, cmd[8], tab[96], end[1024]; stmt = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 64); @@ -440,60 +440,60 @@ char *TDBODBC::MakeUpdate(PGLOBAL g) strcat(stmt, end); return stmt; - } // end of MakeUpdate +} // end of MakeUpdate /***********************************************************************/ /* MakeDelete: make the SQL statement to send to ODBC connection. */ /***********************************************************************/ char *TDBODBC::MakeDelete(PGLOBAL g) - { - char *qc, *stmt = NULL, cmd[8], from[8], tab[96], end[512]; +{ + char *qc, *stmt = NULL, cmd[8], from[8], tab[96], end[512]; - stmt = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 64); - memset(end, 0, sizeof(end)); + stmt = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 64); + memset(end, 0, sizeof(end)); - if (sscanf(Qrystr, "%s %s `%[^`]`%511c", cmd, from, tab, end) > 2 || - sscanf(Qrystr, "%s %s \"%[^\"]\"%511c", cmd, from, tab, end) > 2) - qc = Ocp->GetQuoteChar(); - else if (sscanf(Qrystr, "%s %s %s%511c", cmd, from, tab, end) > 2) - qc = (Quoted) ? Quote : ""; - else { - strcpy(g->Message, "Cannot use this DELETE command"); - return NULL; - } // endif sscanf + if (sscanf(Qrystr, "%s %s `%[^`]`%511c", cmd, from, tab, end) > 2 || + sscanf(Qrystr, "%s %s \"%[^\"]\"%511c", cmd, from, tab, end) > 2) + qc = Ocp->GetQuoteChar(); + else if (sscanf(Qrystr, "%s %s %s%511c", cmd, from, tab, end) > 2) + qc = (Quoted) ? Quote : ""; + else { + strcpy(g->Message, "Cannot use this DELETE command"); + return NULL; + } // endif sscanf - assert(!stricmp(cmd, "delete") && !stricmp(from, "from")); - strcat(strcat(strcat(strcpy(stmt, "DELETE FROM "), qc), TableName), qc); + assert(!stricmp(cmd, "delete") && !stricmp(from, "from")); + strcat(strcat(strcat(strcpy(stmt, "DELETE FROM "), qc), TableName), qc); - if (*end) { - for (int i = 0; end[i]; i++) - if (end[i] == '`') - end[i] = *qc; + if (*end) { + for (int i = 0; end[i]; i++) + if (end[i] == '`') + end[i] = *qc; - strcat(stmt, end); - } // endif end + strcat(stmt, end); + } // endif end - return stmt; - } // end of MakeDelete + return stmt; +} // end of MakeDelete #endif // 0 /***********************************************************************/ /* ResetSize: call by TDBMUL when calculating size estimate. */ /***********************************************************************/ void TDBODBC::ResetSize(void) - { +{ MaxSize = -1; if (Ocp && Ocp->IsOpen()) Ocp->Close(); - } // end of ResetSize +} // end of ResetSize /***********************************************************************/ /* ODBC Cardinality: returns table size in number of rows. */ /***********************************************************************/ int TDBODBC::Cardinality(PGLOBAL g) - { +{ if (!g) return (Mode == MODE_ANY && !Srcdef) ? 1 : 0; @@ -526,7 +526,7 @@ int TDBODBC::Cardinality(PGLOBAL g) Cardinal = 10; // To make MySQL happy return Cardinal; - } // end of Cardinality +} // end of Cardinality /***********************************************************************/ /* ODBC Access Method opening routine. */ @@ -535,7 +535,7 @@ int TDBODBC::Cardinality(PGLOBAL g) /* join block of next table if it exists or else are discarted. */ /***********************************************************************/ bool TDBODBC::OpenDB(PGLOBAL g) - { +{ bool rc = true; if (trace(1)) @@ -571,7 +571,7 @@ bool TDBODBC::OpenDB(PGLOBAL g) Fpos = 0; Curpos = 1; return false; - } // endif use + } // endif use /*********************************************************************/ /* Open an ODBC connection for this table. */ @@ -593,7 +593,7 @@ bool TDBODBC::OpenDB(PGLOBAL g) Use = USE_OPEN; // Do it now in case we are recursively called /*********************************************************************/ - /* Make the command and allocate whatever is used for getting results. */ + /* Make the command and allocate whatever is used for getting results*/ /*********************************************************************/ if (Mode == MODE_READ || Mode == MODE_READX) { if (Memory > 1 && !Srcdef) { @@ -624,7 +624,7 @@ bool TDBODBC::OpenDB(PGLOBAL g) } else return true; - } // endif Memory + } // endif Memory if (!(rc = MakeSQL(g, false))) { for (PODBCCOL colp = (PODBCCOL)Columns; colp; @@ -635,7 +635,7 @@ bool TDBODBC::OpenDB(PGLOBAL g) rc = (Mode == MODE_READ) ? ((Rows = Ocp->ExecDirectSQL(Query->GetStr(), (PODBCCOL)Columns)) < 0) : false; - } // endif rc + } // endif rc } else if (Mode == MODE_INSERT) { if (!(rc = MakeInsert(g))) { @@ -645,7 +645,7 @@ bool TDBODBC::OpenDB(PGLOBAL g) } else rc = BindParameters(g); - } // endif rc + } // endif rc } else if (Mode == MODE_UPDATE || Mode == MODE_DELETE) { rc = false; // wait for CheckCond before calling MakeCommand(g); @@ -655,30 +655,30 @@ bool TDBODBC::OpenDB(PGLOBAL g) if (rc) { Ocp->Close(); return true; - } // endif rc + } // endif rc /*********************************************************************/ /* Reset statistics values. */ /*********************************************************************/ num_read = num_there = num_eq[0] = num_eq[1] = 0; return false; - } // end of OpenDB +} // end of OpenDB #if 0 /***********************************************************************/ /* GetRecpos: return the position of last read record. */ /***********************************************************************/ int TDBODBC::GetRecpos(void) - { +{ return Fpos; - } // end of GetRecpos +} // end of GetRecpos #endif // 0 /***********************************************************************/ /* SetRecpos: set the position of next read record. */ /***********************************************************************/ bool TDBODBC::SetRecpos(PGLOBAL g, int recpos) - { +{ if (Ocp->m_Full) { Fpos = 0; CurNum = recpos - 1; @@ -696,14 +696,15 @@ bool TDBODBC::SetRecpos(PGLOBAL g, int recpos) } // endif recpos } else { - strcpy(g->Message, "This action requires a scrollable cursor"); + strcpy(g->Message, + "This action requires Memory setting or a scrollable cursor"); return true; } // endif's // Indicate the table position was externally set Placed = true; return false; - } // end of SetRecpos +} // end of SetRecpos /***********************************************************************/ /* Data Base indexed read routine for ODBC access method. */ @@ -721,7 +722,7 @@ bool TDBODBC::ReadKey(PGLOBAL g, OPVAL op, const key_range *kr) Rows = Ocp->ExecDirectSQL((char*)Query->GetStr(), (PODBCCOL)Columns); Mode = MODE_READ; return (Rows < 0); - } // endif key + } // endif key return false; } else { @@ -737,7 +738,7 @@ bool TDBODBC::ReadKey(PGLOBAL g, OPVAL op, const key_range *kr) if ((To_CondFil = hc->CheckCond(g, To_CondFil, Cond))) PlugSubAlloc(g, NULL, strlen(To_CondFil->Body) + 1); - } // endif active_index + } // endif active_index if (To_CondFil) if (Query->Append(" AND ") || Query->Append(To_CondFil->Body)) { @@ -762,7 +763,7 @@ bool TDBODBC::ReadKey(PGLOBAL g, OPVAL op, const key_range *kr) /* VRDNDOS: Data Base read routine for odbc access method. */ /***********************************************************************/ int TDBODBC::ReadDB(PGLOBAL g) - { +{ int rc; if (trace(2)) @@ -784,7 +785,7 @@ int TDBODBC::ReadDB(PGLOBAL g) } else return RC_FX; // Error - } // endif Mode + } // endif Mode /*********************************************************************/ /* Now start the reading process. */ @@ -813,7 +814,7 @@ int TDBODBC::ReadDB(PGLOBAL g) Qrp->Nblin++; Fpos++; // Used for memory and pos - } // endif rc + } // endif rc } // endif Placed @@ -821,13 +822,13 @@ int TDBODBC::ReadDB(PGLOBAL g) htrc(" Read: Rbuf=%d rc=%d\n", Rbuf, rc); return rc; - } // end of ReadDB +} // end of ReadDB /***********************************************************************/ /* Data Base Insert write routine for ODBC access method. */ /***********************************************************************/ int TDBODBC::WriteDB(PGLOBAL g) - { +{ int n = Ocp->ExecuteSQL(); if (n < 0) { @@ -837,13 +838,13 @@ int TDBODBC::WriteDB(PGLOBAL g) AftRows += n; return RC_OK; - } // end of WriteDB +} // end of WriteDB /***********************************************************************/ /* Data Base delete line routine for ODBC access method. */ /***********************************************************************/ int TDBODBC::DeleteDB(PGLOBAL g, int irc) - { +{ if (irc == RC_FX) { if (!Query && MakeCommand(g)) return RC_FX; @@ -863,13 +864,13 @@ int TDBODBC::DeleteDB(PGLOBAL g, int irc) } else return RC_OK; // Ignore - } // end of DeleteDB +} // end of DeleteDB /***********************************************************************/ /* Data Base close routine for ODBC access method. */ /***********************************************************************/ void TDBODBC::CloseDB(PGLOBAL g) - { +{ if (Ocp) Ocp->Close(); @@ -877,7 +878,7 @@ void TDBODBC::CloseDB(PGLOBAL g) if (trace(1)) htrc("ODBC CloseDB: closing %s\n", Name); - } // end of CloseDB +} // end of CloseDB /* --------------------------- ODBCCOL ------------------------------- */ @@ -886,33 +887,33 @@ void TDBODBC::CloseDB(PGLOBAL g) /***********************************************************************/ ODBCCOL::ODBCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am) : EXTCOL(cdp, tdbp, cprec, i, am) - { +{ // Set additional ODBC access method information for column. Slen = 0; StrLen = &Slen; Sqlbuf = NULL; - } // end of ODBCCOL constructor +} // end of ODBCCOL constructor /***********************************************************************/ /* ODBCCOL private constructor. */ /***********************************************************************/ ODBCCOL::ODBCCOL(void) : EXTCOL() - { +{ Slen = 0; StrLen = &Slen; Sqlbuf = NULL; - } // end of ODBCCOL constructor +} // end of ODBCCOL constructor /***********************************************************************/ /* ODBCCOL constructor used for copying columns. */ /* tdbp is the pointer to the new table descriptor. */ /***********************************************************************/ ODBCCOL::ODBCCOL(ODBCCOL *col1, PTDB tdbp) : EXTCOL(col1, tdbp) - { +{ Slen = col1->Slen; StrLen = col1->StrLen; Sqlbuf = col1->Sqlbuf; - } // end of ODBCCOL copy constructor +} // end of ODBCCOL copy constructor /***********************************************************************/ /* ReadColumn: when SQLFetch is used there is nothing to do as the */ @@ -920,7 +921,7 @@ ODBCCOL::ODBCCOL(ODBCCOL *col1, PTDB tdbp) : EXTCOL(col1, tdbp) /* when calculating MaxSize (Bufp is NULL even when Rows is not). */ /***********************************************************************/ void ODBCCOL::ReadColumn(PGLOBAL g) - { +{ PTDBODBC tdbp = (PTDBODBC)To_Tdb; int i = tdbp->Fpos - 1, n = tdbp->CurNum; @@ -953,7 +954,7 @@ void ODBCCOL::ReadColumn(PGLOBAL g) else Value->SetValue_pvblk(Blkp, n); - } // endif Bufp + } // endif Bufp if (Buf_Type == TYPE_DATE) { struct tm dbtime; @@ -980,7 +981,7 @@ void ODBCCOL::ReadColumn(PGLOBAL g) htrc("ODBC Column %s: rows=%d buf=%p type=%d value=%s\n", Name, tdbp->Rows, Bufp, Buf_Type, Value->GetCharString(buf)); - } // endif trace + } // endif trace put: if (tdbp->Memory != 2) @@ -997,7 +998,7 @@ void ODBCCOL::ReadColumn(PGLOBAL g) } else Crp->Kdata->SetValue(Value, i); - } // end of ReadColumn +} // end of ReadColumn /***********************************************************************/ /* AllocateBuffers: allocate the extended buffer for SQLExtendedFetch */ @@ -1005,7 +1006,7 @@ void ODBCCOL::ReadColumn(PGLOBAL g) /* for the ending null character. */ /***********************************************************************/ void ODBCCOL::AllocateBuffers(PGLOBAL g, int rows) - { +{ if (Buf_Type == TYPE_DATE) Sqlbuf = (TIMESTAMP_STRUCT*)PlugSubAlloc(g, NULL, sizeof(TIMESTAMP_STRUCT)); @@ -1019,31 +1020,31 @@ void ODBCCOL::AllocateBuffers(PGLOBAL g, int rows) Blkp = AllocValBlock(g, NULL, Buf_Type, rows, GetBuflen(), GetScale(), true, false, false); Bufp = Blkp->GetValPointer(); - } // endelse + } // endelse if (rows > 1) StrLen = (SQLLEN *)PlugSubAlloc(g, NULL, rows * sizeof(SQLLEN)); - } // end of AllocateBuffers +} // end of AllocateBuffers /***********************************************************************/ /* Returns the buffer to use for Fetch or Extended Fetch. */ /***********************************************************************/ void *ODBCCOL::GetBuffer(DWORD rows) - { +{ if (rows && To_Tdb) { assert(rows == (DWORD)((TDBODBC*)To_Tdb)->Rows); return Bufp; } else return (Buf_Type == TYPE_DATE) ? Sqlbuf : Value->GetTo_Val(); - } // end of GetBuffer +} // end of GetBuffer /***********************************************************************/ /* Returns the buffer length to use for Fetch or Extended Fetch. */ /***********************************************************************/ SWORD ODBCCOL::GetBuflen(void) - { +{ SWORD flen; switch (Buf_Type) { @@ -1059,13 +1060,13 @@ SWORD ODBCCOL::GetBuflen(void) } // endswitch Buf_Type return flen; - } // end of GetBuflen +} // end of GetBuflen /***********************************************************************/ /* WriteColumn: make sure the bind buffer is updated. */ /***********************************************************************/ void ODBCCOL::WriteColumn(PGLOBAL g) - { +{ /*********************************************************************/ /* Do convert the column value if necessary. */ /*********************************************************************/ @@ -1095,7 +1096,7 @@ void ODBCCOL::WriteColumn(PGLOBAL g) *StrLen = (Value->IsNull()) ? SQL_NULL_DATA : (IsTypeChar(Buf_Type)) ? SQL_NTS : 0; - } // end of WriteColumn +} // end of WriteColumn /* -------------------------- Class TDBXDBC -------------------------- */ @@ -1119,7 +1120,7 @@ TDBXDBC::TDBXDBC(PTDBXDBC tdbp) : TDBODBC(tdbp) } // end of TDBXDBC copy constructor PTDB TDBXDBC::Clone(PTABS t) - { +{ PTDB tp; PXSRCCOL cp1, cp2; PGLOBAL g = t->G; // Is this really useful ??? @@ -1129,29 +1130,29 @@ PTDB TDBXDBC::Clone(PTABS t) for (cp1 = (PXSRCCOL)Columns; cp1; cp1 = (PXSRCCOL)cp1->GetNext()) { cp2 = new(g) XSRCCOL(cp1, tp); // Make a copy NewPointer(t, cp1, cp2); - } // endfor cp1 + } // endfor cp1 return tp; - } // end of CopyOne +} // end of CopyOne /***********************************************************************/ /* Allocate XSRC column description block. */ /***********************************************************************/ PCOL TDBXDBC::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n) - { +{ PXSRCCOL colp = new(g) XSRCCOL(cdp, this, cprec, n); if (!colp->Flag) Cmdcol = colp->GetName(); return colp; - } // end of MakeCol +} // end of MakeCol /***********************************************************************/ /* MakeCMD: make the SQL statement to send to ODBC connection. */ /***********************************************************************/ PCMD TDBXDBC::MakeCMD(PGLOBAL g) - { +{ PCMD xcmd = NULL; if (To_CondFil) { @@ -1171,14 +1172,14 @@ PCMD TDBXDBC::MakeCMD(PGLOBAL g) xcmd = new(g) CMD(g, Srcdef); return xcmd; - } // end of MakeCMD +} // end of MakeCMD #if 0 /***********************************************************************/ /* ODBC Bind Parameter function. */ /***********************************************************************/ bool TDBXDBC::BindParameters(PGLOBAL g) - { +{ PODBCCOL colp; for (colp = (PODBCCOL)Columns; colp; colp = (PODBCCOL)colp->Next) { @@ -1190,19 +1191,19 @@ bool TDBXDBC::BindParameters(PGLOBAL g) } // endfor colp return false; - } // end of BindParameters +} // end of BindParameters #endif // 0 /***********************************************************************/ /* XDBC GetMaxSize: returns table size (not always one row). */ /***********************************************************************/ int TDBXDBC::GetMaxSize(PGLOBAL g) - { +{ if (MaxSize < 0) MaxSize = 10; // Just a guess return MaxSize; - } // end of GetMaxSize +} // end of GetMaxSize /***********************************************************************/ /* ODBC Access Method opening routine. */ @@ -1211,7 +1212,7 @@ int TDBXDBC::GetMaxSize(PGLOBAL g) /* join block of next table if it exists or else are discarted. */ /***********************************************************************/ bool TDBXDBC::OpenDB(PGLOBAL g) - { +{ bool rc = false; if (trace(1)) @@ -1221,7 +1222,7 @@ bool TDBXDBC::OpenDB(PGLOBAL g) if (Use == USE_OPEN) { strcpy(g->Message, "Multiple execution is not allowed"); return true; - } // endif use + } // endif use /*********************************************************************/ /* Open an ODBC connection for this table. */ @@ -1243,7 +1244,7 @@ bool TDBXDBC::OpenDB(PGLOBAL g) if (Mode != MODE_READ && Mode != MODE_READX) { strcpy(g->Message, "No INSERT/DELETE/UPDATE of XDBC tables"); return true; - } // endif Mode + } // endif Mode /*********************************************************************/ /* Get the command to execute. */ @@ -1256,13 +1257,13 @@ bool TDBXDBC::OpenDB(PGLOBAL g) Rows = 1; return false; - } // end of OpenDB +} // end of OpenDB /***********************************************************************/ /* ReadDB: Data Base read routine for xdbc access method. */ /***********************************************************************/ int TDBXDBC::ReadDB(PGLOBAL g) - { +{ if (Cmdlist) { if (!Query) Query = new(g)STRING(g, 0, Cmdlist->Cmd); @@ -1280,25 +1281,25 @@ int TDBXDBC::ReadDB(PGLOBAL g) return RC_EF; } // endif Cmdlist - } // end of ReadDB +} // end of ReadDB /***********************************************************************/ -/* Data Base delete line routine for ODBC access method. */ +/* Data Base write line routine for XDBC access method. */ /***********************************************************************/ int TDBXDBC::WriteDB(PGLOBAL g) - { +{ strcpy(g->Message, "Execsrc tables are read only"); return RC_FX; - } // end of DeleteDB +} // end of DeleteDB /***********************************************************************/ -/* Data Base delete line routine for ODBC access method. */ +/* Data Base delete line routine for XDBC access method. */ /***********************************************************************/ int TDBXDBC::DeleteDB(PGLOBAL g, int irc) - { +{ strcpy(g->Message, MSG(NO_ODBC_DELETE)); return RC_FX; - } // end of DeleteDB +} // end of DeleteDB /* --------------------------- XSRCCOL ------------------------------- */ @@ -1307,25 +1308,25 @@ int TDBXDBC::DeleteDB(PGLOBAL g, int irc) /***********************************************************************/ XSRCCOL::XSRCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am) : ODBCCOL(cdp, tdbp, cprec, i, am) - { +{ // Set additional ODBC access method information for column. Flag = cdp->GetOffset(); - } // end of XSRCCOL constructor +} // end of XSRCCOL constructor /***********************************************************************/ /* XSRCCOL constructor used for copying columns. */ /* tdbp is the pointer to the new table descriptor. */ /***********************************************************************/ XSRCCOL::XSRCCOL(XSRCCOL *col1, PTDB tdbp) : ODBCCOL(col1, tdbp) - { +{ Flag = col1->Flag; - } // end of XSRCCOL copy constructor +} // end of XSRCCOL copy constructor /***********************************************************************/ /* ReadColumn: set column value according to Flag. */ /***********************************************************************/ void XSRCCOL::ReadColumn(PGLOBAL g) - { +{ PTDBXDBC tdbp = (PTDBXDBC)To_Tdb; switch (Flag) { @@ -1335,15 +1336,15 @@ void XSRCCOL::ReadColumn(PGLOBAL g) default: Value->SetValue_psz("Invalid Flag"); break; } // endswitch Flag - } // end of ReadColumn +} // end of ReadColumn /***********************************************************************/ /* WriteColumn: Should never be called. */ /***********************************************************************/ void XSRCCOL::WriteColumn(PGLOBAL g) - { +{ // Should never be called - } // end of WriteColumn +} // end of WriteColumn /* ---------------------------TDBDRV class --------------------------- */ @@ -1351,9 +1352,9 @@ void XSRCCOL::WriteColumn(PGLOBAL g) /* GetResult: Get the list of ODBC drivers. */ /***********************************************************************/ PQRYRES TDBDRV::GetResult(PGLOBAL g) - { +{ return ODBCDrivers(g, Maxres, false); - } // end of GetResult +} // end of GetResult /* ---------------------------TDBSRC class --------------------------- */ @@ -1361,9 +1362,9 @@ PQRYRES TDBDRV::GetResult(PGLOBAL g) /* GetResult: Get the list of ODBC data sources. */ /***********************************************************************/ PQRYRES TDBSRC::GetResult(PGLOBAL g) - { +{ return ODBCDataSources(g, Maxres, false); - } // end of GetResult +} // end of GetResult /* ---------------------------TDBOTB class --------------------------- */ @@ -1371,7 +1372,7 @@ PQRYRES TDBSRC::GetResult(PGLOBAL g) /* TDBOTB class constructor. */ /***********************************************************************/ TDBOTB::TDBOTB(PODEF tdp) : TDBDRV(tdp) - { +{ Dsn = tdp->GetConnect(); Schema = tdp->GetTabschema(); Tab = tdp->GetTabname(); @@ -1381,15 +1382,15 @@ TDBOTB::TDBOTB(PODEF tdp) : TDBDRV(tdp) Ops.Cto = tdp->Cto; Ops.Qto = tdp->Qto; Ops.UseCnc = tdp->UseCnc; - } // end of TDBOTB constructor +} // end of TDBOTB constructor /***********************************************************************/ /* GetResult: Get the list of ODBC tables. */ /***********************************************************************/ PQRYRES TDBOTB::GetResult(PGLOBAL g) - { +{ return ODBCTables(g, Dsn, Schema, Tab, Tabtyp, Maxres, false, &Ops); - } // end of GetResult +} // end of GetResult /* ---------------------------TDBOCL class --------------------------- */ @@ -1405,8 +1406,8 @@ TDBOCL::TDBOCL(PODEF tdp) : TDBOTB(tdp) /* GetResult: Get the list of ODBC table columns. */ /***********************************************************************/ PQRYRES TDBOCL::GetResult(PGLOBAL g) - { +{ return ODBCColumns(g, Dsn, Schema, Tab, Colpat, Maxres, false, &Ops); - } // end of GetResult +} // end of GetResult /* ------------------------ End of Tabodbc --------------------------- */ diff --git a/storage/connect/tabxml.cpp b/storage/connect/tabxml.cpp index c96e0844497..d808bd5ecd4 100644 --- a/storage/connect/tabxml.cpp +++ b/storage/connect/tabxml.cpp @@ -163,8 +163,11 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info) return NULL; tdp->Tabname = tab; + tdp->Tabname = (char*)GetStringTableOption(g, topt, "Tabname", tab); + tdp->Rowname = (char*)GetStringTableOption(g, topt, "Rownode", NULL); tdp->Zipped = GetBooleanTableOption(g, topt, "Zipped", false); tdp->Entry = GetStringTableOption(g, topt, "Entry", NULL); + tdp->Skip = GetBooleanTableOption(g, topt, "Skipnull", false); if (!(op = GetStringTableOption(g, topt, "Xmlsup", NULL))) #if defined(__WIN__) @@ -280,7 +283,9 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info) if (!vp->atp) node = vp->nl->GetItem(g, vp->k++, tdp->Usedom ? node : NULL); - strncat(fmt, colname, XLEN(fmt)); + if (!j) + strncat(fmt, colname, XLEN(fmt)); + strncat(fmt, "/", XLEN(fmt)); strncat(xcol->Name, "_", XLEN(xcol->Name)); j++; @@ -302,6 +307,7 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info) case RC_INFO: PushWarning(g, txmp); case RC_OK: + xcol->Cbn = !strlen(buf); break; default: goto err; @@ -327,9 +333,9 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info) xcp->Len = MY_MAX(xcp->Len, xcol->Len); xcp->Scale = MY_MAX(xcp->Scale, xcol->Scale); - xcp->Cbn |= xcol->Cbn; + xcp->Cbn |= (xcol->Cbn || !xcol->Len); xcp->Found = true; - } else { + } else if(xcol->Len || !tdp->Skip) { // New column xcp = new(g) XMCOL(g, xcol, fmt, i); length[0] = MY_MAX(length[0], strlen(xcol->Name)); @@ -344,7 +350,8 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info) n++; } // endif xcp - pxcp = xcp; + if (xcp) + pxcp = xcp; if (vp->atp) vp->atp = vp->atp->GetNext(g); @@ -445,6 +452,7 @@ XMLDEF::XMLDEF(void) Usedom = false; Zipped = false; Mulentries = false; + Skip = false; } // end of XMLDEF constructor /***********************************************************************/ @@ -681,6 +689,14 @@ PTDB TDBXML::Clone(PTABS t) return tp; } // end of Clone +/***********************************************************************/ +/* Must not be in tabxml.h because of OEM tables */ +/***********************************************************************/ +const CHARSET_INFO *TDBXML::data_charset() +{ + return &my_charset_utf8_general_ci; +} // end of data_charset + /***********************************************************************/ /* Allocate XML column description block. */ /***********************************************************************/ @@ -806,127 +822,141 @@ bool TDBXML::Initialize(PGLOBAL g) } // endif Bufdone #if !defined(UNIX) - if (!Root) try { + if (!Root) try { #else - if (!Root) { + if (!Root) { #endif - char tabpath[64], filename[_MAX_PATH]; + char tabpath[64], filename[_MAX_PATH]; - // We used the file name relative to recorded datapath - PlugSetPath(filename, Xfile, GetPath()); + // We used the file name relative to recorded datapath + PlugSetPath(filename, Xfile, GetPath()); - // Load or re-use the table file - rc = LoadTableFile(g, filename); + // Load or re-use the table file + rc = LoadTableFile(g, filename); - if (rc == RC_OK) { - // Get root node - if (!(Root = Docp->GetRoot(g))) { - // This should never happen as load should have failed - strcpy(g->Message, MSG(EMPTY_DOC)); - goto error; - } // endif Root + if (rc == RC_OK) { + // Get root node + if (!(Root = Docp->GetRoot(g))) { + // This should never happen as load should have failed + strcpy(g->Message, MSG(EMPTY_DOC)); + goto error; + } // endif Root - // If tabname is not an Xpath, - // construct one that will find it anywhere - if (!strchr(Tabname, '/')) - strcat(strcpy(tabpath, "//"), Tabname); - else - strcpy(tabpath, Tabname); + // If tabname is not an Xpath, + // construct one that will find it anywhere + if (!strchr(Tabname, '/')) + strcat(strcpy(tabpath, "//"), Tabname); + else + strcpy(tabpath, Tabname); - // Evaluate table xpath - if ((TabNode = Root->SelectSingleNode(g, tabpath))) { - if (TabNode->GetType() != XML_ELEMENT_NODE) { - sprintf(g->Message, MSG(BAD_NODE_TYPE), TabNode->GetType()); - goto error; - } // endif Type + // Evaluate table xpath + if ((TabNode = Root->SelectSingleNode(g, tabpath))) { + if (TabNode->GetType() != XML_ELEMENT_NODE) { + sprintf(g->Message, MSG(BAD_NODE_TYPE), TabNode->GetType()); + goto error; + } // endif Type - } else if (Mode == MODE_INSERT && XmlDB) { - // We are adding a new table to a multi-table file + } else if (Mode == MODE_INSERT && XmlDB) { + // We are adding a new table to a multi-table file - // If XmlDB is not an Xpath, - // construct one that will find it anywhere - if (!strchr(XmlDB, '/')) - strcat(strcpy(tabpath, "//"), XmlDB); - else - strcpy(tabpath, XmlDB); + // If XmlDB is not an Xpath, + // construct one that will find it anywhere + if (!strchr(XmlDB, '/')) + strcat(strcpy(tabpath, "//"), XmlDB); + else + strcpy(tabpath, XmlDB); - if (!(DBnode = Root->SelectSingleNode(g, tabpath))) { - // DB node does not exist yet; we cannot create it - // because we don't know where it should be placed - sprintf(g->Message, MSG(MISSING_NODE), XmlDB, Xfile); - goto error; - } // endif DBnode + if (!(DBnode = Root->SelectSingleNode(g, tabpath))) { + // DB node does not exist yet; we cannot create it + // because we don't know where it should be placed + sprintf(g->Message, MSG(MISSING_NODE), XmlDB, Xfile); + goto error; + } // endif DBnode - if (!(TabNode = DBnode->AddChildNode(g, Tabname))) { - sprintf(g->Message, MSG(FAIL_ADD_NODE), Tabname); - goto error; - } // endif TabNode + if (!(TabNode = DBnode->AddChildNode(g, Tabname))) { + sprintf(g->Message, MSG(FAIL_ADD_NODE), Tabname); + goto error; + } // endif TabNode - DBnode->AddText(g, "\n"); - } else - TabNode = Root; // Try this ? + DBnode->AddText(g, "\n"); + } else { + TabNode = Root; // Try this ? + Tabname = TabNode->GetName(g); + } // endif's - } else if (rc == RC_NF || rc == RC_EF) { - // The XML file does not exist or is void - if (Mode == MODE_INSERT) { - // New Document - char buf[64]; + } else if (rc == RC_NF || rc == RC_EF) { + // The XML file does not exist or is void + if (Mode == MODE_INSERT) { + // New Document + char buf[64]; - // Create the XML node - if (Docp->NewDoc(g, "1.0")) { - strcpy(g->Message, MSG(NEW_DOC_FAILED)); - goto error; - } // endif NewDoc + // Create the XML node + if (Docp->NewDoc(g, "1.0")) { + strcpy(g->Message, MSG(NEW_DOC_FAILED)); + goto error; + } // endif NewDoc - // Now we can link the Xblock - To_Xb = Docp->LinkXblock(g, Mode, rc, filename); + // Now we can link the Xblock + To_Xb = Docp->LinkXblock(g, Mode, rc, filename); - // Add a CONNECT comment node - strcpy(buf, " Created by the MariaDB CONNECT Storage Engine"); - Docp->AddComment(g, buf); + // Add a CONNECT comment node + strcpy(buf, " Created by the MariaDB CONNECT Storage Engine"); + Docp->AddComment(g, buf); - if (XmlDB) { - // This is a multi-table file - DBnode = Root = Docp->NewRoot(g, XmlDB); - DBnode->AddText(g, "\n"); - TabNode = DBnode->AddChildNode(g, Tabname); - DBnode->AddText(g, "\n"); - } else - TabNode = Root = Docp->NewRoot(g, Tabname); + if (XmlDB) { + // This is a multi-table file + DBnode = Root = Docp->NewRoot(g, XmlDB); + DBnode->AddText(g, "\n"); + TabNode = DBnode->AddChildNode(g, Tabname); + DBnode->AddText(g, "\n"); + } else + TabNode = Root = Docp->NewRoot(g, Tabname); - if (TabNode == NULL || Root == NULL) { - strcpy(g->Message, MSG(XML_INIT_ERROR)); - goto error; - } else if (SetTabNode(g)) - goto error; + if (TabNode == NULL || Root == NULL) { + strcpy(g->Message, MSG(XML_INIT_ERROR)); + goto error; + } else if (SetTabNode(g)) + goto error; - } else { - sprintf(g->Message, MSG(FILE_UNFOUND), Xfile); + } else { + sprintf(g->Message, MSG(FILE_UNFOUND), Xfile); - if (Mode == MODE_READ) { - PushWarning(g, this); - Void = true; - } // endif Mode + if (Mode == MODE_READ) { + PushWarning(g, this); + Void = true; + } // endif Mode - goto error; - } // endif Mode + goto error; + } // endif Mode - } else if (rc == RC_INFO) { - // Loading failed - sprintf(g->Message, MSG(LOADING_FAILED), Xfile); - goto error; - } else // (rc == RC_FX) - goto error; + } else if (rc == RC_INFO) { + // Loading failed + sprintf(g->Message, MSG(LOADING_FAILED), Xfile); + goto error; + } else // (rc == RC_FX) + goto error; - // Get row node list - if (Rowname) - Nlist = TabNode->SelectNodes(g, Rowname); - else - Nlist = TabNode->GetChildElements(g); + if (!Rowname) { + for (PXNODE n = TabNode->GetChild(g); n; n = n->GetNext(g)) + if (n->GetType() == XML_ELEMENT_NODE) { + Rowname = n->GetName(g); + break; + } // endif Type - Docp->SetNofree(true); // For libxml2 + if (!Rowname) + Rowname = TabNode->GetName(g); + } // endif Rowname + + // Get row node list + if (strcmp(Rowname, Tabname)) + Nlist = TabNode->SelectNodes(g, Rowname); + else + Nrow = 1; + + + Docp->SetNofree(true); // For libxml2 #if defined(__WIN__) - } catch(_com_error e) { + } catch (_com_error e) { // We come here if a DOM command threw an error char buf[128]; @@ -1213,10 +1243,14 @@ int TDBXML::ReadDB(PGLOBAL g) htrc("TDBXML ReadDB: Irow=%d RowNode=%p\n", Irow, RowNode); // Get the new row node - if ((RowNode = Nlist->GetItem(g, Irow, RowNode)) == NULL) { - sprintf(g->Message, MSG(MISSING_ROWNODE), Irow); - return RC_FX; - } // endif RowNode + if (Nlist) { + if ((RowNode = Nlist->GetItem(g, Irow, RowNode)) == NULL) { + sprintf(g->Message, MSG(MISSING_ROWNODE), Irow); + return RC_FX; + } // endif RowNode + + } else + RowNode = TabNode; if (Colname && Coltype == 2) Clist = RowNode->SelectNodes(g, Colname, Clist); @@ -1271,6 +1305,7 @@ int TDBXML::WriteDB(PGLOBAL g) /***********************************************************************/ int TDBXML::DeleteDB(PGLOBAL g, int irc) { + // TODO: Handle null Nlist if (irc == RC_FX) { // Delete all rows for (Irow = 0; Irow < Nrow; Irow++) @@ -2209,8 +2244,9 @@ void XPOSCOL::WriteColumn(PGLOBAL g) TDBXCT::TDBXCT(PXMLDEF tdp) : TDBCAT(tdp) { Topt = tdp->GetTopt(); - Db = (char*)tdp->GetDB(); - Tabn = tdp->Tabname; + //Db = (char*)tdp->GetDB(); + Db = (char*)tdp->Schema; + Tabn = tdp->Tabname; } // end of TDBXCT constructor /***********************************************************************/ diff --git a/storage/connect/tabxml.h b/storage/connect/tabxml.h index f55b7d98de7..fb3913f08ea 100644 --- a/storage/connect/tabxml.h +++ b/storage/connect/tabxml.h @@ -9,6 +9,8 @@ typedef class XMLDEF *PXMLDEF; typedef class TDBXML *PTDBXML; typedef class XMLCOL *PXMLCOL; +DllExport PQRYRES XMLColumns(PGLOBAL, char *, char *, PTOS, bool); + /* --------------------------- XML classes --------------------------- */ /***********************************************************************/ @@ -50,6 +52,7 @@ class DllExport XMLDEF : public TABDEF { /* Logical table description */ bool Usedom; /* True: DOM, False: libxml2 */ bool Zipped; /* True: Zipped XML file(s) */ bool Mulentries; /* True: multiple entries in zip file*/ + bool Skip; /* Skip null columns */ }; // end of XMLDEF #if defined(INCLUDE_TDBXML) @@ -100,8 +103,7 @@ class DllExport TDBXML : public TDBASE { virtual int DeleteDB(PGLOBAL g, int irc); virtual void CloseDB(PGLOBAL g); virtual int CheckWrite(PGLOBAL g) {Checked = true; return 0;} - virtual const CHARSET_INFO *data_charset() - {return &my_charset_utf8_general_ci;} + virtual const CHARSET_INFO *data_charset(); protected: // Members diff --git a/storage/connect/user_connect.cc b/storage/connect/user_connect.cc index e2d3b664aeb..a2a8faf9b38 100644 --- a/storage/connect/user_connect.cc +++ b/storage/connect/user_connect.cc @@ -107,7 +107,7 @@ bool user_connect::user_init() g= PlugInit(NULL, worksize); // Check whether the initialization is complete - if (!g || !g->Sarea || PlugSubSet(g, g->Sarea, g->Sarea_Size) + if (!g || !g->Sarea || PlugSubSet(g->Sarea, g->Sarea_Size) || !(dup= PlgMakeUser(g))) { if (g) printf("%s\n", g->Message); @@ -172,7 +172,7 @@ bool user_connect::CheckCleanup(bool force) } // endif worksize - PlugSubSet(g, g->Sarea, g->Sarea_Size); + PlugSubSet(g->Sarea, g->Sarea_Size); g->Xchk = NULL; g->Createas = 0; g->Alchecked = 0; From ef0b91ea941785be1f3913fc44ba735d5d03a6f6 Mon Sep 17 00:00:00 2001 From: Andrei Elkin Date: Thu, 24 Jan 2019 16:57:29 +0200 Subject: [PATCH 043/106] MDEV-17803: ulonglongization of table_mapping entry::table_id to fix windows compilation in particular. --- sql/log_event.cc | 4 ++-- sql/rpl_tblmap.cc | 18 +++++++++--------- sql/rpl_tblmap.h | 10 +++++----- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/sql/log_event.cc b/sql/log_event.cc index 1369ba2d687..4879e9fcecf 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -11332,8 +11332,8 @@ int Table_map_log_event::do_apply_event(rpl_group_info *rgi) table_list->updating= 1; table_list->required_type= FRMTYPE_TABLE; - DBUG_PRINT("debug", ("table: %s is mapped to %u", table_list->table_name, - table_list->table_id)); + DBUG_PRINT("debug", ("table: %s is mapped to %llu", table_list->table_name, + table_list->table_id)); table_list->master_had_triggers= ((m_flags & TM_BIT_HAS_TRIGGERS_F) ? 1 : 0); DBUG_PRINT("debug", ("table->master_had_triggers=%d", (int)table_list->master_had_triggers)); diff --git a/sql/rpl_tblmap.cc b/sql/rpl_tblmap.cc index 4c521cf0c16..80114f50d62 100644 --- a/sql/rpl_tblmap.cc +++ b/sql/rpl_tblmap.cc @@ -43,7 +43,7 @@ table_mapping::table_mapping() constructor is called at startup only. */ (void) my_hash_init(&m_table_ids,&my_charset_bin,TABLE_ID_HASH_SIZE, - offsetof(entry,table_id),sizeof(ulong), + offsetof(entry,table_id),sizeof(ulonglong), 0,0,0); /* We don't preallocate any block, this is consistent with m_free=0 above */ init_alloc_root(&m_mem_root, TABLE_ID_HASH_SIZE*sizeof(entry), 0, MYF(0)); @@ -59,20 +59,20 @@ table_mapping::~table_mapping() free_root(&m_mem_root, MYF(0)); } -TABLE* table_mapping::get_table(ulong table_id) +TABLE* table_mapping::get_table(ulonglong table_id) { DBUG_ENTER("table_mapping::get_table(ulong)"); - DBUG_PRINT("enter", ("table_id: %lu", table_id)); + DBUG_PRINT("enter", ("table_id: %llu", table_id)); entry *e= find_entry(table_id); if (e) { - DBUG_PRINT("info", ("tid %lu -> table 0x%lx (%s)", + DBUG_PRINT("info", ("tid %llu -> table 0x%lx (%s)", table_id, (long) e->table, MAYBE_TABLE_NAME(e->table))); DBUG_RETURN(e->table); } - DBUG_PRINT("info", ("tid %lu is not mapped!", table_id)); + DBUG_PRINT("info", ("tid %llu is not mapped!", table_id)); DBUG_RETURN(NULL); } @@ -102,10 +102,10 @@ int table_mapping::expand() return 0; } -int table_mapping::set_table(ulong table_id, TABLE* table) +int table_mapping::set_table(ulonglong table_id, TABLE* table) { DBUG_ENTER("table_mapping::set_table(ulong,TABLE*)"); - DBUG_PRINT("enter", ("table_id: %lu table: 0x%lx (%s)", + DBUG_PRINT("enter", ("table_id: %llu table: 0x%lx (%s)", table_id, (long) table, MAYBE_TABLE_NAME(table))); entry *e= find_entry(table_id); @@ -133,13 +133,13 @@ int table_mapping::set_table(ulong table_id, TABLE* table) DBUG_RETURN(ERR_MEMORY_ALLOCATION); } - DBUG_PRINT("info", ("tid %lu -> table 0x%lx (%s)", + DBUG_PRINT("info", ("tid %llu -> table 0x%lx (%s)", table_id, (long) e->table, MAYBE_TABLE_NAME(e->table))); DBUG_RETURN(0); // All OK } -int table_mapping::remove_table(ulong table_id) +int table_mapping::remove_table(ulonglong table_id) { entry *e= find_entry(table_id); if (e) diff --git a/sql/rpl_tblmap.h b/sql/rpl_tblmap.h index 9fb1c4afbd7..05b298e6053 100644 --- a/sql/rpl_tblmap.h +++ b/sql/rpl_tblmap.h @@ -70,10 +70,10 @@ public: table_mapping(); ~table_mapping(); - TABLE* get_table(ulong table_id); + TABLE* get_table(ulonglong table_id); - int set_table(ulong table_id, TABLE* table); - int remove_table(ulong table_id); + int set_table(ulonglong table_id, TABLE* table); + int remove_table(ulonglong table_id); void clear_tables(); ulong count() const { return m_table_ids.records; } @@ -83,14 +83,14 @@ private: it, which only works for PODs) */ struct entry { - ulong table_id; + ulonglong table_id; union { TABLE *table; entry *next; }; }; - entry *find_entry(ulong table_id) + entry *find_entry(ulonglong table_id) { return (entry *) my_hash_search(&m_table_ids, (uchar*)&table_id, From bcb8a52295906a41eb94fd06d0e86b72a2f61cd9 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Fri, 25 Jan 2019 13:02:40 +0100 Subject: [PATCH 044/106] - Fix MDEV-18192: CONNECT Engine JDBC not able to issue simple UPDATE statement from trigger or stored procedure modified: storage/connect/tabext.cpp modified: storage/connect/tabext.h modified: storage/connect/tabjdbc.cpp - Make user and password defined in CREATE TABLE have precedence on the ones specified in a Federated Server. modified: storage/connect/tabjdbc.cpp - JSONColumns: Copy locally constant strings to fix error in OEM modules modified: storage/connect/tabjson.cpp --- storage/connect/tabext.cpp | 43 +++++++++++++++++++++++-- storage/connect/tabext.h | 5 +-- storage/connect/tabjdbc.cpp | 63 +++++++++++++++++++++---------------- storage/connect/tabjson.cpp | 8 ++--- 4 files changed, 84 insertions(+), 35 deletions(-) diff --git a/storage/connect/tabext.cpp b/storage/connect/tabext.cpp index f2d5eb0e69d..e9c7b2490d8 100644 --- a/storage/connect/tabext.cpp +++ b/storage/connect/tabext.cpp @@ -1,7 +1,7 @@ /************* Tabext C++ Functions Source Code File (.CPP) ************/ -/* Name: TABEXT.CPP Version 1.0 */ +/* Name: TABEXT.CPP Version 1.1 */ /* */ -/* (C) Copyright to the author Olivier BERTRAND 2017 */ +/* (C) Copyright to the author Olivier BERTRAND 2017 - 2019 */ /* */ /* This file contains the TBX, TDB and OPJOIN classes functions. */ /***********************************************************************/ @@ -445,6 +445,43 @@ bool TDBEXT::MakeSQL(PGLOBAL g, bool cnt) return false; } // end of MakeSQL +/***********************************************************************/ +/* Remove the NAME_CONST functions that are added by procedures. */ +/***********************************************************************/ +void TDBEXT::RemoveConst(PGLOBAL g, char *stmt) +{ + char *p, *p2; + char val[1025], nval[1025]; + int n, nc; + + while ((p = strstr(stmt, "NAME_CONST"))) + if ((n = sscanf(p, "%*[^,],%1024[^)])%n", val, &nc))) { + if (trace(33)) + htrc("p=%s\nn=%d val=%s nc=%d\n", p, n, val, nc); + + *p = 0; + + if ((p2 = strstr(val, "'"))) { + if ((n = sscanf(p2, "%*['\\]%1024[^'\\]", nval))) { + if (trace(33)) + htrc("p2=%s\nn=%d nval=%s\n", p2, n, nval); + + strcat(strcat(strcat(strcat(stmt, "'"), nval), "'"), p + nc); + } else + break; + + } else + strcat(strcat(strcat(strcat(stmt, "("), val), ")"), p + nc); + + if (trace(33)) + htrc("stmt=%s\n", stmt); + + } else + break; + + return; +} // end of RemoveConst + /***********************************************************************/ /* MakeCommand: make the Update or Delete statement to send to the */ /* MySQL server. Limited to remote values and filtering. */ @@ -524,6 +561,8 @@ bool TDBEXT::MakeCommand(PGLOBAL g) stmt[i++] = (Qrystr[k] == '`') ? q : Qrystr[k]; } while (Qrystr[k++]); + RemoveConst(g, stmt); + if (body) strcat(stmt, body); diff --git a/storage/connect/tabext.h b/storage/connect/tabext.h index 6b67c2ab5ed..5fef1b9ece0 100644 --- a/storage/connect/tabext.h +++ b/storage/connect/tabext.h @@ -1,7 +1,7 @@ /*************** Tabext H Declares Source Code File (.H) ***************/ -/* Name: TABEXT.H Version 1.0 */ +/* Name: TABEXT.H Version 1.1 */ /* */ -/* (C) Copyright to the author Olivier BERTRAND 2017 */ +/* (C) Copyright to the author Olivier BERTRAND 2017 - 2019 */ /* */ /* This is the EXTDEF, TABEXT and EXTCOL classes definitions. */ /***********************************************************************/ @@ -130,6 +130,7 @@ protected: virtual bool MakeSQL(PGLOBAL g, bool cnt); //virtual bool MakeInsert(PGLOBAL g); virtual bool MakeCommand(PGLOBAL g); + void RemoveConst(PGLOBAL g, char *stmt); int Decode(PCSZ utf, char *buf, size_t n); // Members diff --git a/storage/connect/tabjdbc.cpp b/storage/connect/tabjdbc.cpp index adb3fc4fb51..c6b2802c1f6 100644 --- a/storage/connect/tabjdbc.cpp +++ b/storage/connect/tabjdbc.cpp @@ -1,11 +1,11 @@ /************* TabJDBC C++ Program Source Code File (.CPP) *************/ /* PROGRAM NAME: TABJDBC */ /* ------------- */ -/* Version 1.2 */ +/* Version 1.3 */ /* */ /* COPYRIGHT: */ /* ---------- */ -/* (C) Copyright to the author Olivier BERTRAND 2016-2017 */ +/* (C) Copyright to the author Olivier BERTRAND 2016-2019 */ /* */ /* WHAT THIS PROGRAM DOES: */ /* ----------------------- */ @@ -185,10 +185,10 @@ int JDBCDEF::ParseURL(PGLOBAL g, char *url, bool b) } else // host is a URL Url = PlugDup(g, server->host); - if (server->username) + if (!Username && server->username) Username = PlugDup(g, server->username); - if (server->password) + if (!Password && server->password) Password = PlugDup(g, server->password); return RC_NF; @@ -558,33 +558,42 @@ bool TDBJDBC::OpenDB(PGLOBAL g) this, Tdb_No, Use, Mode); if (Use == USE_OPEN) { - /*******************************************************************/ - /* Table already open, just replace it at its beginning. */ - /*******************************************************************/ - if (Memory == 1) { - if ((Qrp = Jcp->AllocateResult(g, this))) - Memory = 2; // Must be filled - else - Memory = 0; // Allocation failed, don't use it + if (Mode == MODE_READ || Mode == MODE_READX) { + /*****************************************************************/ + /* Table already open, just replace it at its beginning. */ + /*****************************************************************/ + if (Memory == 1) { + if ((Qrp = Jcp->AllocateResult(g, this))) + Memory = 2; // Must be filled + else + Memory = 0; // Allocation failed, don't use it - } else if (Memory == 2) - Memory = 3; // Ok to use memory result + } else if (Memory == 2) + Memory = 3; // Ok to use memory result - if (Memory < 3) { - // Method will depend on cursor type - if ((Rbuf = Query ? Jcp->Rewind(Query->GetStr()) : 0) < 0) - if (Mode != MODE_READX) { - Jcp->Close(); - return true; - } else - Rbuf = 0; + if (Memory < 3) { + // Method will depend on cursor type + if ((Rbuf = Query ? Jcp->Rewind(Query->GetStr()) : 0) < 0) + if (Mode != MODE_READX) { + Jcp->Close(); + return true; + } else + Rbuf = 0; - } else - Rbuf = Qrp->Nblin; + } else + Rbuf = Qrp->Nblin; + + CurNum = 0; + Fpos = 0; + Curpos = 1; + } else if (Mode == MODE_UPDATE || Mode == MODE_DELETE) { + // new update coming from a trigger or procedure + Query = NULL; + SetCondFil(NULL); + Qrystr = To_Def->GetStringCatInfo(g, "Query_String", "?"); + } else { //if (Mode == MODE_INSERT) + } // endif Mode - CurNum = 0; - Fpos = 0; - Curpos = 1; return false; } // endif use diff --git a/storage/connect/tabjson.cpp b/storage/connect/tabjson.cpp index c0d36efcf42..afab52aa282 100644 --- a/storage/connect/tabjson.cpp +++ b/storage/connect/tabjson.cpp @@ -1,6 +1,6 @@ /************* tabjson C++ Program Source Code File (.CPP) *************/ -/* PROGRAM NAME: tabjson Version 1.6 */ -/* (C) Copyright to the author Olivier BERTRAND 2014 - 2018 */ +/* PROGRAM NAME: tabjson Version 1.7 */ +/* (C) Copyright to the author Olivier BERTRAND 2014 - 2019 */ /* This program are the JSON class DB execution routines. */ /***********************************************************************/ @@ -110,8 +110,8 @@ PQRYRES JSONColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt, bool info) buftyp, fldtyp, length, false, false); crp = qrp->Colresp->Next->Next->Next->Next->Next->Next; - crp->Name = "Nullable"; - crp->Next->Name = "Jpath"; + crp->Name = PlugDup(g, "Nullable"); + crp->Next->Name = PlugDup(g, "Jpath"); if (info || !qrp) return qrp; From 4aea6b3e3f3fd1a8a2526bc40fc5e85e571d8242 Mon Sep 17 00:00:00 2001 From: Julius Goryavsky Date: Sat, 26 Jan 2019 01:11:45 +0100 Subject: [PATCH 045/106] MDEV-18379: Unification of check for IPv6 This patch contains the port of the MDEV-18379 patch for 10.1 branch, but also includes a number of changes made within MDEV-17835, which are necessary for the normal operation of tests that use IPv6: 1) Fixed flaws in the galera_3nodes mtr suite control scripts, because of which they could not work with mariabackup. 2) Fixed numerous bugs in the SST scripts and in the mtr test files (galera_3nodes mtr suite) that prevented the use of Galera with IPv6 addresses. 3) Fixed flaws in tests for rsync and mysqldump (for galera_3nodes mtr tests suite). These tests were not performed successfully without these fixes. 4) Currently, the three-node mtr suite for Galera (galera_3nodes) uses a separate IPv6 availability check using the "have_ipv6.inc" file. This check duplicates a more accurate check at suite.pm level, which can be used by including the file "check_ipv6.inc". This patch removes this discrepancy between suites. 5) GAL-501 test in the galera_3nodes suite does not contain the option "--bind-address=::" which is needed for the test to work correctly with IPv6 (at least on some systems), since without it the server will not wait for connections on the IPv6 interface. https://jira.mariadb.org/browse/MDEV-18379 and partially https://jira.mariadb.org/browse/MDEV-17835 --- mysql-test/suite/galera_3nodes/disabled.def | 1 - .../suite/galera_3nodes/galera_2x3nodes.cnf | 12 ++-- .../suite/galera_3nodes/galera_3nodes.cnf | 6 +- .../suite/galera_3nodes/include/have_ipv6.inc | 15 ----- .../r/galera_ipv6_mariabackup.result | 18 ++++++ .../r/galera_ipv6_mysqldump.result | 9 ++- mysql-test/suite/galera_3nodes/suite.pm | 53 ++++++++++++++--- mysql-test/suite/galera_3nodes/t/GAL-501.opt | 1 + mysql-test/suite/galera_3nodes/t/GAL-501.test | 2 +- .../t/galera_innobackupex_backup.cnf | 4 ++ .../t/galera_innobackupex_backup.test | 28 ++++++++- .../t/galera_ipv6_mariabackup.cnf | 29 +++++++++ .../t/galera_ipv6_mariabackup.opt | 1 + .../t/galera_ipv6_mariabackup.test | 59 +++++++++++++++++++ .../galera_3nodes/t/galera_ipv6_mysqldump.cnf | 10 +++- .../t/galera_ipv6_mysqldump.test | 43 +++++++++++--- .../galera_3nodes/t/galera_ipv6_rsync.cnf | 10 +++- .../galera_3nodes/t/galera_ipv6_rsync.test | 2 +- .../t/galera_ipv6_xtrabackup-v2.cnf | 3 + .../t/galera_ipv6_xtrabackup-v2.opt | 1 + .../t/galera_ipv6_xtrabackup-v2.test | 6 +- .../sys_vars/r/wsrep_sst_method_basic.result | 4 ++ .../sys_vars/t/wsrep_sst_method_basic.test | 5 ++ scripts/wsrep_sst_common.sh | 6 +- scripts/wsrep_sst_mariabackup.sh | 28 +++++++-- scripts/wsrep_sst_rsync.sh | 10 +++- sql/wsrep_utils.h | 3 +- support-files/policy/apparmor/usr.sbin.mysqld | 1 + .../policy/selinux/mariadb-server.fc | 1 + 29 files changed, 302 insertions(+), 69 deletions(-) delete mode 100644 mysql-test/suite/galera_3nodes/include/have_ipv6.inc create mode 100644 mysql-test/suite/galera_3nodes/r/galera_ipv6_mariabackup.result create mode 100644 mysql-test/suite/galera_3nodes/t/GAL-501.opt create mode 100644 mysql-test/suite/galera_3nodes/t/galera_innobackupex_backup.cnf create mode 100644 mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup.cnf create mode 100644 mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup.opt create mode 100644 mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup.test create mode 100644 mysql-test/suite/galera_3nodes/t/galera_ipv6_xtrabackup-v2.opt diff --git a/mysql-test/suite/galera_3nodes/disabled.def b/mysql-test/suite/galera_3nodes/disabled.def index a9b9b00b40c..1683485981b 100644 --- a/mysql-test/suite/galera_3nodes/disabled.def +++ b/mysql-test/suite/galera_3nodes/disabled.def @@ -1,3 +1,2 @@ galera_slave_options_do :MDEV-8798 galera_slave_options_ignore : MDEV-8798 - diff --git a/mysql-test/suite/galera_3nodes/galera_2x3nodes.cnf b/mysql-test/suite/galera_3nodes/galera_2x3nodes.cnf index 3f39b82f7b7..df51920c13c 100644 --- a/mysql-test/suite/galera_3nodes/galera_2x3nodes.cnf +++ b/mysql-test/suite/galera_3nodes/galera_2x3nodes.cnf @@ -22,7 +22,7 @@ wsrep_node_address=127.0.0.1 #ist_port=@OPT.port #sst_port=@OPT.port wsrep-cluster-address='gcomm://' -wsrep_provider_options='base_port=@mysqld.1.#galera_port;evs.suspect_timeout=PT300S;evs.inactive_timeout=PT1000M;evs.install_timeout=PT155S;evs.keepalive_period = PT100S' +wsrep_provider_options='repl.causal_read_timeout=PT90S;base_port=@mysqld.1.#galera_port;evs.suspect_timeout=PT300S;evs.inactive_timeout=PT1000M;evs.install_timeout=PT155S;evs.keepalive_period = PT100S' wsrep_sst_receive_address=127.0.0.2:@mysqld.1.#sst_port wsrep_node_incoming_address=127.0.0.1:@mysqld.1.port @@ -33,7 +33,7 @@ wsrep_sst_receive_address='127.0.0.1:@mysqld.1.#sst_port' #ist_port=@OPT.port #sst_port=@OPT.port wsrep_cluster_address='gcomm://127.0.0.1:@mysqld.1.#galera_port' -wsrep_provider_options='base_port=@mysqld.2.#galera_port;evs.suspect_timeout=PT300S;evs.inactive_timeout=PT1000M;evs.install_timeout=PT155S;evs.keepalive_period = PT100S' +wsrep_provider_options='repl.causal_read_timeout=PT90S;base_port=@mysqld.2.#galera_port;evs.suspect_timeout=PT300S;evs.inactive_timeout=PT1000M;evs.install_timeout=PT155S;evs.keepalive_period = PT100S' wsrep_sst_receive_address=127.0.0.2:@mysqld.2.#sst_port wsrep_node_incoming_address=127.0.0.1:@mysqld.2.port @@ -44,7 +44,7 @@ wsrep_sst_receive_address='127.0.0.1:@mysqld.2.#sst_port' #ist_port=@OPT.port #sst_port=@OPT.port wsrep_cluster_address='gcomm://127.0.0.1:@mysqld.1.#galera_port' -wsrep_provider_options='base_port=@mysqld.3.#galera_port;evs.suspect_timeout=PT300S;evs.inactive_timeout=PT1000M;evs.install_timeout=PT155S;evs.keepalive_period = PT100S' +wsrep_provider_options='repl.causal_read_timeout=PT90S;base_port=@mysqld.3.#galera_port;evs.suspect_timeout=PT300S;evs.inactive_timeout=PT1000M;evs.install_timeout=PT155S;evs.keepalive_period = PT100S' wsrep_sst_receive_address=127.0.0.2:@mysqld.3.#sst_port wsrep_node_incoming_address=127.0.0.1:@mysqld.3.port @@ -58,7 +58,7 @@ wsrep_cluster_name=cluster2 #sst_port=@OPT.port wsrep-cluster-address='gcomm://' -wsrep_provider_options='base_port=@mysqld.4.#galera_port;evs.suspect_timeout=PT300S;evs.inactive_timeout=PT1000M;evs.install_timeout=PT155S;evs.keepalive_period = PT100S' +wsrep_provider_options='repl.causal_read_timeout=PT90S;base_port=@mysqld.4.#galera_port;evs.suspect_timeout=PT300S;evs.inactive_timeout=PT1000M;evs.install_timeout=PT155S;evs.keepalive_period = PT100S' wsrep_sst_receive_address=127.0.0.2:@mysqld.4.#sst_port wsrep_node_incoming_address=127.0.0.1:@mysqld.4.port @@ -70,7 +70,7 @@ wsrep_cluster_name=cluster2 #ist_port=@OPT.port #sst_port=@OPT.port wsrep_cluster_address='gcomm://127.0.0.1:@mysqld.4.#galera_port' -wsrep_provider_options='base_port=@mysqld.5.#galera_port;evs.suspect_timeout=PT300S;evs.inactive_timeout=PT1000M;evs.install_timeout=PT155S;evs.keepalive_period = PT100S' +wsrep_provider_options='repl.causal_read_timeout=PT90S;base_port=@mysqld.5.#galera_port;evs.suspect_timeout=PT300S;evs.inactive_timeout=PT1000M;evs.install_timeout=PT155S;evs.keepalive_period = PT100S' wsrep_sst_receive_address=127.0.0.2:@mysqld.5.#sst_port wsrep_node_incoming_address=127.0.0.1:@mysqld.5.port @@ -82,7 +82,7 @@ wsrep_cluster_name=cluster2 #ist_port=@OPT.port #sst_port=@OPT.port wsrep_cluster_address='gcomm://127.0.0.1:@mysqld.4.#galera_port' -wsrep_provider_options='base_port=@mysqld.6.#galera_port;evs.suspect_timeout=PT300S;evs.inactive_timeout=PT1000M;evs.install_timeout=PT155S;evs.keepalive_period = PT100S' +wsrep_provider_options='repl.causal_read_timeout=PT90S;base_port=@mysqld.6.#galera_port;evs.suspect_timeout=PT300S;evs.inactive_timeout=PT1000M;evs.install_timeout=PT155S;evs.keepalive_period = PT100S' wsrep_sst_receive_address=127.0.0.2:@mysqld.6.#sst_port wsrep_node_incoming_address=127.0.0.1:@mysqld.6.port diff --git a/mysql-test/suite/galera_3nodes/galera_3nodes.cnf b/mysql-test/suite/galera_3nodes/galera_3nodes.cnf index 91aa53ad7b1..7b68d36c04a 100644 --- a/mysql-test/suite/galera_3nodes/galera_3nodes.cnf +++ b/mysql-test/suite/galera_3nodes/galera_3nodes.cnf @@ -18,7 +18,7 @@ wsrep-sync-wait=15 #ist_port=@OPT.port #sst_port=@OPT.port wsrep-cluster-address='gcomm://' -wsrep_provider_options='base_port=@mysqld.1.#galera_port;evs.suspect_timeout=PT10S;evs.inactive_timeout=PT30S;evs.install_timeout=PT15S' +wsrep_provider_options='repl.causal_read_timeout=PT90S;base_port=@mysqld.1.#galera_port;evs.suspect_timeout=PT10S;evs.inactive_timeout=PT30S;evs.install_timeout=PT15S' wsrep_sst_receive_address=127.0.0.2:@mysqld.1.#sst_port wsrep_node_incoming_address=127.0.0.1:@mysqld.1.port @@ -29,7 +29,7 @@ wsrep_sst_receive_address='127.0.0.1:@mysqld.1.#sst_port' #ist_port=@OPT.port #sst_port=@OPT.port wsrep_cluster_address='gcomm://127.0.0.1:@mysqld.1.#galera_port' -wsrep_provider_options='base_port=@mysqld.2.#galera_port;evs.suspect_timeout=PT10S;evs.inactive_timeout=PT30S;evs.install_timeout=PT15S' +wsrep_provider_options='repl.causal_read_timeout=PT90S;base_port=@mysqld.2.#galera_port;evs.suspect_timeout=PT10S;evs.inactive_timeout=PT30S;evs.install_timeout=PT15S' wsrep_sst_receive_address=127.0.0.2:@mysqld.2.#sst_port wsrep_node_incoming_address=127.0.0.1:@mysqld.2.port @@ -40,7 +40,7 @@ wsrep_sst_receive_address='127.0.0.1:@mysqld.2.#sst_port' #ist_port=@OPT.port #sst_port=@OPT.port wsrep_cluster_address='gcomm://127.0.0.1:@mysqld.1.#galera_port' -wsrep_provider_options='base_port=@mysqld.3.#galera_port;evs.suspect_timeout=PT10S;evs.inactive_timeout=PT30S;evs.install_timeout=PT15S' +wsrep_provider_options='repl.causal_read_timeout=PT90S;base_port=@mysqld.3.#galera_port;evs.suspect_timeout=PT10S;evs.inactive_timeout=PT30S;evs.install_timeout=PT15S' wsrep_sst_receive_address=127.0.0.2:@mysqld.3.#sst_port wsrep_node_incoming_address=127.0.0.1:@mysqld.3.port diff --git a/mysql-test/suite/galera_3nodes/include/have_ipv6.inc b/mysql-test/suite/galera_3nodes/include/have_ipv6.inc deleted file mode 100644 index 560cad03350..00000000000 --- a/mysql-test/suite/galera_3nodes/include/have_ipv6.inc +++ /dev/null @@ -1,15 +0,0 @@ -# Check if ipv6 is available. -# ---disable_query_log ---disable_result_log -connect (checkcon123456789,::1,root,,test); -if($mysql_errno) -{ - skip No IPv6 support; -} -connection default; -disconnect checkcon123456789; ---enable_result_log ---enable_query_log -# end check - diff --git a/mysql-test/suite/galera_3nodes/r/galera_ipv6_mariabackup.result b/mysql-test/suite/galera_3nodes/r/galera_ipv6_mariabackup.result new file mode 100644 index 00000000000..53e35939a79 --- /dev/null +++ b/mysql-test/suite/galera_3nodes/r/galera_ipv6_mariabackup.result @@ -0,0 +1,18 @@ +SELECT VARIABLE_VALUE LIKE '%[::1]%' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_incoming_addresses'; +VARIABLE_VALUE LIKE '%[::1]%' +1 +SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +VARIABLE_VALUE = 3 +1 +SET GLOBAL wsrep_provider_options='gmcast.isolate=1'; +CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +SET GLOBAL wsrep_provider_options='gmcast.isolate=0'; +SELECT COUNT(*) = 1 FROM t1; +COUNT(*) = 1 +1 +DROP TABLE t1; +include/assert_grep.inc [Streaming the backup to joiner at \[::1\]] +include/assert_grep.inc [async IST sender starting to serve tcp://\[::1\]:] +include/assert_grep.inc [IST receiver addr using tcp://\[::1\]] +include/assert_grep.inc [Prepared IST receiver, listening at: tcp://\[::1\]] diff --git a/mysql-test/suite/galera_3nodes/r/galera_ipv6_mysqldump.result b/mysql-test/suite/galera_3nodes/r/galera_ipv6_mysqldump.result index f519654952b..1d9ae940cfb 100644 --- a/mysql-test/suite/galera_3nodes/r/galera_ipv6_mysqldump.result +++ b/mysql-test/suite/galera_3nodes/r/galera_ipv6_mysqldump.result @@ -1,11 +1,14 @@ +call mtr.add_suppression("WSREP: wsrep_sst_method is set to 'mysqldump' yet mysqld bind_address is set to'"); +call mtr.add_suppression("Failed to load slave replication state from table mysql.gtid_slave_pos"); +CREATE USER 'sst'; GRANT ALL PRIVILEGES ON *.* TO 'sst'; SET GLOBAL wsrep_sst_auth = 'sst:'; SET GLOBAL wsrep_sst_method = 'mysqldump'; -Unloading wsrep provider ... -SET GLOBAL wsrep_provider = 'none'; +Shutting down server ... +Cleaning var directory ... CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; INSERT INTO t1 VALUES (1); -Loading wsrep provider ... +Starting server ... SELECT COUNT(*) = 1 FROM t1; COUNT(*) = 1 1 diff --git a/mysql-test/suite/galera_3nodes/suite.pm b/mysql-test/suite/galera_3nodes/suite.pm index c91e6e07d76..66502c00c6b 100644 --- a/mysql-test/suite/galera_3nodes/suite.pm +++ b/mysql-test/suite/galera_3nodes/suite.pm @@ -9,8 +9,10 @@ return "Not run for embedded server" if $::opt_embedded_server; return "WSREP is not compiled in" unless defined $::mysqld_variables{'wsrep-on'}; my ($provider) = grep { -f $_ } $ENV{WSREP_PROVIDER}, - "/usr/lib/galera/libgalera_smm.so", - "/usr/lib64/galera/libgalera_smm.so"; + "/usr/lib64/galera-3/libgalera_smm.so", + "/usr/lib64/galera/libgalera_smm.so", + "/usr/lib/galera-3/libgalera_smm.so", + "/usr/lib/galera/libgalera_smm.so"; return "No wsrep provider library" unless -f $provider; @@ -19,14 +21,21 @@ $ENV{WSREP_PROVIDER} = $provider; my ($spath) = grep { -f "$_/wsrep_sst_rsync"; } "$::bindir/scripts", $::path_client_bindir; return "No SST scripts" unless $spath; +my ($cpath) = grep { -f "$_/mysql"; } "$::bindir/scripts", $::path_client_bindir; +return "No scritps" unless $cpath; + my ($epath) = grep { -f "$_/my_print_defaults"; } "$::bindir/extra", $::path_client_bindir; return "No my_print_defaults" unless $epath; +my ($bpath) = grep { -f "$_/mariabackup"; } "$::bindir/extra/mariabackup", $::path_client_bindir; + +sub which($) { return `sh -c "command -v $_[0]"` } + push @::global_suppressions, ( qr(WSREP: wsrep_sst_receive_address is set to '127.0.0.1), - qr(WSREP: Could not open saved state file for reading: ), - qr(WSREP: Could not open state file for reading: ), + qr(WSREP: Could not open saved state file for reading: .*), + qr(WSREP: Could not open state file for reading: .*), qr(WSREP: Gap in state sequence. Need state transfer.), qr(WSREP: Failed to prepare for incremental state transfer:), qr(WSREP:.*down context.*), @@ -40,16 +49,46 @@ push @::global_suppressions, qr|WSREP: discarding established \(time wait\) .*|, qr(WSREP: There are no nodes in the same segment that will ever be able to become donors, yet there is a suitable donor outside. Will use that one.), qr(WSREP: evs::proto.*), - qr|WSREP: Ignoring possible split-brain (allowed by configuration) from view:.*|, + qr|WSREP: Ignoring possible split-brain \(allowed by configuration\) from view:.*|, + qr(WSREP: no nodes coming from prim view, prim not possible), qr(WSREP: Member .* requested state transfer from .* but it is impossible to select State Transfer donor: Resource temporarily unavailable), + qr(WSREP: user message in state LEAVING), + qr(WSREP: .* sending install message failed: Transport endpoint is not connected), + qr(WSREP: .* sending install message failed: Resource temporarily unavailable), + qr(WSREP: Sending JOIN failed: -107 \(Transport endpoint is not connected\). Will retry in new primary component.), qr(WSREP: Could not find peer:), - qr(WSREP: Protocol violation. JOIN message sender .*), - qr(WSREP: JOIN message from member [0-9]* in non-primary configuration. Ignored.), + qr|WSREP: gcs_caused\(\) returned .*|, + qr|WSREP: Protocol violation. JOIN message sender .* is not in state transfer \(SYNCED\). Message ignored.|, + qr|WSREP: Protocol violation. JOIN message sender .* is not in state transfer \(JOINED\). Message ignored.|, + qr(WSREP: Action message in non-primary configuration from member [0-9]*), + qr(WSREP: --wsrep-causal-reads=ON takes precedence over --wsrep-sync-wait=0. WSREP_SYNC_WAIT_BEFORE_READ is on), + qr(WSREP: JOIN message from member .* in non-primary configuration. Ignored.), ); $ENV{PATH}="$epath:$ENV{PATH}"; $ENV{PATH}="$spath:$ENV{PATH}" unless $epath eq $spath; +$ENV{PATH}="$cpath:$ENV{PATH}" unless $cpath eq $spath; +$ENV{PATH}="$bpath:$ENV{PATH}" unless $bpath eq $spath; + +if (which(socat)) { + $ENV{MTR_GALERA_TFMT}='socat'; +} elsif (which(nc)) { + $ENV{MTR_GALERA_TFMT}='nc'; +} + +sub skip_combinations { + my %skip = (); + $skip{'include/have_filekeymanagement.inc'} = 'needs file_key_management plugin' + unless $ENV{FILE_KEY_MANAGEMENT_SO}; + $skip{'include/have_mariabackup.inc'} = 'Need mariabackup' + unless which(mariabackup); + $skip{'include/have_mariabackup.inc'} = 'Need ss' + unless which(ss); + $skip{'include/have_mariabackup.inc'} = 'Need socat or nc' + unless $ENV{MTR_GALERA_TFMT}; + %skip; +} bless { }; diff --git a/mysql-test/suite/galera_3nodes/t/GAL-501.opt b/mysql-test/suite/galera_3nodes/t/GAL-501.opt new file mode 100644 index 00000000000..c2bb4d156af --- /dev/null +++ b/mysql-test/suite/galera_3nodes/t/GAL-501.opt @@ -0,0 +1 @@ +--bind-address=:: diff --git a/mysql-test/suite/galera_3nodes/t/GAL-501.test b/mysql-test/suite/galera_3nodes/t/GAL-501.test index 60ed5989227..a36f21630ac 100644 --- a/mysql-test/suite/galera_3nodes/t/GAL-501.test +++ b/mysql-test/suite/galera_3nodes/t/GAL-501.test @@ -5,7 +5,7 @@ # ist.recv_addr=[::1] --source include/galera_cluster.inc ---source include/have_ipv6.inc +--source include/check_ipv6.inc # Confirm that initial handshake happened over ipv6 diff --git a/mysql-test/suite/galera_3nodes/t/galera_innobackupex_backup.cnf b/mysql-test/suite/galera_3nodes/t/galera_innobackupex_backup.cnf new file mode 100644 index 00000000000..35ecb8b5937 --- /dev/null +++ b/mysql-test/suite/galera_3nodes/t/galera_innobackupex_backup.cnf @@ -0,0 +1,4 @@ +!include ../galera_3nodes.cnf + +[mysqld] +wsrep-causal-reads=OFF diff --git a/mysql-test/suite/galera_3nodes/t/galera_innobackupex_backup.test b/mysql-test/suite/galera_3nodes/t/galera_innobackupex_backup.test index cc3f42c7290..8dfb4660f3e 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_innobackupex_backup.test +++ b/mysql-test/suite/galera_3nodes/t/galera_innobackupex_backup.test @@ -4,6 +4,17 @@ --source include/galera_cluster.inc --source include/have_innodb.inc +--source include/have_mariabackup.inc + +--let $galera_connection_name = node_3 +--let $galera_server_number = 3 +--source include/galera_connect.inc + +# Save original auto_increment_offset values. +--let $node_1=node_1 +--let $node_2=node_2 +--let $node_3=node_3 +--source ../galera/include/auto_increment_offset_save.inc --connection node_1 CREATE TABLE t1 (f1 INTEGER); @@ -13,8 +24,8 @@ INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); SELECT COUNT(*) = 10 FROM t1; --exec rm -rf $MYSQL_TMP_DIR/innobackupex_backup ---exec innobackupex --defaults-file=$MYSQLTEST_VARDIR/my.cnf --defaults-group=mysqld.2 $MYSQL_TMP_DIR/innobackupex_backup --galera-info --port=$NODE_MYPORT_2 --host=127.0.0.1 --no-timestamp > $MYSQL_TMP_DIR/innobackupex-backup.log ---exec innobackupex --defaults-file=$MYSQLTEST_VARDIR/my.cnf --defaults-group=mysqld.2 $MYSQL_TMP_DIR/innobackupex_backup --apply-log --galera-info --port=$NODE_MYPORT_2 --host=127.0.0.1 --no-timestamp > $MYSQL_TMP_DIR/innobackupex-apply.log +--exec mariabackup --innobackupex --defaults-file=$MYSQLTEST_VARDIR/my.cnf --defaults-group=mysqld.2 --galera-info --port=$NODE_MYPORT_2 --host=127.0.0.1 --no-timestamp $MYSQL_TMP_DIR/innobackupex_backup &> $MYSQL_TMP_DIR/innobackupex-backup.log +--exec mariabackup --innobackupex --defaults-file=$MYSQLTEST_VARDIR/my.cnf --defaults-group=mysqld.2 --apply-log --galera-info --port=$NODE_MYPORT_2 --host=127.0.0.1 --no-timestamp $MYSQL_TMP_DIR/innobackupex_backup &> $MYSQL_TMP_DIR/innobackupex-apply.log --source ../galera/include/kill_galera.inc --sleep 1 @@ -23,7 +34,7 @@ SELECT COUNT(*) = 10 FROM t1; INSERT INTO t1 VALUES (11),(12),(13),(14),(15),(16),(17),(18),(19),(20); --exec rm -rf $MYSQLTEST_VARDIR/mysqld.2/data/* ---exec innobackupex --defaults-file=$MYSQLTEST_VARDIR/my.cnf --defaults-group=mysqld.2 --copy-back $MYSQL_TMP_DIR/innobackupex_backup --port=$NODE_MYPORT_2 --host=127.0.0.1 > $MYSQL_TMP_DIR/innobackupex-restore.log +--exec mariabackup --innobackupex --defaults-file=$MYSQLTEST_VARDIR/my.cnf --defaults-group=mysqld.2 --copy-back --port=$NODE_MYPORT_2 --host=127.0.0.1 $MYSQL_TMP_DIR/innobackupex_backup &> $MYSQL_TMP_DIR/innobackupex-restore.log # # Convert the xtrabackup_galera_info into a grastate.dat file @@ -51,8 +62,19 @@ EOF --sleep 5 --source include/wait_until_connected_again.inc +--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc + SELECT COUNT(*) = 20 FROM t1; DROP TABLE t1; --sleep 10 + +--let $galera_connection_name = node_2a +--let $galera_server_number = 2 +--source include/galera_connect.inc +--let $node_2=node_2a + +# Restore original auto_increment_offset values. +--source ../galera/include/auto_increment_offset_restore.inc diff --git a/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup.cnf b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup.cnf new file mode 100644 index 00000000000..5ac00fa056b --- /dev/null +++ b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup.cnf @@ -0,0 +1,29 @@ +!include ../galera_3nodes.cnf + +[mysqld] +wsrep_sst_method=mariabackup +wsrep_sst_auth="root:" +wsrep_node_address=::1 + +[mysqld.1] +wsrep-cluster-address=gcomm:// +wsrep_provider_options='base_host=[::1];base_port=@mysqld.1.#galera_port;gmcast.listen_addr=tcp://[::]:@mysqld.1.#galera_port;ist.recv_addr=[::1]:@mysqld.1.#ist_port' +wsrep_sst_receive_address='[::1]:@mysqld.1.#sst_port' +wsrep_node_incoming_address='[::1]:@mysqld.1.port' + +[mysqld.2] +wsrep_cluster_address='gcomm://[::1]:@mysqld.1.#galera_port' +wsrep_provider_options='base_host=[::1];base_port=@mysqld.2.#galera_port;gmcast.listen_addr=tcp://[::]:@mysqld.2.#galera_port;ist.recv_addr=[::1]:@mysqld.2.#ist_port' +wsrep_sst_receive_address='[::1]:@mysqld.2.#sst_port' +wsrep_node_incoming_address='[::1]:@mysqld.2.port' + +[mysqld.3] +wsrep_cluster_address='gcomm://[::1]:@mysqld.1.#galera_port' +wsrep_provider_options='base_host=[::1];base_port=@mysqld.3.#galera_port;gmcast.listen_addr=tcp://[::]:@mysqld.3.#galera_port;ist.recv_addr=[::1]:@mysqld.3.#ist_port' +wsrep_sst_receive_address='[::1]:@mysqld.3.#sst_port' +wsrep_node_incoming_address='[::1]:@mysqld.3.port' + +[SST] +transferfmt=@ENV.MTR_GALERA_TFMT +streamfmt=xbstream +sockopt=",pf=ip6" diff --git a/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup.opt b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup.opt new file mode 100644 index 00000000000..c2bb4d156af --- /dev/null +++ b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup.opt @@ -0,0 +1 @@ +--bind-address=:: diff --git a/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup.test b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup.test new file mode 100644 index 00000000000..8cbd8cf2454 --- /dev/null +++ b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup.test @@ -0,0 +1,59 @@ +--source include/galera_cluster.inc +--source include/check_ipv6.inc +--source include/have_mariabackup.inc + +# Confirm that initial handshake happened over ipv6 + +SELECT VARIABLE_VALUE LIKE '%[::1]%' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_incoming_addresses'; +SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; + +# Force IST + +--connection node_2 +SET GLOBAL wsrep_provider_options='gmcast.isolate=1'; + +--connection node_1 +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc + +CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); + +--connection node_2 +SET GLOBAL wsrep_provider_options='gmcast.isolate=0'; + +--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc + +--let $wait_condition = SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready'; +--source include/wait_condition.inc + +SELECT COUNT(*) = 1 FROM t1; + +DROP TABLE t1; + +# Confirm that key messages around SST and IST reference IPv6 + +--connection node_1 +--let $assert_file = $MYSQLTEST_VARDIR/log/mysqld.1.err +--let $assert_only_after = CURRENT_TEST + +--let $assert_count = 2 +--let $assert_text = Streaming the backup to joiner at \[::1\] +--let $assert_select = Streaming the backup to joiner at \[::1\] +--source include/assert_grep.inc + +--let $assert_count = 1 +--let $assert_text = async IST sender starting to serve tcp://\[::1\]: +--let $assert_select = async IST sender starting to serve tcp://\[::1\]: +--source include/assert_grep.inc + +--let $assert_file = $MYSQLTEST_VARDIR/log/mysqld.2.err + +--let $assert_text = IST receiver addr using tcp://\[::1\] +--let $assert_select = IST receiver addr using tcp://\[::1\] +--source include/assert_grep.inc + +--let $assert_text = Prepared IST receiver, listening at: tcp://\[::1\] +--let $assert_select = Prepared IST receiver, listening at: tcp://\[::1\] +--source include/assert_grep.inc diff --git a/mysql-test/suite/galera_3nodes/t/galera_ipv6_mysqldump.cnf b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mysqldump.cnf index 3728e1ce005..80dd0c41cc3 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_ipv6_mysqldump.cnf +++ b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mysqldump.cnf @@ -2,21 +2,25 @@ [mysqld] wsrep_sst_method=rsync +wsrep_node_address=::1 [mysqld.1] wsrep-cluster-address=gcomm:// -wsrep_provider_options='base_port=@mysqld.1.#galera_port;gmcast.listen_addr=tcp://[::]:@mysqld.1.#galera_port;ist.recv_addr=[::1]:@mysqld.1.#ist_port' +wsrep_provider_options='base_host=[::1];base_port=@mysqld.1.#galera_port;gmcast.listen_addr=tcp://[::]:@mysqld.1.#galera_port;ist.recv_addr=[::1]:@mysqld.1.#ist_port' wsrep_sst_receive_address='[::1]:@mysqld.1.#sst_port' wsrep_node_incoming_address='[::1]:@mysqld.1.port' [mysqld.2] wsrep_cluster_address='gcomm://[::1]:@mysqld.1.#galera_port' -wsrep_provider_options='base_port=@mysqld.2.#galera_port;gmcast.listen_addr=tcp://[::]:@mysqld.2.#galera_port;ist.recv_addr=[::1]:@mysqld.2.#ist_port' +wsrep_provider_options='base_host=[::1];base_port=@mysqld.2.#galera_port;gmcast.listen_addr=tcp://[::]:@mysqld.2.#galera_port;ist.recv_addr=[::1]:@mysqld.2.#ist_port' wsrep_sst_receive_address='[::1]:@mysqld.2.#sst_port' wsrep_node_incoming_address='[::1]:@mysqld.2.port' [mysqld.3] wsrep_cluster_address='gcomm://[::1]:@mysqld.1.#galera_port' -wsrep_provider_options='base_port=@mysqld.3.#galera_port;gmcast.listen_addr=tcp://[::]:@mysqld.3.#galera_port;ist.recv_addr=[::1]:@mysqld.3.#ist_port' +wsrep_provider_options='base_host=[::1];base_port=@mysqld.3.#galera_port;gmcast.listen_addr=tcp://[::]:@mysqld.3.#galera_port;ist.recv_addr=[::1]:@mysqld.3.#ist_port' wsrep_sst_receive_address='[::1]:@mysqld.3.#sst_port' wsrep_node_incoming_address='[::1]:@mysqld.3.port' + +[SST] +sockopt=",pf=ip6" diff --git a/mysql-test/suite/galera_3nodes/t/galera_ipv6_mysqldump.test b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mysqldump.test index 5b06e617eef..4a6de8abb9c 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_ipv6_mysqldump.test +++ b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mysqldump.test @@ -1,7 +1,21 @@ --source include/galera_cluster.inc ---source include/have_ipv6.inc +--source include/check_ipv6.inc + +call mtr.add_suppression("WSREP: wsrep_sst_method is set to 'mysqldump' yet mysqld bind_address is set to'"); +call mtr.add_suppression("Failed to load slave replication state from table mysql.gtid_slave_pos"); + +--let $galera_connection_name = node_3 +--let $galera_server_number = 3 +--source include/galera_connect.inc + +# Save original auto_increment_offset values. +--let $node_1=node_1 +--let $node_2=node_2 +--let $node_3=node_3 +--source ../galera/include/auto_increment_offset_save.inc --connection node_1 +CREATE USER 'sst'; GRANT ALL PRIVILEGES ON *.* TO 'sst'; --let $wsrep_sst_auth_orig = `SELECT @@wsrep_sst_auth` @@ -17,25 +31,37 @@ SET GLOBAL wsrep_sst_auth = 'sst:'; --enable_query_log SET GLOBAL wsrep_sst_method = 'mysqldump'; - # # Force mysqldump SST # ---connection node_2 ---source suite/galera/include/galera_unload_provider.inc ---remove_file $MYSQLTEST_VARDIR/mysqld.2/data/grastate.dat +#--connection node_2 +#--source suite/galera/include/galera_unload_provider.inc + +--echo Shutting down server ... +--source include/shutdown_mysqld.inc --connection node_1 --let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' --source include/wait_condition.inc +--echo Cleaning var directory ... +--remove_file $MYSQLTEST_VARDIR/mysqld.2/data/grastate.dat +--remove_files_wildcard $MYSQLTEST_VARDIR/mysqld.2/data/mtr +--remove_files_wildcard $MYSQLTEST_VARDIR/mysqld.2/data/performance_schema +--remove_files_wildcard $MYSQLTEST_VARDIR/mysqld.2/data/test +--remove_files_wildcard $MYSQLTEST_VARDIR/mysqld.2/data/mysql +--remove_files_wildcard $MYSQLTEST_VARDIR/mysqld.2/data + CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; INSERT INTO t1 VALUES (1); - --connection node_2 ---source suite/galera/include/galera_load_provider.inc +--echo Starting server ... +--let $start_mysqld_params = --wsrep_sst_auth=sst: --wsrep_sst_method=mysqldump --wsrep-sst-receive-address=[::1].1:$NODE_MYPORT_2 +--source include/start_mysqld.inc + +#--source suite/galera/include/galera_load_provider.inc --let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' --source include/wait_condition.inc @@ -54,3 +80,6 @@ SELECT VARIABLE_VALUE LIKE '%[::1]%' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE --source suite/galera/include/galera_sst_restore.inc --connection node_2 CALL mtr.add_suppression("Unsupported protocol downgrade: incremental data collection disabled. Expect abort"); + +# Restore original auto_increment_offset values. +--source ../galera/include/auto_increment_offset_restore.inc diff --git a/mysql-test/suite/galera_3nodes/t/galera_ipv6_rsync.cnf b/mysql-test/suite/galera_3nodes/t/galera_ipv6_rsync.cnf index 3728e1ce005..80dd0c41cc3 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_ipv6_rsync.cnf +++ b/mysql-test/suite/galera_3nodes/t/galera_ipv6_rsync.cnf @@ -2,21 +2,25 @@ [mysqld] wsrep_sst_method=rsync +wsrep_node_address=::1 [mysqld.1] wsrep-cluster-address=gcomm:// -wsrep_provider_options='base_port=@mysqld.1.#galera_port;gmcast.listen_addr=tcp://[::]:@mysqld.1.#galera_port;ist.recv_addr=[::1]:@mysqld.1.#ist_port' +wsrep_provider_options='base_host=[::1];base_port=@mysqld.1.#galera_port;gmcast.listen_addr=tcp://[::]:@mysqld.1.#galera_port;ist.recv_addr=[::1]:@mysqld.1.#ist_port' wsrep_sst_receive_address='[::1]:@mysqld.1.#sst_port' wsrep_node_incoming_address='[::1]:@mysqld.1.port' [mysqld.2] wsrep_cluster_address='gcomm://[::1]:@mysqld.1.#galera_port' -wsrep_provider_options='base_port=@mysqld.2.#galera_port;gmcast.listen_addr=tcp://[::]:@mysqld.2.#galera_port;ist.recv_addr=[::1]:@mysqld.2.#ist_port' +wsrep_provider_options='base_host=[::1];base_port=@mysqld.2.#galera_port;gmcast.listen_addr=tcp://[::]:@mysqld.2.#galera_port;ist.recv_addr=[::1]:@mysqld.2.#ist_port' wsrep_sst_receive_address='[::1]:@mysqld.2.#sst_port' wsrep_node_incoming_address='[::1]:@mysqld.2.port' [mysqld.3] wsrep_cluster_address='gcomm://[::1]:@mysqld.1.#galera_port' -wsrep_provider_options='base_port=@mysqld.3.#galera_port;gmcast.listen_addr=tcp://[::]:@mysqld.3.#galera_port;ist.recv_addr=[::1]:@mysqld.3.#ist_port' +wsrep_provider_options='base_host=[::1];base_port=@mysqld.3.#galera_port;gmcast.listen_addr=tcp://[::]:@mysqld.3.#galera_port;ist.recv_addr=[::1]:@mysqld.3.#ist_port' wsrep_sst_receive_address='[::1]:@mysqld.3.#sst_port' wsrep_node_incoming_address='[::1]:@mysqld.3.port' + +[SST] +sockopt=",pf=ip6" diff --git a/mysql-test/suite/galera_3nodes/t/galera_ipv6_rsync.test b/mysql-test/suite/galera_3nodes/t/galera_ipv6_rsync.test index 7ee209d8e72..1937eb43e13 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_ipv6_rsync.test +++ b/mysql-test/suite/galera_3nodes/t/galera_ipv6_rsync.test @@ -1,5 +1,5 @@ --source include/galera_cluster.inc ---source include/have_ipv6.inc +--source include/check_ipv6.inc # Confirm that initial handshake happened over ipv6 diff --git a/mysql-test/suite/galera_3nodes/t/galera_ipv6_xtrabackup-v2.cnf b/mysql-test/suite/galera_3nodes/t/galera_ipv6_xtrabackup-v2.cnf index 8a80be0d2a9..78fbd793aa0 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_ipv6_xtrabackup-v2.cnf +++ b/mysql-test/suite/galera_3nodes/t/galera_ipv6_xtrabackup-v2.cnf @@ -3,6 +3,7 @@ [mysqld] wsrep_sst_method=xtrabackup-v2 wsrep_sst_auth="root:" +wsrep_node_address=::1 [mysqld.1] wsrep-cluster-address=gcomm:// @@ -23,4 +24,6 @@ wsrep_sst_receive_address='[::1]:@mysqld.3.#sst_port' wsrep_node_incoming_address='[::1]:@mysqld.3.port' [SST] +transferfmt=@ENV.MTR_GALERA_TFMT +streamfmt=xbstream sockopt=",pf=ip6" diff --git a/mysql-test/suite/galera_3nodes/t/galera_ipv6_xtrabackup-v2.opt b/mysql-test/suite/galera_3nodes/t/galera_ipv6_xtrabackup-v2.opt new file mode 100644 index 00000000000..c2bb4d156af --- /dev/null +++ b/mysql-test/suite/galera_3nodes/t/galera_ipv6_xtrabackup-v2.opt @@ -0,0 +1 @@ +--bind-address=:: diff --git a/mysql-test/suite/galera_3nodes/t/galera_ipv6_xtrabackup-v2.test b/mysql-test/suite/galera_3nodes/t/galera_ipv6_xtrabackup-v2.test index 84eee017700..fd7e0c50887 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_ipv6_xtrabackup-v2.test +++ b/mysql-test/suite/galera_3nodes/t/galera_ipv6_xtrabackup-v2.test @@ -1,5 +1,5 @@ --source include/galera_cluster.inc ---source include/have_ipv6.inc +--source include/check_ipv6.inc # Confirm that initial handshake happened over ipv6 @@ -56,7 +56,3 @@ DROP TABLE t1; --let $assert_text = Prepared IST receiver, listening at: tcp://\[::1\] --let $assert_select = Prepared IST receiver, listening at: tcp://\[::1\] --source include/assert_grep.inc - - - - diff --git a/mysql-test/suite/sys_vars/r/wsrep_sst_method_basic.result b/mysql-test/suite/sys_vars/r/wsrep_sst_method_basic.result index cbdac640c36..51f167b8f47 100644 --- a/mysql-test/suite/sys_vars/r/wsrep_sst_method_basic.result +++ b/mysql-test/suite/sys_vars/r/wsrep_sst_method_basic.result @@ -33,6 +33,10 @@ SET @@global.wsrep_sst_method="xtrabackup-v2"; SELECT @@global.wsrep_sst_method; @@global.wsrep_sst_method xtrabackup-v2 +SET @@global.wsrep_sst_method="mariabackup"; +SELECT @@global.wsrep_sst_method; +@@global.wsrep_sst_method +mariabackup SET @@global.wsrep_sst_method=default; SELECT @@global.wsrep_sst_method; @@global.wsrep_sst_method diff --git a/mysql-test/suite/sys_vars/t/wsrep_sst_method_basic.test b/mysql-test/suite/sys_vars/t/wsrep_sst_method_basic.test index 3f40a3922dd..4eda96a7723 100644 --- a/mysql-test/suite/sys_vars/t/wsrep_sst_method_basic.test +++ b/mysql-test/suite/sys_vars/t/wsrep_sst_method_basic.test @@ -23,10 +23,15 @@ SET @@global.wsrep_sst_method=rsync; SELECT @@global.wsrep_sst_method; SET @@global.wsrep_sst_method=mysqldump; SELECT @@global.wsrep_sst_method; +# The xtrabackup and xtrabackup-v2 methods are obsolete, +# but we can still select them (they will be automatically +# replaced to mariabackup in next versions of server): SET @@global.wsrep_sst_method=xtrabackup; SELECT @@global.wsrep_sst_method; SET @@global.wsrep_sst_method="xtrabackup-v2"; SELECT @@global.wsrep_sst_method; +SET @@global.wsrep_sst_method="mariabackup"; +SELECT @@global.wsrep_sst_method; SET @@global.wsrep_sst_method=default; SELECT @@global.wsrep_sst_method; diff --git a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh index e63ffdfa58b..976f0e0cf2d 100644 --- a/scripts/wsrep_sst_common.sh +++ b/scripts/wsrep_sst_common.sh @@ -44,13 +44,15 @@ case "$1" in addr_no_bracket=${WSREP_SST_OPT_ADDR#\[} readonly WSREP_SST_OPT_HOST_UNESCAPED=${addr_no_bracket%%\]*} readonly WSREP_SST_OPT_HOST="[${WSREP_SST_OPT_HOST_UNESCAPED}]" + readonly WSREP_SST_OPT_HOST_ESCAPED="\\[${WSREP_SST_OPT_HOST_UNESCAPED}\\]" ;; *) readonly WSREP_SST_OPT_HOST=${WSREP_SST_OPT_ADDR%%[:/]*} readonly WSREP_SST_OPT_HOST_UNESCAPED=$WSREP_SST_OPT_HOST + readonly WSREP_SST_OPT_HOST_ESCAPED=$WSREP_SST_OPT_HOST ;; esac - remain=${WSREP_SST_OPT_ADDR#${WSREP_SST_OPT_HOST}} + remain=${WSREP_SST_OPT_ADDR#${WSREP_SST_OPT_HOST_ESCAPED}} remain=${remain#:} readonly WSREP_SST_OPT_ADDR_PORT=${remain%%/*} remain=${remain#*/} @@ -277,7 +279,7 @@ wsrep_check_programs() } # -# user can specify xtrabackup specific settings that will be used during sst +# user can specify mariabackup specific settings that will be used during sst # process like encryption, etc..... # parse such configuration option. (group for xb settings is [sst] in my.cnf # diff --git a/scripts/wsrep_sst_mariabackup.sh b/scripts/wsrep_sst_mariabackup.sh index 70bd76a36eb..4891ade7c3c 100644 --- a/scripts/wsrep_sst_mariabackup.sh +++ b/scripts/wsrep_sst_mariabackup.sh @@ -520,12 +520,24 @@ kill_xtrabackup() setup_ports() { if [[ "$WSREP_SST_OPT_ROLE" == "donor" ]];then - SST_PORT=$(echo $WSREP_SST_OPT_ADDR | awk -F '[:/]' '{ print $2 }') - REMOTEIP=$(echo $WSREP_SST_OPT_ADDR | awk -F ':' '{ print $1 }') - lsn=$(echo $WSREP_SST_OPT_ADDR | awk -F '[:/]' '{ print $4 }') - sst_ver=$(echo $WSREP_SST_OPT_ADDR | awk -F '[:/]' '{ print $5 }') + if [[ ${WSREP_SST_OPT_ADDR:0:1} == '[' ]];then + remain=$(echo $WSREP_SST_OPT_ADDR | awk -F '\\][:/]' '{ print $2 }') + REMOTEIP=$(echo $WSREP_SST_OPT_ADDR | awk -F '\\]:' '{ print $1 }')"]" + SST_PORT=$(echo $remain | awk -F '[:/]' '{ print $1 }') + lsn=$(echo $remain | awk -F '[:/]' '{ print $3 }') + sst_ver=$(echo $remain | awk -F '[:/]' '{ print $4 }') + else + SST_PORT=$(echo $WSREP_SST_OPT_ADDR | awk -F '[:/]' '{ print $2 }') + REMOTEIP=$(echo $WSREP_SST_OPT_ADDR | awk -F ':' '{ print $1 }') + lsn=$(echo $WSREP_SST_OPT_ADDR | awk -F '[:/]' '{ print $4 }') + sst_ver=$(echo $WSREP_SST_OPT_ADDR | awk -F '[:/]' '{ print $5 }') + fi else - SST_PORT=$(echo ${WSREP_SST_OPT_ADDR} | awk -F ':' '{ print $2 }') + if [[ ${WSREP_SST_OPT_ADDR:0:1} == '[' ]];then + SST_PORT=$(echo ${WSREP_SST_OPT_ADDR} | awk -F '\\]:' '{ print $2 }') + else + SST_PORT=$(echo ${WSREP_SST_OPT_ADDR} | awk -F ':' '{ print $2 }') + fi fi } @@ -940,7 +952,11 @@ then if [ -z "${SST_PORT}" ] then SST_PORT=4444 - ADDR="$(echo ${WSREP_SST_OPT_ADDR} | awk -F ':' '{ print $1 }'):${SST_PORT}" + if [[ ${ADDR:0:1} == '[' ]];then + ADDR="$(echo ${WSREP_SST_OPT_ADDR} | awk -F '\\]:' '{ print $1 }')]:${SST_PORT}" + else + ADDR="$(echo ${WSREP_SST_OPT_ADDR} | awk -F ':' '{ print $1 }'):${SST_PORT}" + fi fi wait_for_listen ${SST_PORT} ${ADDR} ${MODULE} & diff --git a/scripts/wsrep_sst_rsync.sh b/scripts/wsrep_sst_rsync.sh index 1b42903e094..1bded37a6b6 100644 --- a/scripts/wsrep_sst_rsync.sh +++ b/scripts/wsrep_sst_rsync.sh @@ -364,11 +364,17 @@ then rm -rf "$RSYNC_PID" ADDR=$WSREP_SST_OPT_ADDR - RSYNC_PORT=$(echo $ADDR | awk -F ':' '{ print $2 }') + if [[ ${ADDR:0:1} == '[' ]]; then + RSYNC_PORT=$(echo $ADDR | awk -F '\\]:' '{ print $2 }') + RSYNC_ADDR=$(echo $ADDR | awk -F '\\]:' '{ print $1 }')"]" + else + RSYNC_PORT=$(echo $ADDR | awk -F ':' '{ print $2 }') + RSYNC_ADDR=$(echo $ADDR | awk -F ':' '{ print $1 }') + fi if [ -z "$RSYNC_PORT" ] then RSYNC_PORT=4444 - ADDR="$(echo $ADDR | awk -F ':' '{ print $1 }'):$RSYNC_PORT" + ADDR="$RSYNC_ADDR:$RSYNC_PORT" fi trap "exit 32" HUP PIPE diff --git a/sql/wsrep_utils.h b/sql/wsrep_utils.h index 88a4c1e1a70..dee7eb11504 100644 --- a/sql/wsrep_utils.h +++ b/sql/wsrep_utils.h @@ -108,7 +108,8 @@ private: /* Hostname with port (host:port) */ start= addr_in; end= colon; - parse_port(colon + 1); + if (parse_port(colon + 1)) + return; /* Error: invalid port */ break; default: /* IPv6 address */ diff --git a/support-files/policy/apparmor/usr.sbin.mysqld b/support-files/policy/apparmor/usr.sbin.mysqld index 307872c0fff..a362aa78c7a 100644 --- a/support-files/policy/apparmor/usr.sbin.mysqld +++ b/support-files/policy/apparmor/usr.sbin.mysqld @@ -106,6 +106,7 @@ /usr/bin/wsrep_sst* rix, /usr/bin/wsrep_sst_common r, /usr/bin/xtrabackup* rix, + /usr/bin/mariabackup* rix, /var/lib/mysql/ r, /var/lib/mysql/** rw, /var/lib/mysql/*.log w, diff --git a/support-files/policy/selinux/mariadb-server.fc b/support-files/policy/selinux/mariadb-server.fc index 409f72923aa..39ec152c1ec 100644 --- a/support-files/policy/selinux/mariadb-server.fc +++ b/support-files/policy/selinux/mariadb-server.fc @@ -7,4 +7,5 @@ /var/lib/mysql/.*\.pid -- gen_context(system_u:object_r:mysqld_var_run_t,s0) /var/lib/mysql/.*\.cnf -- gen_context(system_u:object_r:mysqld_etc_t,s0) /usr/bin/xtrabackup.* -- gen_context(system_u:object_r:mysqld_exec_t,s0) +/usr/bin/mariabackup.* -- gen_context(system_u:object_r:mysqld_exec_t,s0) /usr/bin/wsrep.* -- gen_context(system_u:object_r:mysqld_safe_exec_t,s0) From bece44be4fea1c2b0fed0e53c80ab18485335eb8 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Sun, 27 Jan 2019 14:21:39 +0100 Subject: [PATCH 046/106] - Enable CONNECT tables to have triggers Update version number modified: storage/connect/ha_connect.cc --- storage/connect/ha_connect.cc | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index 9b40253b090..b34db942530 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -170,9 +170,9 @@ #define JSONMAX 10 // JSON Default max grp size extern "C" { - char version[]= "Version 1.06.0008 October 06, 2018"; + char version[]= "Version 1.06.0009 January 27, 2019"; #if defined(__WIN__) - char compver[]= "Version 1.06.0008 " __DATE__ " " __TIME__; + char compver[]= "Version 1.06.0009 " __DATE__ " " __TIME__; char slash= '\\'; #else // !__WIN__ char slash= '/'; @@ -1914,9 +1914,11 @@ int ha_connect::OpenTable(PGLOBAL g, bool del) break; } // endswitch xmode - if (xmod != MODE_INSERT || tdbp->GetAmType() == TYPE_AM_MYSQL - || tdbp->GetAmType() == TYPE_AM_ODBC - || tdbp->GetAmType() == TYPE_AM_JDBC) { + // g->More is 1 when executing commands from triggers + if (!g->More && (xmod != MODE_INSERT + || tdbp->GetAmType() == TYPE_AM_MYSQL + || tdbp->GetAmType() == TYPE_AM_ODBC + || tdbp->GetAmType() == TYPE_AM_JDBC)) { // Get the list of used fields (columns) char *p; unsigned int k1, k2, n1, n2; @@ -4631,7 +4633,9 @@ MODE ha_connect::CheckMode(PGLOBAL g, THD *thd, break; case SQLCOM_CREATE_VIEW: case SQLCOM_DROP_VIEW: - newmode= MODE_ANY; + case SQLCOM_CREATE_TRIGGER: + case SQLCOM_DROP_TRIGGER: + newmode= MODE_ANY; break; case SQLCOM_ALTER_TABLE: *chk= true; @@ -4674,6 +4678,9 @@ int ha_connect::start_stmt(THD *thd, thr_lock_type lock_type) PGLOBAL g= GetPlug(thd, xp); DBUG_ENTER("ha_connect::start_stmt"); + if (table->triggers) + g->More= 1; // We don't know which columns are used by the trigger + if (check_privileges(thd, GetTableOptionStruct(), table->s->db.str, true)) DBUG_RETURN(HA_ERR_INTERNAL_ERROR); @@ -7310,7 +7317,7 @@ maria_declare_plugin(connect) 0x0106, /* version number (1.06) */ NULL, /* status variables */ connect_system_variables, /* system variables */ - "1.06.0008", /* string version */ + "1.06.0009", /* string version */ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */ } maria_declare_plugin_end; From 21f9037186f8a4bfb45486b9c28dd146e9df0e00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vicen=C8=9Biu=20Ciorbaru?= Date: Thu, 24 Jan 2019 00:58:20 +0200 Subject: [PATCH 047/106] MDEV-18360 Prevent set_max_open_files from allocating too many files If the rlimit.rlim_cur value returned by getrlimit is not the RLIM_INFINITY magic constant, but a *very* large number, we can allocate too many open files. Restrict set_max_open_files to only return at most max_file_limit, as passed via its parameter. --- mysys/my_file.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/mysys/my_file.c b/mysys/my_file.c index 8d01285a94b..b3aef8494cb 100644 --- a/mysys/my_file.c +++ b/mysys/my_file.c @@ -52,10 +52,9 @@ static uint set_max_open_files(uint max_file_limit) DBUG_PRINT("info", ("rlim_cur: %u rlim_max: %u", (uint) rlimit.rlim_cur, (uint) rlimit.rlim_max)); - if ((ulonglong) rlimit.rlim_cur == (ulonglong) RLIM_INFINITY) - rlimit.rlim_cur = max_file_limit; - if (rlimit.rlim_cur >= max_file_limit) - DBUG_RETURN(rlimit.rlim_cur); /* purecov: inspected */ + if ((ulonglong) rlimit.rlim_cur == (ulonglong) RLIM_INFINITY || + rlimit.rlim_cur >= max_file_limit) + DBUG_RETURN(max_file_limit); rlimit.rlim_cur= rlimit.rlim_max= max_file_limit; if (setrlimit(RLIMIT_NOFILE, &rlimit)) max_file_limit= old_cur; /* Use original value */ From 2175bfce3e9da8332f10ab0e0286dc93915533a2 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 25 Jan 2019 23:12:35 +0100 Subject: [PATCH 048/106] Crude "auto-load-data-local-infile" mode Disable LOAD DATA LOCAL INFILE suport by default and auto-enable it for the duration of one query, if the query string starts with the word "load". In all other cases the application should enable LOAD DATA LOCAL INFILE support explicitly. --- CMakeLists.txt | 10 +++++-- client/mysqltest.cc | 2 -- .../build_configurations/mysql_release.cmake | 1 - config.h.cmake | 6 +++- include/mysql.h | 2 +- include/mysql.h.pp | 2 +- mysql-test/r/mysql.result | 26 ++++++++++++++++ mysql-test/t/mysql.test | 22 ++++++++++++++ sql-common/client.c | 30 +++++++++++++++++-- 9 files changed, 90 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b15512683fa..bc4c4e4f103 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -256,9 +256,15 @@ IF(HAVE_GGDB3) SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -ggdb3") ENDIF() -OPTION(ENABLED_LOCAL_INFILE - "If we should should enable LOAD DATA LOCAL by default" ${IF_WIN}) +SET(ENABLED_LOCAL_INFILE "AUTO" CACHE STRING "If we should should enable LOAD DATA LOCAL by default (OFF/ON/AUTO)") MARK_AS_ADVANCED(ENABLED_LOCAL_INFILE) +IF (ENABLED_LOCAL_INFILE MATCHES "^(0|FALSE)$") + SET(ENABLED_LOCAL_INFILE OFF) +ELSEIF(ENABLED_LOCAL_INFILE MATCHES "^(1|TRUE)$") + SET(ENABLED_LOCAL_INFILE ON) +ELSEIF (NOT ENABLED_LOCAL_INFILE MATCHES "^(ON|OFF|AUTO)$") + MESSAGE(FATAL_ERROR "ENABLED_LOCAL_INFILE must be one of OFF, ON, AUTO") +ENDIF() OPTION(WITH_FAST_MUTEXES "Compile with fast mutexes" OFF) MARK_AS_ADVANCED(WITH_FAST_MUTEXES) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 2b7401878ef..842bde3b99e 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -6045,7 +6045,6 @@ void do_connect(struct st_command *command) #endif if (opt_compress || con_compress) mysql_options(con_slot->mysql, MYSQL_OPT_COMPRESS, NullS); - mysql_options(con_slot->mysql, MYSQL_OPT_LOCAL_INFILE, 0); mysql_options(con_slot->mysql, MYSQL_SET_CHARSET_NAME, charset_info->csname); if (opt_charsets_dir) @@ -9110,7 +9109,6 @@ int main(int argc, char **argv) (void *) &opt_connect_timeout); if (opt_compress) mysql_options(con->mysql,MYSQL_OPT_COMPRESS,NullS); - mysql_options(con->mysql, MYSQL_OPT_LOCAL_INFILE, 0); mysql_options(con->mysql, MYSQL_SET_CHARSET_NAME, charset_info->csname); if (opt_charsets_dir) diff --git a/cmake/build_configurations/mysql_release.cmake b/cmake/build_configurations/mysql_release.cmake index 39ad0e68d35..a464631e9a2 100644 --- a/cmake/build_configurations/mysql_release.cmake +++ b/cmake/build_configurations/mysql_release.cmake @@ -94,7 +94,6 @@ IF(FEATURE_SET) ENDFOREACH() ENDIF() -OPTION(ENABLED_LOCAL_INFILE "" ON) IF(RPM) SET(WITH_SSL system CACHE STRING "") SET(WITH_ZLIB system CACHE STRING "") diff --git a/config.h.cmake b/config.h.cmake index 99a2ebdd093..271d77f2e5a 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -530,7 +530,11 @@ /* MySQL features */ -#cmakedefine ENABLED_LOCAL_INFILE 1 +#define LOCAL_INFILE_MODE_OFF 0 +#define LOCAL_INFILE_MODE_ON 1 +#define LOCAL_INFILE_MODE_AUTO 2 +#define ENABLED_LOCAL_INFILE LOCAL_INFILE_MODE_@ENABLED_LOCAL_INFILE@ + #cmakedefine ENABLED_PROFILING 1 #cmakedefine EXTRA_DEBUG 1 #cmakedefine BACKUP_TEST 1 diff --git a/include/mysql.h b/include/mysql.h index 2f205ec6463..1ed6ffe67c8 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -274,7 +274,7 @@ typedef struct st_mysql /* session-wide random string */ char scramble[SCRAMBLE_LENGTH+1]; - my_bool unused1; + my_bool auto_local_infile; void *unused2, *unused3, *unused4, *unused5; LIST *stmts; /* list of all statements */ diff --git a/include/mysql.h.pp b/include/mysql.h.pp index 4f7407095c9..8bff18d7bb0 100644 --- a/include/mysql.h.pp +++ b/include/mysql.h.pp @@ -341,7 +341,7 @@ typedef struct st_mysql my_bool free_me; my_bool reconnect; char scramble[20 +1]; - my_bool unused1; + my_bool auto_local_infile; void *unused2, *unused3, *unused4, *unused5; LIST *stmts; const struct st_mysql_methods *methods; diff --git a/mysql-test/r/mysql.result b/mysql-test/r/mysql.result index 8a24128daa2..ffa5d020153 100644 --- a/mysql-test/r/mysql.result +++ b/mysql-test/r/mysql.result @@ -587,3 +587,29 @@ a 2 drop table "a1\""b1"; set sql_mode=default; +create table t1 (a text); +select count(*) from t1; +count(*) +41 +truncate table t1; +select count(*) from t1; +count(*) +41 +truncate table t1; +select count(*) from t1; +count(*) +0 +truncate table t1; +select count(*) from t1; +count(*) +0 +truncate table t1; +select count(*) from t1; +count(*) +41 +truncate table t1; +select count(*) from t1; +count(*) +0 +truncate table t1; +drop table t1; diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test index 87756768c7f..f526a3fea91 100644 --- a/mysql-test/t/mysql.test +++ b/mysql-test/t/mysql.test @@ -656,3 +656,25 @@ show create table "a1\""b1"; select * from "a1\""b1"; drop table "a1\""b1"; set sql_mode=default; + +# +# mysql --local-infile +# +--let $ldli = load data local infile '$MYSQLTEST_VARDIR/tmp/bug.sql' into table test.t1; +create table t1 (a text); +--exec $MYSQL -e "$ldli" +select count(*) from t1; truncate table t1; +--exec $MYSQL --enable-local-infile -e "$ldli" +select count(*) from t1; truncate table t1; +--error 1 +--exec $MYSQL --disable-local-infile -e "$ldli" +select count(*) from t1; truncate table t1; +--error 1 +--exec $MYSQL -e "/*q*/$ldli" +select count(*) from t1; truncate table t1; +--exec $MYSQL --enable-local-infile -e "/*q*/$ldli" +select count(*) from t1; truncate table t1; +--error 1 +--exec $MYSQL --disable-local-infile -e "/*q*/$ldli" +select count(*) from t1; truncate table t1; +drop table t1; diff --git a/sql-common/client.c b/sql-common/client.c index 952b6a199ee..bec778e7d51 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -115,6 +115,12 @@ my_bool net_flush(NET *net); #include #include +typedef enum { + ALWAYS_ACCEPT, /* heuristics is disabled, use CLIENT_LOCAL_FILES */ + WAIT_FOR_QUERY, /* heuristics is enabled, not sending files */ + ACCEPT_FILE_REQUEST /* heuristics is enabled, ready to send a file */ +} auto_local_infile_state; + #define native_password_plugin_name "mysql_native_password" #define old_password_plugin_name "mysql_old_password" @@ -1765,8 +1771,10 @@ mysql_init(MYSQL *mysql) --enable-local-infile */ -#if defined(ENABLED_LOCAL_INFILE) && !defined(MYSQL_SERVER) +#if ENABLED_LOCAL_INFILE && !defined(MYSQL_SERVER) mysql->options.client_flag|= CLIENT_LOCAL_FILES; + mysql->auto_local_infile= ENABLED_LOCAL_INFILE == LOCAL_INFILE_MODE_AUTO + ? WAIT_FOR_QUERY : ALWAYS_ACCEPT; #endif #ifdef HAVE_SMEM @@ -3951,8 +3959,14 @@ static my_bool cli_read_query_result(MYSQL *mysql) ulong field_count; MYSQL_DATA *fields; ulong length; +#ifdef MYSQL_CLIENT + my_bool can_local_infile= mysql->auto_local_infile != WAIT_FOR_QUERY; +#endif DBUG_ENTER("cli_read_query_result"); + if (mysql->auto_local_infile == ACCEPT_FILE_REQUEST) + mysql->auto_local_infile= WAIT_FOR_QUERY; + if ((length = cli_safe_read(mysql)) == packet_error) DBUG_RETURN(1); free_old_query(mysql); /* Free old result */ @@ -3989,7 +4003,8 @@ get_info: { int error; - if (!(mysql->options.client_flag & CLIENT_LOCAL_FILES)) + if (!(mysql->options.client_flag & CLIENT_LOCAL_FILES) || + !can_local_infile) { set_mysql_error(mysql, CR_MALFORMED_PACKET, unknown_sqlstate); DBUG_RETURN(1); @@ -4027,6 +4042,13 @@ int STDCALL mysql_send_query(MYSQL* mysql, const char* query, ulong length) { DBUG_ENTER("mysql_send_query"); + if (mysql->options.client_flag & CLIENT_LOCAL_FILES && + mysql->auto_local_infile == WAIT_FOR_QUERY && + (*query == 'l' || *query == 'L')) + { + if (strncasecmp(query, STRING_WITH_LEN("load")) == 0) + mysql->auto_local_infile= ACCEPT_FILE_REQUEST; + } DBUG_RETURN(simple_command(mysql, COM_QUERY, (uchar*) query, length, 1)); } @@ -4241,10 +4263,12 @@ mysql_options(MYSQL *mysql,enum mysql_option option, const void *arg) mysql->options.protocol=MYSQL_PROTOCOL_PIPE; /* Force named pipe */ break; case MYSQL_OPT_LOCAL_INFILE: /* Allow LOAD DATA LOCAL ?*/ - if (!arg || test(*(uint*) arg)) + if (!arg || *(uint*) arg) mysql->options.client_flag|= CLIENT_LOCAL_FILES; else mysql->options.client_flag&= ~CLIENT_LOCAL_FILES; + mysql->auto_local_infile= arg && *(uint*)arg == LOCAL_INFILE_MODE_AUTO + ? WAIT_FOR_QUERY : ALWAYS_ACCEPT; break; case MYSQL_INIT_COMMAND: add_init_command(&mysql->options,arg); From 94b68b35f46918fb1e145cad6387c9fcd045c392 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Mon, 28 Jan 2019 15:39:27 +0100 Subject: [PATCH 049/106] Reverting part of da34c7de5dacac85c4dc1f714bcd7edf3b7fe5f9 that was already fixed by MDEV-17531 by Marko --- storage/innobase/row/row0mysql.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 68329658618..f623845f289 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -5129,9 +5129,6 @@ row_rename_table_for_mysql( " = TO_BINARY(:old_table_name);\n" "END;\n" , FALSE, trx); - if (err != DB_SUCCESS) { - goto end; - } } else if (n_constraints_to_drop > 0) { /* Drop some constraints of tmp tables. */ From 724b09d5e726be612be6154a900bd907897d4124 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Mon, 28 Jan 2019 15:42:16 +0100 Subject: [PATCH 050/106] Version fix after merge --- storage/innobase/include/univ.i | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i index 5027b9cab5e..f1bf416b370 100644 --- a/storage/innobase/include/univ.i +++ b/storage/innobase/include/univ.i @@ -45,7 +45,7 @@ Created 1/20/1994 Heikki Tuuri #define INNODB_VERSION_MAJOR 5 #define INNODB_VERSION_MINOR 6 -#define INNODB_VERSION_BUGFIX 42 +#define INNODB_VERSION_BUGFIX 43 /* The following is the InnoDB version as shown in SELECT plugin_version FROM information_schema.plugins; From 8c2f3e0c16a4b9c2961a474f399b88be5ec330d1 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Mon, 28 Jan 2019 20:17:54 +0100 Subject: [PATCH 051/106] Fix detection of version in tokudb --- storage/tokudb/PerconaFT/portability/toku_instr_mysql.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/tokudb/PerconaFT/portability/toku_instr_mysql.h b/storage/tokudb/PerconaFT/portability/toku_instr_mysql.h index 695624acd6d..beb833a163c 100644 --- a/storage/tokudb/PerconaFT/portability/toku_instr_mysql.h +++ b/storage/tokudb/PerconaFT/portability/toku_instr_mysql.h @@ -16,7 +16,7 @@ #include "mysql/psi/mysql_thread.h" // PSI_mutex #include "mysql/psi/mysql_stage.h" // PSI_stage -#if (MYSQL_VERSION_ID >= 80000) +#if (MYSQL_VERSION_ID >= 80000) && ( MYSQL_VERSION_ID <= 100000) #include "mysql/psi/mysql_cond.h" #include "mysql/psi/mysql_mutex.h" #include "mysql/psi/mysql_rwlock.h" From eff71f39ddc117d09da5465f7ea9fe007ed89009 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 28 Jan 2019 11:51:12 +0100 Subject: [PATCH 052/106] disable an old test @@open_files_limit now behaves differenly and cannot be used to skip the test anymore. --- mysql-test/disabled.def | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/disabled.def b/mysql-test/disabled.def index c7fa62ff7dd..d4856f0b7aa 100644 --- a/mysql-test/disabled.def +++ b/mysql-test/disabled.def @@ -15,3 +15,4 @@ read_many_rows_innodb : Bug#11748886 2010-11-15 mattiasj report already exist mysql_embedded : Bug#12561297 2011-05-14 Anitha Dependent on PB2 changes - eventum#41836 file_contents : MDEV-6526 these files are not installed anymore lowercase_fs_on : lower_case_table_names=0 is not an error until 10.1 +partition_open_files_limit : open_files_limit check broken by MDEV-18360 From c991939bab7677b0af2ac3fd8c504d858e44e8dd Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Tue, 29 Jan 2019 09:34:08 +0100 Subject: [PATCH 053/106] MariaDB detect incorrect table name --- storage/tokudb/mysql-test/tokudb_bugs/r/PS-4979.result | 2 +- storage/tokudb/mysql-test/tokudb_bugs/t/PS-4979.test | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/storage/tokudb/mysql-test/tokudb_bugs/r/PS-4979.result b/storage/tokudb/mysql-test/tokudb_bugs/r/PS-4979.result index f0d2f93f630..5bf7a270fe5 100644 --- a/storage/tokudb/mysql-test/tokudb_bugs/r/PS-4979.result +++ b/storage/tokudb/mysql-test/tokudb_bugs/r/PS-4979.result @@ -1,2 +1,2 @@ CREATE TABLE `#mysql50#q.q`(f1 INT KEY) ENGINE=TOKUDB; -ERROR HY000: Got error 1632 from storage engine +ERROR 42000: Incorrect table name '#mysql50#q.q' diff --git a/storage/tokudb/mysql-test/tokudb_bugs/t/PS-4979.test b/storage/tokudb/mysql-test/tokudb_bugs/t/PS-4979.test index 1e4b5d11922..cb902f6e52a 100644 --- a/storage/tokudb/mysql-test/tokudb_bugs/t/PS-4979.test +++ b/storage/tokudb/mysql-test/tokudb_bugs/t/PS-4979.test @@ -7,6 +7,7 @@ # engine expects a table name in the form of a relative path like # "./databasename/tablename". InnoDB detects this in parsing the table name # during the creation and returns an error. +# MariaDB server detect above error. ---error ER_GET_ERRNO +--error ER_WRONG_TABLE_NAME CREATE TABLE `#mysql50#q.q`(f1 INT KEY) ENGINE=TOKUDB; From f877f6b49d97c02b307f83770c47c613c4bd669f Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Tue, 29 Jan 2019 11:50:07 +0100 Subject: [PATCH 054/106] Fix xtradb version after merge --- storage/xtradb/include/univ.i | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i index 976bed244a0..6522a19c128 100644 --- a/storage/xtradb/include/univ.i +++ b/storage/xtradb/include/univ.i @@ -45,7 +45,7 @@ Created 1/20/1994 Heikki Tuuri #define INNODB_VERSION_MAJOR 5 #define INNODB_VERSION_MINOR 6 -#define INNODB_VERSION_BUGFIX 39 +#define INNODB_VERSION_BUGFIX 42 #ifndef PERCONA_INNODB_VERSION #define PERCONA_INNODB_VERSION 84.2 From 5e06ee41a46dd9f336e73c0f9b6622c5ea5d548f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 29 Jan 2019 14:07:59 +0200 Subject: [PATCH 055/106] MDEV-18222: Duplicated call to dict_foreign_remove_from_cache() innobase_rename_column_try(): Declare fk_evict as std::set instead of std::list, in order to filter out duplicates. --- mysql-test/suite/innodb/r/foreign_key.result | 12 ++++++++++++ mysql-test/suite/innodb/t/foreign_key.test | 13 +++++++++++++ storage/innobase/handler/handler0alter.cc | 8 ++++---- storage/xtradb/handler/handler0alter.cc | 8 ++++---- 4 files changed, 33 insertions(+), 8 deletions(-) diff --git a/mysql-test/suite/innodb/r/foreign_key.result b/mysql-test/suite/innodb/r/foreign_key.result index b6462000b46..f62a251161a 100644 --- a/mysql-test/suite/innodb/r/foreign_key.result +++ b/mysql-test/suite/innodb/r/foreign_key.result @@ -49,3 +49,15 @@ INSERT INTO t3 SET a=1; kill query @id; ERROR 70100: Query execution was interrupted DROP TABLE t3,t1; +# +# MDEV-18222 InnoDB: Failing assertion: heap->magic_n == MEM_BLOCK_MAGIC_N +# or ASAN heap-use-after-free in dict_foreign_remove_from_cache upon CHANGE COLUMN +# +CREATE TABLE t1 (a INT, UNIQUE(a), KEY(a)) ENGINE=InnoDB; +ALTER TABLE t1 ADD FOREIGN KEY (a) REFERENCES t1 (a); +SET SESSION FOREIGN_KEY_CHECKS = OFF; +ALTER TABLE t1 CHANGE COLUMN a a TIME NOT NULL; +ALTER TABLE t1 ADD pk INT NOT NULL AUTO_INCREMENT PRIMARY KEY; +ALTER TABLE t1 CHANGE COLUMN a b TIME; +SET SESSION FOREIGN_KEY_CHECKS = ON; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/foreign_key.test b/mysql-test/suite/innodb/t/foreign_key.test index c1a92697dab..dc55a5c3a96 100644 --- a/mysql-test/suite/innodb/t/foreign_key.test +++ b/mysql-test/suite/innodb/t/foreign_key.test @@ -73,3 +73,16 @@ reap; disconnect fk; DROP TABLE t3,t1; + +--echo # +--echo # MDEV-18222 InnoDB: Failing assertion: heap->magic_n == MEM_BLOCK_MAGIC_N +--echo # or ASAN heap-use-after-free in dict_foreign_remove_from_cache upon CHANGE COLUMN +--echo # +CREATE TABLE t1 (a INT, UNIQUE(a), KEY(a)) ENGINE=InnoDB; +ALTER TABLE t1 ADD FOREIGN KEY (a) REFERENCES t1 (a); +SET SESSION FOREIGN_KEY_CHECKS = OFF; +ALTER TABLE t1 CHANGE COLUMN a a TIME NOT NULL; +ALTER TABLE t1 ADD pk INT NOT NULL AUTO_INCREMENT PRIMARY KEY; +ALTER TABLE t1 CHANGE COLUMN a b TIME; +SET SESSION FOREIGN_KEY_CHECKS = ON; +DROP TABLE t1; diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 25019b8f964..d67defa56e8 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2005, 2018, 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 @@ -4579,7 +4579,7 @@ err_exit: rename_foreign: trx->op_info = "renaming column in SYS_FOREIGN_COLS"; - std::list fk_evict; + std::set fk_evict; bool foreign_modified; for (dict_foreign_set::const_iterator it = user_table->foreign_set.begin(); @@ -4619,7 +4619,7 @@ rename_foreign: } if (foreign_modified) { - fk_evict.push_back(foreign); + fk_evict.insert(foreign); } } @@ -4661,7 +4661,7 @@ rename_foreign: } if (foreign_modified) { - fk_evict.push_back(foreign); + fk_evict.insert(foreign); } } diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc index e932e2cbbdb..b7705691949 100644 --- a/storage/xtradb/handler/handler0alter.cc +++ b/storage/xtradb/handler/handler0alter.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2005, 2018, 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 @@ -4593,7 +4593,7 @@ err_exit: rename_foreign: trx->op_info = "renaming column in SYS_FOREIGN_COLS"; - std::list fk_evict; + std::set fk_evict; bool foreign_modified; for (dict_foreign_set::const_iterator it = user_table->foreign_set.begin(); @@ -4633,7 +4633,7 @@ rename_foreign: } if (foreign_modified) { - fk_evict.push_back(foreign); + fk_evict.insert(foreign); } } @@ -4675,7 +4675,7 @@ rename_foreign: } if (foreign_modified) { - fk_evict.push_back(foreign); + fk_evict.insert(foreign); } } From 6699cac0bf10464feab631ff3909ca8c66405628 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 29 Jan 2019 14:14:57 +0200 Subject: [PATCH 056/106] MDEV-18256 Duplicated call to dict_foreign_remove_from_cache() ha_innobase::prepare_inplace_alter_table(): Filter out duplicates from ha_alter_info->alter_info->drop_list.elements. --- mysql-test/suite/innodb/r/foreign_key.result | 9 +++++++++ mysql-test/suite/innodb/t/foreign_key.test | 10 ++++++++++ storage/innobase/handler/handler0alter.cc | 18 +++++++++++++----- storage/xtradb/handler/handler0alter.cc | 18 +++++++++++++----- 4 files changed, 45 insertions(+), 10 deletions(-) diff --git a/mysql-test/suite/innodb/r/foreign_key.result b/mysql-test/suite/innodb/r/foreign_key.result index f62a251161a..6573d744714 100644 --- a/mysql-test/suite/innodb/r/foreign_key.result +++ b/mysql-test/suite/innodb/r/foreign_key.result @@ -61,3 +61,12 @@ ALTER TABLE t1 ADD pk INT NOT NULL AUTO_INCREMENT PRIMARY KEY; ALTER TABLE t1 CHANGE COLUMN a b TIME; SET SESSION FOREIGN_KEY_CHECKS = ON; DROP TABLE t1; +# +# MDEV-18256 InnoDB: Failing assertion: heap->magic_n == MEM_BLOCK_MAGIC_N +# upon DROP FOREIGN KEY +# +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t2 (b INT PRIMARY KEY, FOREIGN KEY fk1 (b) REFERENCES t1 (a)) +ENGINE=InnoDB; +ALTER TABLE t2 DROP FOREIGN KEY fk1, DROP FOREIGN KEY fk1; +DROP TABLE t2, t1; diff --git a/mysql-test/suite/innodb/t/foreign_key.test b/mysql-test/suite/innodb/t/foreign_key.test index dc55a5c3a96..aa35e3abf00 100644 --- a/mysql-test/suite/innodb/t/foreign_key.test +++ b/mysql-test/suite/innodb/t/foreign_key.test @@ -86,3 +86,13 @@ ALTER TABLE t1 ADD pk INT NOT NULL AUTO_INCREMENT PRIMARY KEY; ALTER TABLE t1 CHANGE COLUMN a b TIME; SET SESSION FOREIGN_KEY_CHECKS = ON; DROP TABLE t1; + +--echo # +--echo # MDEV-18256 InnoDB: Failing assertion: heap->magic_n == MEM_BLOCK_MAGIC_N +--echo # upon DROP FOREIGN KEY +--echo # +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t2 (b INT PRIMARY KEY, FOREIGN KEY fk1 (b) REFERENCES t1 (a)) +ENGINE=InnoDB; +ALTER TABLE t2 DROP FOREIGN KEY fk1, DROP FOREIGN KEY fk1; +DROP TABLE t2, t1; diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index d67defa56e8..17e2810b649 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -3690,12 +3690,14 @@ check_if_ok_to_rename: continue; } + dict_foreign_t* foreign; + for (dict_foreign_set::iterator it = prebuilt->table->foreign_set.begin(); it != prebuilt->table->foreign_set.end(); ++it) { - dict_foreign_t* foreign = *it; + foreign = *it; const char* fid = strchr(foreign->id, '/'); DBUG_ASSERT(fid); @@ -3706,7 +3708,6 @@ check_if_ok_to_rename: if (!my_strcasecmp(system_charset_info, fid, drop->name)) { - drop_fk[n_drop_fk++] = foreign; goto found_fk; } } @@ -3715,12 +3716,19 @@ check_if_ok_to_rename: drop->name); goto err_exit; found_fk: + for (ulint i = n_drop_fk; i--; ) { + if (drop_fk[i] == foreign) { + goto dup_fk; + } + } + drop_fk[n_drop_fk++] = foreign; +dup_fk: continue; } DBUG_ASSERT(n_drop_fk > 0); DBUG_ASSERT(n_drop_fk - == ha_alter_info->alter_info->drop_list.elements); + <= ha_alter_info->alter_info->drop_list.elements); } else { drop_fk = NULL; } @@ -5057,7 +5065,7 @@ commit_try_rebuild( & Alter_inplace_info::DROP_FOREIGN_KEY) || ctx->num_to_drop_fk > 0); DBUG_ASSERT(ctx->num_to_drop_fk - == ha_alter_info->alter_info->drop_list.elements); + <= ha_alter_info->alter_info->drop_list.elements); for (dict_index_t* index = dict_table_get_first_index(rebuilt_table); index; @@ -5309,7 +5317,7 @@ commit_try_norebuild( & Alter_inplace_info::DROP_FOREIGN_KEY) || ctx->num_to_drop_fk > 0); DBUG_ASSERT(ctx->num_to_drop_fk - == ha_alter_info->alter_info->drop_list.elements); + <= ha_alter_info->alter_info->drop_list.elements); for (ulint i = 0; i < ctx->num_to_add_index; i++) { dict_index_t* index = ctx->add_index[i]; diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc index b7705691949..c27cd7f1b40 100644 --- a/storage/xtradb/handler/handler0alter.cc +++ b/storage/xtradb/handler/handler0alter.cc @@ -3704,12 +3704,14 @@ check_if_ok_to_rename: continue; } + dict_foreign_t* foreign; + for (dict_foreign_set::iterator it = prebuilt->table->foreign_set.begin(); it != prebuilt->table->foreign_set.end(); ++it) { - dict_foreign_t* foreign = *it; + foreign = *it; const char* fid = strchr(foreign->id, '/'); DBUG_ASSERT(fid); @@ -3720,7 +3722,6 @@ check_if_ok_to_rename: if (!my_strcasecmp(system_charset_info, fid, drop->name)) { - drop_fk[n_drop_fk++] = foreign; goto found_fk; } } @@ -3729,12 +3730,19 @@ check_if_ok_to_rename: drop->name); goto err_exit; found_fk: + for (ulint i = n_drop_fk; i--; ) { + if (drop_fk[i] == foreign) { + goto dup_fk; + } + } + drop_fk[n_drop_fk++] = foreign; +dup_fk: continue; } DBUG_ASSERT(n_drop_fk > 0); DBUG_ASSERT(n_drop_fk - == ha_alter_info->alter_info->drop_list.elements); + <= ha_alter_info->alter_info->drop_list.elements); } else { drop_fk = NULL; } @@ -5071,7 +5079,7 @@ commit_try_rebuild( & Alter_inplace_info::DROP_FOREIGN_KEY) || ctx->num_to_drop_fk > 0); DBUG_ASSERT(ctx->num_to_drop_fk - == ha_alter_info->alter_info->drop_list.elements); + <= ha_alter_info->alter_info->drop_list.elements); for (dict_index_t* index = dict_table_get_first_index(rebuilt_table); index; @@ -5325,7 +5333,7 @@ commit_try_norebuild( & Alter_inplace_info::DROP_FOREIGN_KEY) || ctx->num_to_drop_fk > 0); DBUG_ASSERT(ctx->num_to_drop_fk - == ha_alter_info->alter_info->drop_list.elements); + <= ha_alter_info->alter_info->drop_list.elements); for (ulint i = 0; i < ctx->num_to_add_index; i++) { dict_index_t* index = ctx->add_index[i]; From 1522ee2949ae304ad9092894896a6272dc08bb39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 29 Jan 2019 15:00:41 +0200 Subject: [PATCH 057/106] MDEV-18016: Assertion failure on ALTER TABLE after foreign_key_checks=0 ha_innobase::commit_inplace_alter_table(): Do not crash if innobase_update_foreign_cache() returns an error. It can return an error on ALTER TABLE if an inconsistent FOREIGN KEY constraint was created earlier when SET foreign_key_checks=0 was in effect. Instead, report a warning to the client that constraints cannot be loaded. --- mysql-test/suite/innodb/r/foreign_key.result | 12 ++++ mysql-test/suite/innodb/t/foreign_key.test | 8 +++ storage/innobase/handler/handler0alter.cc | 58 ++++++++------------ storage/xtradb/handler/handler0alter.cc | 58 ++++++++------------ 4 files changed, 68 insertions(+), 68 deletions(-) diff --git a/mysql-test/suite/innodb/r/foreign_key.result b/mysql-test/suite/innodb/r/foreign_key.result index 6573d744714..4e253261f2e 100644 --- a/mysql-test/suite/innodb/r/foreign_key.result +++ b/mysql-test/suite/innodb/r/foreign_key.result @@ -70,3 +70,15 @@ CREATE TABLE t2 (b INT PRIMARY KEY, FOREIGN KEY fk1 (b) REFERENCES t1 (a)) ENGINE=InnoDB; ALTER TABLE t2 DROP FOREIGN KEY fk1, DROP FOREIGN KEY fk1; DROP TABLE t2, t1; +CREATE TABLE t1 (f VARCHAR(256)) ENGINE=InnoDB; +SET SESSION FOREIGN_KEY_CHECKS = OFF; +ALTER TABLE t1 ADD FOREIGN KEY (f) REFERENCES non_existing_table (x); +SET SESSION FOREIGN_KEY_CHECKS = ON; +ALTER TABLE t1 ADD FULLTEXT INDEX ft1 (f); +Warnings: +Warning 124 InnoDB rebuilding table to add column FTS_DOC_ID +Warning 1088 failed to load FOREIGN KEY constraints +ALTER TABLE t1 ADD FULLTEXT INDEX ft2 (f); +Warnings: +Warning 1088 failed to load FOREIGN KEY constraints +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/foreign_key.test b/mysql-test/suite/innodb/t/foreign_key.test index aa35e3abf00..b4e2ee1bbe7 100644 --- a/mysql-test/suite/innodb/t/foreign_key.test +++ b/mysql-test/suite/innodb/t/foreign_key.test @@ -96,3 +96,11 @@ CREATE TABLE t2 (b INT PRIMARY KEY, FOREIGN KEY fk1 (b) REFERENCES t1 (a)) ENGINE=InnoDB; ALTER TABLE t2 DROP FOREIGN KEY fk1, DROP FOREIGN KEY fk1; DROP TABLE t2, t1; + +CREATE TABLE t1 (f VARCHAR(256)) ENGINE=InnoDB; +SET SESSION FOREIGN_KEY_CHECKS = OFF; +ALTER TABLE t1 ADD FOREIGN KEY (f) REFERENCES non_existing_table (x); +SET SESSION FOREIGN_KEY_CHECKS = ON; +ALTER TABLE t1 ADD FULLTEXT INDEX ft1 (f); +ALTER TABLE t1 ADD FULLTEXT INDEX ft2 (f); +DROP TABLE t1; diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 17e2810b649..40a04c8848f 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -5638,7 +5638,6 @@ ha_innobase::commit_inplace_alter_table( Alter_inplace_info* ha_alter_info, bool commit) { - dberr_t error; ha_innobase_inplace_ctx* ctx0 = static_cast (ha_alter_info->handler_ctx); @@ -5705,7 +5704,7 @@ ha_innobase::commit_inplace_alter_table( transactions collected during crash recovery could be holding InnoDB locks only, not MySQL locks. */ - error = row_merge_lock_table( + dberr_t error = row_merge_lock_table( prebuilt->trx, ctx->old_table, LOCK_X); if (error != DB_SUCCESS) { @@ -5890,9 +5889,9 @@ rollback_trx: file operations that will be performed in commit_cache_rebuild(), and if none, generate the redo log for these operations. */ - error = fil_mtr_rename_log(ctx->old_table, - ctx->new_table, - ctx->tmp_name, &mtr); + dberr_t error = fil_mtr_rename_log( + ctx->old_table, ctx->new_table, ctx->tmp_name, + &mtr); if (error != DB_SUCCESS) { /* Out of memory or a problem will occur when renaming files. */ @@ -6017,39 +6016,30 @@ rollback_trx: /* Rename the tablespace files. */ commit_cache_rebuild(ctx); - error = innobase_update_foreign_cache(ctx, user_thd); - if (error != DB_SUCCESS) { - goto foreign_fail; + if (innobase_update_foreign_cache(ctx, user_thd) + != DB_SUCCESS + && prebuilt->trx->check_foreigns) { +foreign_fail: + push_warning_printf( + user_thd, + Sql_condition::WARN_LEVEL_WARN, + ER_ALTER_INFO, + "failed to load FOREIGN KEY" + " constraints"); } } else { - error = innobase_update_foreign_cache(ctx, user_thd); + bool fk_fail = innobase_update_foreign_cache( + ctx, user_thd) != DB_SUCCESS; - if (error != DB_SUCCESS) { -foreign_fail: - /* The data dictionary cache - should be corrupted now. The - best solution should be to - kill and restart the server, - but the *.frm file has not - been replaced yet. */ - my_error(ER_CANNOT_ADD_FOREIGN, - MYF(0)); - sql_print_error( - "InnoDB: dict_load_foreigns()" - " returned %u for %s", - (unsigned) error, - thd_query_string(user_thd) - ->str); - ut_ad(0); - } else { - if (!commit_cache_norebuild( - ctx, table, trx)) { - ut_a(!prebuilt->trx->check_foreigns); - } + if (!commit_cache_norebuild(ctx, table, trx)) { + fk_fail = true; + ut_ad(!prebuilt->trx->check_foreigns); + } - innobase_rename_columns_cache( - ha_alter_info, table, - ctx->new_table); + innobase_rename_columns_cache(ha_alter_info, table, + ctx->new_table); + if (fk_fail && prebuilt->trx->check_foreigns) { + goto foreign_fail; } } DBUG_INJECT_CRASH("ib_commit_inplace_crash", diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc index c27cd7f1b40..cd8fc8ad589 100644 --- a/storage/xtradb/handler/handler0alter.cc +++ b/storage/xtradb/handler/handler0alter.cc @@ -5654,7 +5654,6 @@ ha_innobase::commit_inplace_alter_table( Alter_inplace_info* ha_alter_info, bool commit) { - dberr_t error; ha_innobase_inplace_ctx* ctx0 = static_cast (ha_alter_info->handler_ctx); @@ -5721,7 +5720,7 @@ ha_innobase::commit_inplace_alter_table( transactions collected during crash recovery could be holding InnoDB locks only, not MySQL locks. */ - error = row_merge_lock_table( + dberr_t error = row_merge_lock_table( prebuilt->trx, ctx->old_table, LOCK_X); if (error != DB_SUCCESS) { @@ -5906,9 +5905,9 @@ rollback_trx: file operations that will be performed in commit_cache_rebuild(), and if none, generate the redo log for these operations. */ - error = fil_mtr_rename_log(ctx->old_table, - ctx->new_table, - ctx->tmp_name, &mtr); + dberr_t error = fil_mtr_rename_log( + ctx->old_table, ctx->new_table, ctx->tmp_name, + &mtr); if (error != DB_SUCCESS) { /* Out of memory or a problem will occur when renaming files. */ @@ -6033,39 +6032,30 @@ rollback_trx: /* Rename the tablespace files. */ commit_cache_rebuild(ctx); - error = innobase_update_foreign_cache(ctx, user_thd); - if (error != DB_SUCCESS) { - goto foreign_fail; + if (innobase_update_foreign_cache(ctx, user_thd) + != DB_SUCCESS + && prebuilt->trx->check_foreigns) { +foreign_fail: + push_warning_printf( + user_thd, + Sql_condition::WARN_LEVEL_WARN, + ER_ALTER_INFO, + "failed to load FOREIGN KEY" + " constraints"); } } else { - error = innobase_update_foreign_cache(ctx, user_thd); + bool fk_fail = innobase_update_foreign_cache( + ctx, user_thd) != DB_SUCCESS; - if (error != DB_SUCCESS) { -foreign_fail: - /* The data dictionary cache - should be corrupted now. The - best solution should be to - kill and restart the server, - but the *.frm file has not - been replaced yet. */ - my_error(ER_CANNOT_ADD_FOREIGN, - MYF(0)); - sql_print_error( - "InnoDB: dict_load_foreigns()" - " returned %u for %s", - (unsigned) error, - thd_query_string(user_thd) - ->str); - ut_ad(0); - } else { - if (!commit_cache_norebuild( - ctx, table, trx)) { - ut_a(!prebuilt->trx->check_foreigns); - } + if (!commit_cache_norebuild(ctx, table, trx)) { + fk_fail = true; + ut_ad(!prebuilt->trx->check_foreigns); + } - innobase_rename_columns_cache( - ha_alter_info, table, - ctx->new_table); + innobase_rename_columns_cache(ha_alter_info, table, + ctx->new_table); + if (fk_fail && prebuilt->trx->check_foreigns) { + goto foreign_fail; } } DBUG_INJECT_CRASH("ib_commit_inplace_crash", From 368eda060f5922929eb4741e97b37a205591bdf3 Mon Sep 17 00:00:00 2001 From: Elena Stepanova Date: Tue, 29 Jan 2019 20:33:43 +0200 Subject: [PATCH 058/106] List of unstable tests for 10.0.38 release --- mysql-test/unstable-tests | 119 ++++++++++++++------------------------ 1 file changed, 45 insertions(+), 74 deletions(-) diff --git a/mysql-test/unstable-tests b/mysql-test/unstable-tests index 6725e2ae9ff..10f15f3ddc4 100644 --- a/mysql-test/unstable-tests +++ b/mysql-test/unstable-tests @@ -23,93 +23,72 @@ # ############################################################################## -# Based on 10.0 6ced789186fabd7dce97b3d6d171ff9e5ddc5f48 +# Based on bb-10.0-release 1522ee2949ae304ad9092894896a6272dc08bb39 main.alter_table : Modified in 10.0.37 -main.assign_key_cache : Added in 10.0.36 -main.assign_key_cache_debug : Added in 10.0.36 -main.auto_increment : Modified in 10.0.36 -main.bootstrap : Modified in 10.0.36 -main.connect_debug : Added in 10.0.36 +main.auto_increment_ranges_innodb : Modified in 10.0.38 +main.bigint : Modified in 10.0.38 main.count_distinct2 : MDEV-11768 - timeout main.create_delayed : MDEV-10605 - failed with timeout main.create_or_replace : Modified in 10.0.37 -main.ctype_binary : Modified in 10.0.36 -main.ctype_eucjpms : Modified in 10.0.36 -main.ctype_euckr : Modified in 10.0.36 -main.ctype_gbk : Modified in 10.0.36 -main.ctype_latin1 : Modified in 10.0.36 +main.ctype_latin1 : Modified in 10.0.38 main.ctype_uca : Modified in 10.0.37 -main.ctype_ucs : Modified in 10.0.36 -main.ctype_ujis : Modified in 10.0.36 -main.ctype_utf16le : Modified in 10.0.36 -main.ctype_utf16 : Modified in 10.0.36 -main.ctype_utf32 : Modified in 10.0.36 -main.ctype_utf8mb4 : Modified in 10.0.36 -main.ctype_utf8 : Modified in 10.0.36 main.debug_sync : MDEV-10607 - internal error -main.derived : Modified in 10.0.36 main.derived_opt : MDEV-11768 - timeout; modified in 10.0.37 +main.events_bugs : MDEV-12892 - Server crash main.events_slowlog : MDEV-12821 - wrong result main.func_concat : Modified in 10.0.37 +main.func_group_innodb : Modified in 10.0.38 main.func_isnull : Modified in 10.0.37 main.func_time : Modified in 10.0.37 main.gis : MDEV-13411 - wrong result on P8; modified in 10.0.37 main.grant : Modified in 10.0.37 -main.grant2 : Modified in 10.0.36 -main.grant_not_windows : Added in 10.0.36 main.group_min_max : Modified in 10.0.37 -main.having : Modified in 10.0.36 main.host_cache_size_functionality : MDEV-10606 - sporadic failure on shutdown +main.huge_frm-6224 : Modified in 10.0.38 main.index_intersect_innodb : MDEV-10643 - failed with timeout main.index_merge_innodb : MDEV-7142 - wrong result +main.index_merge_myisam : Modified in 10.0.38 +main.innodb_ext_key : Modified in 10.0.38 main.innodb_mysql_lock : MDEV-7861 - sporadic lock detection failure -main.insert_select : Modified in 10.0.36 main.join : Modified in 10.0.37 -main.join_cache : Modified in 10.0.36 -main.join_outer : Modified in 10.0.36 main.kill_processlist-6619 : MDEV-10793 - wrong result -main.limit : Modified in 10.0.36 main.log_tables-big : MDEV-13408 - wrong result main.lowercase_fs_off : Modified in 10.0.37 main.mdev-504 : MDEV-10607 - sporadic "can't connect" main.mdev375 : MDEV-10607 - sporadic "can't connect" main.merge : MDEV-10607 - sporadic "can't connect" -main.myisam : Modified in 10.0.36 -main.mysql : Modified in 10.0.36 -main.mysql_cp932 : Modified in 10.0.36 -main.mysqldump : Modified in 10.0.36 +main.mysql : Modified in 10.0.38 +main.mysqldump : Modified in 10.0.38 main.mysqlhotcopy_myisam : MDEV-10995 - test hangs on debug build -main.mysqlslap : Modified in 10.0.36 main.mysqltest : MDEV-9269 - fails on Alpha main.mysql_client_test_nonblock : MDEV-15096 - exec failed main.order_by_zerolength-4285 : Modified in 10.0.37 +main.partition : Modified in 10.0.38 main.partition_explicit_prune : Modified in 10.0.37 +main.partition_innodb : Modified in 10.0.38 main.ps : MDEV-11017 - sporadic wrong Prepared_stmt_count -main.rename : Modified in 10.0.36 main.query_cache_debug : MDEV-15281 - resize or similar command in progress +main.range_innodb : Modified in 10.0.38 +main.read_only : Modified in 10.0.38 +main.row-checksum : Modified in 10.0.38 main.selectivity : Modified in 10.0.37 main.show_explain : MDEV-10674 - wrong result main.sp : Modified in 10.0.37 -main.sp-innodb : Modified in 10.0.36 main.sp_notembedded : MDEV-10607 - internal error main.sp-security : MDEV-10607 - sporadic "can't connect"; modified in 10.0.37 -main.statistics : Modified in 10.0.36 -main.statistics_close : Added in 10.0.36 -main.stat_tables : Modified in 10.0.37 +main.stat_tables : Modified in 10.0.38 main.stat_tables_par_innodb : MDEV-14155 - wrong rounding -main.subselect : Modified in 10.0.36 +main.subselect2 : Modified in 10.0.38 main.subselect_extra_no_semijoin : Modified in 10.0.37 main.subselect_innodb : MDEV-10614 - sporadic wrong results -main.subselect_sj : Modified in 10.0.36 -main.subselect_sj_mat : Modified in 10.0.36 -main.subselect_sj2_mat : Modified in 10.0.36 -main.subselect4 : Modified in 10.0.36 +main.subselect_mat : Modified in 10.0.38 main.tc_heuristic_recover : MDEV-15200 - wrong error on mysqld_stub_cmd main.type_datetime : Modified in 10.0.37 main.type_float : Modified in 10.0.37 +main.type_newdecimal : Modified in 10.0.38 main.type_year : Modified in 10.0.37 -main.union : Modified in 10.0.36 +main.union : Modified in 10.0.38 main.xa : MDEV-11769 - lock wait timeout #---------------------------------------------------------------- @@ -124,11 +103,11 @@ archive-test_sql_discovery.discover : MDEV-16817 - Table marked as crashed #---------------------------------------------------------------- binlog.binlog_commit_wait : MDEV-10150 - Error: too much time elapsed -binlog.binlog_tmp_table_row : Added in 10.0.36 binlog.binlog_xa_recover : MDEV-8517 - Extra checkpoint #---------------------------------------------------------------- +connect.part_table : Modified in 10.0.38 connect.zip : MDEV-13884 - wrong result #---------------------------------------------------------------- @@ -137,16 +116,14 @@ engines/rr_trx.* : MDEV-10998 - tests not maintained #---------------------------------------------------------------- -federated.assisted_discovery : Include file modified in 10.0.36 -federated.federatedx : MDEV-10617 - Wrong checksum, timeouts; include file modified in 10.0.36 +federated.federatedx : MDEV-10617 - Wrong checksum, timeouts federated.federated_bug_35333 : MDEV-13410 - Wrong result federated.federated_innodb : MDEV-10617, MDEV-10417 - Wrong checksum, timeouts, fails on Mips -federated.federated_partition : MDEV-10417 - Fails on Mips; include file modified in 10.0.36 -federated.federated_transactions : MDEV-10617, MDEV-10417 - Wrong checksum, timeouts, fails on Mips; include file modified in 10.0.36 +federated.federated_partition : MDEV-10417 - Fails on Mips +federated.federated_transactions : MDEV-10617, MDEV-10417 - Wrong checksum, timeouts, fails on Mips #---------------------------------------------------------------- -funcs_1.is_engines_federated : Include file modified in 10.0.36 funcs_1.memory_views : MDEV-11773 - timeout funcs_1.processlist_val_ps : MDEV-12175 - Wrong result funcs_1.processlist_val_no_prot : MDEV-11223 - Wrong result @@ -155,50 +132,43 @@ funcs_2/charset.* : MDEV-10999 - test not maintained #---------------------------------------------------------------- -handler.ps : Added in 10.0.36 - -#---------------------------------------------------------------- - -heap.heap_auto_increment : Modified in 10.0.36 heap.heap_btree : Modified in 10.0.37 #---------------------------------------------------------------- +innodb.alter_candidate_key : Added in 10.0.38 innodb.alter_inplace_perfschema : Added in 10.0.37 -innodb.alter_partitioned_xa : Added in 10.0.36 innodb.binlog_consistent : MDEV-10618 - Server fails to start innodb.foreign-keys : Modified in 10.0.37 -innodb.foreign_key : Added in 10.0.37 +innodb.foreign_key : Modified in 10.0.38 innodb.group_commit_crash : MDEV-11770 - checksum mismatch innodb.group_commit_crash_no_optimize_thread : MDEV-11770 - checksum mismatch -innodb.innodb-alter : Modified in 10.0.36 +innodb.innodb_28867993 : Added in 10.0.38 +innodb.innodb-alter : Modified in 10.0.38 innodb.innodb-alter-debug : Modified in 10.0.37 innodb.innodb-alter-table : MDEV-10619 - Testcase timeout innodb.innodb_bug30423 : MDEV-7311 - Wrong number of rows in the plan innodb.innodb_bug48024 : MDEV-14352 - Assertion failure -innodb.innodb_bug54044 : Modified in 10.0.36 -innodb.innodb-mdev7046 : Modified in 10.0.36 +innodb.innodb-index : Modified in 10.0.38 innodb.innodb_monitor : MDEV-10939 - Testcase timeout -innodb.innodb-wl5522 : Modified in 10.0.36 +innodb.innodb_simulate_comp_failures : MDEV-18417 - ASAN failures +innodb.innodb-table-online : Modified in 10.0.38 +innodb.innodb-virtual-columns : Modified in 10.0.38 innodb.log_file_size : MDEV-15668 - Not found pattern innodb.recovery_shutdown : MDEV-15671 - Warning: database page corruption -innodb.rename_table : Added in 10.0.36 innodb.table_definition_cache_debug : MDEV-14206 - Unexpected warning innodb.table_flags : Modified in 10.0.37 innodb.xa_recovery : MDEV-15279 - mysqld got exception -innodb_fts.basic : Added in 10.0.36 innodb_fts.fts_kill_query : Modified in 10.0.37 innodb_fts.innodb-fts-fic : MDEV-14154 - Assertion failure innodb_fts.innodb_fts_misc_debug : MDEV-14156 - Unexpected warning -innodb_fts.sync_ddl : Added in 10.0.36 #---------------------------------------------------------------- -maria.alter : Modified in 10.0.36 maria.create : Added in 10.0.37 maria.fulltext2 : Added in 10.0.37 -maria.lock : Modified in 10.0.36 +maria.insert_select : MDEV-12757 - Timeout maria.maria : MDEV-14430 - Wrong result; modified in 10.0.37 #---------------------------------------------------------------- @@ -221,16 +191,15 @@ multi_source.status_vars : MDEV-4632 - failed while waiting for Slave_received_h #---------------------------------------------------------------- -parts.alter_data_directory_innodb : Added in 10.0.36 parts.partition_auto_increment_archive : MDEV-16491 - Table marked as crashed parts.partition_auto_increment_maria : MDEV-14430 - wrong result parts.partition_exch_qa_10 : MDEV-11765 - wrong result -parts.truncate_locked : Added in 10.0.36 parts.update_and_cache : Added in 10.0.37 #---------------------------------------------------------------- perfschema.connect_attrs : MDEV-17283 - Wrong result +perfschema.dml_setup_instruments : Modified in 10.0.38 perfschema.func_file_io : MDEV-5708 - fails for s390x perfschema.func_mutex : MDEV-5708 - fails for s390x perfschema.hostcache_ipv6_ssl : MDEV-10696 - crash on shutdown @@ -242,17 +211,17 @@ perfschema_stress.* : MDEV-10996 - tests not maintained #---------------------------------------------------------------- plugins.feedback_plugin_send : MDEV-7932 - ssl failed for url, MDEV-11118 - wrong result -plugins.server_audit : MDEV-9562 - crashes on sol10-sparc; modified in 10.0.36 +plugins.server_audit : MDEV-9562 - crashes on sol10-sparc plugins.thread_pool_server_audit : MDEV-9562 - crashes on sol10-sparc, MDEV-14295 - wrong result #---------------------------------------------------------------- roles.create_and_grant_role : MDEV-11772 - wrong result +roles.flush_roles-17898 : Added in 10.0.38 #---------------------------------------------------------------- rpl.last_insert_id : MDEV-10625 - warnings in error log -rpl.rename : Added in 10.0.36 rpl.rpl_15919 : Added in 10.0.37 rpl.rpl_auto_increment : MDEV-10417 - Fails on Mips rpl.rpl_auto_increment_bug45679 : MDEV-10417 - Fails on Mips @@ -263,6 +232,7 @@ rpl.rpl_foreign_key_innodb : Modified in 10.0.37 rpl.rpl_gtid_crash : MDEV-9501 - Warning: failed registering on master rpl.rpl_gtid_stop_start : MDEV-10629 - Crash on shutdown rpl.rpl_gtid_until : MDEV-10625 - warnings in error log +rpl.rpl_idempotency : Modified in 10.0.38 rpl.rpl_innodb_bug30888 : MDEV-10417 - Fails on Mips rpl.rpl_insert : MDEV-9329 - Fails on Ubuntu/s390x rpl.rpl_insert_delayed : MDEV-9329 - Fails on Ubuntu/s390x @@ -270,14 +240,14 @@ rpl.rpl_insert_id_pk : MDEV-16567 - Assertion failure rpl.rpl_invoked_features : MDEV-10417 - Fails on Mips rpl.rpl_lcase_tblnames_rewrite_db : Added in 10.0.37 rpl.rpl_mdev6020 : MDEV-10417 - Timeouts, fails on Mips -rpl.rpl_mixed_implicit_commit_binlog : Included file modified in 10.0.36 rpl.rpl_parallel : MDEV-10653 - Timeouts rpl.rpl_parallel_mdev6589 : MDEV-12979 - Assertion failure rpl.rpl_parallel_multilevel2 : MDEV-14723 - Timeout rpl.rpl_parallel_temptable : MDEV-10356 - Crash in close_thread_tables rpl.rpl_partition_innodb : MDEV-10417 - Fails on Mips rpl.rpl_row_basic_11bugs : MDEV-12171 - Server failed to start -rpl.rpl_row_implicit_commit_binlog : Included file modified in 10.0.36 +rpl.rpl_row_big_table_id_32bit : Added in 10.0.38 +rpl.rpl_row_big_table_id_64bit : Added in 10.0.38 rpl.rpl_row_index_choice : MDEV-13409 - Server crash rpl.rpl_row_lcase_tblnames : Added in 10.0.37 rpl.rpl_row_sp001 : MDEV-9329 - Fails on Ubuntu/s390x @@ -287,7 +257,7 @@ rpl.rpl_semi_sync_uninstall_plugin : MDEV-7140 - Wrong plugin status rpl.rpl_show_slave_hosts : MDEV-12171 - Server failed to start rpl.rpl_skip_replication : MDEV-9268 - Fails with timeout in sync_slave_with_master on Alpha rpl.rpl_slave_grp_exec : MDEV-10514 - Unexpected deadlock -rpl.rpl_stm_implicit_commit_binlog : Included file modified in 10.0.36 +rpl.rpl_start_stop_slave : MDEV-13567 - Timeout in sync rpl.rpl_stm_lcase_tblnames : Added in 10.0.37 rpl.rpl_sync : MDEV-10633 - Database page corruption rpl.rpl_temporary_error2 : MDEV-10634 - Wrong number of retries @@ -324,6 +294,7 @@ stress.ddl_innodb : MDEV-10635 - Testcase timeout sys_vars.autocommit_func2 : MDEV-9329 - Fails on Ubuntu/s390x sys_vars.innodb_ft_result_cache_limit_32 : Added in 10.0.37 sys_vars.innodb_ft_result_cache_limit_64 : Added in 10.0.37 +sys_vars.table_definition_cache_basic : Modified in 10.0.38 sys_vars.thread_cache_size_func : MDEV-11775 - wrong result #---------------------------------------------------------------- @@ -345,6 +316,7 @@ tokudb.savepoint-5 : MDEV-15280 - wrong result tokudb_backup.* : MDEV-11001 - tests don't work tokudb_bugs.PS-3773 : Added in 10.0.37 +tokudb_bugs.PS-4979 : Added in 10.0.38 tokudb_bugs.alter_table_comment_rebuild_data : Added in 10.0.37 tokudb_bugs.checkpoint_lock : MDEV-10637 - Wrong processlist output tokudb_bugs.checkpoint_lock_3 : MDEV-10637 - Wrong processlist output @@ -360,14 +332,13 @@ rpl-tokudb.* : MDEV-14354 - Tests fail with tcmalloc #---------------------------------------------------------------- -unit.lf : MDEV-12897 - Unexpected return code +unit.lf : MDEV-18416 - Object was probably modified after being freed unit.ma_test_loghandler : MDEV-10638 - record read not ok -unit.my_atomic : MDEV-15670 - Signal 11 thrown #---------------------------------------------------------------- vcol.not_supported : MDEV-10639 - Testcase timeout vcol.vcol_keys_innodb : MDEV-10639 - Testcase timeout -vcol.vcol_misc : MDEV-16651 - Wrong error message; modified in 10.0.36 +vcol.vcol_misc : MDEV-16651 - Wrong error message #---------------------------------------------------------------- From 6e2af7d084ca1bba79e60f05616aaefb6028ee9d Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Wed, 30 Jan 2019 09:31:32 +0100 Subject: [PATCH 059/106] mariabackup : Remove unused parameter innodb_buffer_pool_size --- extra/mariabackup/xtrabackup.cc | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index 338b70dc874..2d28a6caa84 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -250,7 +250,6 @@ static ulong innobase_log_block_size = 512; char* innobase_doublewrite_file = NULL; char* innobase_buffer_pool_filename = NULL; -longlong innobase_buffer_pool_size = 8*1024*1024L; longlong innobase_log_file_size = 48*1024*1024L; /* The default values for the following char* start-up parameters @@ -1023,11 +1022,6 @@ struct my_option xb_server_options[] = (G_PTR*) &srv_auto_extend_increment, (G_PTR*) &srv_auto_extend_increment, 0, GET_ULONG, REQUIRED_ARG, 8L, 1L, 1000L, 0, 1L, 0}, - {"innodb_buffer_pool_size", OPT_INNODB_BUFFER_POOL_SIZE, - "The size of the memory buffer InnoDB uses to cache data and indexes of its tables.", - (G_PTR*) &innobase_buffer_pool_size, (G_PTR*) &innobase_buffer_pool_size, 0, - GET_LL, REQUIRED_ARG, 8*1024*1024L, 1024*1024L, LONGLONG_MAX, 0, - 1024*1024L, 0}, {"innodb_checksums", OPT_INNODB_CHECKSUMS, "Enable InnoDB checksums validation (enabled by default). \ Disable with --skip-innodb-checksums.", (G_PTR*) &innobase_use_checksums, (G_PTR*) &innobase_use_checksums, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, @@ -1546,13 +1540,6 @@ innodb_init_param(void) " on 32-bit systems\n"); } - if (innobase_buffer_pool_size > UINT_MAX32) { - msg("mariabackup: innobase_buffer_pool_size can't be " - "over 4GB on 32-bit systems\n"); - - goto error; - } - if (innobase_log_file_size > UINT_MAX32) { msg("mariabackup: innobase_log_file_size can't be " "over 4GB on 32-bit systemsi\n"); @@ -1677,8 +1664,6 @@ mem_free_and_error: /* We set srv_pool_size here in units of 1 kB. InnoDB internally changes the value so that it becomes the number of database pages. */ - - //srv_buf_pool_size = (ulint) innobase_buffer_pool_size; srv_buf_pool_size = (ulint) xtrabackup_use_memory; srv_mem_pool_size = (ulint) innobase_additional_mem_pool_size; From d9d83f1d92b696ef56f4944df036b8a78364ebb4 Mon Sep 17 00:00:00 2001 From: Daniel Bartholomew Date: Thu, 31 Jan 2019 09:09:50 -0500 Subject: [PATCH 060/106] bump the VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 163137684a2..0924461861a 100644 --- a/VERSION +++ b/VERSION @@ -1,3 +1,3 @@ MYSQL_VERSION_MAJOR=10 MYSQL_VERSION_MINOR=0 -MYSQL_VERSION_PATCH=38 +MYSQL_VERSION_PATCH=39 From a3a4ea935541bbe4b44a51d7f808119702e35841 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Thu, 31 Jan 2019 19:28:38 +0100 Subject: [PATCH 061/106] postmerge rollbacks and fixes --- mysql-test/mysql-test-run.pl | 21 +++++++++++++------ .../suite/galera/r/galera_defaults.result | 1 + .../wsrep_info/mysql-test/wsrep_info/suite.pm | 2 ++ sql/log_event.cc | 12 +---------- zlib/CMakeLists.txt | 3 ++- 5 files changed, 21 insertions(+), 18 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index da72e7e1a9a..5fe616c67ae 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -139,6 +139,8 @@ my $opt_start_exit; my $start_only; my $file_wsrep_provider; +our @global_suppressions; + END { if ( defined $opt_tmpdir_pid and $opt_tmpdir_pid == $$ ) { @@ -193,6 +195,8 @@ my @DEFAULT_SUITES= qw( sys_vars- unit- vcol- + wsrep- + galera- ); my $opt_suites; @@ -353,6 +357,7 @@ my $opt_max_test_fail= env_or_val(MTR_MAX_TEST_FAIL => 10); my $opt_core_on_failure= 0; my $opt_parallel= $ENV{MTR_PARALLEL} || 1; +my $opt_port_group_size = $ENV{MTR_PORT_GROUP_SIZE} || 20; # lock file to stop tests my $opt_stop_file= $ENV{MTR_STOP_FILE}; @@ -1113,6 +1118,7 @@ sub command_line_setup { # Specify ports 'build-thread|mtr-build-thread=i' => \$opt_build_thread, 'port-base|mtr-port-base=i' => \$opt_port_base, + 'port-group-size=s' => \$opt_port_group_size, # Test case authoring 'record' => \$opt_record, @@ -1818,16 +1824,16 @@ sub set_build_thread_ports($) { $ENV{MTR_BUILD_THREAD}= $build_thread; # Calculate baseport - $baseport= $build_thread * 20 + 10000; - if ( $baseport < 5001 or $baseport + 19 >= 32767 ) + $baseport= $build_thread * $opt_port_group_size + 10000; + if ( $baseport < 5001 or $baseport + $opt_port_group_size >= 32767 ) { mtr_error("MTR_BUILD_THREAD number results in a port", "outside 5001 - 32767", - "($baseport - $baseport + 19)"); + "($baseport - $baseport + $opt_port_group_size)"); } mtr_report("Using MTR_BUILD_THREAD $build_thread,", - "with reserved ports $baseport..".($baseport+19)); + "with reserved ports $baseport..".($baseport+($opt_port_group_size-1))); } @@ -2988,8 +2994,8 @@ sub kill_leftovers ($) { sub check_ports_free ($) { my $bthread= shift; - my $portbase = $bthread * 10 + 10000; - for ($portbase..$portbase+9){ + my $portbase = $bthread * $opt_port_group_size + 10000; + for ($portbase..$portbase+($opt_port_group_size-1)){ if (mtr_ping_port($_)){ mtr_report(" - 'localhost:$_' was not free"); return 0; # One port was not free @@ -4401,6 +4407,7 @@ sub extract_warning_lines ($$) { # Perl code. my @antipatterns = ( + @global_suppressions, qr/error .*connecting to master/, qr/InnoDB: Error: in ALTER TABLE `test`.`t[12]`/, qr/InnoDB: Error: table `test`.`t[12]` .*does not exist in the InnoDB internal/, @@ -6110,6 +6117,8 @@ Options that specify ports build-thread=# Can be set in environment variable MTR_BUILD_THREAD. Set MTR_BUILD_THREAD="auto" to automatically aquire a build thread id that is unique to current host + port-group-size=N Reserve groups of TCP ports of size N for each MTR thread + Options for test case authoring diff --git a/mysql-test/suite/galera/r/galera_defaults.result b/mysql-test/suite/galera/r/galera_defaults.result index 6871ec6d56b..e7a2508c0f3 100644 --- a/mysql-test/suite/galera/r/galera_defaults.result +++ b/mysql-test/suite/galera/r/galera_defaults.result @@ -19,6 +19,7 @@ ORDER BY VARIABLE_NAME; VARIABLE_NAME VARIABLE_VALUE WSREP_AUTO_INCREMENT_CONTROL ON WSREP_CAUSAL_READS ON +WSREP_CERTIFICATION_RULES strict WSREP_CERTIFY_NONPK ON WSREP_CLUSTER_ADDRESS gcomm:// WSREP_CLUSTER_NAME my_wsrep_cluster diff --git a/plugin/wsrep_info/mysql-test/wsrep_info/suite.pm b/plugin/wsrep_info/mysql-test/wsrep_info/suite.pm index 9f684ae6b0c..cf4d124cb53 100644 --- a/plugin/wsrep_info/mysql-test/wsrep_info/suite.pm +++ b/plugin/wsrep_info/mysql-test/wsrep_info/suite.pm @@ -30,10 +30,12 @@ push @::global_suppressions, qr(WSREP: Failed to send state UUID:.*), qr(WSREP: wsrep_sst_receive_address.*), qr(WSREP: Could not open saved state file for reading: .*), + qr(WSREP: Could not open state file for reading: .*), qr(WSREP: last inactive check more than .* skipping check), qr(WSREP: Gap in state sequence. Need state transfer.), qr(WSREP: Failed to prepare for incremental state transfer: .*), qr(WSREP: SYNC message from member .* in non-primary configuration. Ignored.), + qr|WSREP: access file\(.*gvwstate.dat\) failed\(No such file or directory\)|, ); diff --git a/sql/log_event.cc b/sql/log_event.cc index a4fc2dd5398..1b372778b88 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -7941,12 +7941,7 @@ User_var_log_event(const char* buf, uint event_len, val_len= uint4korr(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE + UV_CHARSET_NUMBER_SIZE); - if (val + val_len > buf_end) - { - error= true; - goto err; - } - + /** We need to check if this is from an old server that did not pack information for flags. @@ -7959,11 +7954,6 @@ User_var_log_event(const char* buf, uint event_len, we keep the flags set to UNDEF_F. */ uint bytes_read= ((val + val_len) - buf_start); - if (bytes_read > event_len) - { - error= true; - goto err; - } if ((data_written - bytes_read) > 0) { flags= (uint) *(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE + diff --git a/zlib/CMakeLists.txt b/zlib/CMakeLists.txt index d09f6c13f50..0c224e7ce22 100644 --- a/zlib/CMakeLists.txt +++ b/zlib/CMakeLists.txt @@ -116,6 +116,7 @@ if(NOT MINGW) win32/zlib1.rc # If present will override custom build rule below. ) endif() + # parse the full version number from zlib.h and include in ZLIB_FULL_VERSION file(READ ${CMAKE_CURRENT_SOURCE_DIR}/zlib.h _zlib_h_contents) string(REGEX REPLACE ".*#define[ \t]+ZLIB_VERSION[ \t]+\"([-0-9A-Za-z.]+)\".*" @@ -144,4 +145,4 @@ elseif(UNIX) if(NOT APPLE) set_target_properties(zlib PROPERTIES LINK_FLAGS "-Wl,--version-script,\"${CMAKE_CURRENT_SOURCE_DIR}/zlib.map\"") endif() -endif() \ No newline at end of file +endif() From 6051842cd0b2bdf584e630f89d4fdec42c56908f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 1 Feb 2019 09:13:18 +0200 Subject: [PATCH 062/106] Minor clean-up --- storage/innobase/row/row0ins.cc | 11 ++++------- storage/xtradb/row/row0ins.cc | 9 +++------ 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index c031c38163e..22588d33418 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -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 @@ -1643,16 +1643,14 @@ run_again: } if (check_ref) { -#ifdef WITH_WSREP - enum wsrep_key_type key_type = WSREP_KEY_EXCLUSIVE; -#endif WITH_WSREP err = DB_SUCCESS; - #ifdef WITH_WSREP + enum wsrep_key_type key_type; if (upd_node != NULL) { key_type = WSREP_KEY_SHARED; } else { switch (wsrep_certification_rules) { + default: case WSREP_CERTIFICATION_RULES_STRICT: key_type = WSREP_KEY_EXCLUSIVE; break; @@ -1669,8 +1667,7 @@ run_again: check_index, check_ref, key_type); - #endif /* WITH_WSREP */ - +#endif /* WITH_WSREP */ goto end_scan; } else if (foreign->type != 0) { /* There is an ON UPDATE or ON DELETE diff --git a/storage/xtradb/row/row0ins.cc b/storage/xtradb/row/row0ins.cc index f146d1f68b1..b14d43e4f42 100644 --- a/storage/xtradb/row/row0ins.cc +++ b/storage/xtradb/row/row0ins.cc @@ -1655,16 +1655,14 @@ run_again: } if (check_ref) { -#ifdef WITH_WSREP - enum wsrep_key_type key_type = WSREP_KEY_EXCLUSIVE; -#endif /* WITH_WSREP */ err = DB_SUCCESS; - #ifdef WITH_WSREP + enum wsrep_key_type key_type; if (upd_node != NULL) { key_type = WSREP_KEY_SHARED; } else { switch (wsrep_certification_rules) { + default: case WSREP_CERTIFICATION_RULES_STRICT: key_type = WSREP_KEY_EXCLUSIVE; break; @@ -1681,8 +1679,7 @@ run_again: check_index, check_ref, key_type); - #endif /* WITH_WSREP */ - +#endif /* WITH_WSREP */ goto end_scan; } else if (foreign->type != 0) { /* There is an ON UPDATE or ON DELETE From 94e6a226a3145c3cc0871ea5cdc2f8c55ff313ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 1 Feb 2019 09:14:10 +0200 Subject: [PATCH 063/106] my_malloc(): Invoke TRASH_ALLOC even WITH_SAFEMALLOC=OFF --- mysys/my_malloc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mysys/my_malloc.c b/mysys/my_malloc.c index 719c13a040e..99a15e6f432 100644 --- a/mysys/my_malloc.c +++ b/mysys/my_malloc.c @@ -117,6 +117,7 @@ void *my_malloc(size_t size, myf my_flags) MY_TEST(my_flags & MY_THREAD_SPECIFIC)); update_malloc_size(size + MALLOC_PREFIX_SIZE, MY_TEST(my_flags & MY_THREAD_SPECIFIC)); + TRASH_ALLOC(point, size); DBUG_EXECUTE_IF("simulate_out_of_memory", { /* my_free() handles memory accounting */ From a193c5720ea461ce82390af3fe9c292581242223 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 1 Feb 2019 11:05:29 +0200 Subject: [PATCH 064/106] MDEV-17206: Fix the .rdiff file that was broken in MDEV-17804 Only starting with MariaDB 10.2, the .result file will echo "connect" and "connection" statements. There is no way how the test could have passed on debug builds after commit 1037edcb1140aa0bdf1d52f118d9008084f842b5 (which looks like an untested backport from a later version). --- .../galera/r/galera_ist_mysqldump,debug.rdiff | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/mysql-test/suite/galera/r/galera_ist_mysqldump,debug.rdiff b/mysql-test/suite/galera/r/galera_ist_mysqldump,debug.rdiff index 141b1ebd25f..49d216d0f83 100644 --- a/mysql-test/suite/galera/r/galera_ist_mysqldump,debug.rdiff +++ b/mysql-test/suite/galera/r/galera_ist_mysqldump,debug.rdiff @@ -1,12 +1,11 @@ ---- r/galera_ist_mysqldump.result 2018-11-22 14:25:28.551554055 +0200 -+++ r/galera_ist_mysqldump.reject 2018-11-22 15:46:33.119441931 +0200 -@@ -200,6 +200,114 @@ +--- r/galera_ist_mysqldump.result ++++ r/galera_ist_mysqldump,debug.result +@@ -180,6 +180,103 @@ DROP TABLE t1; COMMIT; SET AUTOCOMMIT=ON; +Performing State Transfer on a server that has been killed and restarted +while a DDL was in progress on it -+connection node_1; +CREATE TABLE t1 (f1 CHAR(255)) ENGINE=InnoDB; +SET AUTOCOMMIT=OFF; +START TRANSACTION; @@ -15,7 +14,6 @@ +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); -+connection node_2; +START TRANSACTION; +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); @@ -24,12 +22,9 @@ +INSERT INTO t1 VALUES ('node2_committed_before'); +COMMIT; +SET GLOBAL debug_dbug = 'd,sync.alter_opened_table'; -+connection node_1; +ALTER TABLE t1 ADD COLUMN f2 INTEGER; -+connection node_2; +SET wsrep_sync_wait = 0; +Killing server ... -+connection node_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 (f1) VALUES ('node1_committed_during'); @@ -44,7 +39,6 @@ +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); -+connect node_1a_galera_st_kill_slave_ddl, 127.0.0.1, root, , test, $NODE_MYPORT_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); @@ -52,9 +46,7 @@ +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); -+connection node_2; +Performing --wsrep-recover ... -+connection node_2; +Starting server ... +Using --wsrep-start-position when starting mysqld ... +SET AUTOCOMMIT=OFF; @@ -65,7 +57,6 @@ +INSERT INTO t1 (f1) VALUES ('node2_committed_after'); +INSERT INTO t1 (f1) VALUES ('node2_committed_after'); +COMMIT; -+connection node_1; +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); @@ -80,7 +71,6 @@ +INSERT INTO t1 (f1) VALUES ('node1_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_committed_after'); +COMMIT; -+connection node_1a_galera_st_kill_slave_ddl; +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); @@ -98,7 +88,6 @@ +1 +COMMIT; +SET AUTOCOMMIT=ON; -+connection node_1; +SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1'; +COUNT(*) = 2 +1 @@ -112,6 +101,6 @@ +COMMIT; +SET AUTOCOMMIT=ON; +SET GLOBAL debug_dbug = $debug_orig; - connection node_1; CALL mtr.add_suppression("Slave SQL: Error 'The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement' on query"); DROP USER sst; + CALL mtr.add_suppression("Slave SQL: Error 'The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement' on query"); From dfc9bff5a9f402ebe9beff2912aab2f53b0c27ad Mon Sep 17 00:00:00 2001 From: Julius Goryavsky Date: Fri, 1 Feb 2019 17:45:15 +0100 Subject: [PATCH 065/106] MDEV-18379: IPv6 compatibility changes/Unification of check for IPv6 This patch contains the port of the MDEV-18379 patch for 10.2 branch, but also includes a number of changes made within MDEV-17835, which are necessary for the normal operation of tests that use IPv6: 1) Currently, the three-node mtr suite for Galera (galera_3nodes) uses a separate IPv6 availability check using the "have_ipv6.inc" file. This check duplicates a more accurate check at suite.pm level, which can be used by including the file "check_ipv6.inc". This patch removes this discrepancy between suites. 2) Fixed numerous bugs in the SST scripts and in the mtr test files (galera_3nodes mtr suite) that prevented the use of Galera with IPv6 addresses. 3) Fixed flaws in the galera_3nodes mtr suite control scripts, because of which they could not work with mariabackup. 4) Fixed flaws in the rsync and mysqldump tests (for galera_3nodes mtr tests suite). These tests were not performed successfully without these fixes. 5) GAL-501 test in the galera_3nodes suite does not contain the option "--bind-address=::" that is needed for the test to work correctly with IPv6 (at least on some systems), since without it the server will not wait for connections on the IPv6 interface. https://jira.mariadb.org/browse/MDEV-18379 and partially https://jira.mariadb.org/browse/MDEV-17835 --- mysql-test/suite/galera_3nodes/disabled.def | 2 -- mysql-test/suite/galera_3nodes/r/GAL-501.result | 3 +++ .../r/galera_innobackupex_backup.result | 6 ++++++ .../galera_3nodes/r/galera_ipv6_mariabackup.result | 4 ++++ .../galera_3nodes/r/galera_ipv6_mysqldump.result | 12 ++++++++++-- .../suite/galera_3nodes/r/galera_ipv6_rsync.result | 3 +++ .../galera_3nodes/r/galera_ipv6_xtrabackup-v2.result | 4 ++++ mysql-test/suite/galera_3nodes/suite.pm | 6 +++--- .../galera_3nodes/t/galera_ipv6_mariabackup.test | 2 +- .../suite/galera_3nodes/t/galera_ipv6_mysqldump.opt | 1 + .../suite/galera_3nodes/t/galera_ipv6_rsync.opt | 1 + .../galera_3nodes/t/galera_ipv6_xtrabackup-v2.opt | 2 +- scripts/wsrep_sst_mariabackup.sh | 6 +++--- scripts/wsrep_sst_rsync.sh | 4 ++-- 14 files changed, 42 insertions(+), 14 deletions(-) create mode 100644 mysql-test/suite/galera_3nodes/t/galera_ipv6_mysqldump.opt create mode 100644 mysql-test/suite/galera_3nodes/t/galera_ipv6_rsync.opt diff --git a/mysql-test/suite/galera_3nodes/disabled.def b/mysql-test/suite/galera_3nodes/disabled.def index e640baebf7d..1683485981b 100644 --- a/mysql-test/suite/galera_3nodes/disabled.def +++ b/mysql-test/suite/galera_3nodes/disabled.def @@ -1,4 +1,2 @@ galera_slave_options_do :MDEV-8798 galera_slave_options_ignore : MDEV-8798 -galera_innobackupex_backup : xtrabackup is deprecated -galera_ipv6_xtrabackup-v2 : xtrabackup is deprecated diff --git a/mysql-test/suite/galera_3nodes/r/GAL-501.result b/mysql-test/suite/galera_3nodes/r/GAL-501.result index a2bf5f4d98c..bcf74142144 100644 --- a/mysql-test/suite/galera_3nodes/r/GAL-501.result +++ b/mysql-test/suite/galera_3nodes/r/GAL-501.result @@ -4,9 +4,12 @@ VARIABLE_VALUE LIKE '%[::1]%' SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; VARIABLE_VALUE = 3 1 +connection node_2; SET GLOBAL wsrep_provider_options='gmcast.isolate=1'; +connection node_1; CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; INSERT INTO t1 VALUES (1); +connection node_2; SET GLOBAL wsrep_provider_options='gmcast.isolate=0'; SELECT COUNT(*) = 1 FROM t1; COUNT(*) = 1 diff --git a/mysql-test/suite/galera_3nodes/r/galera_innobackupex_backup.result b/mysql-test/suite/galera_3nodes/r/galera_innobackupex_backup.result index 85000db8e77..6ed7587303d 100644 --- a/mysql-test/suite/galera_3nodes/r/galera_innobackupex_backup.result +++ b/mysql-test/suite/galera_3nodes/r/galera_innobackupex_backup.result @@ -1,9 +1,15 @@ +connection node_1; +connection node_2; +connection node_3; +connection node_1; CREATE TABLE t1 (f1 INTEGER); INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); +connection node_2; SELECT COUNT(*) = 10 FROM t1; COUNT(*) = 10 1 Killing server ... +connection node_1; INSERT INTO t1 VALUES (11),(12),(13),(14),(15),(16),(17),(18),(19),(20); SELECT COUNT(*) = 20 FROM t1; COUNT(*) = 20 diff --git a/mysql-test/suite/galera_3nodes/r/galera_ipv6_mariabackup.result b/mysql-test/suite/galera_3nodes/r/galera_ipv6_mariabackup.result index 53e35939a79..5665ed5f46a 100644 --- a/mysql-test/suite/galera_3nodes/r/galera_ipv6_mariabackup.result +++ b/mysql-test/suite/galera_3nodes/r/galera_ipv6_mariabackup.result @@ -4,14 +4,18 @@ VARIABLE_VALUE LIKE '%[::1]%' SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; VARIABLE_VALUE = 3 1 +connection node_2; SET GLOBAL wsrep_provider_options='gmcast.isolate=1'; +connection node_1; CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; INSERT INTO t1 VALUES (1); +connection node_2; SET GLOBAL wsrep_provider_options='gmcast.isolate=0'; SELECT COUNT(*) = 1 FROM t1; COUNT(*) = 1 1 DROP TABLE t1; +connection node_1; include/assert_grep.inc [Streaming the backup to joiner at \[::1\]] include/assert_grep.inc [async IST sender starting to serve tcp://\[::1\]:] include/assert_grep.inc [IST receiver addr using tcp://\[::1\]] diff --git a/mysql-test/suite/galera_3nodes/r/galera_ipv6_mysqldump.result b/mysql-test/suite/galera_3nodes/r/galera_ipv6_mysqldump.result index 1d9ae940cfb..3564dc8c5a1 100644 --- a/mysql-test/suite/galera_3nodes/r/galera_ipv6_mysqldump.result +++ b/mysql-test/suite/galera_3nodes/r/galera_ipv6_mysqldump.result @@ -1,13 +1,20 @@ call mtr.add_suppression("WSREP: wsrep_sst_method is set to 'mysqldump' yet mysqld bind_address is set to'"); call mtr.add_suppression("Failed to load slave replication state from table mysql.gtid_slave_pos"); +connection node_1; +connection node_2; +connection node_3; +connection node_1; CREATE USER 'sst'; GRANT ALL PRIVILEGES ON *.* TO 'sst'; SET GLOBAL wsrep_sst_auth = 'sst:'; +connection node_2; SET GLOBAL wsrep_sst_method = 'mysqldump'; Shutting down server ... +connection node_1; Cleaning var directory ... CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; INSERT INTO t1 VALUES (1); +connection node_2; Starting server ... SELECT COUNT(*) = 1 FROM t1; COUNT(*) = 1 @@ -16,14 +23,15 @@ DROP TABLE t1; SELECT VARIABLE_VALUE LIKE '%[::1]%' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_incoming_addresses'; VARIABLE_VALUE LIKE '%[::1]%' 1 +connection node_1; CALL mtr.add_suppression("Slave SQL: Error 'The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement' on query"); DROP USER sst; +connection node_2; CALL mtr.add_suppression("Slave SQL: Error 'The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement' on query"); CALL mtr.add_suppression("InnoDB: Error: Table \"mysql\"\\.\"innodb_index_stats\" not found"); -CALL mtr.add_suppression("InnoDB: New log files created"); -CALL mtr.add_suppression("InnoDB: Creating foreign key constraint system tables"); CALL mtr.add_suppression("Can't open and lock time zone table"); CALL mtr.add_suppression("Can't open and lock privilege tables"); CALL mtr.add_suppression("Info table is not ready to be used"); CALL mtr.add_suppression("Native table .* has the wrong structure"); +connection node_2; CALL mtr.add_suppression("Unsupported protocol downgrade: incremental data collection disabled. Expect abort"); diff --git a/mysql-test/suite/galera_3nodes/r/galera_ipv6_rsync.result b/mysql-test/suite/galera_3nodes/r/galera_ipv6_rsync.result index a2bf5f4d98c..bcf74142144 100644 --- a/mysql-test/suite/galera_3nodes/r/galera_ipv6_rsync.result +++ b/mysql-test/suite/galera_3nodes/r/galera_ipv6_rsync.result @@ -4,9 +4,12 @@ VARIABLE_VALUE LIKE '%[::1]%' SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; VARIABLE_VALUE = 3 1 +connection node_2; SET GLOBAL wsrep_provider_options='gmcast.isolate=1'; +connection node_1; CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; INSERT INTO t1 VALUES (1); +connection node_2; SET GLOBAL wsrep_provider_options='gmcast.isolate=0'; SELECT COUNT(*) = 1 FROM t1; COUNT(*) = 1 diff --git a/mysql-test/suite/galera_3nodes/r/galera_ipv6_xtrabackup-v2.result b/mysql-test/suite/galera_3nodes/r/galera_ipv6_xtrabackup-v2.result index 53e35939a79..5665ed5f46a 100644 --- a/mysql-test/suite/galera_3nodes/r/galera_ipv6_xtrabackup-v2.result +++ b/mysql-test/suite/galera_3nodes/r/galera_ipv6_xtrabackup-v2.result @@ -4,14 +4,18 @@ VARIABLE_VALUE LIKE '%[::1]%' SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; VARIABLE_VALUE = 3 1 +connection node_2; SET GLOBAL wsrep_provider_options='gmcast.isolate=1'; +connection node_1; CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; INSERT INTO t1 VALUES (1); +connection node_2; SET GLOBAL wsrep_provider_options='gmcast.isolate=0'; SELECT COUNT(*) = 1 FROM t1; COUNT(*) = 1 1 DROP TABLE t1; +connection node_1; include/assert_grep.inc [Streaming the backup to joiner at \[::1\]] include/assert_grep.inc [async IST sender starting to serve tcp://\[::1\]:] include/assert_grep.inc [IST receiver addr using tcp://\[::1\]] diff --git a/mysql-test/suite/galera_3nodes/suite.pm b/mysql-test/suite/galera_3nodes/suite.pm index 66502c00c6b..a7c1bf79c06 100644 --- a/mysql-test/suite/galera_3nodes/suite.pm +++ b/mysql-test/suite/galera_3nodes/suite.pm @@ -81,11 +81,11 @@ sub skip_combinations { my %skip = (); $skip{'include/have_filekeymanagement.inc'} = 'needs file_key_management plugin' unless $ENV{FILE_KEY_MANAGEMENT_SO}; - $skip{'include/have_mariabackup.inc'} = 'Need mariabackup' + $skip{'suite/galera/include/have_mariabackup.inc'} = 'Need mariabackup' unless which(mariabackup); - $skip{'include/have_mariabackup.inc'} = 'Need ss' + $skip{'suite/galera/include/have_mariabackup.inc'} = 'Need ss' unless which(ss); - $skip{'include/have_mariabackup.inc'} = 'Need socat or nc' + $skip{'suite/galera/include/have_mariabackup.inc'} = 'Need socat or nc' unless $ENV{MTR_GALERA_TFMT}; %skip; } diff --git a/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup.test b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup.test index 8cbd8cf2454..84c33251c98 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup.test +++ b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup.test @@ -1,6 +1,6 @@ --source include/galera_cluster.inc --source include/check_ipv6.inc ---source include/have_mariabackup.inc +--source suite/galera/include/have_mariabackup.inc # Confirm that initial handshake happened over ipv6 diff --git a/mysql-test/suite/galera_3nodes/t/galera_ipv6_mysqldump.opt b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mysqldump.opt new file mode 100644 index 00000000000..c2bb4d156af --- /dev/null +++ b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mysqldump.opt @@ -0,0 +1 @@ +--bind-address=:: diff --git a/mysql-test/suite/galera_3nodes/t/galera_ipv6_rsync.opt b/mysql-test/suite/galera_3nodes/t/galera_ipv6_rsync.opt new file mode 100644 index 00000000000..c2bb4d156af --- /dev/null +++ b/mysql-test/suite/galera_3nodes/t/galera_ipv6_rsync.opt @@ -0,0 +1 @@ +--bind-address=:: diff --git a/mysql-test/suite/galera_3nodes/t/galera_ipv6_xtrabackup-v2.opt b/mysql-test/suite/galera_3nodes/t/galera_ipv6_xtrabackup-v2.opt index c2bb4d156af..c195dd0f35b 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_ipv6_xtrabackup-v2.opt +++ b/mysql-test/suite/galera_3nodes/t/galera_ipv6_xtrabackup-v2.opt @@ -1 +1 @@ ---bind-address=:: +--bind-address=:: --skip-innodb-safe-truncate diff --git a/scripts/wsrep_sst_mariabackup.sh b/scripts/wsrep_sst_mariabackup.sh index 2eedbb4b189..039a350b18a 100644 --- a/scripts/wsrep_sst_mariabackup.sh +++ b/scripts/wsrep_sst_mariabackup.sh @@ -522,7 +522,7 @@ kill_xtrabackup() setup_ports() { if [[ "$WSREP_SST_OPT_ROLE" == "donor" ]];then - if [[ ${WSREP_SST_OPT_ADDR:0:1} == '[' ]];then + if [ "${WSREP_SST_OPT_ADDR#\[}" != "$WSREP_SST_OPT_ADDR" ]; then remain=$(echo $WSREP_SST_OPT_ADDR | awk -F '\\][:/]' '{ print $2 }') REMOTEIP=$(echo $WSREP_SST_OPT_ADDR | awk -F '\\]:' '{ print $1 }')"]" SST_PORT=$(echo $remain | awk -F '[:/]' '{ print $1 }') @@ -535,7 +535,7 @@ setup_ports() sst_ver=$(echo $WSREP_SST_OPT_ADDR | awk -F '[:/]' '{ print $5 }') fi else - if [[ ${WSREP_SST_OPT_ADDR:0:1} == '[' ]];then + if [ "${WSREP_SST_OPT_ADDR#\[}" != "$WSREP_SST_OPT_ADDR" ]; then SST_PORT=$(echo ${WSREP_SST_OPT_ADDR} | awk -F '\\]:' '{ print $2 }') else SST_PORT=$(echo ${WSREP_SST_OPT_ADDR} | awk -F ':' '{ print $2 }') @@ -957,7 +957,7 @@ then if [ -z "${SST_PORT}" ] then SST_PORT=4444 - if [[ ${ADDR:0:1} == '[' ]];then + if [ "${ADDR#\[}" != "$ADDR" ]; then ADDR="$(echo ${WSREP_SST_OPT_ADDR} | awk -F '\\]:' '{ print $1 }')]:${SST_PORT}" else ADDR="$(echo ${WSREP_SST_OPT_ADDR} | awk -F ':' '{ print $1 }'):${SST_PORT}" diff --git a/scripts/wsrep_sst_rsync.sh b/scripts/wsrep_sst_rsync.sh index 72ad080591c..0563343fbea 100644 --- a/scripts/wsrep_sst_rsync.sh +++ b/scripts/wsrep_sst_rsync.sh @@ -88,7 +88,7 @@ check_pid_and_port() local is_listening_all="$(echo $port_info | \ grep "*:$rsync_port" 2>/dev/null)" local is_listening_addr="$(echo $port_info | \ - grep "$rsync_addr:$rsync_port" 2>/dev/null)" + grep -F "$rsync_addr:$rsync_port" 2>/dev/null)" if [ ! -z "$is_listening_all" -o ! -z "$is_listening_addr" ]; then if [ -z "$is_rsync" ]; then @@ -118,7 +118,7 @@ is_local_ip() address="$address " fi - $get_addr_bin | grep "$address" > /dev/null + $get_addr_bin | grep -F "$address" > /dev/null } STUNNEL_CONF="$WSREP_SST_OPT_DATA/stunnel.conf" From 915ed7e614383093d688db6b4fd8bc7b948e1b70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 1 Feb 2019 19:19:33 +0200 Subject: [PATCH 066/106] Some more fixes for --suite=galera_3nodes --- .../r/galera_pc_bootstrap.result | 11 ++++++++++ .../galera_3nodes/r/galera_pc_weight.result | 22 +++++++++++++++++++ .../r/galera_safe_to_bootstrap.result | 14 ++++++++++++ .../r/galera_var_dirty_reads2.result | 5 +++++ .../t/galera_innobackupex_backup.test | 2 +- 5 files changed, 53 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/galera_3nodes/r/galera_pc_bootstrap.result b/mysql-test/suite/galera_3nodes/r/galera_pc_bootstrap.result index 69995acb982..3405beef12f 100644 --- a/mysql-test/suite/galera_3nodes/r/galera_pc_bootstrap.result +++ b/mysql-test/suite/galera_3nodes/r/galera_pc_bootstrap.result @@ -1,8 +1,13 @@ CREATE TABLE t1 (f1 INTEGER); +connection node_1; SET GLOBAL wsrep_provider_options = 'gmcast.isolate=1'; +connection node_2; SET GLOBAL wsrep_provider_options = 'gmcast.isolate=1'; +connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3; +connection node_3; SET GLOBAL wsrep_provider_options = 'gmcast.isolate=1'; SET SESSION wsrep_sync_wait = 0; +connection node_2; SET GLOBAL wsrep_provider_options = 'pc.bootstrap=1'; SHOW STATUS LIKE 'wsrep_cluster_size'; Variable_name Value @@ -11,15 +16,21 @@ SHOW STATUS LIKE 'wsrep_cluster_status'; Variable_name Value wsrep_cluster_status Primary INSERT INTO t1 VALUES (1); +connection node_2; SET GLOBAL wsrep_provider_options = 'gmcast.isolate=0'; +connection node_1; SET GLOBAL wsrep_provider_options = 'gmcast.isolate=0'; +connection node_3; SET GLOBAL wsrep_provider_options = 'gmcast.isolate=0'; +connection node_1; SELECT COUNT(*) FROM t1; COUNT(*) 1 +connection node_2; SELECT COUNT(*) FROM t1; COUNT(*) 1 +connection node_3; SELECT COUNT(*) FROM t1; COUNT(*) 1 diff --git a/mysql-test/suite/galera_3nodes/r/galera_pc_weight.result b/mysql-test/suite/galera_3nodes/r/galera_pc_weight.result index 9f845ffe776..5fb9c1b9d66 100644 --- a/mysql-test/suite/galera_3nodes/r/galera_pc_weight.result +++ b/mysql-test/suite/galera_3nodes/r/galera_pc_weight.result @@ -1,9 +1,13 @@ +connection node_1; SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_weight'; VARIABLE_VALUE = 3 +1 SET GLOBAL wsrep_provider_options = 'pc.weight=3'; SELECT VARIABLE_VALUE = 5 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_weight'; VARIABLE_VALUE = 5 +1 SET GLOBAL wsrep_provider_options = 'gmcast.isolate=1'; +connection node_2; SET SESSION wsrep_sync_wait=0; SET SESSION wsrep_on=OFF; SET SESSION wsrep_on=ON; @@ -12,6 +16,7 @@ Variable_name Value wsrep_cluster_size 2 SHOW STATUS LIKE 'wsrep_cluster_weight'; Variable_name Value +wsrep_cluster_weight 0 SHOW STATUS LIKE 'wsrep_cluster_status'; Variable_name Value wsrep_cluster_status non-Primary @@ -27,6 +32,7 @@ wsrep_local_state 0 SHOW STATUS LIKE 'wsrep_local_state_comment'; Variable_name Value wsrep_local_state_comment Initialized +connection node_3; SET SESSION wsrep_sync_wait=0; SET SESSION wsrep_on=OFF; SET SESSION wsrep_on=ON; @@ -35,6 +41,7 @@ Variable_name Value wsrep_cluster_size 2 SHOW STATUS LIKE 'wsrep_cluster_weight'; Variable_name Value +wsrep_cluster_weight 0 SHOW STATUS LIKE 'wsrep_cluster_status'; Variable_name Value wsrep_cluster_status non-Primary @@ -50,8 +57,10 @@ wsrep_local_state 0 SHOW STATUS LIKE 'wsrep_local_state_comment'; Variable_name Value wsrep_local_state_comment Initialized +connection node_1; SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_weight'; VARIABLE_VALUE = 3 +1 SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; VARIABLE_VALUE = 'Primary' 1 @@ -70,12 +79,18 @@ VARIABLE_VALUE = 'Synced' SET GLOBAL wsrep_provider_options = 'pc.weight=1'; SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_weight'; VARIABLE_VALUE = 1 +1 +connection node_1; SET GLOBAL wsrep_provider_options = 'gmcast.isolate=0'; +connection node_2; +connection node_3; +connection node_1; SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; VARIABLE_VALUE = 3 1 SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_weight'; VARIABLE_VALUE = 3 +1 SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; VARIABLE_VALUE = 'Primary' 1 @@ -91,11 +106,13 @@ VARIABLE_VALUE = 4 SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; VARIABLE_VALUE = 'Synced' 1 +connection node_2; SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; VARIABLE_VALUE = 3 1 SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_weight'; VARIABLE_VALUE = 3 +1 SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; VARIABLE_VALUE = 'Primary' 1 @@ -111,11 +128,13 @@ VARIABLE_VALUE = 4 SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; VARIABLE_VALUE = 'Synced' 1 +connection node_3; SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; VARIABLE_VALUE = 3 1 SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_weight'; VARIABLE_VALUE = 3 +1 SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; VARIABLE_VALUE = 'Primary' 1 @@ -131,12 +150,15 @@ VARIABLE_VALUE = 4 SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; VARIABLE_VALUE = 'Synced' 1 +connection node_1; SET GLOBAL wsrep_provider_options = 'pc.weight=1'; CALL mtr.add_suppression('WSREP: gcs_caused\\(\\) returned -1'); +connection node_2; CALL mtr.add_suppression('overriding reported weight for'); CALL mtr.add_suppression('SYNC message from member'); CALL mtr.add_suppression('user message in state LEAVING'); CALL mtr.add_suppression('sending install message failed: (Transport endpoint is not connected|Socket is not connected)'); +connection node_3; CALL mtr.add_suppression('WSREP: user message in state LEAVING'); CALL mtr.add_suppression('sending install message failed: (Transport endpoint is not connected|Socket is not connected)'); CALL mtr.add_suppression('overriding reported weight for'); diff --git a/mysql-test/suite/galera_3nodes/r/galera_safe_to_bootstrap.result b/mysql-test/suite/galera_3nodes/r/galera_safe_to_bootstrap.result index 21f747d280b..1676ef9b07b 100644 --- a/mysql-test/suite/galera_3nodes/r/galera_safe_to_bootstrap.result +++ b/mysql-test/suite/galera_3nodes/r/galera_safe_to_bootstrap.result @@ -2,21 +2,35 @@ CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; include/assert_grep.inc [grastate.dat does not have 'safe_to_bootstrap: 0'] include/assert_grep.inc [grastate.dat does not have 'safe_to_bootstrap: 0'] include/assert_grep.inc [grastate.dat does not have 'safe_to_bootstrap: 0'] +connection node_2; +connection node_1; include/assert_grep.inc [grastate.dat does not have 'safe_to_bootstrap: 0'] include/assert_grep.inc [grastate.dat does not have 'safe_to_bootstrap: 0'] include/assert_grep.inc [grastate.dat does not have 'safe_to_bootstrap: 0'] +connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3; +connection node_3; +connection node_1; include/assert_grep.inc [grastate.dat does not have 'safe_to_bootstrap: 0'] include/assert_grep.inc [grastate.dat does not have 'safe_to_bootstrap: 0'] include/assert_grep.inc [grastate.dat does not have 'safe_to_bootstrap: 1'] +connection node_2; +connection node_1; include/assert_grep.inc [grastate.dat does not have 'safe_to_bootstrap: 0'] include/assert_grep.inc [grastate.dat does not have 'safe_to_bootstrap: 0'] include/assert_grep.inc [grastate.dat does not have 'safe_to_bootstrap: 0'] +connection node_2; +connection node_1; SET SESSION wsrep_on = OFF; Killing server ... safe_to_bootstrap: 1 safe_to_bootstrap: 0 safe_to_bootstrap: 0 +connection node_1; +connection node_2; +connection node_3; +connection node_2; CALL mtr.add_suppression("Failed to prepare for incremental state transfer"); +connection node_3; CALL mtr.add_suppression("Failed to prepare for incremental state transfer"); SHOW CREATE TABLE t1; Table Create Table diff --git a/mysql-test/suite/galera_3nodes/r/galera_var_dirty_reads2.result b/mysql-test/suite/galera_3nodes/r/galera_var_dirty_reads2.result index 88780a2c87f..c6756bce210 100644 --- a/mysql-test/suite/galera_3nodes/r/galera_var_dirty_reads2.result +++ b/mysql-test/suite/galera_3nodes/r/galera_var_dirty_reads2.result @@ -1,6 +1,9 @@ CREATE TABLE t1 (f1 INTEGER); INSERT INTO t1 VALUES (1); +connection node_2; SET GLOBAL wsrep_provider_options='gmcast.isolate=1'; +connection node_1; +connection node_2; SET SESSION wsrep_sync_wait = 0; SET SESSION wsrep_dirty_reads = 1; SELECT f1 FROM t1; @@ -45,4 +48,6 @@ SELECT COUNT(*) > 0 FROM INFORMATION_SCHEMA.PROCESSLIST; COUNT(*) > 0 1 SET GLOBAL wsrep_provider_options='gmcast.isolate=0'; +connection node_1; +connection node_2; DROP TABLE t1; diff --git a/mysql-test/suite/galera_3nodes/t/galera_innobackupex_backup.test b/mysql-test/suite/galera_3nodes/t/galera_innobackupex_backup.test index 8dfb4660f3e..cd5c020ae38 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_innobackupex_backup.test +++ b/mysql-test/suite/galera_3nodes/t/galera_innobackupex_backup.test @@ -4,7 +4,7 @@ --source include/galera_cluster.inc --source include/have_innodb.inc ---source include/have_mariabackup.inc +--source suite/galera/include/have_mariabackup.inc --let $galera_connection_name = node_3 --let $galera_server_number = 3 From c1e1764fc4b913ee688b383aac2698b83661d64c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Sat, 2 Feb 2019 12:49:04 +0200 Subject: [PATCH 067/106] Fix embedded innodb_plugin after 560799ebd8efe11f4c4ae1bb9ed4d39185e03800 wsrep_certification_rules: Define as a weak global symbol. While there are separate _embedded.a for statically linked storage engine plugins, there is only one ha_innodb.so which is supposed to work with both values of WITH_WSREP. The merge from 10.0-galera introduced a reference to a global variable that is only defined when the server is built WITH_WSREP. We must define that symbol as weak global, so that when a dynamically linked InnoDB or XtraDB is used with the embedded server (which never includes write-set replication patches), the variable will be read as 0, instead of causing a failure to load the InnoDB or XtraDB plugin. --- sql/wsrep_mysqld_c.h | 6 +++++- storage/innobase/row/row0ins.cc | 6 +++++- storage/xtradb/row/row0ins.cc | 6 +++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/sql/wsrep_mysqld_c.h b/sql/wsrep_mysqld_c.h index 15ca0ae2a6d..235a871c113 100644 --- a/sql/wsrep_mysqld_c.h +++ b/sql/wsrep_mysqld_c.h @@ -21,6 +21,10 @@ enum enum_wsrep_certification_rules { WSREP_CERTIFICATION_RULES_OPTIMIZED }; -extern ulong wsrep_certification_rules; +/* This is intentionally declared as a weak global symbol, so that +the same ha_innodb.so can be used with the embedded server +(which does not link to the definition of this variable) +and with the regular server built WITH_WSREP. */ +extern ulong wsrep_certification_rules __attribute__((weak)); #endif /* WSREP_MYSQLD_C_H */ diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index 22588d33418..65a27ebeb37 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -56,6 +56,7 @@ Created 4/20/1996 Heikki Tuuri #include "m_string.h" #ifdef WITH_WSREP +#include #include "../../../wsrep/wsrep_api.h" #include "wsrep_mysqld_c.h" #endif /* WITH_WSREP */ @@ -1645,6 +1646,9 @@ run_again: if (check_ref) { err = DB_SUCCESS; #ifdef WITH_WSREP + if (!wsrep_on(trx->mysql_thd)) { + goto end_scan; + } enum wsrep_key_type key_type; if (upd_node != NULL) { key_type = WSREP_KEY_SHARED; @@ -1661,7 +1665,7 @@ run_again: } err = wsrep_append_foreign_key( - thr_get_trx(thr), + trx, foreign, rec, check_index, diff --git a/storage/xtradb/row/row0ins.cc b/storage/xtradb/row/row0ins.cc index b14d43e4f42..476c18680f3 100644 --- a/storage/xtradb/row/row0ins.cc +++ b/storage/xtradb/row/row0ins.cc @@ -56,6 +56,7 @@ Created 4/20/1996 Heikki Tuuri #include "m_string.h" #ifdef WITH_WSREP +#include #include "../../../wsrep/wsrep_api.h" #include "wsrep_mysqld_c.h" #endif /* WITH_WSREP */ @@ -1657,6 +1658,9 @@ run_again: if (check_ref) { err = DB_SUCCESS; #ifdef WITH_WSREP + if (!wsrep_on(trx->mysql_thd)) { + goto end_scan; + } enum wsrep_key_type key_type; if (upd_node != NULL) { key_type = WSREP_KEY_SHARED; @@ -1673,7 +1677,7 @@ run_again: } err = wsrep_append_foreign_key( - thr_get_trx(thr), + trx, foreign, rec, check_index, From 261ce5286f266f1a5fab5e8adc2c08adef658d13 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Sat, 2 Feb 2019 10:02:03 +0100 Subject: [PATCH 068/106] MDEV-18281 COM_RESET_CONNECTION changes the connection encoding Store original charset during client authentication, and restore it for COM_RESET_CONNECTION --- client/mysqltest.cc | 9 ++++++++- mysql-test/r/reset_connection.result | 20 ++++++++++++++++++++ mysql-test/t/reset_connection.test | 15 +++++++++++++++ sql/sql_class.cc | 1 + sql/sql_class.h | 3 +++ sql/sql_connect.cc | 1 + sql/sql_parse.cc | 3 +++ 7 files changed, 51 insertions(+), 1 deletion(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 227c40f8d01..0d7b54acf8e 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -5938,6 +5938,7 @@ void do_connect(struct st_command *command) int read_timeout= 0; int write_timeout= 0; int connect_timeout= 0; + char *csname=0; struct st_connection* con_slot; static DYNAMIC_STRING ds_connection_name; @@ -6049,6 +6050,11 @@ void do_connect(struct st_command *command) { connect_timeout= atoi(con_options + sizeof("connect_timeout=")-1); } + else if (strncasecmp(con_options, "CHARSET=", + sizeof("CHARSET=") - 1) == 0) + { + csname= strdup(con_options + sizeof("CHARSET=") - 1); + } else die("Illegal option to connect: %.*s", (int) (end - con_options), con_options); @@ -6086,7 +6092,7 @@ void do_connect(struct st_command *command) mysql_options(con_slot->mysql, MYSQL_OPT_COMPRESS, NullS); mysql_options(con_slot->mysql, MYSQL_OPT_LOCAL_INFILE, 0); mysql_options(con_slot->mysql, MYSQL_SET_CHARSET_NAME, - charset_info->csname); + csname?csname: charset_info->csname); if (opt_charsets_dir) mysql_options(con_slot->mysql, MYSQL_SET_CHARSET_DIR, opt_charsets_dir); @@ -6197,6 +6203,7 @@ void do_connect(struct st_command *command) #ifdef HAVE_SMEM dynstr_free(&ds_shm); #endif + free(csname); DBUG_VOID_RETURN; } diff --git a/mysql-test/r/reset_connection.result b/mysql-test/r/reset_connection.result index 925195f704e..54f6ffdbd25 100644 --- a/mysql-test/r/reset_connection.result +++ b/mysql-test/r/reset_connection.result @@ -5,3 +5,23 @@ Com_select 10 SHOW local STATUS LIKE 'com_select'; Variable_name Value Com_select 0 +# Test if charset changes after reset (utf8) +connect utf8_conn,localhost,root,,,,,CHARSET=utf8; +connection utf8_conn; +SELECT IF(@@character_set_client='utf8','OK', 'FAIL') AS RESULT; +RESULT +OK +SELECT IF(@@character_set_client='utf8','OK', 'FAIL') AS RESULT; +RESULT +OK +disconnect utf8_conn; +# Test if charset changes after reset (latin1) +connect latin1_conn,localhost,root,,,,,CHARSET=latin1; +connection latin1_conn; +SELECT IF(@@character_set_client='latin1','OK', 'FAIL') AS RESULT; +RESULT +OK +SELECT IF(@@character_set_client='latin1','OK', 'FAIL') AS RESULT; +RESULT +OK +disconnect latin1_conn; diff --git a/mysql-test/t/reset_connection.test b/mysql-test/t/reset_connection.test index 49f41c32fc3..73c8280703c 100644 --- a/mysql-test/t/reset_connection.test +++ b/mysql-test/t/reset_connection.test @@ -23,3 +23,18 @@ SHOW local STATUS LIKE 'com_select'; SHOW local STATUS LIKE 'com_select'; +--echo # Test if charset changes after reset (utf8) +connect(utf8_conn,localhost,root,,,,,CHARSET=utf8); +connection utf8_conn; +SELECT IF(@@character_set_client='utf8','OK', 'FAIL') AS RESULT; +--reset_connection +SELECT IF(@@character_set_client='utf8','OK', 'FAIL') AS RESULT; +disconnect utf8_conn; + +--echo # Test if charset changes after reset (latin1) +connect(latin1_conn,localhost,root,,,,,CHARSET=latin1); +connection latin1_conn; +SELECT IF(@@character_set_client='latin1','OK', 'FAIL') AS RESULT; +--reset_connection +SELECT IF(@@character_set_client='latin1','OK', 'FAIL') AS RESULT; +disconnect latin1_conn; \ No newline at end of file diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 1146359f451..6592dcd8f6f 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -840,6 +840,7 @@ THD::THD(my_thread_id id, bool is_wsrep_applier) prepare_derived_at_open= FALSE; create_tmp_table_for_derived= FALSE; save_prep_leaf_list= FALSE; + org_charset= 0; /* Restore THR_THD */ set_current_thd(old_THR_THD); inc_thread_count(); diff --git a/sql/sql_class.h b/sql/sql_class.h index 1d8730ae008..d678a20078a 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2312,6 +2312,9 @@ public: uint dbug_sentry; // watch out for memory corruption #endif struct st_my_thread_var *mysys_var; + + /* Original charset number from the first client packet, or COM_CHANGE_USER*/ + CHARSET_INFO *org_charset; private: /* Type of current query: COM_STMT_PREPARE, COM_QUERY, etc. Set from diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index 99fc1e8c1aa..278677b8b2d 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -793,6 +793,7 @@ bool thd_init_client_charset(THD *thd, uint cs_number) cs->csname); return true; } + thd->org_charset= cs; thd->update_charset(cs,cs,cs); } return false; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 244719f39a3..ef5d1afcab2 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1689,6 +1689,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd->status_var.com_other++; thd->change_user(); thd->clear_error(); // if errors from rollback + /* Restore original charset from client authentication packet.*/ + if(thd->org_charset) + thd->update_charset(thd->org_charset,thd->org_charset,thd->org_charset); my_ok(thd, 0, 0, 0); break; } From a0e26599a3a772ccaa06410c722a770e300b5bb8 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Sun, 3 Feb 2019 15:19:04 +0100 Subject: [PATCH 069/106] - Fix MDEV-13136: enhance CREATE SERVER MyServerName FOREIGN DATA WRAPPER to work with CONNECT engine modified: storage/connect/tabjdbc.cpp - Add a function to retrieve User variable value (DEVELOPMENT only) modified: storage/connect/ha_connect.cc modified: storage/connect/jsonudf.cpp modified: storage/connect/jsonudf.h modified: storage/connect/tabjdbc.cpp --- storage/connect/ha_connect.cc | 20 ++++++++++++++ storage/connect/jsonudf.cpp | 49 ++++++++++++++++++++++++++++++++++- storage/connect/jsonudf.h | 5 ++++ storage/connect/tabjdbc.cpp | 22 +++++++++++----- 4 files changed, 88 insertions(+), 8 deletions(-) diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index b34db942530..f4d6e35453e 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -204,6 +204,26 @@ pthread_mutex_t parmut; pthread_mutex_t usrmut; pthread_mutex_t tblmut; +#if defined(DEVELOPMENT) +char *GetUserVariable(PGLOBAL g, const uchar *varname); + +char *GetUserVariable(PGLOBAL g, const uchar *varname) +{ + char buf[1024]; + bool b; + THD *thd = current_thd; + CHARSET_INFO *cs = system_charset_info; + String *str = NULL, tmp(buf, sizeof(buf), cs); + HASH uvars = thd->user_vars; + user_var_entry *uvar = (user_var_entry*)my_hash_search(&uvars, varname, 0); + + if (uvar) + str = uvar->val_str(&b, &tmp, NOT_FIXED_DEC); + + return str ? PlugDup(g, str->ptr()) : NULL; +}; // end of GetUserVariable +#endif // DEVELOPMENT + /***********************************************************************/ /* Utility functions. */ /***********************************************************************/ diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp index d5a3a840173..a1d7287833e 100644 --- a/storage/connect/jsonudf.cpp +++ b/storage/connect/jsonudf.cpp @@ -1666,7 +1666,8 @@ static PCSZ MakeKey(PGLOBAL g, UDF_ARGS *args, int i) if (args->arg_count > (unsigned)i) { int j = 0, n = args->attribute_lengths[i]; my_bool b; // true if attribute is zero terminated - PSZ p, s = args->attributes[i]; + PSZ p; + PCSZ s = args->attributes[i]; if (s && *s && (n || *s == '\'')) { if ((b = (!n || !s[n]))) @@ -5805,6 +5806,52 @@ char *envar(UDF_INIT *initid, UDF_ARGS *args, char *result, return str; } // end of envar +#if defined(DEVELOPMENT) +extern char *GetUserVariable(PGLOBAL g, const uchar *varname); + +/*********************************************************************************/ +/* Utility function returning a user variable value. */ +/*********************************************************************************/ +my_bool uvar_init(UDF_INIT *initid, UDF_ARGS *args, char *message) +{ + unsigned long reslen, memlen; + + if (args->arg_count != 1) { + strcpy(message, "Unique argument must be a user variable name"); + return true; + } else + CalcLen(args, false, reslen, memlen, true); + + initid->maybe_null = true; + return JsonInit(initid, args, message, true, reslen, memlen, 2048); +} // end of uvar_init + +char *uvar(UDF_INIT *initid, UDF_ARGS *args, char *result, + unsigned long *res_length, char *is_null, char *) +{ + char *str, varname[256]; + PGLOBAL g = (PGLOBAL)initid->ptr; + int n = MY_MIN(args->lengths[0], sizeof(varname) - 1); + + PlugSubSet(g->Sarea, g->Sarea_Size); + memcpy(varname, args->args[0], n); + varname[n] = 0; + + if (!(str = GetUserVariable(g, (const uchar*)&varname))) { + *res_length = 0; + *is_null = 1; + } else + *res_length = strlen(str); + + return str; +} // end of uvar + +void uvar_deinit(UDF_INIT* initid) +{ + JsonFreeMem((PGLOBAL)initid->ptr); +} // end of uvar_deinit +#endif // DEVELOPMENT + /*********************************************************************************/ /* Returns the distinct number of B occurences in A. */ /*********************************************************************************/ diff --git a/storage/connect/jsonudf.h b/storage/connect/jsonudf.h index 23e8c0e1aed..ee56869a111 100644 --- a/storage/connect/jsonudf.h +++ b/storage/connect/jsonudf.h @@ -238,6 +238,11 @@ extern "C" { DllExport my_bool envar_init(UDF_INIT*, UDF_ARGS*, char*); DllExport char *envar(UDF_EXEC_ARGS); +#if defined(DEVELOPMENT) + DllExport my_bool uvar_init(UDF_INIT*, UDF_ARGS*, char*); + DllExport char *uvar(UDF_EXEC_ARGS); +#endif // DEVELOPMENT + DllExport my_bool countin_init(UDF_INIT*, UDF_ARGS*, char*); DllExport long long countin(UDF_EXEC_ARGS); } // extern "C" diff --git a/storage/connect/tabjdbc.cpp b/storage/connect/tabjdbc.cpp index c6b2802c1f6..789daff6fcd 100644 --- a/storage/connect/tabjdbc.cpp +++ b/storage/connect/tabjdbc.cpp @@ -72,7 +72,6 @@ #include "tabext.h" #include "tabjdbc.h" #include "tabmul.h" -//#include "reldef.h" #include "tabcol.h" #include "valblk.h" #include "ha_connect.h" @@ -89,6 +88,9 @@ extern int num_read, num_there, num_eq[2]; // Statistics /* External function. */ /***********************************************************************/ bool ExactInfo(void); +#if defined(DEVELOPMENT) +extern char *GetUserVariable(PGLOBAL g, const uchar *varname); +#endif // DEVELOPMENT /* -------------------------- Class JDBCDEF -------------------------- */ @@ -147,10 +149,6 @@ int JDBCDEF::ParseURL(PGLOBAL g, char *url, bool b) return RC_FX; Tabname = p; -// } else if (b) { -// // Otherwise, straight server name, -// Tabname = GetStringCatInfo(g, "Name", NULL); -// Tabname = GetStringCatInfo(g, "Tabname", Tabname); } // endif if (trace(1)) @@ -165,6 +163,11 @@ int JDBCDEF::ParseURL(PGLOBAL g, char *url, bool b) return RC_FX; } // endif server +#if defined(DEVELOPMENT) + if (*server->host == '@') { + Url = GetUserVariable(g, (const uchar*)&server->host[1]); + } else +#endif // 0 if (strncmp(server->host, "jdbc:", 5)) { // Now make the required URL Url = (PSZ)PlugSubAlloc(g, NULL, 0); @@ -191,6 +194,9 @@ int JDBCDEF::ParseURL(PGLOBAL g, char *url, bool b) if (!Password && server->password) Password = PlugDup(g, server->password); + Driver = PlugDup(g, GetListOption(g, "Driver", server->owner, NULL)); + Wrapname = PlugDup(g, GetListOption(g, "Wrapper", server->owner, NULL)); + Memory = atoi(GetListOption(g, "Memory", server->owner, "0")); return RC_NF; } // endif @@ -208,7 +214,6 @@ bool JDBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) if (EXTDEF::DefineAM(g, am, poff)) return true; - Driver = GetStringCatInfo(g, "Driver", NULL); Desc = Url = GetStringCatInfo(g, "Connect", NULL); if (!Url && !Catfunc) { @@ -228,7 +233,10 @@ bool JDBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) return true; } // endif rc - Wrapname = GetStringCatInfo(g, "Wrapper", NULL); + // Default values may have been set in ParseURL + Memory = GetIntCatInfo("Memory", Memory); + Driver = GetStringCatInfo(g, "Driver", Driver); + Wrapname = GetStringCatInfo(g, "Wrapper", Wrapname); return false; } // end of DefineAM From 955c7b32226c816b24a2ed1750e12bc0256565ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Sun, 3 Feb 2019 17:00:39 +0200 Subject: [PATCH 070/106] MDEV-16896 encryption.innodb-checksum-algorithm crashes buf_page_is_corrupted(): Read the global variable srv_checksum_algorithm only once in order to avoid a race condition when SET GLOBAL innodb_checksum_algorithm=...; is being executed concurrently with this function. --- storage/innobase/buf/buf0buf.cc | 21 +++++++++------------ storage/xtradb/buf/buf0buf.cc | 21 +++++++++------------ 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index af68f894aca..621433c1c5c 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -2,7 +2,7 @@ Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. -Copyright (c) 2013, 2018, MariaDB Corporation. +Copyright (c) 2013, 2019, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -925,7 +925,10 @@ buf_page_is_corrupted( /* Check whether the checksum fields have correct values */ - if (srv_checksum_algorithm == SRV_CHECKSUM_ALGORITHM_NONE) { + const srv_checksum_algorithm_t curr_algo = + static_cast(srv_checksum_algorithm); + + if (curr_algo == SRV_CHECKSUM_ALGORITHM_NONE) { return(false); } @@ -957,9 +960,6 @@ buf_page_is_corrupted( return(false); } - const srv_checksum_algorithm_t curr_algo = - static_cast(srv_checksum_algorithm); - switch (curr_algo) { case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32: return !buf_page_is_checksum_valid_crc32( @@ -988,9 +988,7 @@ buf_page_is_corrupted( for writing checksums because we assume that the chance of it matching is higher. */ - if (srv_checksum_algorithm - == SRV_CHECKSUM_ALGORITHM_CRC32) { - + if (curr_algo == SRV_CHECKSUM_ALGORITHM_CRC32) { crc32 = buf_calc_page_crc32(read_buf); crc32_inited = true; @@ -1000,7 +998,7 @@ buf_page_is_corrupted( return true; } } else { - ut_ad(srv_checksum_algorithm + ut_ad(curr_algo == SRV_CHECKSUM_ALGORITHM_INNODB); if (checksum_field2 @@ -1029,8 +1027,7 @@ buf_page_is_corrupted( for writing checksums because we assume that the chance of it matching is higher. */ - if (srv_checksum_algorithm - == SRV_CHECKSUM_ALGORITHM_CRC32) { + if (curr_algo == SRV_CHECKSUM_ALGORITHM_CRC32) { if (!crc32_inited) { crc32 = buf_calc_page_crc32(read_buf); @@ -1043,7 +1040,7 @@ buf_page_is_corrupted( return true; } } else { - ut_ad(srv_checksum_algorithm + ut_ad(curr_algo == SRV_CHECKSUM_ALGORITHM_INNODB); if (checksum_field1 diff --git a/storage/xtradb/buf/buf0buf.cc b/storage/xtradb/buf/buf0buf.cc index 85b337f641a..f4ef3ca7015 100644 --- a/storage/xtradb/buf/buf0buf.cc +++ b/storage/xtradb/buf/buf0buf.cc @@ -2,7 +2,7 @@ Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. -Copyright (c) 2013, 2018, MariaDB Corporation. +Copyright (c) 2013, 2019, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -924,7 +924,10 @@ buf_page_is_corrupted( /* Check whether the checksum fields have correct values */ - if (srv_checksum_algorithm == SRV_CHECKSUM_ALGORITHM_NONE) { + const srv_checksum_algorithm_t curr_algo = + static_cast(srv_checksum_algorithm); + + if (curr_algo == SRV_CHECKSUM_ALGORITHM_NONE) { return(false); } @@ -956,9 +959,6 @@ buf_page_is_corrupted( return(false); } - const srv_checksum_algorithm_t curr_algo = - static_cast(srv_checksum_algorithm); - switch (curr_algo) { case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32: return !buf_page_is_checksum_valid_crc32( @@ -987,9 +987,7 @@ buf_page_is_corrupted( for writing checksums because we assume that the chance of it matching is higher. */ - if (srv_checksum_algorithm - == SRV_CHECKSUM_ALGORITHM_CRC32) { - + if (curr_algo == SRV_CHECKSUM_ALGORITHM_CRC32) { crc32 = buf_calc_page_crc32(read_buf); crc32_inited = true; @@ -999,7 +997,7 @@ buf_page_is_corrupted( return true; } } else { - ut_ad(srv_checksum_algorithm + ut_ad(curr_algo == SRV_CHECKSUM_ALGORITHM_INNODB); if (checksum_field2 @@ -1028,8 +1026,7 @@ buf_page_is_corrupted( for writing checksums because we assume that the chance of it matching is higher. */ - if (srv_checksum_algorithm - == SRV_CHECKSUM_ALGORITHM_CRC32) { + if (curr_algo == SRV_CHECKSUM_ALGORITHM_CRC32) { if (!crc32_inited) { crc32 = buf_calc_page_crc32(read_buf); @@ -1042,7 +1039,7 @@ buf_page_is_corrupted( return true; } } else { - ut_ad(srv_checksum_algorithm + ut_ad(curr_algo == SRV_CHECKSUM_ALGORITHM_INNODB); if (checksum_field1 From 564f63ccf78678dffc32841381deb19954dd36e3 Mon Sep 17 00:00:00 2001 From: Eugene Kosov Date: Mon, 4 Feb 2019 16:28:27 +0300 Subject: [PATCH 071/106] MDEV-18468 merge instant_varchar_enlarge.test and alter_varchar_change.test --- mysql-test/suite/innodb/r/alter_varchar_change.result | 9 +++++++++ mysql-test/suite/innodb/r/instant_varchar_enlarge.result | 9 --------- mysql-test/suite/innodb/t/alter_varchar_change.test | 7 +++++++ mysql-test/suite/innodb/t/instant_varchar_enlarge.test | 8 -------- 4 files changed, 16 insertions(+), 17 deletions(-) delete mode 100644 mysql-test/suite/innodb/r/instant_varchar_enlarge.result delete mode 100644 mysql-test/suite/innodb/t/instant_varchar_enlarge.test diff --git a/mysql-test/suite/innodb/r/alter_varchar_change.result b/mysql-test/suite/innodb/r/alter_varchar_change.result index 0b06fddd35e..8ffc6e5cfe2 100644 --- a/mysql-test/suite/innodb/r/alter_varchar_change.result +++ b/mysql-test/suite/innodb/r/alter_varchar_change.result @@ -459,3 +459,12 @@ t1 CREATE TABLE `t1` ( DROP TABLE t1; DROP PROCEDURE get_index_id; DROP PROCEDURE get_table_id; +create table t (a varchar(100)) engine=innodb; +select name, pos, mtype, prtype, len from information_schema.innodb_sys_columns where name='a'; +name pos mtype prtype len +a 0 1 524303 100 +alter table t modify a varchar(110), algorithm=inplace; +select name, pos, mtype, prtype, len from information_schema.innodb_sys_columns where name='a'; +name pos mtype prtype len +a 0 1 524303 110 +drop table t; diff --git a/mysql-test/suite/innodb/r/instant_varchar_enlarge.result b/mysql-test/suite/innodb/r/instant_varchar_enlarge.result deleted file mode 100644 index 14f16bd4fe2..00000000000 --- a/mysql-test/suite/innodb/r/instant_varchar_enlarge.result +++ /dev/null @@ -1,9 +0,0 @@ -create table t (a varchar(100)) engine=innodb; -select name, pos, mtype, prtype, len from information_schema.innodb_sys_columns where name='a'; -name pos mtype prtype len -a 0 1 524303 100 -alter table t modify a varchar(110), algorithm=inplace; -select name, pos, mtype, prtype, len from information_schema.innodb_sys_columns where name='a'; -name pos mtype prtype len -a 0 1 524303 110 -drop table t; diff --git a/mysql-test/suite/innodb/t/alter_varchar_change.test b/mysql-test/suite/innodb/t/alter_varchar_change.test index f435125e581..6a5719a1ef0 100644 --- a/mysql-test/suite/innodb/t/alter_varchar_change.test +++ b/mysql-test/suite/innodb/t/alter_varchar_change.test @@ -334,3 +334,10 @@ DROP TABLE t1; DROP PROCEDURE get_index_id; DROP PROCEDURE get_table_id; + +# LEN must increase here +create table t (a varchar(100)) engine=innodb; +select name, pos, mtype, prtype, len from information_schema.innodb_sys_columns where name='a'; +alter table t modify a varchar(110), algorithm=inplace; +select name, pos, mtype, prtype, len from information_schema.innodb_sys_columns where name='a'; +drop table t; diff --git a/mysql-test/suite/innodb/t/instant_varchar_enlarge.test b/mysql-test/suite/innodb/t/instant_varchar_enlarge.test deleted file mode 100644 index 42689deca11..00000000000 --- a/mysql-test/suite/innodb/t/instant_varchar_enlarge.test +++ /dev/null @@ -1,8 +0,0 @@ ---source include/have_innodb.inc - -# LEN must increase here -create table t (a varchar(100)) engine=innodb; -select name, pos, mtype, prtype, len from information_schema.innodb_sys_columns where name='a'; -alter table t modify a varchar(110), algorithm=inplace; -select name, pos, mtype, prtype, len from information_schema.innodb_sys_columns where name='a'; -drop table t; From 4c490d6df63695dc97b2c808e59954e6877d3a51 Mon Sep 17 00:00:00 2001 From: Elena Stepanova Date: Mon, 4 Feb 2019 18:55:35 +0200 Subject: [PATCH 072/106] Updated list of unstable tests for 10.1.38 release --- mysql-test/unstable-tests | 94 ++++++++++++++++++++++++++------------- 1 file changed, 62 insertions(+), 32 deletions(-) diff --git a/mysql-test/unstable-tests b/mysql-test/unstable-tests index d26ce111375..a5ff43c0c48 100644 --- a/mysql-test/unstable-tests +++ b/mysql-test/unstable-tests @@ -23,15 +23,20 @@ # ############################################################################## -# Based on 10.1 a5cbdd63bc2ff25a52e2e10f84b6aaf59837dbae +# Based on 10.1 955c7b32226c816b24a2ed1750e12bc0256565ad main.alter_table : Modified in 10.1.37 main.alter_table_trans : MDEV-12084 - timeout main.analyze_stmt_slow_query_log : MDEV-12237 - Wrong result main.auth_named_pipe : MDEV-14724 - System error 2 +main.auto_increment_ranges_innodb : Modified in 10.1.38 +main.bigint : Modified in 10.1.38 +main.connect : Modified in 10.1.38 main.count_distinct2 : MDEV-11768 - timeout main.create_delayed : MDEV-10605 - failed with timeout +main.create_drop_event : MDEV-16271 - Wrong result main.create_or_replace : Modified in 10.1.37 +main.ctype_latin1 : Modified in 10.1.38 main.ctype_uca : Modified in 10.1.37 main.ctype_utf16 : MDEV-10675: timeout or extra warnings main.debug_sync : MDEV-10607 - internal error @@ -40,51 +45,61 @@ main.events_2 : MDEV-13277 - Server crash main.events_bugs : MDEV-12892 - Crash in fill_schema_processlist main.events_slowlog : MDEV-12821 - Wrong result main.events_restart : MDEV-12236 - Server shutdown problem -main.flush : Modified in 10.1.36 +main.flush : Modified in 10.1.38 main.func_concat : Modified in 10.1.37 -main.func_isnull : Modified in 10.1.36 +main.func_group_innodb : Modified in 10.1.38 +main.func_misc : Modified in 10.1.38 main.func_time : Modified in 10.1.37 -main.gis : MDEV-13411 - wrong result on P8; modified in 10.1.36 +main.gis : MDEV-13411 - wrong result on P8 main.grant : Modified in 10.1.37 -main.group_min_max : Modified in 10.1.36 +main.grant5 : Modified in 10.1.38 main.host_cache_size_functionality : MDEV-10606 - sporadic failure on shutdown +main.huge_frm-6224 : Modified in 10.1.38 main.index_intersect_innodb : MDEV-10643 - failed with timeout main.index_merge_innodb : MDEV-7142 - Wrong execution plan, timeout with valgrind +main.index_merge_myisam : Modified in 10.1.38 main.innodb_mysql_lock : MDEV-7861 - sporadic lock detection failure -main.join : Modified in 10.1.36 main.kill_processlist-6619 : MDEV-10793 - wrong result in processlist +main.lock : Modified in 10.1.38 +main.lock_multi : Modified in 10.1.38 +main.lock_sync : Modified in 10.1.38 main.log_tables-big : MDEV-13408 - wrong result main.lowercase_fs_off : Modified in 10.1.37 main.mdev-504 : MDEV-10607 - sporadic "can't connect" main.mdev375 : MDEV-10607 - sporadic "can't connect" main.merge : MDEV-10607 - sporadic "can't connect" -main.mysql : Modified in 10.1.36 -main.mysql_not_windows : Modified in 10.1.36 +main.mysql : Modified in 10.1.38 main.mysql_client_test_nonblock : MDEV-15096 - exec failed main.mysql_upgrade_noengine : MDEV-14355 - Plugin is busy +main.mysqlbinlog_row_minimal : Modified in 10.1.38 +main.mysqldump : Modified in 10.1.38 main.mysqlhotcopy_myisam : MDEV-10995 - test hangs on debug build main.mysqlslap : MDEV-11801 - timeout main.mysqltest : MDEV-9269 - fails on Alpha main.order_by_optimizer_innodb : MDEV-10683 - wrong execution plan main.order_by_zerolength-4285 : Modified in 10.1.37 +main.partition : Modified in 10.1.38 main.partition_debug_sync : MDEV-15669 - Deadlock found when trying to get lock main.partition_explicit_prune : Modified in 10.1.37 +main.partition_innodb : Modified in 10.1.38 main.partition_innodb_plugin : MDEV-12901 - Valgrind warnings main.ps : MDEV-11017 - sporadic wrong Prepared_stmt_count main.query_cache : MDEV-12895 - Wrong result main.query_cache_debug : MDEV-15281 - Resize or similar command in progress +main.range_innodb : Modified in 10.1.38 main.range_vs_index_merge_innodb : MDEV-15283 - Server has gone away -main.selectivity : Modified in 10.1.36 +main.read_only : Modified in 10.1.38 +main.row-checksum : Modified in 10.1.38 main.set_statement : MDEV-13183 - Wrong result main.show_explain : MDEV-10674 - sporadic failure -main.sp : Modified in 10.1.36 main.sp_notembedded : MDEV-10607 - internal error main.sp-security : MDEV-10607 - sporadic "can't connect"; modified in 10.1.37 -main.stat_tables : Modified in 10.1.37 +main.stat_tables : Modified in 10.1.38 main.stat_tables_par_innodb : MDEV-14155 - wrong rounding main.status : MDEV-8510 - sporadic wrong result -main.subselect_extra_no_semijoin : Modified in 10.1.36 main.subselect_innodb : MDEV-10614 - sporadic wrong results +main.subselect_mat : Modified in 10.1.38 +main.subselect2 : Modified in 10.1.38 main.tc_heuristic_recover : MDEV-15200 - wrong error on mysqld_stub_cmd main.type_blob : MDEV-15195 - Wrong result main.type_datetime : Modified in 10.1.37 @@ -92,6 +107,7 @@ main.type_datetime_hires : MDEV-10687 - timeout main.type_float : Modified in 10.1.37 main.type_newdecimal : Modified in 10.1.37 main.type_year : Modified in 10.1.37 +main.union : Modified in 10.1.38 main.xa : MDEV-11769 - lock wait timeout #---------------------------------------------------------------- @@ -109,15 +125,15 @@ auth_gssapi.basic : Modified in 10.1.37 #---------------------------------------------------------------- +binlog.binlog_base64_flag : Modified in 10.1.38 binlog.binlog_commit_wait : MDEV-10150 - Error: too much time elapsed binlog.binlog_flush_binlogs_delete_domain : Modified in 10.1.37 -binlog.binlog_incident : Modified in 10.1.36 binlog.binlog_killed : MDEV-12925 - Wrong result +binlog.binlog_mysqlbinlog_row_frag : Added in 10.1.38 binlog.binlog_xa_recover : MDEV-8517 - Extra checkpoint #---------------------------------------------------------------- -binlog_encryption.binlog_incident : Modified in 10.1.36 binlog_encryption.binlog_xa_recover : MDEV-12908 - Extra checkpoint binlog_encryption.encrypted_master : MDEV-12906 - Failed to sync binlog_encryption.rpl_parallel : MDEV-10653 - Timeout @@ -129,6 +145,7 @@ binlog.load_data_stm_view : MDEV-16948 - Wrong result #---------------------------------------------------------------- +connect.part_table : Modified in 10.1.38 connect.pivot : MDEV-14803 - failed to discover table connect.xml2 : Modified in 10.1.37 connect.zip : MDEV-13884 - Wrong result @@ -138,13 +155,15 @@ connect.zip : MDEV-13884 - Wrong result encryption.create_or_replace : MDEV-16115 - Trying to access tablespace encryption.debug_key_management : MDEV-13841 - Timeout on wait condition encryption.encrypt_and_grep : MDEV-13765 - Wrong result -encryption.innodb-checksum-algorithm : MDEV-16896 - Server crash +encryption.innodb-checksum-algorithm : Modified in 10.1.38 encryption.innodb-compressed-blob : MDEV-14728 - Unable to get certificate +encryption.innodb-encryption-alter : Modified in 10.1.38 encryption.innodb_encryption_discard_import : MDEV-16116 - Wrong result encryption.innodb_encryption-page-compression : MDEV-12630 - crash or assertion failure encryption.innodb_encryption_row_compressed : MDEV-16113 - Crash encryption.innodb_first_page : MDEV-10689 - Crash encryption.innodb-first-page-read : MDEV-14356 - Timeout on wait condition +encryption.innodb-force-corrupt : Modified in 10.1.38 encryption.innodb_lotoftables : MDEV-16111 - Wrong result encryption.innodb-page_encryption : MDEV-10641 - mutex problem encryption.innodb-read-only : MDEV-14728 - Unable to get certificate; MDEV-16563 - Crash on startup @@ -190,29 +209,35 @@ heap.heap_btree : Modified in 10.1.37 #---------------------------------------------------------------- +innodb.alter_candidate_key : Added in 10.1.38 innodb.alter_inplace_perfschema : Added in 10.1.37 innodb.binlog_consistent : MDEV-10618 - Server fails to start innodb.doublewrite : MDEV-12905 - Lost connection to MySQL server -innodb.foreign-keys : Modified in 10.1.36 -innodb.foreign_key : Modified in 10.1.37 +innodb.foreign_key : Modified in 10.1.38 innodb.group_commit_crash : MDEV-11770 - checksum mismatch innodb.group_commit_crash_no_optimize_thread : MDEV-11770 - checksum mismatch +innodb.innodb_28867993 : Added in 10.1.38 innodb.innodb-64k-crash : MDEV-13872 - Failure and crash on startup -innodb.innodb-alter-debug : MDEV-13182 - InnoDB: adjusting FSP_SPACE_FLAGS; modified in 10.1.37 +innodb.innodb-alter : Modified in 10.1.38 +innodb.innodb-alter-debug : MDEV-13182 - InnoDB: adjusting FSP_SPACE_FLAGS; modified in 10.1.38 innodb.innodb-alter-table : MDEV-10619 - Testcase timeout innodb.innodb-blob : MDEV-12053 - Client crash innodb.innodb_bug14147491 : MDEV-11808 - wrong error codes innodb.innodb_bug30423 : MDEV-7311 - Wrong number of rows in the plan innodb.innodb_bug48024 : MDEV-14352 - Assertion failure innodb.innodb-fk : MDEV-13832 - Assertion failure on shutdown -innodb.innodb-lock : Modified in 10.1.36 +innodb.innodb-index : Modified in 10.1.38 innodb.innodb_max_recordsize_64k : MDEV-15203 - wrong result innodb.innodb_monitor : MDEV-10939 - Testcase timeout innodb.innodb-page_compression_default : MDEV-14121 - Assertion failure innodb.innodb-page_compression_lzma : MDEV-14353 - wrong result on Fedora 25 innodb.innodb-page_compression_zip : MDEV-10641 - mutex problem +innodb.innodb_simulate_comp_failures : MDEV-18417 - ASAN failures innodb.innodb_stats : MDEV-10682 - wrong result innodb.innodb_sys_semaphore_waits : MDEV-10331 - wrong result +innodb.innodb-table-online : Modified in 10.1.38 +innodb.innodb-virtual-columns : Modified in 10.1.38 +innodb.innodb_zip_innochecksum : Modified in 10.1.38 innodb.innodb_zip_innochecksum2 : MDEV-13882 - Warning: difficult to find free blocks innodb.log_file_size : MDEV-15668 - Not found pattern innodb.recovery_shutdown : MDEV-15671 - Warning: database page corruption @@ -223,23 +248,24 @@ innodb.xa_recovery : MDEV-15279 - mysqld got exception #---------------------------------------------------------------- -innodb_fts.fts_kill_query : Modified in 10.0.37 innodb_fts.innodb-fts-fic : MDEV-14154 - Assertion failure innodb_fts.innodb_fts_misc_debug : MDEV-14156 - Unexpected warning #---------------------------------------------------------------- -maria.concurrent : Added in 10.1.36 -maria.create : Added in 10.1.36 maria.fulltext2 : Added in 10.1.37 maria.insert_select : MDEV-12757 - Timeout maria.insert_select-7314 : MDEV-16492 - Timeout -maria.maria : MDEV-14430 - Wrong result; modified in 10.1.36 +maria.maria : MDEV-14430 - Wrong result #---------------------------------------------------------------- +mariabackup.encrypted_page_compressed : Added in 10.1.38 +mariabackup.encrypted_page_corruption : Added in 10.1.38 +mariabackup.huge_lsn : Opt file modified in 10.1.38 mariabackup.incremental_encrypted : MDEV-15667 - Timeout mariabackup.mdev-14447 : MDEV-15201 - Timeout +mariabackup.unencrypted_page_compressed : Added in 10.1.38 mariabackup.xb_compressed_encrypted : MDEV-14812 - Segfault mariabackup.xb_partition : MDEV-17584 - Crash on shutdown @@ -277,11 +303,13 @@ parts.update_and_cache : Added in 10.1.37 #---------------------------------------------------------------- perfschema.connect_attrs : MDEV-17283 - Wrong result +perfschema.dml_setup_instruments : Modified in 10.1.38 perfschema.func_file_io : MDEV-5708 - fails for s390x perfschema.func_mutex : MDEV-5708 - fails for s390x perfschema.hostcache_ipv6_ssl : MDEV-10696 - crash on shutdown perfschema.privilege_table_io : MDEV-13184 - Extra lines perfschema.rpl_gtid_func : MDEV-16897 - Wrong result +perfschema.socket_connect : Modified in 10.1.38 perfschema.socket_summary_by_event_name_func : MDEV-10622 - Socket summary tables do not match perfschema.stage_mdl_global : MDEV-11803 - wrong result on slow builders perfschema.stage_mdl_procedure : MDEV-11545 - Wrong result @@ -299,6 +327,7 @@ plugins.thread_pool_server_audit : MDEV-9562 - crashes on sol10-sparc #---------------------------------------------------------------- roles.create_and_grant_role : MDEV-11772 - wrong result +roles.flush_roles-17898 : Added in 10.1.38 #---------------------------------------------------------------- @@ -313,7 +342,6 @@ rpl.rpl_ddl : MDEV-10417 - Fails on Mips rpl.rpl_domain_id_filter_io_crash : MDEV-14357 - Wrong result rpl.rpl_domain_id_filter_restart : MDEV-10684 - Wrong result rpl.rpl_drop_db_fail : MDEV-16898 - Slave fails to start -rpl.rpl_foreign_key_innodb : Modified in 10.1.36 rpl.rpl_gtid_basic : MDEV-10681 - server startup problem rpl.rpl_gtid_crash : MDEV-9501 - Warning: failed registering on master rpl.rpl_gtid_delete_domain : MDEV-14463 - Timeout in include @@ -321,6 +349,7 @@ rpl.rpl_gtid_mdev9033 : MDEV-10680 - warnings rpl.rpl_gtid_reconnect : MDEV-14497 - Timeout rpl.rpl_gtid_stop_start : MDEV-10629 - Crash on shutdown, MDEV-12629 - Valgrind warnings rpl.rpl_gtid_until : MDEV-10625 - warnings in error log +rpl.rpl_idempotency : Modified in 10.1.38 rpl.rpl_innodb_bug30888 : MDEV-10417 - Fails on Mips rpl.rpl_insert : MDEV-9329 - Fails on Ubuntu/s390x rpl.rpl_insert_delayed : MDEV-9329 - Fails on Ubuntu/s390x @@ -346,6 +375,7 @@ rpl.rpl_partition_innodb : MDEV-10417 - Fails on Mips rpl.rpl_password_boundaries : MDEV-11534 - Slave IO warnings rpl.rpl_row_basic_11bugs : MDEV-12171 - Server failed to start rpl.rpl_row_basic_2myisam : MDEV-13875 - command "diff_files" failed +rpl.rpl_row_big_table_id : Added in 10.1.38 rpl.rpl_row_drop_create_temp_table : MDEV-14487 - Wrong result rpl.rpl_row_img_blobs : MDEV-13875 - command "diff_files" failed rpl.rpl_row_img_eng_min : MDEV-13875 - command "diff_files" failed @@ -353,7 +383,6 @@ rpl.rpl_row_img_eng_noblob : MDEV-13875 - command "diff_files" failed rpl.rpl_row_index_choice : MDEV-15196 - Slave crash rpl.rpl_row_lcase_tblnames : Added in 10.1.37 rpl.rpl_row_sp001 : MDEV-9329 - Fails on Ubuntu/s390x -rpl.rpl_row_spatial : Added in 10.1.36 rpl.rpl_semi_sync : MDEV-11220 - Wrong result rpl.rpl_semi_sync_after_sync : MDEV-14366 - Wrong result rpl.rpl_semi_sync_after_sync_row : MDEV-14366 - Wrong result @@ -369,6 +398,7 @@ rpl.rpl_stm_mixing_engines : MDEV-14489 - Sync slave with master fail rpl.rpl_stm_relay_ign_space : MDEV-14360 - Test assertion rpl.rpl_sync : MDEV-10633 - Database page corruption rpl.rpl_temporary_error2 : MDEV-10634 - Wrong number of retries +rpl.rpl_trigger : MDEV-18055 - Wrong result rpl.sec_behind_master-5114 : MDEV-13878 - Wrong result rpl/extra/rpl_tests.* : MDEV-10994 - tests not maintained @@ -403,18 +433,20 @@ stress.ddl_innodb : MDEV-10635 - Testcase timeout #---------------------------------------------------------------- sys_vars.autocommit_func2 : MDEV-9329 - Fails on Ubuntu/s390x +sys_vars.delayed_insert_limit_func : MDEV-17683 - Wrong result; modified in 10.1.38 sys_vars.innodb_ft_result_cache_limit_32 : Added in 10.1.37 sys_vars.innodb_ft_result_cache_limit_64 : Added in 10.1.37 sys_vars.keep_files_on_create_basic : MDEV-10676 - timeout sys_vars.log_slow_admin_statements_func : MDEV-12235 - Server crash sys_vars.rpl_init_slave_func : MDEV-10149 - wrong results +sys_vars.sql_low_priority_updates_func : Modified in 10.1.38 +sys_vars.table_definition_cache_basic : Modified in 10.1.38 sys_vars.thread_cache_size_func : MDEV-11775 - Wrong result sys_vars.wait_timeout_func : MDEV-12896 - Wrong result +sys_vars.wsrep_sst_method_basic : Modified in 10.1.38 #---------------------------------------------------------------- -tokudb.* : suite.pm and multiple modifications in 10.1.36 - tokudb.change_column_all_1000_10 : MDEV-12640 - Crash tokudb.change_column_bin : MDEV-12640 - Crash tokudb.change_column_char : MDEV-12822 - Lost connection to MySQL server @@ -436,13 +468,12 @@ tokudb.type_datetime : MDEV-15193 - Wrong result tokudb_backup.* : MDEV-11001 - tests don't work -tokudb_bugs.alter_table_comment_rebuild_data : Added in 10.1.36 +tokudb_bugs.PS-4979 : Added in 10.1.38 tokudb_bugs.checkpoint_lock : MDEV-10637 - Wrong processlist output tokudb_bugs.checkpoint_lock_3 : MDEV-10637 - Wrong processlist output tokudb_bugs.frm_store : MDEV-12823 - Valgrind tokudb_bugs.frm_store2 : MDEV-12823 - Valgrind tokudb_bugs.frm_store3 : MDEV-12823 - Valgrind -tokudb_bugs.PS-3773 : Added in 10.1.36 tokudb_bugs.xa : MDEV-11804 - Lock wait timeout tokudb_rpl.* : MDEV-11001 - tests don't work @@ -452,10 +483,9 @@ rpl-tokudb.* : MDEV-14354 - Tests fail with tcmalloc #---------------------------------------------------------------- -unit.lf : MDEV-12897 - Signal 11 thrown +unit.lf : MDEV-18416 - object was probably modified after being freed unit.ma_test_loghandler : MDEV-10638 - record read not ok -unit.mf_iocache : MDEV-17586 - total matches eof, cache is read up to eof -unit.my_atomic : MDEV-15670 - Signal 11 thrown +unit.my_atomic : MDEV-18472 - Signal 11 thrown #---------------------------------------------------------------- From 78d5a764b2e4ad25adc7c2d7bcf0da6b403232d4 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 3 Feb 2019 17:10:31 +0100 Subject: [PATCH 073/106] compiler warnings --- sql/sql_show.cc | 4 ++-- storage/innobase/fts/fts0opt.cc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 39763451dfb..e13952cbb6c 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -6480,8 +6480,8 @@ static int get_check_constraints_record(THD *thd, TABLE_LIST *tables, push_warning(thd, Sql_condition::WARN_LEVEL_WARN, thd->get_stmt_da()->sql_errno(), thd->get_stmt_da()->message()); - thd->clear_error(); - DBUG_RETURN(0); + thd->clear_error(); + DBUG_RETURN(0); } if(!tables->view) { diff --git a/storage/innobase/fts/fts0opt.cc b/storage/innobase/fts/fts0opt.cc index a87e7091c1a..91d59e01e57 100644 --- a/storage/innobase/fts/fts0opt.cc +++ b/storage/innobase/fts/fts0opt.cc @@ -2655,7 +2655,7 @@ fts_optimize_new_table( empty_slot = i; } else if (slot->table == table) { /* Already exists in our optimize queue. */ - ut_ad(slot->table_id = table->id); + ut_ad(slot->table_id == table->id); return(FALSE); } } From 3b7694b7f89412e869ac63804d424a3f29f7e2af Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 3 Feb 2019 18:38:27 +0100 Subject: [PATCH 074/106] cleanup: don't search for a just-opened tmp table in ALTER remove thd->find_temporary_table() --- sql/sql_table.cc | 46 +++++++--------------------------------------- 1 file changed, 7 insertions(+), 39 deletions(-) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 5329bc81ec7..58698936476 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -9447,52 +9447,20 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, /* Mark that we have created table in storage engine. */ no_ha_table= false; - if (create_info->tmp_table()) - { - TABLE *tmp_table= - thd->create_and_open_tmp_table(new_db_type, &frm, - alter_ctx.get_tmp_path(), - alter_ctx.new_db, alter_ctx.tmp_name, - true); - if (!tmp_table) - { - goto err_new_table_cleanup; - } - /* in case of alter temp table send the tracker in OK packet */ - SESSION_TRACKER_CHANGED(thd, SESSION_STATE_CHANGE_TRACKER, NULL); - } - + new_table= + thd->create_and_open_tmp_table(new_db_type, &frm, alter_ctx.get_tmp_path(), + alter_ctx.new_db, alter_ctx.tmp_name, true); + if (!new_table) + goto err_new_table_cleanup; /* Open the table since we need to copy the data. */ if (table->s->tmp_table != NO_TMP_TABLE) { - TABLE_LIST tbl; - tbl.init_one_table(alter_ctx.new_db, strlen(alter_ctx.new_db), - alter_ctx.tmp_name, strlen(alter_ctx.tmp_name), - alter_ctx.tmp_name, TL_READ_NO_INSERT); - /* - Table can be found in the list of open tables in THD::all_temp_tables - list. - */ - if ((tbl.table= thd->find_temporary_table(&tbl)) == NULL) - goto err_new_table_cleanup; - new_table= tbl.table; - DBUG_ASSERT(new_table); + /* in case of alter temp table send the tracker in OK packet */ + SESSION_TRACKER_CHANGED(thd, SESSION_STATE_CHANGE_TRACKER, NULL); } else { - /* - table is a normal table: Create temporary table in same directory. - Open our intermediate table. - */ - new_table= - thd->create_and_open_tmp_table(new_db_type, &frm, - alter_ctx.get_tmp_path(), - alter_ctx.new_db, alter_ctx.tmp_name, - true); - if (!new_table) - goto err_new_table_cleanup; - /* Normally, an attempt to modify an FK parent table will cause FK children to be prelocked, so the table-being-altered cannot From ef4ccb6ce2fd36014a7d065c3c4cf7611d113211 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 3 Feb 2019 18:40:27 +0100 Subject: [PATCH 075/106] MDEV-18083 ASAN heap-use-after-free in Field::set_warning_truncated_wrong_value upon inserting into temporary table remove TABLE_SHARE::error_table_name() and TABLE_SHARE::orig_table_name (that was allocated in a wrong memroot in this bug). instead, simply set TABLE_SHARE::table_name correctly. --- mysql-test/r/alter_table_errors.result | 6 ++++++ mysql-test/t/alter_table_errors.test | 10 +++++++++ sql/field.cc | 4 ++-- sql/sql_select.cc | 28 ++++++++++---------------- sql/sql_table.cc | 5 ++--- sql/sql_time.cc | 2 +- sql/table.cc | 2 +- sql/table.h | 10 --------- 8 files changed, 33 insertions(+), 34 deletions(-) diff --git a/mysql-test/r/alter_table_errors.result b/mysql-test/r/alter_table_errors.result index b26409e3d05..1e2a8100e84 100644 --- a/mysql-test/r/alter_table_errors.result +++ b/mysql-test/r/alter_table_errors.result @@ -27,3 +27,9 @@ t2 CREATE TEMPORARY TABLE `t2` ( `a` int(11) DEFAULT NULL, `v` int(11) GENERATED ALWAYS AS (`a`) VIRTUAL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop temporary table t1, t2; +create temporary table t1 (a int); +alter table t1 add column f text; +insert into t1 values ('x','foo'); +ERROR 22007: Incorrect integer value: 'x' for column `test`.`t1`.`a` at row 1 +drop temporary table t1; diff --git a/mysql-test/t/alter_table_errors.test b/mysql-test/t/alter_table_errors.test index 8fa65b0f330..8726410ea0a 100644 --- a/mysql-test/t/alter_table_errors.test +++ b/mysql-test/t/alter_table_errors.test @@ -19,3 +19,13 @@ lock table t2 write; --error ER_ALTER_OPERATION_NOT_SUPPORTED alter table t2 change column a b int, algorithm=inplace; show create table t2; +drop temporary table t1, t2; + +# +# MDEV-18083 ASAN heap-use-after-free in Field::set_warning_truncated_wrong_value upon inserting into temporary table +# +create temporary table t1 (a int); +alter table t1 add column f text; +--error ER_TRUNCATED_WRONG_VALUE_FOR_FIELD +insert into t1 values ('x','foo'); +drop temporary table t1; diff --git a/sql/field.cc b/sql/field.cc index c2317e9a748..855cc5e0b79 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -8635,7 +8635,7 @@ int Field_geom::store(const char *from, uint length, CHARSET_INFO *cs) (uint32) geom_type != wkb_type) { const char *db= table->s->db.str; - const char *tab_name= table->s->error_table_name(); + const char *tab_name= table->s->table_name.str; if (!db) db= ""; @@ -10821,7 +10821,7 @@ void Field::set_warning_truncated_wrong_value(const char *type_arg, { THD *thd= get_thd(); const char *db_name= table->s->db.str; - const char *table_name= table->s->error_table_name(); + const char *table_name= table->s->table_name.str; if (!db_name) db_name= ""; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index b1ae11fef03..5e5878ebf65 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -16753,7 +16753,7 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List &fields, table->no_rows_with_nulls= param->force_not_null_cols; table->s= share; - init_tmp_table_share(thd, share, "", 0, tmpname, tmpname); + init_tmp_table_share(thd, share, "", 0, "(temporary)", tmpname); share->blob_field= blob_field; share->table_charset= param->table_charset; share->primary_key= MAX_KEY; // Indicate no primary key @@ -17539,7 +17539,7 @@ bool Virtual_tmp_table::open() bool open_tmp_table(TABLE *table) { int error; - if ((error= table->file->ha_open(table, table->s->table_name.str, O_RDWR, + if ((error= table->file->ha_open(table, table->s->path.str, O_RDWR, HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE))) { @@ -17735,13 +17735,9 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo, } } - if ((error= maria_create(share->table_name.str, - file_type, - share->keys, &keydef, - (uint) (*recinfo-start_recinfo), - start_recinfo, - share->uniques, &uniquedef, - &create_info, + if ((error= maria_create(share->path.str, file_type, share->keys, &keydef, + (uint) (*recinfo-start_recinfo), start_recinfo, + share->uniques, &uniquedef, &create_info, create_flags))) { table->file->print_error(error,MYF(0)); /* purecov: inspected */ @@ -17891,11 +17887,9 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo, bzero((char*) &create_info,sizeof(create_info)); create_info.data_file_length= table->in_use->variables.tmp_disk_table_size; - if ((error=mi_create(share->table_name.str, share->keys, &keydef, - (uint) (*recinfo-start_recinfo), - start_recinfo, - share->uniques, &uniquedef, - &create_info, + if ((error=mi_create(share->path.str, share->keys, &keydef, + (uint) (*recinfo-start_recinfo), start_recinfo, + share->uniques, &uniquedef, &create_info, HA_CREATE_TMP_TABLE | HA_CREATE_INTERNAL_TABLE | ((share->db_create_options & HA_OPTION_PACK_RECORD) ? HA_PACK_RECORD : 0) @@ -18049,7 +18043,7 @@ err_killed: (void) table->file->ha_rnd_end(); (void) new_table.file->ha_close(); err1: - new_table.file->ha_delete_table(new_table.s->table_name.str); + new_table.file->ha_delete_table(new_table.s->path.str); err2: delete new_table.file; thd_proc_info(thd, save_proc_info); @@ -18074,9 +18068,9 @@ free_tmp_table(THD *thd, TABLE *entry) { entry->file->ha_index_or_rnd_end(); if (entry->db_stat) - entry->file->ha_drop_table(entry->s->table_name.str); + entry->file->ha_drop_table(entry->s->path.str); else - entry->file->ha_delete_table(entry->s->table_name.str); + entry->file->ha_delete_table(entry->s->path.str); delete entry->file; } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 58698936476..4f9adc3338c 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -9440,7 +9440,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, goto err_new_table_cleanup; if (ha_create_table(thd, alter_ctx.get_tmp_path(), - alter_ctx.new_db, alter_ctx.tmp_name, + alter_ctx.new_db, alter_ctx.new_name, create_info, &frm)) goto err_new_table_cleanup; @@ -9449,7 +9449,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, new_table= thd->create_and_open_tmp_table(new_db_type, &frm, alter_ctx.get_tmp_path(), - alter_ctx.new_db, alter_ctx.tmp_name, true); + alter_ctx.new_db, alter_ctx.new_name, true); if (!new_table) goto err_new_table_cleanup; @@ -9511,7 +9511,6 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, goto err_new_table_cleanup; } } - new_table->s->orig_table_name= table->s->table_name.str; /* Note: In case of MERGE table, we do not attach children. We do not diff --git a/sql/sql_time.cc b/sql/sql_time.cc index 53e380f59c8..bba8c974ccb 100644 --- a/sql/sql_time.cc +++ b/sql/sql_time.cc @@ -880,7 +880,7 @@ void make_truncated_value_warning(THD *thd, if (field_name) { const char *db_name= s->db.str; - const char *table_name= s->error_table_name(); + const char *table_name= s->table_name.str; if (!db_name) db_name= ""; diff --git a/sql/table.cc b/sql/table.cc index 58e90787925..7c5410aed84 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -5182,7 +5182,7 @@ int TABLE::verify_constraints(bool ignore_failure) field_error.append((*chk)->name.str); my_error(ER_CONSTRAINT_FAILED, MYF(ignore_failure ? ME_JUST_WARNING : 0), field_error.c_ptr(), - s->db.str, s->error_table_name()); + s->db.str, s->table_name.str); return ignore_failure ? VIEW_CHECK_SKIP : VIEW_CHECK_ERROR; } } diff --git a/sql/table.h b/sql/table.h index 13acae533f7..c3c138c1278 100644 --- a/sql/table.h +++ b/sql/table.h @@ -625,16 +625,6 @@ struct TABLE_SHARE LEX_STRING normalized_path; /* unpack_filename(path) */ LEX_STRING connect_string; - const char* orig_table_name; /* Original table name for this tmp table */ - const char* error_table_name() const /* Get table name for error messages */ - { - return tmp_table ? ( - orig_table_name ? - orig_table_name : - "(temporary)") : - table_name.str; - } - /* Set of keys in use, implemented as a Bitmap. Excludes keys disabled by ALTER TABLE ... DISABLE KEYS. From 676f43da3a1951e4e41d1cdb08d2c6c7833cb26e Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 3 Feb 2019 22:37:56 +0100 Subject: [PATCH 076/106] cleanup: don't ---replace_regex /#sql-.*/#sql-temporary/ no longer needed --- mysql-test/include/check-testcase.test | 1 - mysql-test/r/check_constraint.result | 2 +- mysql-test/r/error_simulation.result | 5 +---- .../suite/archive/partition_archive.result | 4 ++-- .../suite/archive/partition_archive.test | 3 +-- .../r/innodb-encryption-alter.result | 4 ++-- .../encryption/r/innodb-spatial-index.result | 2 +- .../encryption/t/innodb-encryption-alter.test | 2 -- .../encryption/t/innodb-spatial-index.test | 2 -- .../suite/gcol/inc/gcol_column_def_options.inc | 1 - mysql-test/suite/gcol/inc/gcol_keys.inc | 1 - .../suite/gcol/r/gcol_keys_innodb.result | 2 +- .../suite/gcol/r/innodb_virtual_fk.result | 4 ++-- mysql-test/suite/gcol/t/innodb_virtual_fk.test | 2 -- .../suite/innodb/r/add_constraint.result | 2 +- mysql-test/suite/innodb/r/foreign_key.result | 2 +- .../suite/innodb/r/innodb-fk-warnings.result | 16 ++++++++-------- mysql-test/suite/innodb/r/innodb-fk.result | 4 ++-- .../suite/innodb/r/innodb-index-online.result | 2 +- mysql-test/suite/innodb/r/innodb-index.result | 10 +++++----- .../innodb/r/innodb_force_recovery.result | 8 ++++---- mysql-test/suite/innodb/t/add_constraint.test | 1 - mysql-test/suite/innodb/t/foreign_key.test | 1 - .../suite/innodb/t/innodb-fk-warnings.test | 18 ------------------ mysql-test/suite/innodb/t/innodb-fk.test | 2 -- .../suite/innodb/t/innodb-index-online.test | 1 - mysql-test/suite/innodb/t/innodb-index.test | 5 ----- .../t/innodb-page_compression_tables.test | 4 ---- .../suite/innodb/t/innodb_force_recovery.test | 4 ---- .../suite/innodb_gis/r/point_basic.result | 8 ++++---- mysql-test/suite/innodb_gis/t/point_basic.test | 6 ------ mysql-test/suite/plugins/t/audit_null.test | 2 +- .../sys_vars/r/tmp_disk_table_size_func.result | 2 +- .../sys_vars/t/tmp_disk_table_size_func.test | 1 - mysql-test/suite/vcol/inc/vcol_keys.inc | 1 - .../suite/vcol/r/vcol_keys_innodb.result | 2 +- mysql-test/t/check_constraint.test | 1 - mysql-test/t/error_simulation.test | 7 +------ mysql-test/t/gis.test | 1 - 39 files changed, 41 insertions(+), 105 deletions(-) diff --git a/mysql-test/include/check-testcase.test b/mysql-test/include/check-testcase.test index 4ca53989d06..46601a67edf 100644 --- a/mysql-test/include/check-testcase.test +++ b/mysql-test/include/check-testcase.test @@ -83,7 +83,6 @@ call mtr.check_testcase(); let $datadir=`select @@datadir`; list_files $datadir mysql_upgrade_info; list_files_write_file $datadir.tempfiles.txt $datadir/test #sql*; ---replace_regex /#sql-ib[0-9a-f]+-[0-9a-f]+\.ibd\n// cat_file $datadir.tempfiles.txt; remove_file $datadir.tempfiles.txt; list_files $datadir/mysql #sql*; diff --git a/mysql-test/r/check_constraint.result b/mysql-test/r/check_constraint.result index 9a228f9ccc7..8cb1066ba9a 100644 --- a/mysql-test/r/check_constraint.result +++ b/mysql-test/r/check_constraint.result @@ -44,7 +44,7 @@ a b 103 103 set check_constraint_checks=@save_check_constraint; alter table t1 add c int default 0 check (c < 10); -ERROR 23000: CONSTRAINT `max` failed for table +ERROR 23000: CONSTRAINT `max` failed for `test`.`t1` set check_constraint_checks=0; alter table t1 add c int default 0 check (c < 10); alter table t1 add check (a+b+c < 500); diff --git a/mysql-test/r/error_simulation.result b/mysql-test/r/error_simulation.result index e0ec26b2d1c..7e728d24fc8 100644 --- a/mysql-test/r/error_simulation.result +++ b/mysql-test/r/error_simulation.result @@ -1,6 +1,3 @@ -DROP TABLE IF EXISTS t1; -Warnings: -Note 1051 Unknown table 'test.t1' CREATE TABLE t1 ( a varchar(32) character set utf8 collate utf8_bin NOT NULL, b varchar(32) character set utf8 collate utf8_bin NOT NULL ) @@ -15,7 +12,7 @@ INSERT INTO t1 VALUES set tmp_table_size=1024; set session debug_dbug="+d,raise_error"; SELECT MAX(a) FROM t1 GROUP BY a,b; -ERROR 23000: Can't write; duplicate key in table 'tmp_table' +ERROR 23000: Can't write; duplicate key in table '(temporary)' set tmp_table_size=default; DROP TABLE t1; # diff --git a/mysql-test/suite/archive/partition_archive.result b/mysql-test/suite/archive/partition_archive.result index a2e0fe7420f..41be0b31bce 100644 --- a/mysql-test/suite/archive/partition_archive.result +++ b/mysql-test/suite/archive/partition_archive.result @@ -30,7 +30,7 @@ partition by list (a) (partition p0 values in (1), partition p1 values in (2)); insert into t1 values (1), (2); create index inx on t1 (a); -ERROR HY000: Can't create table `db99`.`#sql-temporary` (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `db99`.`t1` (errno: 140 "Wrong create options") alter table t1 add partition (partition p2 values in (3)); alter table t1 drop partition p2; use test; @@ -141,7 +141,7 @@ t1 CREATE TABLE `t1` ( PARTITION BY HASH (`fld1`) PARTITIONS 5 ALTER TABLE t1 ENGINE= ARCHIVE; -ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") #After the patch, the ENGINE is correctly displayed as MyISAM SHOW CREATE TABLE t1; Table Create Table diff --git a/mysql-test/suite/archive/partition_archive.test b/mysql-test/suite/archive/partition_archive.test index aa2adb7e44d..dff6ec598d0 100644 --- a/mysql-test/suite/archive/partition_archive.test +++ b/mysql-test/suite/archive/partition_archive.test @@ -47,7 +47,7 @@ engine=archive partition by list (a) (partition p0 values in (1), partition p1 values in (2)); insert into t1 values (1), (2); ---replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ /Not owner/Operation not permitted/ +--replace_regex /Not owner/Operation not permitted/ --error ER_CANT_CREATE_TABLE create index inx on t1 (a); alter table t1 add partition (partition p2 values in (3)); @@ -138,7 +138,6 @@ CREATE TABLE t1 (fld1 INT PRIMARY KEY) ENGINE= MYISAM PARTITION BY HASH(fld1) PARTITIONS 5; SHOW CREATE TABLE t1; ---replace_regex /#sql-[0-9a-f_]*/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 ENGINE= ARCHIVE; diff --git a/mysql-test/suite/encryption/r/innodb-encryption-alter.result b/mysql-test/suite/encryption/r/innodb-encryption-alter.result index 995360a5744..2c6372e1c61 100644 --- a/mysql-test/suite/encryption/r/innodb-encryption-alter.result +++ b/mysql-test/suite/encryption/r/innodb-encryption-alter.result @@ -65,11 +65,11 @@ t1 CREATE TABLE `t1` ( DROP TABLE t1; CREATE TABLE t2 (a int not null primary key) engine=innodb; ALTER TABLE t2 ENCRYPTION_KEY_ID=4, ALGORITHM=COPY; -ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t2` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: innodb_encrypt_tables=OFF only allows ENCRYPTION_KEY_ID=1 -Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t2` (errno: 140 "Wrong create options") Warning 1030 Got error 140 "Wrong create options" from storage engine InnoDB SHOW CREATE TABLE t2; Table Create Table diff --git a/mysql-test/suite/encryption/r/innodb-spatial-index.result b/mysql-test/suite/encryption/r/innodb-spatial-index.result index 6856d1eecc9..d8b686d1b68 100644 --- a/mysql-test/suite/encryption/r/innodb-spatial-index.result +++ b/mysql-test/suite/encryption/r/innodb-spatial-index.result @@ -10,7 +10,7 @@ DROP TABLE t1; CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256), coordinate POINT NOT NULL) ENCRYPTED=YES ENGINE=INNODB; ALTER TABLE t1 ADD SPATIAL INDEX b(coordinate), ALGORITHM=COPY; -ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") ALTER TABLE t1 ADD SPATIAL INDEX b(coordinate), FORCE, ALGORITHM=INPLACE; ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'ENCRYPTED' ALTER TABLE t1 ADD SPATIAL INDEX(coordinate); diff --git a/mysql-test/suite/encryption/t/innodb-encryption-alter.test b/mysql-test/suite/encryption/t/innodb-encryption-alter.test index a6a4dbaff9b..bc7c3b3f13d 100644 --- a/mysql-test/suite/encryption/t/innodb-encryption-alter.test +++ b/mysql-test/suite/encryption/t/innodb-encryption-alter.test @@ -92,10 +92,8 @@ SHOW CREATE TABLE t1; DROP TABLE t1; CREATE TABLE t2 (a int not null primary key) engine=innodb; ---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ --error ER_CANT_CREATE_TABLE ALTER TABLE t2 ENCRYPTION_KEY_ID=4, ALGORITHM=COPY; ---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ SHOW WARNINGS; SHOW CREATE TABLE t2; diff --git a/mysql-test/suite/encryption/t/innodb-spatial-index.test b/mysql-test/suite/encryption/t/innodb-spatial-index.test index 28b35379a6b..2bf56817740 100644 --- a/mysql-test/suite/encryption/t/innodb-spatial-index.test +++ b/mysql-test/suite/encryption/t/innodb-spatial-index.test @@ -9,7 +9,6 @@ # (1) Do not allow creating table with ENCRYPTED=YES # # ---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ --error ER_CANT_CREATE_TABLE CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256), coordinate POINT NOT NULL, SPATIAL index(coordinate)) ENGINE=INNODB @@ -31,7 +30,6 @@ CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256), coordinate POINT NOT NULL) ENCRYPTED=YES ENGINE=INNODB; # FIXME: MDEV-13851 Encrypted table refuses some form of ALGORITHM=COPY, # but allows rebuild by FORCE ---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 ADD SPATIAL INDEX b(coordinate), ALGORITHM=COPY; --error ER_ILLEGAL_HA_CREATE_OPTION diff --git a/mysql-test/suite/gcol/inc/gcol_column_def_options.inc b/mysql-test/suite/gcol/inc/gcol_column_def_options.inc index ac70701e2cc..28c854c44f4 100644 --- a/mysql-test/suite/gcol/inc/gcol_column_def_options.inc +++ b/mysql-test/suite/gcol/inc/gcol_column_def_options.inc @@ -150,7 +150,6 @@ create table t2 (a int); alter table t1 add constraint foreign key fk(d) references t2(a); if ($support_virtual_foreign) { ---replace_regex /`#sql-.*`/`#sql-temporary`/ --error ER_CANT_CREATE_TABLE alter table t1 add constraint foreign key fk(b) references t2(a); } diff --git a/mysql-test/suite/gcol/inc/gcol_keys.inc b/mysql-test/suite/gcol/inc/gcol_keys.inc index a16d425ed24..97c9e41b5e8 100644 --- a/mysql-test/suite/gcol/inc/gcol_keys.inc +++ b/mysql-test/suite/gcol/inc/gcol_keys.inc @@ -156,7 +156,6 @@ create table t1 (a int, b int generated always as (a+1) virtual, foreign key (b) references t2(a)); create table t1 (a int, b int generated always as (a+1) virtual); ---replace_regex /`#sql-.*`/`#sql-temporary`/ --error ER_CANT_CREATE_TABLE alter table t1 add foreign key (b) references t2(a); drop table t1; diff --git a/mysql-test/suite/gcol/r/gcol_keys_innodb.result b/mysql-test/suite/gcol/r/gcol_keys_innodb.result index fadbb3b8031..04ba512aad9 100644 --- a/mysql-test/suite/gcol/r/gcol_keys_innodb.result +++ b/mysql-test/suite/gcol/r/gcol_keys_innodb.result @@ -153,7 +153,7 @@ foreign key (b) references t2(a)); ERROR HY000: Can't create table `test`.`t1` (errno: 150 "Foreign key constraint is incorrectly formed") create table t1 (a int, b int generated always as (a+1) virtual); alter table t1 add foreign key (b) references t2(a); -ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") +ERROR HY000: Can't create table `test`.`t1` (errno: 150 "Foreign key constraint is incorrectly formed") drop table t1; # Allowed FK options. create table t2 (a int primary key, b char(5)); diff --git a/mysql-test/suite/gcol/r/innodb_virtual_fk.result b/mysql-test/suite/gcol/r/innodb_virtual_fk.result index 732fa7c3f57..d5b4755e3c5 100644 --- a/mysql-test/suite/gcol/r/innodb_virtual_fk.result +++ b/mysql-test/suite/gcol/r/innodb_virtual_fk.result @@ -702,7 +702,7 @@ v3 TIME AS (c3) VIRTUAL, v4 CHAR(10) AS (c4) VIRTUAL ) ENGINE=InnoDB; ALTER TABLE t1 ADD CONSTRAINT fk FOREIGN KEY (v4) REFERENCES nosuch(col); -ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") +ERROR HY000: Can't create table `test`.`t1` (errno: 150 "Foreign key constraint is incorrectly formed") SET foreign_key_checks=0; ALTER TABLE t1 ADD CONSTRAINT fk FOREIGN KEY (v4) REFERENCES nosuch(col); ERROR HY000: Failed to add the foreign key constaint. Missing index for constraint 'fk' in the foreign table 't1' @@ -725,7 +725,7 @@ t1 CREATE TABLE `t1` ( ) ENGINE=InnoDB DEFAULT CHARSET=latin1 ALTER TABLE t1 DROP FOREIGN KEY fk; ALTER TABLE t1 ADD CONSTRAINT fk FOREIGN KEY (v4) REFERENCES nosuch(col); -ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") +ERROR HY000: Can't create table `test`.`t1` (errno: 150 "Foreign key constraint is incorrectly formed") SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( diff --git a/mysql-test/suite/gcol/t/innodb_virtual_fk.test b/mysql-test/suite/gcol/t/innodb_virtual_fk.test index 92776aa407d..c484bb5dc0c 100644 --- a/mysql-test/suite/gcol/t/innodb_virtual_fk.test +++ b/mysql-test/suite/gcol/t/innodb_virtual_fk.test @@ -590,7 +590,6 @@ CREATE TABLE t1 ( v3 TIME AS (c3) VIRTUAL, v4 CHAR(10) AS (c4) VIRTUAL ) ENGINE=InnoDB; ---replace_regex /#sql-[0-9a-f_]*/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 ADD CONSTRAINT fk FOREIGN KEY (v4) REFERENCES nosuch(col); SET foreign_key_checks=0; @@ -601,7 +600,6 @@ ALTER TABLE t1 ADD CONSTRAINT fk FOREIGN KEY (v4) REFERENCES nosuch(col); SET foreign_key_checks=1; SHOW CREATE TABLE t1; ALTER TABLE t1 DROP FOREIGN KEY fk; ---replace_regex /#sql-[0-9a-f_]*/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 ADD CONSTRAINT fk FOREIGN KEY (v4) REFERENCES nosuch(col); SHOW CREATE TABLE t1; diff --git a/mysql-test/suite/innodb/r/add_constraint.result b/mysql-test/suite/innodb/r/add_constraint.result index 798e87a3761..9d894e530c3 100644 --- a/mysql-test/suite/innodb/r/add_constraint.result +++ b/mysql-test/suite/innodb/r/add_constraint.result @@ -6,7 +6,7 @@ create table t2(a int, b int, key(a),key(b))engine=innodb; alter table t2 add constraint b foreign key (b) references t1(a); alter table t1 add constraint b1 foreign key (b) references t2(a); alter table t2 add constraint b1 foreign key (b) references t1(a); -ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 121 "Duplicate key on write or update") +ERROR HY000: Can't create table `test`.`t2` (errno: 121 "Duplicate key on write or update") alter table t2 drop foreign key b; alter table t1 drop foreign key b1; drop table t2; diff --git a/mysql-test/suite/innodb/r/foreign_key.result b/mysql-test/suite/innodb/r/foreign_key.result index c4c7fd6990e..74f113e1715 100644 --- a/mysql-test/suite/innodb/r/foreign_key.result +++ b/mysql-test/suite/innodb/r/foreign_key.result @@ -10,7 +10,7 @@ ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint create table t2 (f1 int primary key, constraint c1 foreign key (f1) references t1(f1)) engine=innodb; alter table t2 add constraint c1 foreign key (f1) references t1(f1); -ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 121 "Duplicate key on write or update") +ERROR HY000: Can't create table `test`.`t2` (errno: 121 "Duplicate key on write or update") set foreign_key_checks = 0; alter table t2 add constraint c1 foreign key (f1) references t1(f1); ERROR HY000: Duplicate FOREIGN KEY constraint name 'test/c1' diff --git a/mysql-test/suite/innodb/r/innodb-fk-warnings.result b/mysql-test/suite/innodb/r/innodb-fk-warnings.result index 792cae85b55..01a46c8c7bd 100644 --- a/mysql-test/suite/innodb/r/innodb-fk-warnings.result +++ b/mysql-test/suite/innodb/r/innodb-fk-warnings.result @@ -39,20 +39,20 @@ Error 1005 Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is Warning 1215 Cannot add foreign key constraint create table t2(a int, b int, constraint a foreign key a (a) references t1(a)) engine=innodb; alter table t2 add constraint b foreign key (b) references t2(b); -ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") +ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") show warnings; Level Code Message Warning 150 Alter table '`test`.`t2`' with foreign key constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns near ' foreign key (b) references t2(b)'. -Error 1005 Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") +Error 1005 Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") Warning 1215 Cannot add foreign key constraint drop table t2, t1; create table t1 (f1 integer primary key) engine=innodb; alter table t1 add constraint c1 foreign key (f1) references t11(f1); -ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") +ERROR HY000: Can't create table `test`.`t1` (errno: 150 "Foreign key constraint is incorrectly formed") show warnings; Level Code Message Warning 150 Alter table `test`.`t1` with foreign key constraint failed. Referenced table `test`.`t11` not found in the data dictionary near ' foreign key (f1) references t11(f1)'. -Error 1005 Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") +Error 1005 Can't create table `test`.`t1` (errno: 150 "Foreign key constraint is incorrectly formed") Warning 1215 Cannot add foreign key constraint drop table t1; create temporary table t1(a int not null primary key, b int, key(b)) engine=innodb; @@ -78,11 +78,11 @@ Warning 150 Create table `mysqld.1`.`t2` with foreign key constraint failed. Re Error 1005 Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") Warning 1215 Cannot add foreign key constraint alter table t1 add foreign key(b) references t1(a); -ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") +ERROR HY000: Can't create table `test`.`t1` (errno: 150 "Foreign key constraint is incorrectly formed") show warnings; Level Code Message Warning 150 Alter table `mysqld.1`.`t1` with foreign key constraint failed. Referenced table `mysqld.1`.`t1` not found in the data dictionary near 'foreign key(b) references t1(a)'. -Error 1005 Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") +Error 1005 Can't create table `test`.`t1` (errno: 150 "Foreign key constraint is incorrectly formed") Warning 1215 Cannot add foreign key constraint drop table t1; create table t1(a int not null primary key, b int, key(b)) engine=innodb; @@ -101,11 +101,11 @@ Error 1239 Incorrect foreign key definition for 'foreign key without name': Key drop table t1; create table t1 (f1 integer not null primary key) engine=innodb; alter table t1 add constraint c1 foreign key (f1) references t1(f1) on update set null; -ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") +ERROR HY000: Can't create table `test`.`t1` (errno: 150 "Foreign key constraint is incorrectly formed") show warnings; Level Code Message Warning 150 Alter table `test`.`t1` with foreign key constraint failed. You have defined a SET NULL condition but column 'f1' is defined as NOT NULL in ' foreign key (f1) references t1(f1) on update set null' near ' on update set null'. -Error 1005 Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") +Error 1005 Can't create table `test`.`t1` (errno: 150 "Foreign key constraint is incorrectly formed") Warning 1215 Cannot add foreign key constraint create table t2(a int not null, foreign key(a) references t1(f1) on delete set null) engine=innodb; ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") diff --git a/mysql-test/suite/innodb/r/innodb-fk.result b/mysql-test/suite/innodb/r/innodb-fk.result index 2eb19764769..a0c14ee6fe4 100644 --- a/mysql-test/suite/innodb/r/innodb-fk.result +++ b/mysql-test/suite/innodb/r/innodb-fk.result @@ -62,11 +62,11 @@ PRIMARY KEY (`id`), CONSTRAINT fk2 FOREIGN KEY (f2) REFERENCES t1 (`id`) ON DELETE CASCADE ) ENGINE=InnoDB; ALTER TABLE t2 ADD CONSTRAINT fk3 FOREIGN KEY (f3) REFERENCES t3 (id) ON DELETE CASCADE; -ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") +ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") show warnings; Level Code Message Warning 150 Alter table `test`.`t2` with foreign key constraint failed. Referenced table `test`.`t3` not found in the data dictionary near ' FOREIGN KEY (f3) REFERENCES t3 (id) ON DELETE CASCADE'. -Error 1005 Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") +Error 1005 Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") Warning 1215 Cannot add foreign key constraint drop table t2; drop table t1; diff --git a/mysql-test/suite/innodb/r/innodb-index-online.result b/mysql-test/suite/innodb/r/innodb-index-online.result index 3134c64c8c6..e42e93e9989 100644 --- a/mysql-test/suite/innodb/r/innodb-index-online.result +++ b/mysql-test/suite/innodb/r/innodb-index-online.result @@ -513,7 +513,7 @@ SET DEBUG_SYNC = 'RESET'; disconnect con1; CREATE TABLE t2 (c VARCHAR(64)) ENGINE=InnoDB; ALTER TABLE t2 ADD FOREIGN KEY (c) REFERENCES t1 (c); -ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") +ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") DROP TABLE t2,t1; SET GLOBAL innodb_file_per_table = @global_innodb_file_per_table_orig; SET GLOBAL innodb_monitor_enable = default; diff --git a/mysql-test/suite/innodb/r/innodb-index.result b/mysql-test/suite/innodb/r/innodb-index.result index 5f4efbfe6f5..b64fd27fb35 100644 --- a/mysql-test/suite/innodb/r/innodb-index.result +++ b/mysql-test/suite/innodb/r/innodb-index.result @@ -506,7 +506,7 @@ t4 CREATE TABLE `t4` ( CONSTRAINT `dc` FOREIGN KEY (`a`) REFERENCES `t1` (`a`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 alter table t3 add constraint dc foreign key (a) references t1(a); -ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 121 "Duplicate key on write or update") +ERROR HY000: Can't create table `test`.`t3` (errno: 121 "Duplicate key on write or update") SET FOREIGN_KEY_CHECKS=0; alter table t3 add constraint dc foreign key (a) references t1(a); ERROR HY000: Failed to add the foreign key constraint 'test/dc' to system tables @@ -951,13 +951,13 @@ PRIMARY KEY (c1) SET FOREIGN_KEY_CHECKS=0; ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca FOREIGN KEY (c3,c2) REFERENCES t1(c1,c1), ALGORITHM=COPY; -ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") +ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca FOREIGN KEY (c3,c2) REFERENCES t1(c1,c1); ERROR HY000: Failed to add the foreign key constaint. Missing index for constraint 'fk_t2_ca' in the referenced table 't1' ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca FOREIGN KEY (c3,c2) REFERENCES t1(c1,c2), ALGORITHM=COPY; -ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") +ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca FOREIGN KEY (c3,c2) REFERENCES t1(c1,c2); ERROR HY000: Failed to add the foreign key constaint. Missing index for constraint 'fk_t2_ca' in the referenced table 't1' @@ -966,13 +966,13 @@ FOREIGN KEY (c3,c2) REFERENCES t1(c2,c1), ALGORITHM=INPLACE; ERROR HY000: Failed to add the foreign key constraint on table 't2'. Incorrect options in FOREIGN KEY constraint 'test/fk_t2_ca' ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca FOREIGN KEY (c3,c2) REFERENCES t1(c2,c1), ALGORITHM=COPY; -ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") +ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") ALTER TABLE t1 MODIFY COLUMN c2 BIGINT(12) NOT NULL; affected rows: 0 info: Records: 0 Duplicates: 0 Warnings: 0 ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca FOREIGN KEY (c3,c2) REFERENCES t1(c1,c2), ALGORITHM=COPY; -ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") +ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca FOREIGN KEY (c3,c2) REFERENCES t1(c1,c2); ERROR HY000: Failed to add the foreign key constaint. Missing index for constraint 'fk_t2_ca' in the referenced table 't1' diff --git a/mysql-test/suite/innodb/r/innodb_force_recovery.result b/mysql-test/suite/innodb/r/innodb_force_recovery.result index bd533207ad2..0220f68a626 100644 --- a/mysql-test/suite/innodb/r/innodb_force_recovery.result +++ b/mysql-test/suite/innodb/r/innodb_force_recovery.result @@ -10,11 +10,11 @@ f1 f2 insert into t1 values(2, 3); ERROR HY000: Running in read-only mode alter table t1 add f3 int not null, algorithm=copy; -ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 165 "Table is read only") +ERROR HY000: Can't create table `test`.`t1` (errno: 165 "Table is read only") alter table t1 add f3 int not null, algorithm=inplace; ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Running in read-only mode. Try ALGORITHM=COPY drop index idx on t1; -ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 165 "Table is read only") +ERROR HY000: Can't create table `test`.`t1` (errno: 165 "Table is read only") alter table t1 drop index idx, algorithm=inplace; ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Running in read-only mode. Try ALGORITHM=COPY update t1 set f1=3 where f2=2; @@ -38,11 +38,11 @@ f1 f2 insert into t2 values(2, 3); ERROR HY000: Running in read-only mode alter table t2 add f3 int not null, algorithm=copy; -ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 165 "Table is read only") +ERROR HY000: Can't create table `test`.`t2` (errno: 165 "Table is read only") alter table t2 add f3 int not null, algorithm=inplace; ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Running in read-only mode. Try ALGORITHM=COPY drop index idx on t2; -ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 165 "Table is read only") +ERROR HY000: Can't create table `test`.`t2` (errno: 165 "Table is read only") update t2 set f1=3 where f2=2; ERROR HY000: Running in read-only mode create table t1(f1 int not null)engine=innodb; diff --git a/mysql-test/suite/innodb/t/add_constraint.test b/mysql-test/suite/innodb/t/add_constraint.test index 7e86a7e5f97..f43f2977020 100644 --- a/mysql-test/suite/innodb/t/add_constraint.test +++ b/mysql-test/suite/innodb/t/add_constraint.test @@ -10,7 +10,6 @@ create table t2(a int, b int, key(a),key(b))engine=innodb; alter table t2 add constraint b foreign key (b) references t1(a); alter table t1 add constraint b1 foreign key (b) references t2(a); ---replace_regex /#sql-[0-9a-f_]*/#sql-temporary/ --error ER_CANT_CREATE_TABLE alter table t2 add constraint b1 foreign key (b) references t1(a); diff --git a/mysql-test/suite/innodb/t/foreign_key.test b/mysql-test/suite/innodb/t/foreign_key.test index 773fa71761b..3dd24a32711 100644 --- a/mysql-test/suite/innodb/t/foreign_key.test +++ b/mysql-test/suite/innodb/t/foreign_key.test @@ -14,7 +14,6 @@ constraint c1 foreign key (f1) references t1(f1)) engine=InnoDB; create table t2 (f1 int primary key, constraint c1 foreign key (f1) references t1(f1)) engine=innodb; ---replace_regex /#sql-[0-9a-f_]*/#sql-temporary/ --error ER_CANT_CREATE_TABLE alter table t2 add constraint c1 foreign key (f1) references t1(f1); diff --git a/mysql-test/suite/innodb/t/innodb-fk-warnings.test b/mysql-test/suite/innodb/t/innodb-fk-warnings.test index f45ae00d788..55284179692 100644 --- a/mysql-test/suite/innodb/t/innodb-fk-warnings.test +++ b/mysql-test/suite/innodb/t/innodb-fk-warnings.test @@ -48,10 +48,8 @@ create table t2(a int, b int, constraint a foreign key a (a) references t1(a), constraint a foreign key a (a) references t1(b)) engine=innodb; show warnings; create table t2(a int, b int, constraint a foreign key a (a) references t1(a)) engine=innodb; ---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ --error 1005 alter table t2 add constraint b foreign key (b) references t2(b); ---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ show warnings; drop table t2, t1; @@ -60,10 +58,8 @@ drop table t2, t1; # create table t1 (f1 integer primary key) engine=innodb; ---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ --error 1005 alter table t1 add constraint c1 foreign key (f1) references t11(f1); ---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ show warnings; drop table t1; @@ -87,15 +83,11 @@ create temporary table t1(a int not null primary key, b int, key(b)) engine=inno --echo Warning 150 Alter table `mysqld.1`.`t1` with foreign key constraint failed. Referenced table `mysqld.1`.`t1` not found in the data dictionary close to foreign key(b) references t1(a). --echo Error 1005 Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") --echo Warning 1215 Cannot add foreign key constraint ---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ --error 1005 create temporary table t2(a int, foreign key(a) references t1(a)) engine=innodb; ---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ show warnings; ---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ --error 1005 alter table t1 add foreign key(b) references t1(a); ---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ show warnings; drop table t1; @@ -103,17 +95,13 @@ drop table t1; # Column numbers do not match # create table t1(a int not null primary key, b int, key(b)) engine=innodb; ---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ --error 1239 alter table t1 add foreign key(a,b) references t1(a); ---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ show warnings; drop table t1; create table t1(a int not null primary key, b int, key(b)) engine=innodb; ---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ --error 1239 alter table t1 add foreign key(a) references t1(a,b); ---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ show warnings; drop table t1; @@ -121,15 +109,11 @@ drop table t1; # ON UPDATE/DELETE SET NULL on NOT NULL column # create table t1 (f1 integer not null primary key) engine=innodb; ---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ --error 1005 alter table t1 add constraint c1 foreign key (f1) references t1(f1) on update set null; ---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ show warnings; ---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ --error 1005 create table t2(a int not null, foreign key(a) references t1(f1) on delete set null) engine=innodb; ---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ show warnings; drop table t1; @@ -137,9 +121,7 @@ drop table t1; # Incorrect types # create table t1 (id int not null primary key, f1 int, f2 int, key(f1)) engine=innodb; ---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ --error 1005 create table t2(a char(20), key(a), foreign key(a) references t1(f1)) engine=innodb; ---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ show warnings; drop table t1; diff --git a/mysql-test/suite/innodb/t/innodb-fk.test b/mysql-test/suite/innodb/t/innodb-fk.test index 17e926e8647..8809dc55966 100644 --- a/mysql-test/suite/innodb/t/innodb-fk.test +++ b/mysql-test/suite/innodb/t/innodb-fk.test @@ -115,11 +115,9 @@ CREATE TABLE t2 ( CONSTRAINT fk2 FOREIGN KEY (f2) REFERENCES t1 (`id`) ON DELETE CASCADE ) ENGINE=InnoDB; ---replace_regex /#sql-[0-9_a-f-]*/#sql-temporary/ --error 1005 ALTER TABLE t2 ADD CONSTRAINT fk3 FOREIGN KEY (f3) REFERENCES t3 (id) ON DELETE CASCADE; ---replace_regex /#sql-[0-9_a-f-]*/#sql-temporary/ show warnings; drop table t2; diff --git a/mysql-test/suite/innodb/t/innodb-index-online.test b/mysql-test/suite/innodb/t/innodb-index-online.test index efe1c796cf1..5d92b010e60 100644 --- a/mysql-test/suite/innodb/t/innodb-index-online.test +++ b/mysql-test/suite/innodb/t/innodb-index-online.test @@ -492,7 +492,6 @@ reap; SET DEBUG_SYNC = 'RESET'; disconnect con1; CREATE TABLE t2 (c VARCHAR(64)) ENGINE=InnoDB; ---replace_regex /#sql-[0-9a-f_]*/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t2 ADD FOREIGN KEY (c) REFERENCES t1 (c); DROP TABLE t2,t1; diff --git a/mysql-test/suite/innodb/t/innodb-index.test b/mysql-test/suite/innodb/t/innodb-index.test index bfbe62699fd..17cb9e7b4e1 100644 --- a/mysql-test/suite/innodb/t/innodb-index.test +++ b/mysql-test/suite/innodb/t/innodb-index.test @@ -218,7 +218,6 @@ alter table t4 add constraint dc foreign key (a) references t1(a); --disable_info show create table t4; # mysqltest first does replace_regex, then replace_result ---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ # Embedded server doesn't chdir to data directory --replace_result $MYSQLD_DATADIR ./ master-data/ '' # a foreign key 'test/dc' already exists @@ -416,7 +415,6 @@ SET FOREIGN_KEY_CHECKS=0; --enable_info # mysqltest first does replace_regex, then replace_result ---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ # Embedded server doesn't chdir to data directory --replace_result $MYSQLD_DATADIR ./ master-data/ '' --error ER_CANT_CREATE_TABLE @@ -426,7 +424,6 @@ ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca FOREIGN KEY (c3,c2) REFERENCES t1(c1,c1); # mysqltest first does replace_regex, then replace_result ---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ # Embedded server doesn't chdir to data directory --replace_result $MYSQLD_DATADIR ./ master-data/ '' --error ER_CANT_CREATE_TABLE @@ -441,7 +438,6 @@ ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca FOREIGN KEY (c3,c2) REFERENCES t1(c2,c1), ALGORITHM=INPLACE; # mysqltest first does replace_regex, then replace_result ---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ # Embedded server doesn't chdir to data directory --replace_result $MYSQLD_DATADIR ./ master-data/ '' --error ER_CANT_CREATE_TABLE @@ -450,7 +446,6 @@ ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca ALTER TABLE t1 MODIFY COLUMN c2 BIGINT(12) NOT NULL; # mysqltest first does replace_regex, then replace_result ---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ # Embedded server doesn't chdir to data directory --replace_result $MYSQLD_DATADIR ./ master-data/ '' --error ER_CANT_CREATE_TABLE diff --git a/mysql-test/suite/innodb/t/innodb-page_compression_tables.test b/mysql-test/suite/innodb/t/innodb-page_compression_tables.test index bf83ebf5e82..a5244de9e29 100644 --- a/mysql-test/suite/innodb/t/innodb-page_compression_tables.test +++ b/mysql-test/suite/innodb/t/innodb-page_compression_tables.test @@ -9,20 +9,16 @@ set global innodb_compression_algorithm = 1; create table innodb_normal(c1 bigint not null, b char(200)) engine=innodb; create table innodb_compact(c1 bigint not null, b char(200)) engine=innodb row_format=compact page_compressed=1; create table innodb_dynamic(c1 bigint not null, b char(200)) engine=innodb row_format=dynamic page_compressed=1; ---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ --error 1005 create table innodb_compressed(c1 bigint not null, b char(200)) engine=innodb row_format=compressed page_compressed=1; ---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ show warnings; show create table innodb_compact; show create table innodb_dynamic; # MDEV-7133: InnoDB: Assertion failure in thread 140737091569408 in file dict0mem.cc line 74 # InnoDB: Failing assertion: dict_tf_is_valid(flags) ---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ --error 1005 create table innodb_redundant(c1 bigint not null, b char(200)) engine=innodb row_format=redundant page_compressed=1; ---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ show warnings; create table innodb_redundant(c1 bigint not null, b char(200)) engine=innodb row_format=redundant; show create table innodb_redundant; diff --git a/mysql-test/suite/innodb/t/innodb_force_recovery.test b/mysql-test/suite/innodb/t/innodb_force_recovery.test index f9af16f6609..822180dfbfa 100644 --- a/mysql-test/suite/innodb/t/innodb_force_recovery.test +++ b/mysql-test/suite/innodb/t/innodb_force_recovery.test @@ -25,14 +25,12 @@ select * from t1; --error ER_READ_ONLY_MODE insert into t1 values(2, 3); ---replace_regex /#sql-[0-9a-f_]*/#sql-temporary/ --error ER_CANT_CREATE_TABLE alter table t1 add f3 int not null, algorithm=copy; --error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON alter table t1 add f3 int not null, algorithm=inplace; ---replace_regex /#sql-[0-9a-f_]*/#sql-temporary/ --error ER_CANT_CREATE_TABLE drop index idx on t1; --error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON @@ -65,14 +63,12 @@ select * from t2; --error ER_READ_ONLY_MODE insert into t2 values(2, 3); ---replace_regex /#sql-[0-9a-f_]*/#sql-temporary/ --error ER_CANT_CREATE_TABLE alter table t2 add f3 int not null, algorithm=copy; --error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON alter table t2 add f3 int not null, algorithm=inplace; ---replace_regex /#sql-[0-9a-f_]*/#sql-temporary/ --error ER_CANT_CREATE_TABLE drop index idx on t2; diff --git a/mysql-test/suite/innodb_gis/r/point_basic.result b/mysql-test/suite/innodb_gis/r/point_basic.result index faaef07c112..97328584bf7 100644 --- a/mysql-test/suite/innodb_gis/r/point_basic.result +++ b/mysql-test/suite/innodb_gis/r/point_basic.result @@ -1521,11 +1521,11 @@ child CREATE TABLE `child` ( SPATIAL KEY `idx2` (`p`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 ALTER TABLE child ADD FOREIGN KEY(p) REFERENCES parent(p); -ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") +ERROR HY000: Can't create table `test`.`child` (errno: 150 "Foreign key constraint is incorrectly formed") show warnings; Level Code Message Warning 150 Alter table '`test`.`child`' with foreign key constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns near 'FOREIGN KEY(p) REFERENCES parent(p)'. -Error 1005 Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") +Error 1005 Can't create table `test`.`child` (errno: 150 "Foreign key constraint is incorrectly formed") Warning 1215 Cannot add foreign key constraint ALTER TABLE parent DROP INDEX idx1; ALTER TABLE child ADD FOREIGN KEY(p) REFERENCES parent(p); @@ -1533,7 +1533,7 @@ Got one of the listed errors show warnings; Level Code Message Warning 150 Alter table '`test`.`child`' with foreign key constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns near 'FOREIGN KEY(p) REFERENCES parent(p)'. -Error 1005 Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") +Error 1005 Can't create table `test`.`child` (errno: 150 "Foreign key constraint is incorrectly formed") Warning 1215 Cannot add foreign key constraint ALTER TABLE child DROP INDEX idx2; ALTER TABLE child ADD FOREIGN KEY(p) REFERENCES parent(p); @@ -1541,7 +1541,7 @@ Got one of the listed errors show warnings; Level Code Message Warning 150 Alter table '`test`.`child`' with foreign key constraint failed. There is only prefix index in the referenced table where the referenced columns appear as the first columns near 'FOREIGN KEY(p) REFERENCES parent(p)'. -Error 1005 Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") +Error 1005 Can't create table `test`.`child` (errno: 150 "Foreign key constraint is incorrectly formed") Warning 1215 Cannot add foreign key constraint DROP TABLE child, parent; # diff --git a/mysql-test/suite/innodb_gis/t/point_basic.test b/mysql-test/suite/innodb_gis/t/point_basic.test index 1c0d229802b..4ac90b93d4c 100644 --- a/mysql-test/suite/innodb_gis/t/point_basic.test +++ b/mysql-test/suite/innodb_gis/t/point_basic.test @@ -772,24 +772,18 @@ ALTER TABLE child ADD SPATIAL INDEX idx2(p ASC); SHOW CREATE TABLE parent; SHOW CREATE TABLE child; ---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ --error ER_CANT_CREATE_TABLE ALTER TABLE child ADD FOREIGN KEY(p) REFERENCES parent(p); ---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ show warnings; ALTER TABLE parent DROP INDEX idx1; ---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ --error ER_CANNOT_ADD_FOREIGN,ER_CANT_CREATE_TABLE ALTER TABLE child ADD FOREIGN KEY(p) REFERENCES parent(p); ---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ show warnings; ALTER TABLE child DROP INDEX idx2; ---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ --error ER_CANNOT_ADD_FOREIGN,ER_CANT_CREATE_TABLE ALTER TABLE child ADD FOREIGN KEY(p) REFERENCES parent(p); ---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ show warnings; DROP TABLE child, parent; diff --git a/mysql-test/suite/plugins/t/audit_null.test b/mysql-test/suite/plugins/t/audit_null.test index 199e4ba154e..63f5f51e347 100644 --- a/mysql-test/suite/plugins/t/audit_null.test +++ b/mysql-test/suite/plugins/t/audit_null.test @@ -56,6 +56,6 @@ drop user testuser@localhost; set global general_log=@old_global_general_log; let $MYSQLD_DATADIR= `SELECT @@datadir`; ---replace_regex /#sql-[0-9a-f_]*/#sql-temporary/ /#sql2-[-0-9a-f_]*/#sql2-temporary/ /::1// /127.0.0.1// +--replace_regex /::1// /127.0.0.1// cat_file $MYSQLD_DATADIR/audit_null_tables.log; diff --git a/mysql-test/suite/sys_vars/r/tmp_disk_table_size_func.result b/mysql-test/suite/sys_vars/r/tmp_disk_table_size_func.result index d2a5ad46129..bc2301cfd39 100644 --- a/mysql-test/suite/sys_vars/r/tmp_disk_table_size_func.result +++ b/mysql-test/suite/sys_vars/r/tmp_disk_table_size_func.result @@ -18,7 +18,7 @@ Variable_name Value Created_tmp_disk_tables 1 set @@session.tmp_disk_table_size=1000000; select count(*) as c from t1 group by b having c>1; -ERROR HY000: The table '#sql_xxx' is full +ERROR HY000: The table '(temporary)' is full show status like "created_tmp_disk%"; Variable_name Value Created_tmp_disk_tables 2 diff --git a/mysql-test/suite/sys_vars/t/tmp_disk_table_size_func.test b/mysql-test/suite/sys_vars/t/tmp_disk_table_size_func.test index 9c1e596d3e4..6b3d2e1fa1b 100644 --- a/mysql-test/suite/sys_vars/t/tmp_disk_table_size_func.test +++ b/mysql-test/suite/sys_vars/t/tmp_disk_table_size_func.test @@ -21,7 +21,6 @@ insert into t1 values (20000,"A"); select count(*) as c from t1 group by b having c>1; show status like "created_tmp_disk%"; set @@session.tmp_disk_table_size=1000000; ---replace_regex /The table '.*' is full/The table '#sql_xxx' is full/ --error ER_RECORD_FILE_FULL select count(*) as c from t1 group by b having c>1; show status like "created_tmp_disk%"; diff --git a/mysql-test/suite/vcol/inc/vcol_keys.inc b/mysql-test/suite/vcol/inc/vcol_keys.inc index 7c9f60c0fb0..8ec89daff0b 100644 --- a/mysql-test/suite/vcol/inc/vcol_keys.inc +++ b/mysql-test/suite/vcol/inc/vcol_keys.inc @@ -127,7 +127,6 @@ if ($with_foreign_keys) { create table t1 (a int, b int as (a+1), foreign key (b) references t2(a)); create table t1 (a int, b int as (a+1)); ---replace_regex /`#sql-.*`/`#sql-temporary`/ --error ER_CANT_CREATE_TABLE alter table t1 add foreign key (b) references t2(a); drop table t1; diff --git a/mysql-test/suite/vcol/r/vcol_keys_innodb.result b/mysql-test/suite/vcol/r/vcol_keys_innodb.result index 242baba32af..c6c05429978 100644 --- a/mysql-test/suite/vcol/r/vcol_keys_innodb.result +++ b/mysql-test/suite/vcol/r/vcol_keys_innodb.result @@ -126,7 +126,7 @@ create table t1 (a int, b int as (a+1), foreign key (b) references t2(a)); ERROR HY000: Can't create table `test`.`t1` (errno: 150 "Foreign key constraint is incorrectly formed") create table t1 (a int, b int as (a+1)); alter table t1 add foreign key (b) references t2(a); -ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") +ERROR HY000: Can't create table `test`.`t1` (errno: 150 "Foreign key constraint is incorrectly formed") drop table t1; # Allowed FK options. create table t2 (a int primary key, b char(5)); diff --git a/mysql-test/t/check_constraint.test b/mysql-test/t/check_constraint.test index be06c3ec579..37fdc7203b1 100644 --- a/mysql-test/t/check_constraint.test +++ b/mysql-test/t/check_constraint.test @@ -27,7 +27,6 @@ insert into t1 values (101,101),(102,102),(600,600),(103,103); select * from t1; set check_constraint_checks=@save_check_constraint; ---replace_regex /failed for.*/failed for table/ --error ER_CONSTRAINT_FAILED alter table t1 add c int default 0 check (c < 10); diff --git a/mysql-test/t/error_simulation.test b/mysql-test/t/error_simulation.test index beaaf603754..1debed871c7 100644 --- a/mysql-test/t/error_simulation.test +++ b/mysql-test/t/error_simulation.test @@ -1,12 +1,9 @@ --- source include/have_debug.inc +--source include/have_debug.inc --source include/not_embedded.inc # # Bug #28499: crash for grouping query when tmp_table_size is too small # - -DROP TABLE IF EXISTS t1; - CREATE TABLE t1 ( a varchar(32) character set utf8 collate utf8_bin NOT NULL, b varchar(32) character set utf8 collate utf8_bin NOT NULL ) @@ -26,14 +23,12 @@ set tmp_table_size=1024; # tmp table in query is converted from heap to myisam set session debug_dbug="+d,raise_error"; ---replace_regex /in table '[^']+'/in table 'tmp_table'/ --error ER_DUP_KEY SELECT MAX(a) FROM t1 GROUP BY a,b; set tmp_table_size=default; DROP TABLE t1; - --echo # --echo # Bug #50946: fast index creation still seems to copy the table --echo # diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test index 8b678f223a4..ebcea63b083 100644 --- a/mysql-test/t/gis.test +++ b/mysql-test/t/gis.test @@ -761,7 +761,6 @@ drop table t1; --echo # on char > 31 bytes". --echo # create table t1(a char(32) not null) engine=myisam; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ --error ER_WRONG_ARGUMENTS create spatial index i on t1 (a); drop table t1; From db8f0daeb4f86dd5fab1fba292b6682fa4413e8b Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 3 Feb 2019 18:43:42 +0100 Subject: [PATCH 077/106] CONNECT: calculate table_name from the path CONNECT used to compute table file path as table->s->db_name + table->s->table_name instead of using table->s->path. This was incorrect and now it breaks for temporary tables during ALTER TABLE. Temporarily "fix" it by making CONNECT to use what it always used as a table name - the last component in the table->s->path. --- storage/connect/ha_connect.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index 3745cf6dae5..c5fd9483a65 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -1815,7 +1815,9 @@ PCSZ ha_connect::GetDBName(PCSZ name) const char *ha_connect::GetTableName(void) { - return tshp ? tshp->table_name.str : table_share->table_name.str; + const char *path= tshp ? tshp->path.str : table_share->path.str; + const char *name= strrchr(path, '/'); + return name ? name+1 : path; } // end of GetTableName char *ha_connect::GetPartName(void) From b57ae8b58cbfff020ab91f6844fc174f536af43f Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 3 Feb 2019 19:56:41 +0100 Subject: [PATCH 078/106] MDEV-18239 ASAN use-after-poison in process_str_arg / ... / mark_unsupported_func or unexpected ER_BAD_FIELD_ERROR upon ALTER TABLE renaming columns in a CHECK constraint during ALTER TABLE taints the original TABLE and requires m_need_reopen=1. In this case, though, renaming was redundant, so just don't do it. --- mysql-test/r/check_constraint_innodb.result | 9 +++++++++ mysql-test/t/check_constraint_innodb.test | 14 ++++++++++++++ sql/sql_table.cc | 7 ++++++- 3 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 mysql-test/r/check_constraint_innodb.result create mode 100644 mysql-test/t/check_constraint_innodb.test diff --git a/mysql-test/r/check_constraint_innodb.result b/mysql-test/r/check_constraint_innodb.result new file mode 100644 index 00000000000..45af3f512b7 --- /dev/null +++ b/mysql-test/r/check_constraint_innodb.result @@ -0,0 +1,9 @@ +create table t1 (a int, b smallint) engine=innodb; +connect con1,localhost,root,,test; +alter table t1 add constraint check (b < 8); +alter table t1 modify column b int, algorithm=inplace; +ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY +connection default; +alter table t1 add primary key (a); +drop table t1; +disconnect con1; diff --git a/mysql-test/t/check_constraint_innodb.test b/mysql-test/t/check_constraint_innodb.test new file mode 100644 index 00000000000..d02aa320e84 --- /dev/null +++ b/mysql-test/t/check_constraint_innodb.test @@ -0,0 +1,14 @@ +--source include/have_innodb.inc + +# +# MDEV-18239 ASAN use-after-poison in process_str_arg / ... / mark_unsupported_func or unexpected ER_BAD_FIELD_ERROR upon ALTER TABLE +# +create table t1 (a int, b smallint) engine=innodb; +connect con1,localhost,root,,test; +alter table t1 add constraint check (b < 8); +error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON; +alter table t1 modify column b int, algorithm=inplace; +connection default; +alter table t1 add primary key (a); +drop table t1; +disconnect con1; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 4f9adc3338c..f27b61092d2 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -8123,7 +8123,12 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, } if (!drop) { - check->expr->walk(&Item::rename_fields_processor, 1, &column_rename_param); + if (alter_info->flags & Alter_info::ALTER_RENAME_COLUMN) + { + check->expr->walk(&Item::rename_fields_processor, 1, + &column_rename_param); + table->m_needs_reopen= 1; // because new column name is on thd->mem_root + } new_constraint_list.push_back(check, thd->mem_root); } } From 227379988eac3c9ce7be626477f4d138dc34579d Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 3 Feb 2019 20:00:01 +0100 Subject: [PATCH 079/106] MDEV-16905 ASAN heap-use-after-free in __interceptor_strnlen / ... / TABLE::verify_constraints upon INSERT into temporary table with CHECK constraint just a test case --- mysql-test/r/check.result | 7 +++++++ mysql-test/t/check.test | 9 +++++++++ 2 files changed, 16 insertions(+) diff --git a/mysql-test/r/check.result b/mysql-test/r/check.result index e882a4cdbe6..11ed734da0c 100644 --- a/mysql-test/r/check.result +++ b/mysql-test/r/check.result @@ -95,3 +95,10 @@ Warnings: Warning 4025 CONSTRAINT `CONSTRAINT_1` failed for `test`.`t1` alter table t1; drop table t1; +create temporary table t1 (a int default 0, check (a > 0)); +alter table t1 drop constraint if exists non_existing_constraint; +Warnings: +Note 1091 Can't DROP CONSTRAINT `non_existing_constraint`; check that it exists +insert into t1 () values (); +ERROR 23000: CONSTRAINT `CONSTRAINT_1` failed for `test`.`t1` +drop table t1; diff --git a/mysql-test/t/check.test b/mysql-test/t/check.test index 475a7996a09..29587a9f623 100644 --- a/mysql-test/t/check.test +++ b/mysql-test/t/check.test @@ -115,3 +115,12 @@ insert into t1 () values (); alter ignore table t1 add constraint check (f > 0); alter table t1; drop table t1; + +# +# MDEV-16905 ASAN heap-use-after-free in __interceptor_strnlen / ... / TABLE::verify_constraints upon INSERT into temporary table with CHECK constraint +# +create temporary table t1 (a int default 0, check (a > 0)); +alter table t1 drop constraint if exists non_existing_constraint; +--error ER_CONSTRAINT_FAILED +insert into t1 () values (); +drop table t1; From f53e795250133a622eb1c00271c073726ae3c7fc Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Tue, 5 Feb 2019 11:24:19 +0400 Subject: [PATCH 080/106] MDEV-17599 ALTER TABLE DROP CONSTRAINT does not work for foreign keys. The list of table constraints doesn't include foreign keys and uniques. So we replace DROP CONSTRAINT with DROP [FOREIGN] KEY in this case. --- mysql-test/r/alter_table.result | 49 ++++++++++++++++++++++++++++ mysql-test/t/alter_table.test | 17 ++++++++++ sql/sql_table.cc | 58 +++++++++++++++++++++++++++++++++ sql/sql_yacc.yy | 9 +++-- 4 files changed, 131 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result index dcee72e44f7..f243d244486 100644 --- a/mysql-test/r/alter_table.result +++ b/mysql-test/r/alter_table.result @@ -2456,5 +2456,54 @@ ERROR 23000: Duplicate entry '1' for key 'i' UNLOCK TABLES; DROP TABLE t1; # +# MDEV-17599 ALTER TABLE DROP CONSTRAINT does not work for foreign keys. +# +CREATE TABLE t1(id INT PRIMARY KEY, c1 INT) ENGINE= INNODB; +CREATE TABLE t2(id INT PRIMARY KEY, c1 INT, c2 INT NOT NULL, +CONSTRAINT sid FOREIGN KEY (`c1`) REFERENCES t1 (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, +CONSTRAINT UNIQUE `ui`(c2)) ENGINE= INNODB; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `id` int(11) NOT NULL, + `c1` int(11) DEFAULT NULL, + `c2` int(11) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `ui` (`c2`), + KEY `sid` (`c1`), + CONSTRAINT `sid` FOREIGN KEY (`c1`) REFERENCES `t1` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +ALTER TABLE t2 DROP CONSTRAINT sid; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `id` int(11) NOT NULL, + `c1` int(11) DEFAULT NULL, + `c2` int(11) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `ui` (`c2`), + KEY `sid` (`c1`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +ALTER TABLE t2 DROP CONSTRAINT ui; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `id` int(11) NOT NULL, + `c1` int(11) DEFAULT NULL, + `c2` int(11) NOT NULL, + PRIMARY KEY (`id`), + KEY `sid` (`c1`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +ALTER TABLE t2 DROP CONSTRAINT PRIMARY KEY; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `id` int(11) NOT NULL, + `c1` int(11) DEFAULT NULL, + `c2` int(11) NOT NULL, + KEY `sid` (`c1`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +DROP TABLE t2, t1; +# # End of 10.2 tests # diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test index df077c800d2..e6caadcc52c 100644 --- a/mysql-test/t/alter_table.test +++ b/mysql-test/t/alter_table.test @@ -2012,6 +2012,23 @@ UNLOCK TABLES; DROP TABLE t1; +--echo # +--echo # MDEV-17599 ALTER TABLE DROP CONSTRAINT does not work for foreign keys. +--echo # + +CREATE TABLE t1(id INT PRIMARY KEY, c1 INT) ENGINE= INNODB; +CREATE TABLE t2(id INT PRIMARY KEY, c1 INT, c2 INT NOT NULL, + CONSTRAINT sid FOREIGN KEY (`c1`) REFERENCES t1 (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT UNIQUE `ui`(c2)) ENGINE= INNODB; +SHOW CREATE TABLE t2; +ALTER TABLE t2 DROP CONSTRAINT sid; +SHOW CREATE TABLE t2; +ALTER TABLE t2 DROP CONSTRAINT ui; +SHOW CREATE TABLE t2; +ALTER TABLE t2 DROP CONSTRAINT PRIMARY KEY; +SHOW CREATE TABLE t2; +DROP TABLE t2, t1; + --echo # --echo # End of 10.2 tests --echo # diff --git a/sql/sql_table.cc b/sql/sql_table.cc index f27b61092d2..1227f144348 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -8979,6 +8979,64 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, THD_STAGE_INFO(thd, stage_setup); + if (alter_info->flags & Alter_info::ALTER_DROP_CHECK_CONSTRAINT) + { + /* + ALTER TABLE DROP CONSTRAINT + should be replaced with ... DROP [FOREIGN] KEY + if the constraint is the FOREIGN KEY or UNIQUE one. + */ + + List_iterator drop_it(alter_info->drop_list); + Alter_drop *drop; + List fk_child_key_list; + table->file->get_foreign_key_list(thd, &fk_child_key_list); + + alter_info->flags&= ~Alter_info::ALTER_DROP_CHECK_CONSTRAINT; + + while ((drop= drop_it++)) + { + if (drop->type == Alter_drop::CHECK_CONSTRAINT) + { + { + /* Test if there is a FOREIGN KEY with this name. */ + FOREIGN_KEY_INFO *f_key; + List_iterator fk_key_it(fk_child_key_list); + + while ((f_key= fk_key_it++)) + { + if (my_strcasecmp(system_charset_info, f_key->foreign_id->str, + drop->name) == 0) + { + drop->type= Alter_drop::FOREIGN_KEY; + alter_info->flags|= Alter_info::DROP_FOREIGN_KEY; + goto do_continue; + } + } + } + + { + /* Test if there is an UNIQUE with this name. */ + uint n_key; + + for (n_key=0; n_key < table->s->keys; n_key++) + { + if ((table->key_info[n_key].flags & HA_NOSAME) && + my_strcasecmp(system_charset_info, + drop->name, table->key_info[n_key].name) == 0) + { + drop->type= Alter_drop::KEY; + alter_info->flags|= Alter_info::ALTER_DROP_INDEX; + goto do_continue; + } + } + } + } + alter_info->flags|= Alter_info::ALTER_DROP_CHECK_CONSTRAINT; +do_continue:; + } + } + handle_if_exists_options(thd, table, alter_info); /* diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 480c2e9bacb..14d084e7022 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1741,7 +1741,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); IDENT_sys TEXT_STRING_sys TEXT_STRING_literal NCHAR_STRING opt_component key_cache_name sp_opt_label BIN_NUM label_ident TEXT_STRING_filesystem ident_or_empty - opt_constraint constraint opt_ident ident_table_alias + opt_constraint opt_constraint_no_id constraint opt_ident ident_table_alias %type opt_table_alias @@ -6123,6 +6123,11 @@ check_constraint: } ; +opt_constraint_no_id: + /* Empty */ {} + | CONSTRAINT {} + ; + opt_constraint: /* empty */ { $$= null_lex_str; } | constraint { $$= $1; } @@ -7653,7 +7658,7 @@ alter_list_item: lex->alter_info.drop_list.push_back(ad, thd->mem_root); lex->alter_info.flags|= Alter_info::DROP_FOREIGN_KEY; } - | DROP PRIMARY_SYM KEY_SYM + | DROP opt_constraint_no_id PRIMARY_SYM KEY_SYM { LEX *lex=Lex; Alter_drop *ad= (new (thd->mem_root) From 625994b7cc4ebd0bc2652ae80b93386aa4b766ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 5 Feb 2019 11:16:43 +0200 Subject: [PATCH 081/106] MDEV-16982 Server crashes in mem_heap_dup upon DELETE from table with virtual columns An uninitialized buffer is passed to row_sel_store_mysql_rec() but InnoDB may not initialize everything. Looks like it's ok in most cases but not always. The partially initialized buffer was later passed to ha_innobase::write_row() which reads random NULL bit values for virtual columns and random stuff happens. No test case for MariaDB 10.2 was found. The test case for MariaDB 10.3 involves partitioning, system versioning and the TRASH_ALLOC fill pattern 0xA5. Test case depends very much on the number and layout of columns. Think about 0xA5 byte for a NULL bit mask. row_sel_store_mysql_rec(): always initialize virtual columns NULL bit Closes #1144 --- storage/innobase/row/row0sel.cc | 45 ++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc index e27b1b9df77..4a82a345a1d 100644 --- a/storage/innobase/row/row0sel.cc +++ b/storage/innobase/row/row0sel.cc @@ -2,7 +2,7 @@ Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. -Copyright (c) 2015, 2018, MariaDB Corporation. +Copyright (c) 2015, 2019, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -3132,20 +3132,20 @@ row_sel_store_mysql_field_func( Note that the template in prebuilt may advise us to copy only a few columns to mysql_rec, other columns are left blank. All columns may not be needed in the query. -@param[out] mysql_rec row in the MySQL format -@param[in] prebuilt prebuilt structure -@param[in] rec Innobase record in the index - which was described in prebuilt's - template, or in the clustered index; - must be protected by a page latch -@param[in] vrow virtual columns -@param[in] rec_clust whether the rec in the clustered index -@param[in] index index of rec -@param[in] offsets array returned by rec_get_offsets(rec) -@return TRUE on success, FALSE if not all columns could be retrieved */ -static MY_ATTRIBUTE((warn_unused_result)) -ibool -row_sel_store_mysql_rec( +@param[out] mysql_rec row in the MySQL format +@param[in] prebuilt cursor +@param[in] rec Innobase record in the index + which was described in prebuilt's + template, or in the clustered index; + must be protected by a page latch +@param[in] vrow virtual columns +@param[in] rec_clust whether index must be the clustered index +@param[in] index index of rec +@param[in] offsets array returned by rec_get_offsets(rec) +@retval true on success +@retval false if not all columns could be retrieved */ +MY_ATTRIBUTE((warn_unused_result)) +static bool row_sel_store_mysql_rec( byte* mysql_rec, row_prebuilt_t* prebuilt, const rec_t* rec, @@ -3167,13 +3167,18 @@ row_sel_store_mysql_rec( const mysql_row_templ_t*templ = &prebuilt->mysql_template[i]; if (templ->is_virtual && dict_index_is_clust(index)) { + /* Virtual columns are never declared NOT NULL. */ + ut_ad(templ->mysql_null_bit_mask); /* Skip virtual columns if it is not a covered search or virtual key read is not requested. */ - if (!dict_index_has_virtual(prebuilt->index) + if (!rec_clust + || !prebuilt->index->has_virtual() || (!prebuilt->read_just_key - && !prebuilt->m_read_virtual_key) - || !rec_clust) { + && !prebuilt->m_read_virtual_key)) { + /* Initialize the NULL bit. */ + mysql_rec[templ->mysql_null_byte_offset] + |= (byte) templ->mysql_null_bit_mask; continue; } @@ -3247,7 +3252,7 @@ row_sel_store_mysql_rec( rec, index, offsets, field_no, templ)) { - DBUG_RETURN(FALSE); + DBUG_RETURN(false); } } @@ -3264,7 +3269,7 @@ row_sel_store_mysql_rec( } } - DBUG_RETURN(TRUE); + DBUG_RETURN(true); } /*********************************************************************//** From 5eb3e4d83c793713aabe2e09b8cd8069f46f2f0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 5 Feb 2019 17:03:41 +0200 Subject: [PATCH 082/106] MDEV-15798 Mutex leak on accessing INFORMATION_SCHEMA.INNODB_MUTEXES i_s_innodb_mutexes_fill_table(): Use the C++ RAII pattern to ensure that the mutexes are released if an OK() macro returns from the function prematurely. --- storage/innobase/handler/i_s.cc | 153 +++++++++++++++++++------------- storage/xtradb/handler/i_s.cc | 153 +++++++++++++++++++------------- 2 files changed, 180 insertions(+), 126 deletions(-) diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc index 5b471c8cd05..ed6133c172f 100644 --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2014, 2018, MariaDB Corporation. +Copyright (c) 2014, 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 @@ -8819,78 +8819,105 @@ i_s_innodb_mutexes_fill_table( DBUG_RETURN(0); } - mutex_enter(&mutex_list_mutex); + { + struct Locking + { + Locking() { mutex_enter(&mutex_list_mutex); } + ~Locking() { mutex_exit(&mutex_list_mutex); } + } locking; - for (mutex = UT_LIST_GET_FIRST(mutex_list); mutex != NULL; - mutex = UT_LIST_GET_NEXT(list, mutex)) { - if (mutex->count_os_wait == 0) { - continue; + for (mutex = UT_LIST_GET_FIRST(mutex_list); mutex != NULL; + mutex = UT_LIST_GET_NEXT(list, mutex)) { + if (mutex->count_os_wait == 0) { + continue; + } + + if (buf_pool_is_block_mutex(mutex)) { + block_mutex = mutex; + block_mutex_oswait_count + += mutex->count_os_wait; + continue; + } + + OK(field_store_string(fields[MUTEXES_NAME], + mutex->cmutex_name)); + OK(field_store_string( + fields[MUTEXES_CREATE_FILE], + innobase_basename(mutex->cfile_name))); + OK(field_store_ulint(fields[MUTEXES_CREATE_LINE], + mutex->cline)); + OK(field_store_ulint(fields[MUTEXES_OS_WAITS], + mutex->count_os_wait)); + OK(schema_table_store_record(thd, tables->table)); } - if (buf_pool_is_block_mutex(mutex)) { - block_mutex = mutex; - block_mutex_oswait_count += mutex->count_os_wait; - continue; + if (block_mutex) { + char buf1[IO_SIZE]; + + my_snprintf(buf1, sizeof buf1, "combined %s", + innobase_basename(block_mutex->cfile_name)); + + OK(field_store_string(fields[MUTEXES_NAME], + block_mutex->cmutex_name)); + OK(field_store_string(fields[MUTEXES_CREATE_FILE], + buf1)); + OK(field_store_ulint(fields[MUTEXES_CREATE_LINE], + block_mutex->cline)); + OK(field_store_ulint(fields[MUTEXES_OS_WAITS], + block_mutex_oswait_count)); + OK(schema_table_store_record(thd, tables->table)); + } + } + + { + struct Locking + { + Locking() { mutex_enter(&rw_lock_list_mutex); } + ~Locking() { mutex_exit(&rw_lock_list_mutex); } + } locking; + + for (lock = UT_LIST_GET_FIRST(rw_lock_list); lock != NULL; + lock = UT_LIST_GET_NEXT(list, lock)) { + if (lock->count_os_wait == 0) { + continue; + } + + if (buf_pool_is_block_lock(lock)) { + block_lock = lock; + block_lock_oswait_count += lock->count_os_wait; + continue; + } + + OK(field_store_string(fields[MUTEXES_NAME], + lock->lock_name)); + OK(field_store_string( + fields[MUTEXES_CREATE_FILE], + innobase_basename(lock->cfile_name))); + OK(field_store_ulint(fields[MUTEXES_CREATE_LINE], + lock->cline)); + OK(field_store_ulint(fields[MUTEXES_OS_WAITS], + lock->count_os_wait)); + OK(schema_table_store_record(thd, tables->table)); } - OK(field_store_string(fields[MUTEXES_NAME], mutex->cmutex_name)); - OK(field_store_string(fields[MUTEXES_CREATE_FILE], innobase_basename(mutex->cfile_name))); - OK(field_store_ulint(fields[MUTEXES_CREATE_LINE], mutex->cline)); - OK(field_store_ulint(fields[MUTEXES_OS_WAITS], (longlong)mutex->count_os_wait)); - OK(schema_table_store_record(thd, tables->table)); - } + if (block_lock) { + char buf1[IO_SIZE]; - if (block_mutex) { - char buf1[IO_SIZE]; + my_snprintf(buf1, sizeof buf1, "combined %s", + innobase_basename(block_lock->cfile_name)); - my_snprintf(buf1, sizeof buf1, "combined %s", - innobase_basename(block_mutex->cfile_name)); - - OK(field_store_string(fields[MUTEXES_NAME], block_mutex->cmutex_name)); - OK(field_store_string(fields[MUTEXES_CREATE_FILE], buf1)); - OK(field_store_ulint(fields[MUTEXES_CREATE_LINE], block_mutex->cline)); - OK(field_store_ulint(fields[MUTEXES_OS_WAITS], (longlong)block_mutex_oswait_count)); - OK(schema_table_store_record(thd, tables->table)); - } - - mutex_exit(&mutex_list_mutex); - - mutex_enter(&rw_lock_list_mutex); - - for (lock = UT_LIST_GET_FIRST(rw_lock_list); lock != NULL; - lock = UT_LIST_GET_NEXT(list, lock)) { - if (lock->count_os_wait == 0) { - continue; + OK(field_store_string(fields[MUTEXES_NAME], + block_lock->lock_name)); + OK(field_store_string(fields[MUTEXES_CREATE_FILE], + buf1)); + OK(field_store_ulint(fields[MUTEXES_CREATE_LINE], + block_lock->cline)); + OK(field_store_ulint(fields[MUTEXES_OS_WAITS], + block_lock_oswait_count)); + OK(schema_table_store_record(thd, tables->table)); } - - if (buf_pool_is_block_lock(lock)) { - block_lock = lock; - block_lock_oswait_count += lock->count_os_wait; - continue; - } - - OK(field_store_string(fields[MUTEXES_NAME], lock->lock_name)); - OK(field_store_string(fields[MUTEXES_CREATE_FILE], innobase_basename(lock->cfile_name))); - OK(field_store_ulint(fields[MUTEXES_CREATE_LINE], lock->cline)); - OK(field_store_ulint(fields[MUTEXES_OS_WAITS], (longlong)lock->count_os_wait)); - OK(schema_table_store_record(thd, tables->table)); } - if (block_lock) { - char buf1[IO_SIZE]; - - my_snprintf(buf1, sizeof buf1, "combined %s", - innobase_basename(block_lock->cfile_name)); - - OK(field_store_string(fields[MUTEXES_NAME], block_lock->lock_name)); - OK(field_store_string(fields[MUTEXES_CREATE_FILE], buf1)); - OK(field_store_ulint(fields[MUTEXES_CREATE_LINE], block_lock->cline)); - OK(field_store_ulint(fields[MUTEXES_OS_WAITS], (longlong)block_lock_oswait_count)); - OK(schema_table_store_record(thd, tables->table)); - } - - mutex_exit(&rw_lock_list_mutex); - DBUG_RETURN(0); } diff --git a/storage/xtradb/handler/i_s.cc b/storage/xtradb/handler/i_s.cc index 201d2ad13a5..5c2d65e5799 100644 --- a/storage/xtradb/handler/i_s.cc +++ b/storage/xtradb/handler/i_s.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2014, 2018, MariaDB Corporation. +Copyright (c) 2014, 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 @@ -9120,78 +9120,105 @@ i_s_innodb_mutexes_fill_table( DBUG_RETURN(0); } - mutex_enter(&mutex_list_mutex); + { + struct Locking + { + Locking() { mutex_enter(&mutex_list_mutex); } + ~Locking() { mutex_exit(&mutex_list_mutex); } + } locking; - for (mutex = UT_LIST_GET_FIRST(mutex_list); mutex != NULL; - mutex = UT_LIST_GET_NEXT(list, mutex)) { - if (mutex->count_os_wait == 0) { - continue; + for (mutex = UT_LIST_GET_FIRST(mutex_list); mutex != NULL; + mutex = UT_LIST_GET_NEXT(list, mutex)) { + if (mutex->count_os_wait == 0) { + continue; + } + + if (buf_pool_is_block_mutex(mutex)) { + block_mutex = mutex; + block_mutex_oswait_count + += mutex->count_os_wait; + continue; + } + + OK(field_store_string(fields[MUTEXES_NAME], + mutex->cmutex_name)); + OK(field_store_string( + fields[MUTEXES_CREATE_FILE], + innobase_basename(mutex->cfile_name))); + OK(field_store_ulint(fields[MUTEXES_CREATE_LINE], + mutex->cline)); + OK(field_store_ulint(fields[MUTEXES_OS_WAITS], + mutex->count_os_wait)); + OK(schema_table_store_record(thd, tables->table)); } - if (buf_pool_is_block_mutex(mutex)) { - block_mutex = mutex; - block_mutex_oswait_count += mutex->count_os_wait; - continue; + if (block_mutex) { + char buf1[IO_SIZE]; + + my_snprintf(buf1, sizeof buf1, "combined %s", + innobase_basename(block_mutex->cfile_name)); + + OK(field_store_string(fields[MUTEXES_NAME], + block_mutex->cmutex_name)); + OK(field_store_string(fields[MUTEXES_CREATE_FILE], + buf1)); + OK(field_store_ulint(fields[MUTEXES_CREATE_LINE], + block_mutex->cline)); + OK(field_store_ulint(fields[MUTEXES_OS_WAITS], + block_mutex_oswait_count)); + OK(schema_table_store_record(thd, tables->table)); + } + } + + { + struct Locking + { + Locking() { mutex_enter(&rw_lock_list_mutex); } + ~Locking() { mutex_exit(&rw_lock_list_mutex); } + } locking; + + for (lock = UT_LIST_GET_FIRST(rw_lock_list); lock != NULL; + lock = UT_LIST_GET_NEXT(list, lock)) { + if (lock->count_os_wait == 0) { + continue; + } + + if (buf_pool_is_block_lock(lock)) { + block_lock = lock; + block_lock_oswait_count += lock->count_os_wait; + continue; + } + + OK(field_store_string(fields[MUTEXES_NAME], + lock->lock_name)); + OK(field_store_string( + fields[MUTEXES_CREATE_FILE], + innobase_basename(lock->cfile_name))); + OK(field_store_ulint(fields[MUTEXES_CREATE_LINE], + lock->cline)); + OK(field_store_ulint(fields[MUTEXES_OS_WAITS], + lock->count_os_wait)); + OK(schema_table_store_record(thd, tables->table)); } - OK(field_store_string(fields[MUTEXES_NAME], mutex->cmutex_name)); - OK(field_store_string(fields[MUTEXES_CREATE_FILE], innobase_basename(mutex->cfile_name))); - OK(field_store_ulint(fields[MUTEXES_CREATE_LINE], mutex->cline)); - OK(field_store_ulint(fields[MUTEXES_OS_WAITS], (longlong)mutex->count_os_wait)); - OK(schema_table_store_record(thd, tables->table)); - } + if (block_lock) { + char buf1[IO_SIZE]; - if (block_mutex) { - char buf1[IO_SIZE]; + my_snprintf(buf1, sizeof buf1, "combined %s", + innobase_basename(block_lock->cfile_name)); - my_snprintf(buf1, sizeof buf1, "combined %s", - innobase_basename(block_mutex->cfile_name)); - - OK(field_store_string(fields[MUTEXES_NAME], block_mutex->cmutex_name)); - OK(field_store_string(fields[MUTEXES_CREATE_FILE], buf1)); - OK(field_store_ulint(fields[MUTEXES_CREATE_LINE], block_mutex->cline)); - OK(field_store_ulint(fields[MUTEXES_OS_WAITS], (longlong)block_mutex_oswait_count)); - OK(schema_table_store_record(thd, tables->table)); - } - - mutex_exit(&mutex_list_mutex); - - mutex_enter(&rw_lock_list_mutex); - - for (lock = UT_LIST_GET_FIRST(rw_lock_list); lock != NULL; - lock = UT_LIST_GET_NEXT(list, lock)) { - if (lock->count_os_wait == 0) { - continue; + OK(field_store_string(fields[MUTEXES_NAME], + block_lock->lock_name)); + OK(field_store_string(fields[MUTEXES_CREATE_FILE], + buf1)); + OK(field_store_ulint(fields[MUTEXES_CREATE_LINE], + block_lock->cline)); + OK(field_store_ulint(fields[MUTEXES_OS_WAITS], + block_lock_oswait_count)); + OK(schema_table_store_record(thd, tables->table)); } - - if (buf_pool_is_block_lock(lock)) { - block_lock = lock; - block_lock_oswait_count += lock->count_os_wait; - continue; - } - - OK(field_store_string(fields[MUTEXES_NAME], lock->lock_name)); - OK(field_store_string(fields[MUTEXES_CREATE_FILE], innobase_basename(lock->cfile_name))); - OK(field_store_ulint(fields[MUTEXES_CREATE_LINE], lock->cline)); - OK(field_store_ulint(fields[MUTEXES_OS_WAITS], (longlong)lock->count_os_wait)); - OK(schema_table_store_record(thd, tables->table)); } - if (block_lock) { - char buf1[IO_SIZE]; - - my_snprintf(buf1, sizeof buf1, "combined %s", - innobase_basename(block_lock->cfile_name)); - - OK(field_store_string(fields[MUTEXES_NAME], block_lock->lock_name)); - OK(field_store_string(fields[MUTEXES_CREATE_FILE], buf1)); - OK(field_store_ulint(fields[MUTEXES_CREATE_LINE], block_lock->cline)); - OK(field_store_ulint(fields[MUTEXES_OS_WAITS], (longlong)block_lock_oswait_count)); - OK(schema_table_store_record(thd, tables->table)); - } - - mutex_exit(&rw_lock_list_mutex); - DBUG_RETURN(0); } From a4c687c4944723a5dc531e6cff1aa3e6d60df821 Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Wed, 6 Feb 2019 16:53:16 +0400 Subject: [PATCH 083/106] the opt_constraint_no_id should not have the lex_str type. --- sql/sql_yacc.yy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 14d084e7022..133aad53fb1 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1741,7 +1741,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); IDENT_sys TEXT_STRING_sys TEXT_STRING_literal NCHAR_STRING opt_component key_cache_name sp_opt_label BIN_NUM label_ident TEXT_STRING_filesystem ident_or_empty - opt_constraint opt_constraint_no_id constraint opt_ident ident_table_alias + opt_constraint constraint opt_ident ident_table_alias %type opt_table_alias From 8f5ea83ff109827748d2f9f5025ed6c6bb91fd80 Mon Sep 17 00:00:00 2001 From: Julius Goryavsky Date: Wed, 6 Feb 2019 14:47:25 +0100 Subject: [PATCH 084/106] MDEV-18426: Most of the mtr tests in the galera_3nodes suite fail Most of the mtr tests in the galera_3nodes suite fail for a variety of reasons with a variety of errors. Some tests simply need to add the missing "connection" lines to the result files, but many of them fail due to substantial errors that require reworking test files. This patch adds the missing "connection" lines to the result files and fixes several substantial flaws in the galera_3nodes suite tests and in the mtr framework service files, adapting the tests from galera_3nodes for the current version of MariaDB. https://jira.mariadb.org/browse/MDEV-18426 --- .../galera => }/include/galera_resume.inc | 2 +- .../include/galera_suspend.inc | 2 +- mysql-test/include/mtr_check.sql | 1 + .../r/galera_evs_suspect_timeout.result | 6 ++++ .../suite/galera_3nodes/r/galera_garbd.result | 12 +++++++ .../r/galera_ist_gcache_rollover.result | 1 + .../r/galera_safe_to_bootstrap.result | 15 ++++++++- .../r/galera_var_dirty_reads2.result | 4 +++ .../t/galera_evs_suspect_timeout.test | 2 +- .../suite/galera_3nodes/t/galera_garbd.test | 20 ++++++++++-- .../t/galera_ist_gcache_rollover.cnf | 6 ++-- .../t/galera_ist_gcache_rollover.test | 1 + .../t/galera_safe_to_bootstrap.test | 32 ++++++++++++++++--- .../t/galera_var_dirty_reads2.test | 14 ++++++++ 14 files changed, 103 insertions(+), 15 deletions(-) rename mysql-test/{suite/galera => }/include/galera_resume.inc (80%) rename mysql-test/{suite/galera_3nodes => }/include/galera_suspend.inc (86%) diff --git a/mysql-test/suite/galera/include/galera_resume.inc b/mysql-test/include/galera_resume.inc similarity index 80% rename from mysql-test/suite/galera/include/galera_resume.inc rename to mysql-test/include/galera_resume.inc index 232cb46479e..af8f2b956fd 100644 --- a/mysql-test/suite/galera/include/galera_resume.inc +++ b/mysql-test/include/galera_resume.inc @@ -3,7 +3,7 @@ my $pid_filename = $ENV{'_SUSPEND_NODE_PIDFILE'}; my $mysqld_pid = `cat $pid_filename`; chomp($mysqld_pid); - system("kill -18 $mysqld_pid"); + system("kill -SIGCONT $mysqld_pid"); exit(0); EOF diff --git a/mysql-test/suite/galera_3nodes/include/galera_suspend.inc b/mysql-test/include/galera_suspend.inc similarity index 86% rename from mysql-test/suite/galera_3nodes/include/galera_suspend.inc rename to mysql-test/include/galera_suspend.inc index 3495ad2342b..d4037d8958c 100644 --- a/mysql-test/suite/galera_3nodes/include/galera_suspend.inc +++ b/mysql-test/include/galera_suspend.inc @@ -9,6 +9,6 @@ my $pid_filename = $ENV{'_SUSPEND_NODE_PIDFILE'}; my $mysqld_pid = `cat $pid_filename`; chomp($mysqld_pid); - system("kill -19 $mysqld_pid"); + system("kill -SIGSTOP $mysqld_pid"); exit(0); EOF diff --git a/mysql-test/include/mtr_check.sql b/mysql-test/include/mtr_check.sql index d47e7d322b5..067df841ce4 100644 --- a/mysql-test/include/mtr_check.sql +++ b/mysql-test/include/mtr_check.sql @@ -35,6 +35,7 @@ BEGIN AND variable_name != 'INNODB_BUFFER_POOL_LOAD_AT_STARTUP' AND variable_name not like 'GTID%POS' AND variable_name != 'GTID_BINLOG_STATE' + AND variable_name != 'AUTO_INCREMENT_INCREMENT' ORDER BY variable_name; -- Dump all databases, there should be none diff --git a/mysql-test/suite/galera_3nodes/r/galera_evs_suspect_timeout.result b/mysql-test/suite/galera_3nodes/r/galera_evs_suspect_timeout.result index 7e0d282ec7f..6a7eea94077 100644 --- a/mysql-test/suite/galera_3nodes/r/galera_evs_suspect_timeout.result +++ b/mysql-test/suite/galera_3nodes/r/galera_evs_suspect_timeout.result @@ -1,12 +1,17 @@ +connection node_1; SET GLOBAL wsrep_provider_options = 'evs.inactive_timeout=PT100M; evs.suspect_timeout=PT1S'; +connection node_2; SET GLOBAL wsrep_provider_options = 'evs.inactive_timeout=PT100M; evs.suspect_timeout=PT1S'; +connection node_3; Suspending node ... +connection node_1; SET SESSION wsrep_sync_wait = 0; SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; VARIABLE_VALUE = 2 1 CREATE TABLE t1 (f1 INTEGER); INSERT INTO t1 VALUES (1); +connection node_2; SET SESSION wsrep_sync_wait = 0; SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; VARIABLE_VALUE = 2 @@ -17,4 +22,5 @@ COUNT(*) = 1 1 DROP TABLE t1; Resuming node ... +connection node_3; CALL mtr.add_suppression("WSREP: gcs_caused() returned -1 \\(Operation not permitted\\)"); diff --git a/mysql-test/suite/galera_3nodes/r/galera_garbd.result b/mysql-test/suite/galera_3nodes/r/galera_garbd.result index 180aade029c..fb7e729dc77 100644 --- a/mysql-test/suite/galera_3nodes/r/galera_garbd.result +++ b/mysql-test/suite/galera_3nodes/r/galera_garbd.result @@ -1,17 +1,29 @@ +connection node_1; +connection node_2; +connection node_3; Killing node #3 to free ports for garbd ... +connection node_3; +connection node_1; Starting garbd ... CREATE TABLE t1 (f1 INTEGER); INSERT INTO t1 VALUES (1); +connection node_2; SELECT COUNT(*) = 1 FROM t1; COUNT(*) = 1 1 Killing garbd ... +connection node_1; INSERT INTO t1 VALUES (2); +connection node_2; SELECT COUNT(*) = 2 FROM t1; COUNT(*) = 2 1 DROP TABLE t1; Restarting node #3 to satisfy MTR's end-of-test checks +connection node_3; +connection node_1; CALL mtr.add_suppression("WSREP: Protocol violation\. JOIN message sender 1\.0 \(.*\) is not in state transfer \(SYNCED\)"); +connection node_2; CALL mtr.add_suppression("WSREP: Protocol violation\. JOIN message sender 1\.0 \(.*\) is not in state transfer \(SYNCED\)"); +connection node_3; CALL mtr.add_suppression("WSREP: Protocol violation\. JOIN message sender 1\.0 \(.*\) is not in state transfer \(SYNCED\)"); diff --git a/mysql-test/suite/galera_3nodes/r/galera_ist_gcache_rollover.result b/mysql-test/suite/galera_3nodes/r/galera_ist_gcache_rollover.result index 3d4dbcc00b0..aa3e349eda7 100644 --- a/mysql-test/suite/galera_3nodes/r/galera_ist_gcache_rollover.result +++ b/mysql-test/suite/galera_3nodes/r/galera_ist_gcache_rollover.result @@ -1,6 +1,7 @@ connection node_1; connection node_2; connection node_3; +connection node_1; CREATE TABLE t1 (f1 INTEGER PRIMARY KEY); INSERT INTO t1 VALUES (01), (02), (03), (04), (05); connection node_2; diff --git a/mysql-test/suite/galera_3nodes/r/galera_safe_to_bootstrap.result b/mysql-test/suite/galera_3nodes/r/galera_safe_to_bootstrap.result index 1676ef9b07b..45b4d63fb4f 100644 --- a/mysql-test/suite/galera_3nodes/r/galera_safe_to_bootstrap.result +++ b/mysql-test/suite/galera_3nodes/r/galera_safe_to_bootstrap.result @@ -1,3 +1,7 @@ +connection node_1; +connection node_2; +connection node_3; +connection node_1; CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; include/assert_grep.inc [grastate.dat does not have 'safe_to_bootstrap: 0'] include/assert_grep.inc [grastate.dat does not have 'safe_to_bootstrap: 0'] @@ -7,7 +11,6 @@ connection node_1; include/assert_grep.inc [grastate.dat does not have 'safe_to_bootstrap: 0'] include/assert_grep.inc [grastate.dat does not have 'safe_to_bootstrap: 0'] include/assert_grep.inc [grastate.dat does not have 'safe_to_bootstrap: 0'] -connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3; connection node_3; connection node_1; include/assert_grep.inc [grastate.dat does not have 'safe_to_bootstrap: 0'] @@ -29,8 +32,18 @@ connection node_1; connection node_2; connection node_3; connection node_2; +CALL mtr.add_suppression("WSREP: no nodes coming from prim view, prim not possible"); +CALL mtr.add_suppression("WSREP: It may not be safe to bootstrap the cluster from this node"); +CALL mtr.add_suppression("WSREP: wsrep::connect(.*) failed: 7"); +CALL mtr.add_suppression("Aborting"); +CALL mtr.add_suppression("WSREP: moving position backwards: [0-9]+ -> 0"); CALL mtr.add_suppression("Failed to prepare for incremental state transfer"); connection node_3; +CALL mtr.add_suppression("WSREP: no nodes coming from prim view, prim not possible"); +CALL mtr.add_suppression("WSREP: It may not be safe to bootstrap the cluster from this node"); +CALL mtr.add_suppression("WSREP: wsrep::connect(.*) failed: 7"); +CALL mtr.add_suppression("Aborting"); +CALL mtr.add_suppression("WSREP: moving position backwards: [0-9]+ -> 0"); CALL mtr.add_suppression("Failed to prepare for incremental state transfer"); SHOW CREATE TABLE t1; Table Create Table diff --git a/mysql-test/suite/galera_3nodes/r/galera_var_dirty_reads2.result b/mysql-test/suite/galera_3nodes/r/galera_var_dirty_reads2.result index c6756bce210..77991a6d468 100644 --- a/mysql-test/suite/galera_3nodes/r/galera_var_dirty_reads2.result +++ b/mysql-test/suite/galera_3nodes/r/galera_var_dirty_reads2.result @@ -1,3 +1,7 @@ +connection node_1; +connection node_2; +connection node_3; +connection node_1; CREATE TABLE t1 (f1 INTEGER); INSERT INTO t1 VALUES (1); connection node_2; diff --git a/mysql-test/suite/galera_3nodes/t/galera_evs_suspect_timeout.test b/mysql-test/suite/galera_3nodes/t/galera_evs_suspect_timeout.test index 03236a3cb93..4dab936c343 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_evs_suspect_timeout.test +++ b/mysql-test/suite/galera_3nodes/t/galera_evs_suspect_timeout.test @@ -56,8 +56,8 @@ DROP TABLE t1; # Reconnect node #3 so that MTR's end-of-test checks can run ---connection node_3 --source include/galera_resume.inc +--connection node_3 --source include/wait_until_connected_again.inc CALL mtr.add_suppression("WSREP: gcs_caused() returned -1 \\(Operation not permitted\\)"); diff --git a/mysql-test/suite/galera_3nodes/t/galera_garbd.test b/mysql-test/suite/galera_3nodes/t/galera_garbd.test index a68ba8ce15b..2d03e8897b9 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_garbd.test +++ b/mysql-test/suite/galera_3nodes/t/galera_garbd.test @@ -7,10 +7,20 @@ --source include/have_innodb.inc --source include/big_test.inc ---echo Killing node #3 to free ports for garbd ... --let $galera_connection_name = node_3 --let $galera_server_number = 3 --source include/galera_connect.inc + +# Save original auto_increment_offset values. +--let $node_1=node_1 +--let $node_2=node_2 +--let $node_3=node_3 +--source ../galera/include/auto_increment_offset_save.inc + +--echo Killing node #3 to free ports for garbd ... +--connection node_3 +--let $gp3 = `SELECT SUBSTR(@@wsrep_provider_options, LOCATE('base_port =', @@wsrep_provider_options) + LENGTH('base_port = '))` +--let $galera_port_3 = `SELECT SUBSTR('$gp3', 1, LOCATE(';', '$gp3') - 1)` --source include/shutdown_mysqld.inc --connection node_1 @@ -18,7 +28,9 @@ --source include/wait_condition.inc --echo Starting garbd ... ---exec `dirname $WSREP_PROVIDER`/garb/garbd --address "gcomm://127.0.0.1:$NODE_GALERAPORT_1" --group my_wsrep_cluster --options 'base_port=$NODE_GALERAPORT_3' > $MYSQL_TMP_DIR/garbd.log 2>&1 & +--let $gp1 = `SELECT SUBSTR(@@wsrep_provider_options, LOCATE('base_port =', @@wsrep_provider_options) + LENGTH('base_port = '))` +--let $galera_port_1 = `SELECT SUBSTR('$gp1', 1, LOCATE(';', '$gp1') - 1)` +--exec `dirname $WSREP_PROVIDER`/../../bin/garb/garbd --address "gcomm://127.0.0.1:$galera_port_1" --group my_wsrep_cluster --options 'base_port=$galera_port_3' > $MYSQL_TMP_DIR/garbd.log 2>&1 & --sleep 5 @@ -32,7 +44,7 @@ INSERT INTO t1 VALUES (1); SELECT COUNT(*) = 1 FROM t1; --echo Killing garbd ... ---exec pkill --oldest --full garbd.*$NODE_GALERAPORT_3 +--exec pkill --oldest --full garbd.*$galera_port_3 --sleep 5 @@ -51,6 +63,8 @@ DROP TABLE t1; --connection node_3 --source include/start_mysqld.inc +# Restore original auto_increment_offset values. +--source ../galera/include/auto_increment_offset_restore.inc # Workaround for galera#101 diff --git a/mysql-test/suite/galera_3nodes/t/galera_ist_gcache_rollover.cnf b/mysql-test/suite/galera_3nodes/t/galera_ist_gcache_rollover.cnf index 821175220ac..303087dffbb 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_ist_gcache_rollover.cnf +++ b/mysql-test/suite/galera_3nodes/t/galera_ist_gcache_rollover.cnf @@ -1,11 +1,11 @@ !include ../galera_3nodes.cnf [mysqld.1] -wsrep_provider_options='base_port=@mysqld.1.#galera_port;pc.ignore_sb=true;gcache.size=1M' +wsrep_provider_options='repl.causal_read_timeout=PT90S;base_port=@mysqld.1.#galera_port;evs.suspect_timeout=PT10S;evs.inactive_timeout=PT30S;evs.install_timeout=PT15S;pc.ignore_sb=true;gcache.size=1M' [mysqld.2] -wsrep_provider_options='base_port=@mysqld.2.#galera_port;pc.ignore_sb=true;gcache.size=1M' +wsrep_provider_options='repl.causal_read_timeout=PT90S;base_port=@mysqld.2.#galera_port;evs.suspect_timeout=PT10S;evs.inactive_timeout=PT30S;evs.install_timeout=PT15S;pc.ignore_sb=true;gcache.size=1M' [mysqld.3] -wsrep_provider_options='base_port=@mysqld.3.#galera_port;pc.ignore_sb=true;gcache.size=1M' +wsrep_provider_options='repl.causal_read_timeout=PT90S;base_port=@mysqld.3.#galera_port;evs.suspect_timeout=PT10S;evs.inactive_timeout=PT30S;evs.install_timeout=PT15S;pc.ignore_sb=true;gcache.size=1M' diff --git a/mysql-test/suite/galera_3nodes/t/galera_ist_gcache_rollover.test b/mysql-test/suite/galera_3nodes/t/galera_ist_gcache_rollover.test index a67b30e3fa1..ebc756d60b1 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_ist_gcache_rollover.test +++ b/mysql-test/suite/galera_3nodes/t/galera_ist_gcache_rollover.test @@ -23,6 +23,7 @@ --let $node_3=node_3 --source ../galera/include/auto_increment_offset_save.inc +--connection node_1 CREATE TABLE t1 (f1 INTEGER PRIMARY KEY); INSERT INTO t1 VALUES (01), (02), (03), (04), (05); diff --git a/mysql-test/suite/galera_3nodes/t/galera_safe_to_bootstrap.test b/mysql-test/suite/galera_3nodes/t/galera_safe_to_bootstrap.test index 88d0cfba4f4..b7b6c66e5ad 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_safe_to_bootstrap.test +++ b/mysql-test/suite/galera_3nodes/t/galera_safe_to_bootstrap.test @@ -1,8 +1,19 @@ # # Test the safe_to_bootstrap in grastate.dat # - --source include/galera_cluster.inc + +--let $galera_connection_name = node_3 +--let $galera_server_number = 3 +--source include/galera_connect.inc + +# Save original auto_increment_offset values. +--let $node_1=node_1 +--let $node_2=node_2 +--let $node_3=node_3 +--source ../galera/include/auto_increment_offset_save.inc + +--connection node_1 CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; # @@ -47,8 +58,6 @@ CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; # # Shut down one more node # - ---connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3 --connection node_3 --source include/shutdown_mysqld.inc @@ -129,9 +138,9 @@ SET SESSION wsrep_on = OFF; # --error 1 ---exec $MYSQLD --defaults-group-suffix=.2 --defaults-file=$MYSQLTEST_VARDIR/my.cnf --wsrep-new-cluster | grep 'This node is not safe to bootstrap the cluster' +--exec $MYSQLD --defaults-group-suffix=.2 --defaults-file=$MYSQLTEST_VARDIR/my.cnf --wsrep-new-cluster --wsrep-cluster-address='gcomm://' | grep 'This node is not safe to bootstrap the cluster' --error 1 ---exec $MYSQLD --defaults-group-suffix=.3 --defaults-file=$MYSQLTEST_VARDIR/my.cnf --wsrep-new-cluster | grep 'This node is not safe to bootstrap the cluster' +--exec $MYSQLD --defaults-group-suffix=.3 --defaults-file=$MYSQLTEST_VARDIR/my.cnf --wsrep-new-cluster --wsrep-cluster-address='gcomm://' | grep 'This node is not safe to bootstrap the cluster' # # Attempt to bootstrap starting from node #1, should succeed @@ -154,10 +163,23 @@ SET SESSION wsrep_on = OFF; --source include/wait_condition.inc --connection node_2 +CALL mtr.add_suppression("WSREP: no nodes coming from prim view, prim not possible"); +CALL mtr.add_suppression("WSREP: It may not be safe to bootstrap the cluster from this node"); +CALL mtr.add_suppression("WSREP: wsrep::connect(.*) failed: 7"); +CALL mtr.add_suppression("Aborting"); +CALL mtr.add_suppression("WSREP: moving position backwards: [0-9]+ -> 0"); CALL mtr.add_suppression("Failed to prepare for incremental state transfer"); --connection node_3 +CALL mtr.add_suppression("WSREP: no nodes coming from prim view, prim not possible"); +CALL mtr.add_suppression("WSREP: It may not be safe to bootstrap the cluster from this node"); +CALL mtr.add_suppression("WSREP: wsrep::connect(.*) failed: 7"); +CALL mtr.add_suppression("Aborting"); +CALL mtr.add_suppression("WSREP: moving position backwards: [0-9]+ -> 0"); CALL mtr.add_suppression("Failed to prepare for incremental state transfer"); SHOW CREATE TABLE t1; DROP TABLE t1; + +# Restore original auto_increment_offset values. +--source ../galera/include/auto_increment_offset_restore.inc diff --git a/mysql-test/suite/galera_3nodes/t/galera_var_dirty_reads2.test b/mysql-test/suite/galera_3nodes/t/galera_var_dirty_reads2.test index 129ba2e1f38..e3f94a012b8 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_var_dirty_reads2.test +++ b/mysql-test/suite/galera_3nodes/t/galera_var_dirty_reads2.test @@ -5,6 +5,17 @@ --source include/galera_cluster.inc --source include/have_innodb.inc +--let $galera_connection_name = node_3 +--let $galera_server_number = 3 +--source include/galera_connect.inc + +# Save original auto_increment_offset values. +--let $node_1=node_1 +--let $node_2=node_2 +--let $node_3=node_3 +--source ../galera/include/auto_increment_offset_save.inc + +--connection node_1 CREATE TABLE t1 (f1 INTEGER); INSERT INTO t1 VALUES (1); @@ -110,3 +121,6 @@ SET GLOBAL wsrep_provider_options='gmcast.isolate=0'; --source include/wait_condition.inc DROP TABLE t1; + +# Restore original auto_increment_offset values. +--source ../galera/include/auto_increment_offset_restore.inc From af3cbb51cef507e9f233a48a017d1237ee17cca6 Mon Sep 17 00:00:00 2001 From: Daniel Bartholomew Date: Wed, 6 Feb 2019 10:30:33 -0500 Subject: [PATCH 085/106] bump the VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index f95ab5017dc..a7dbe7dfb74 100644 --- a/VERSION +++ b/VERSION @@ -1,3 +1,3 @@ MYSQL_VERSION_MAJOR=10 MYSQL_VERSION_MINOR=1 -MYSQL_VERSION_PATCH=38 +MYSQL_VERSION_PATCH=39 From b3d571c398434c7be3b4a7ebb7a7d731f9ef10ad Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 6 Feb 2019 12:27:56 +0100 Subject: [PATCH 086/106] C/C 3.0.9 --- libmariadb | 2 +- mysql-test/r/mysql.result | 13 ++++++++++++- mysql-test/t/mysql.test | 17 ++++++++--------- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/libmariadb b/libmariadb index 34f8887af03..1e5e21cae95 160000 --- a/libmariadb +++ b/libmariadb @@ -1 +1 @@ -Subproject commit 34f8887af03d022416dd6593de91d0706e57f46b +Subproject commit 1e5e21cae9506db5ecd9da8f4406b32f01c11abc diff --git a/mysql-test/r/mysql.result b/mysql-test/r/mysql.result index 02ca052cfc8..07f49d32b2e 100644 --- a/mysql-test/r/mysql.result +++ b/mysql-test/r/mysql.result @@ -613,5 +613,16 @@ select count(*) from t1; count(*) 0 truncate table t1; -### FIXME: update libmariadb +select count(*) from t1; +count(*) +0 +truncate table t1; +select count(*) from t1; +count(*) +41 +truncate table t1; +select count(*) from t1; +count(*) +0 +truncate table t1; drop table t1; diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test index a90095d06f5..9178658dfbe 100644 --- a/mysql-test/t/mysql.test +++ b/mysql-test/t/mysql.test @@ -693,13 +693,12 @@ select count(*) from t1; truncate table t1; --error 1 --exec $MYSQL --disable-local-infile -e "$ldli" select count(*) from t1; truncate table t1; ---echo ### FIXME: update libmariadb -#--error 1 -#--exec $MYSQL -e "/*q*/$ldli" -#select count(*) from t1; truncate table t1; -#--exec $MYSQL --enable-local-infile -e "/*q*/$ldli" -#select count(*) from t1; truncate table t1; -# --error 1 -# --exec $MYSQL --disable-local-infile -e "/*q*/$ldli" -#select count(*) from t1; truncate table t1; +--error 1 +--exec $MYSQL -e "/*q*/$ldli" +select count(*) from t1; truncate table t1; +--exec $MYSQL --enable-local-infile -e "/*q*/$ldli" +select count(*) from t1; truncate table t1; + --error 1 + --exec $MYSQL --disable-local-infile -e "/*q*/$ldli" +select count(*) from t1; truncate table t1; drop table t1; From 540a1dda7b6ae7b2cbd9a315428e069058a2cc5f Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 7 Feb 2019 12:14:49 +0100 Subject: [PATCH 087/106] update C/C to get latest PS fixes --- libmariadb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmariadb b/libmariadb index 1e5e21cae95..5940917c506 160000 --- a/libmariadb +++ b/libmariadb @@ -1 +1 @@ -Subproject commit 1e5e21cae9506db5ecd9da8f4406b32f01c11abc +Subproject commit 5940917c5062257666c96675724b55f0300c4070 From fef9013d43b734ca062d7f9a2e1e320aa512d9d8 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 7 Feb 2019 18:47:23 +0100 Subject: [PATCH 088/106] update test result Followup for 8f5ea83ff10 --- mysql-test/suite/funcs_1/r/is_routines_embedded.result | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mysql-test/suite/funcs_1/r/is_routines_embedded.result b/mysql-test/suite/funcs_1/r/is_routines_embedded.result index 1fc9f90ae49..d415ea1da96 100644 --- a/mysql-test/suite/funcs_1/r/is_routines_embedded.result +++ b/mysql-test/suite/funcs_1/r/is_routines_embedded.result @@ -197,7 +197,7 @@ sp_6_408002_2 def db_datadict_2 sp_6_408002_2 PROCEDURE NULL NULL NULL NULL NUL SELECT * FROM db_datadict_2.res_6_408002_2; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost latin1 latin1_swedish_ci latin1_swedish_ci add_suppression def mtr add_suppression PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN INSERT INTO test_suppressions (pattern) VALUES (pattern); FLUSH NO_WRITE_TO_BINLOG TABLE test_suppressions; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8 utf8_general_ci latin1_swedish_ci -check_testcase def mtr check_testcase PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE variable_name NOT IN ('timestamp', 'innodb_file_format_max') AND variable_name not like "Last_IO_Err*" AND variable_name != 'INNODB_IBUF_MAX_SIZE' AND variable_name != 'INNODB_USE_NATIVE_AIO' AND variable_name != 'INNODB_BUFFER_POOL_LOAD_AT_STARTUP' AND variable_name not like 'GTID%POS' AND variable_name != 'GTID_BINLOG_STATE' ORDER BY variable_name; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('mtr_wsrep_notify', 'wsrep_schema'); SELECT table_name AS tables_in_test FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='test'; SELECT CONCAT(table_schema, '.', table_name) AS tables_in_mysql FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='mysql' ORDER BY tables_in_mysql; SELECT CONCAT(table_schema, '.', table_name) AS columns_in_mysql, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, character_set_name, collation_name, column_type, column_key, extra, column_comment FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='mysql' ORDER BY columns_in_mysql; SELECT * FROM INFORMATION_SCHEMA.EVENTS; SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME NOT IN ('gs_insert', 'ts_insert'); SELECT * FROM INFORMATION_SCHEMA.ROUTINES; SHOW STATUS LIKE 'slave_open_temp_tables'; checksum table mysql.columns_priv, mysql.db, mysql.func, mysql.help_category, mysql.help_keyword, mysql.help_relation, mysql.host, mysql.plugin, mysql.proc, mysql.procs_priv, mysql.roles_mapping, mysql.tables_priv, mysql.time_zone, mysql.time_zone_leap_second, mysql.time_zone_name, mysql.time_zone_transition, mysql.time_zone_transition_type, mysql.user; SELECT * FROM INFORMATION_SCHEMA.PLUGINS; select * from information_schema.session_variables where variable_name = 'debug_sync'; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8 utf8_general_ci latin1_swedish_ci +check_testcase def mtr check_testcase PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE variable_name NOT IN ('timestamp', 'innodb_file_format_max') AND variable_name not like "Last_IO_Err*" AND variable_name != 'INNODB_IBUF_MAX_SIZE' AND variable_name != 'INNODB_USE_NATIVE_AIO' AND variable_name != 'INNODB_BUFFER_POOL_LOAD_AT_STARTUP' AND variable_name not like 'GTID%POS' AND variable_name != 'GTID_BINLOG_STATE' AND variable_name != 'AUTO_INCREMENT_INCREMENT' ORDER BY variable_name; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('mtr_wsrep_notify', 'wsrep_schema'); SELECT table_name AS tables_in_test FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='test'; SELECT CONCAT(table_schema, '.', table_name) AS tables_in_mysql FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='mysql' ORDER BY tables_in_mysql; SELECT CONCAT(table_schema, '.', table_name) AS columns_in_mysql, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, character_set_name, collation_name, column_type, column_key, extra, column_comment FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='mysql' ORDER BY columns_in_mysql; SELECT * FROM INFORMATION_SCHEMA.EVENTS; SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME NOT IN ('gs_insert', 'ts_insert'); SELECT * FROM INFORMATION_SCHEMA.ROUTINES; SHOW STATUS LIKE 'slave_open_temp_tables'; checksum table mysql.columns_priv, mysql.db, mysql.func, mysql.help_category, mysql.help_keyword, mysql.help_relation, mysql.host, mysql.plugin, mysql.proc, mysql.procs_priv, mysql.roles_mapping, mysql.tables_priv, mysql.time_zone, mysql.time_zone_leap_second, mysql.time_zone_name, mysql.time_zone_transition, mysql.time_zone_transition_type, mysql.user; SELECT * FROM INFORMATION_SCHEMA.PLUGINS; select * from information_schema.session_variables where variable_name = 'debug_sync'; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8 utf8_general_ci latin1_swedish_ci check_warnings def mtr check_warnings PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN DECLARE `pos` bigint unsigned; SET SQL_LOG_BIN=0; UPDATE error_log el, global_suppressions gs SET suspicious=0 WHERE el.suspicious=1 AND el.line REGEXP gs.pattern; UPDATE error_log el, test_suppressions ts SET suspicious=0 WHERE el.suspicious=1 AND el.line REGEXP ts.pattern; SELECT COUNT(*) INTO @num_warnings FROM error_log WHERE suspicious=1; IF @num_warnings > 0 THEN SELECT line FROM error_log WHERE suspicious=1; SELECT 2 INTO result; ELSE SELECT 0 INTO RESULT; END IF; TRUNCATE test_suppressions; DROP TABLE error_log; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8 utf8_general_ci latin1_swedish_ci connect testuser2, localhost, testuser2, , db_datadict; SELECT * FROM information_schema.routines; @@ -209,7 +209,7 @@ sp_6_408002_2 def db_datadict_2 sp_6_408002_2 PROCEDURE NULL NULL NULL NULL NUL SELECT * FROM db_datadict_2.res_6_408002_2; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost latin1 latin1_swedish_ci latin1_swedish_ci add_suppression def mtr add_suppression PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN INSERT INTO test_suppressions (pattern) VALUES (pattern); FLUSH NO_WRITE_TO_BINLOG TABLE test_suppressions; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8 utf8_general_ci latin1_swedish_ci -check_testcase def mtr check_testcase PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE variable_name NOT IN ('timestamp', 'innodb_file_format_max') AND variable_name not like "Last_IO_Err*" AND variable_name != 'INNODB_IBUF_MAX_SIZE' AND variable_name != 'INNODB_USE_NATIVE_AIO' AND variable_name != 'INNODB_BUFFER_POOL_LOAD_AT_STARTUP' AND variable_name not like 'GTID%POS' AND variable_name != 'GTID_BINLOG_STATE' ORDER BY variable_name; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('mtr_wsrep_notify', 'wsrep_schema'); SELECT table_name AS tables_in_test FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='test'; SELECT CONCAT(table_schema, '.', table_name) AS tables_in_mysql FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='mysql' ORDER BY tables_in_mysql; SELECT CONCAT(table_schema, '.', table_name) AS columns_in_mysql, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, character_set_name, collation_name, column_type, column_key, extra, column_comment FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='mysql' ORDER BY columns_in_mysql; SELECT * FROM INFORMATION_SCHEMA.EVENTS; SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME NOT IN ('gs_insert', 'ts_insert'); SELECT * FROM INFORMATION_SCHEMA.ROUTINES; SHOW STATUS LIKE 'slave_open_temp_tables'; checksum table mysql.columns_priv, mysql.db, mysql.func, mysql.help_category, mysql.help_keyword, mysql.help_relation, mysql.host, mysql.plugin, mysql.proc, mysql.procs_priv, mysql.roles_mapping, mysql.tables_priv, mysql.time_zone, mysql.time_zone_leap_second, mysql.time_zone_name, mysql.time_zone_transition, mysql.time_zone_transition_type, mysql.user; SELECT * FROM INFORMATION_SCHEMA.PLUGINS; select * from information_schema.session_variables where variable_name = 'debug_sync'; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8 utf8_general_ci latin1_swedish_ci +check_testcase def mtr check_testcase PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE variable_name NOT IN ('timestamp', 'innodb_file_format_max') AND variable_name not like "Last_IO_Err*" AND variable_name != 'INNODB_IBUF_MAX_SIZE' AND variable_name != 'INNODB_USE_NATIVE_AIO' AND variable_name != 'INNODB_BUFFER_POOL_LOAD_AT_STARTUP' AND variable_name not like 'GTID%POS' AND variable_name != 'GTID_BINLOG_STATE' AND variable_name != 'AUTO_INCREMENT_INCREMENT' ORDER BY variable_name; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('mtr_wsrep_notify', 'wsrep_schema'); SELECT table_name AS tables_in_test FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='test'; SELECT CONCAT(table_schema, '.', table_name) AS tables_in_mysql FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='mysql' ORDER BY tables_in_mysql; SELECT CONCAT(table_schema, '.', table_name) AS columns_in_mysql, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, character_set_name, collation_name, column_type, column_key, extra, column_comment FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='mysql' ORDER BY columns_in_mysql; SELECT * FROM INFORMATION_SCHEMA.EVENTS; SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME NOT IN ('gs_insert', 'ts_insert'); SELECT * FROM INFORMATION_SCHEMA.ROUTINES; SHOW STATUS LIKE 'slave_open_temp_tables'; checksum table mysql.columns_priv, mysql.db, mysql.func, mysql.help_category, mysql.help_keyword, mysql.help_relation, mysql.host, mysql.plugin, mysql.proc, mysql.procs_priv, mysql.roles_mapping, mysql.tables_priv, mysql.time_zone, mysql.time_zone_leap_second, mysql.time_zone_name, mysql.time_zone_transition, mysql.time_zone_transition_type, mysql.user; SELECT * FROM INFORMATION_SCHEMA.PLUGINS; select * from information_schema.session_variables where variable_name = 'debug_sync'; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8 utf8_general_ci latin1_swedish_ci check_warnings def mtr check_warnings PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN DECLARE `pos` bigint unsigned; SET SQL_LOG_BIN=0; UPDATE error_log el, global_suppressions gs SET suspicious=0 WHERE el.suspicious=1 AND el.line REGEXP gs.pattern; UPDATE error_log el, test_suppressions ts SET suspicious=0 WHERE el.suspicious=1 AND el.line REGEXP ts.pattern; SELECT COUNT(*) INTO @num_warnings FROM error_log WHERE suspicious=1; IF @num_warnings > 0 THEN SELECT line FROM error_log WHERE suspicious=1; SELECT 2 INTO result; ELSE SELECT 0 INTO RESULT; END IF; TRUNCATE test_suppressions; DROP TABLE error_log; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8 utf8_general_ci latin1_swedish_ci connect testuser3, localhost, testuser3, , test; SELECT * FROM information_schema.routines; @@ -221,7 +221,7 @@ sp_6_408002_2 def db_datadict_2 sp_6_408002_2 PROCEDURE NULL NULL NULL NULL NUL SELECT * FROM db_datadict_2.res_6_408002_2; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost latin1 latin1_swedish_ci latin1_swedish_ci add_suppression def mtr add_suppression PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN INSERT INTO test_suppressions (pattern) VALUES (pattern); FLUSH NO_WRITE_TO_BINLOG TABLE test_suppressions; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8 utf8_general_ci latin1_swedish_ci -check_testcase def mtr check_testcase PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE variable_name NOT IN ('timestamp', 'innodb_file_format_max') AND variable_name not like "Last_IO_Err*" AND variable_name != 'INNODB_IBUF_MAX_SIZE' AND variable_name != 'INNODB_USE_NATIVE_AIO' AND variable_name != 'INNODB_BUFFER_POOL_LOAD_AT_STARTUP' AND variable_name not like 'GTID%POS' AND variable_name != 'GTID_BINLOG_STATE' ORDER BY variable_name; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('mtr_wsrep_notify', 'wsrep_schema'); SELECT table_name AS tables_in_test FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='test'; SELECT CONCAT(table_schema, '.', table_name) AS tables_in_mysql FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='mysql' ORDER BY tables_in_mysql; SELECT CONCAT(table_schema, '.', table_name) AS columns_in_mysql, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, character_set_name, collation_name, column_type, column_key, extra, column_comment FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='mysql' ORDER BY columns_in_mysql; SELECT * FROM INFORMATION_SCHEMA.EVENTS; SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME NOT IN ('gs_insert', 'ts_insert'); SELECT * FROM INFORMATION_SCHEMA.ROUTINES; SHOW STATUS LIKE 'slave_open_temp_tables'; checksum table mysql.columns_priv, mysql.db, mysql.func, mysql.help_category, mysql.help_keyword, mysql.help_relation, mysql.host, mysql.plugin, mysql.proc, mysql.procs_priv, mysql.roles_mapping, mysql.tables_priv, mysql.time_zone, mysql.time_zone_leap_second, mysql.time_zone_name, mysql.time_zone_transition, mysql.time_zone_transition_type, mysql.user; SELECT * FROM INFORMATION_SCHEMA.PLUGINS; select * from information_schema.session_variables where variable_name = 'debug_sync'; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8 utf8_general_ci latin1_swedish_ci +check_testcase def mtr check_testcase PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE variable_name NOT IN ('timestamp', 'innodb_file_format_max') AND variable_name not like "Last_IO_Err*" AND variable_name != 'INNODB_IBUF_MAX_SIZE' AND variable_name != 'INNODB_USE_NATIVE_AIO' AND variable_name != 'INNODB_BUFFER_POOL_LOAD_AT_STARTUP' AND variable_name not like 'GTID%POS' AND variable_name != 'GTID_BINLOG_STATE' AND variable_name != 'AUTO_INCREMENT_INCREMENT' ORDER BY variable_name; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('mtr_wsrep_notify', 'wsrep_schema'); SELECT table_name AS tables_in_test FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='test'; SELECT CONCAT(table_schema, '.', table_name) AS tables_in_mysql FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='mysql' ORDER BY tables_in_mysql; SELECT CONCAT(table_schema, '.', table_name) AS columns_in_mysql, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, character_set_name, collation_name, column_type, column_key, extra, column_comment FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='mysql' ORDER BY columns_in_mysql; SELECT * FROM INFORMATION_SCHEMA.EVENTS; SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME NOT IN ('gs_insert', 'ts_insert'); SELECT * FROM INFORMATION_SCHEMA.ROUTINES; SHOW STATUS LIKE 'slave_open_temp_tables'; checksum table mysql.columns_priv, mysql.db, mysql.func, mysql.help_category, mysql.help_keyword, mysql.help_relation, mysql.host, mysql.plugin, mysql.proc, mysql.procs_priv, mysql.roles_mapping, mysql.tables_priv, mysql.time_zone, mysql.time_zone_leap_second, mysql.time_zone_name, mysql.time_zone_transition, mysql.time_zone_transition_type, mysql.user; SELECT * FROM INFORMATION_SCHEMA.PLUGINS; select * from information_schema.session_variables where variable_name = 'debug_sync'; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8 utf8_general_ci latin1_swedish_ci check_warnings def mtr check_warnings PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN DECLARE `pos` bigint unsigned; SET SQL_LOG_BIN=0; UPDATE error_log el, global_suppressions gs SET suspicious=0 WHERE el.suspicious=1 AND el.line REGEXP gs.pattern; UPDATE error_log el, test_suppressions ts SET suspicious=0 WHERE el.suspicious=1 AND el.line REGEXP ts.pattern; SELECT COUNT(*) INTO @num_warnings FROM error_log WHERE suspicious=1; IF @num_warnings > 0 THEN SELECT line FROM error_log WHERE suspicious=1; SELECT 2 INTO result; ELSE SELECT 0 INTO RESULT; END IF; TRUNCATE test_suppressions; DROP TABLE error_log; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8 utf8_general_ci latin1_swedish_ci connection default; disconnect testuser1; From 65f22b8fd44c08ea190ed473b7e12b666b1fe60d Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 7 Feb 2019 19:39:23 +0100 Subject: [PATCH 089/106] C/C again --- libmariadb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmariadb b/libmariadb index 5940917c506..7923e8dadd3 160000 --- a/libmariadb +++ b/libmariadb @@ -1 +1 @@ -Subproject commit 5940917c5062257666c96675724b55f0300c4070 +Subproject commit 7923e8dadd3482ee439e8c5618d6bd1735921634 From 0216f87d3819c357330525d7985743350e5f9824 Mon Sep 17 00:00:00 2001 From: Elena Stepanova Date: Fri, 8 Feb 2019 01:07:19 +0200 Subject: [PATCH 090/106] Updated list of unstable tests for 10.2.22 --- mysql-test/unstable-tests | 210 ++++++++++++++++++-------------------- 1 file changed, 100 insertions(+), 110 deletions(-) diff --git a/mysql-test/unstable-tests b/mysql-test/unstable-tests index 59a287547d4..798294d7db1 100644 --- a/mysql-test/unstable-tests +++ b/mysql-test/unstable-tests @@ -23,83 +23,81 @@ # ############################################################################## -# Based on 10.2 2cf30866d7482d83b398e103b444b00661c306c7 +# Based on 10.2 65f22b8fd44c08ea190ed473b7e12b666b1fe60d -main.alter_table : Modified in 10.2.19 -main.alter_table_errors : Modified in 10.2.20 +main.alter_table : Modified in 10.2.22 +main.alter_table_errors : Modified in 10.2.22 main.alter_table_trans : MDEV-12084 - timeout main.analyze_stmt_slow_query_log : MDEV-12237 - Wrong result main.auth_named_pipe : MDEV-14724 - System error 2 -main.auto_increment_ranges_innodb : Modified in 10.2.19 main.bigint : Modified in 10.2.20 -main.check : Modified in 10.2.20 -main.connect : MDEV-17282 - Wrong result; modified in 10.2.20 +main.check : Modified in 10.2.22 +main.check_constraint : Modified in 10.2.22 +main.check_constraint_innodb : Modified in 10.2.22 +main.connect : MDEV-17282 - Wrong result; modified in 10.2.22 main.connect2 : MDEV-13885 - Server crash main.count_distinct2 : MDEV-11768 - timeout main.create_delayed : MDEV-10605 - failed with timeout main.create_drop_event : MDEV-16271 - Wrong result -main.create_or_replace : Modified in 10.2.19 -main.cte_nonrecursive : Modified in 10.2.19 main.cte_recursive : Modified in 10.2.20 -main.ctype_latin1 : Modified in 10.2.19 -main.ctype_uca : Modified in 10.2.19 main.ctype_ucs : MDEV-17681 - Data too long for column main.ctype_upgrade : MDEV-16945 - Error upon mysql_upgrade main.ctype_utf16 : MDEV-10675: timeout or extra warnings main.debug_sync : MDEV-10607 - internal error -main.derived_cond_pushdown : Modified in 10.2.19 -main.derived_opt : MDEV-11768 - timeout; modified in 10.2.19 -main.distinct : MDEV-14194 - Crash; modified in 10.2.19 +main.derived_opt : MDEV-11768 - timeout +main.distinct : MDEV-14194 - Crash main.drop_bad_db_type : MDEV-15676 - Wrong result +main.error_simulation : Modified in 10.2.22 main.events_2 : MDEV-13277 - Crash main.events_bugs : MDEV-12892 - Crash main.events_restart : MDEV-12236 - Server shutdown problem main.events_slowlog : MDEV-12821 - Wrong result -main.flush : Modified in 10.2.19 -main.func_concat : Modified in 10.2.19 main.func_default : Modified in 10.2.20 -main.func_json : Modified in 10.2.19 +main.func_group_innodb : Modified in 10.2.22 +main.func_misc : Modified in 10.2.22 main.func_time : Modified in 10.2.20 -main.gis : MDEV-13411 - wrong result on P8 +main.gis : MDEV-13411 - wrong result on P8; modified in 10.2.22 main.grant5 : Modified in 10.2.20 -main.group_by : Modified in 10.2.19 main.host_cache_size_functionality : MDEV-10606 - sporadic failure on shutdown +main.huge_frm-6224 : Modified in 10.2.22 main.index_intersect_innodb : MDEV-10643 - failed with timeout main.index_merge_innodb : MDEV-7142 - Plan mismatch -main.index_merge_myisam : Modified in 10.2.19 main.information_schema : Modified in 10.2.20 +main.information_schema-big : Modified in 10.2.22 main.innodb_mysql_lock : MDEV-7861 - Wrong result main.kill-2 : MDEV-13257 - Wrong result main.kill_processlist-6619 : MDEV-10793 - Wrong result -main.lock : Modified in 10.2.19 -main.lock_multi : Modified in 10.2.19 main.log_slow : MDEV-13263 - Wrong result main.log_tables-big : MDEV-13408 - wrong result -main.lowercase_fs_off : Modified in 10.2.19 +main.lowercase_table : Modified in 10.2.22 main.mdev-504 : MDEV-15171 - warning main.mdev375 : MDEV-10607 - sporadic "can't connect" main.merge : MDEV-10607 - sporadic "can't connect" +main.mysql : Modified in 10.2.22 main.mysql_client_test_comp : MDEV-16641 - Error in exec main.mysql_client_test_nonblock : CONC-208 - Error on Power; MDEV-15096 - exec failed main.mysql_upgrade_noengine : MDEV-14355 - Wrong result main.mysql_upgrade_ssl : MDEV-13492 - Unknown SSL error -main.mysqldump : MDEV-14800 - Stack smashing detected -main.mysqld_option_err : MDEV-12747 - Timeout +main.mysqlbinlog_row_minimal : Modified in 10.2.22 +main.mysqld_option_err : Modified in 10.2.22 +main.mysqldump : MDEV-14800 - Stack smashing detected; modified in 10.2.22 main.mysqlhotcopy_myisam : MDEV-10995 - Hang on debug main.mysqlslap : MDEV-11801 - timeout main.mysqltest : MDEV-9269 - fails on Alpha; MDEV-13887 - Wrong result -main.openssl_1 : MDEV-13492 - Unknown SSL error +main.openssl_1 : MDEV-13492 - Unknown SSL error; modified in 10.2.22 main.openssl_6975 : MDEV-17184 - Failures with OpenSSL 1.1.1 main.order_by_optimizer_innodb : MDEV-10683 - Wrong result -main.order_by_zerolength-4285 : Modified in 10.2.19 main.partition : Modified in 10.2.20 main.partition_alter : Modified in 10.2.20 main.partition_debug_sync : MDEV-15669 - Deadlock found when trying to get lock -main.partition_explicit_prune : Modified in 10.2.19 main.partition_innodb : Modified in 10.2.20 main.partition_innodb_plugin : MDEV-12901 - Valgrind warnings main.ps : MDEV-11017 - Wrong result main.ps_error : Added in 10.2.20 +main.range_innodb : Modified in 10.2.22 +main.read_only : Modified in 10.2.22 +main.reset_connection : Modified in 10.2.22 +main.row-checksum : Modified in 10.2.22 main.query_cache : MDEV-16180 - Wrong result main.query_cache_debug : MDEV-15281 - Query cache is disabled main.range_vs_index_merge_innodb : MDEV-15283 - Server has gone away @@ -109,29 +107,27 @@ main.show_explain : MDEV-10674 - Wrong result code main.sp : MDEV-7866 - Mismatch main.sp_notembedded : MDEV-10607 - internal error main.sp-security : MDEV-10607 - sporadic "can't connect" -main.ssl : MDEV-17184 - Failures with OpenSSL 1.1.1 +main.ssl : MDEV-17184 - Failures with OpenSSL 1.1.1; modified in 10.2.22 main.ssl_ca : MDEV-10895 - SSL connection error on Power -main.ssl_cert_verify : MDEV-13735 - Server crash -main.ssl_cipher : MDEV-17184 - Failures with OpenSSL 1.1.1 +main.ssl_cert_verify : MDEV-13735 - Server crash; modified in 10.2.22 +main.ssl_cipher : MDEV-17184 - Failures with OpenSSL 1.1.1; modified in 10.2.22 main.ssl_connect : MDEV-13492 - Unknown SSL error main.ssl_timeout : MDEV-11244 - Crash main.stat_tables : Modified in 10.2.20 main.stat_tables_par : MDEV-13266 - Wrong result main.stat_tables_par_innodb : MDEV-14155 - Wrong rounding main.status : MDEV-13255 - Wrong result +main.subselect2 : Modified in 10.2.22 main.subselect_innodb : MDEV-10614 - Sporadic wrong results +main.subselect_mat : Modified in 10.2.22 main.tc_heuristic_recover : MDEV-14189 - Wrong result main.type_blob : MDEV-15195 - Wrong result -main.type_datetime : Modified in 10.2.19 main.type_datetime_hires : MDEV-10687 - Timeout main.type_newdecimal : Modified in 10.2.20 -main.type_year : Modified in 10.2.19 main.udf : Modified in 10.2.20 +main.union : Modified in 10.2.22 main.userstat : MDEV-12904 - SSL errors main.win : Modified in 10.2.20 -main.win_percent_cume : Modified in 10.2.19 -main.win_rank : Modified in 10.2.19 -main.win_std : Modified in 10.2.19 main.xa : MDEV-11769 - lock wait timeout #---------------------------------------------------------------- @@ -140,18 +136,16 @@ archive.archive_bitfield : MDEV-11771 - table is marked as crashed archive.archive_symlink : MDEV-12170 - unexpected error on rmdir archive.discover : MDEV-10510 - Table is marked as crashed archive.mysqlhotcopy_archive : MDEV-10995 - Hang on debug +archive.partition_archive : Modified in 10.2.22 archive-test_sql_discovery.discover : MDEV-16817 - Table marked as crashed #---------------------------------------------------------------- -auth_gssapi.basic : Modified in 10.2.19 - -#---------------------------------------------------------------- - +binlog.binlog_base64_flag : Modified in 10.2.22 binlog.binlog_commit_wait : MDEV-10150 - Mismatch -binlog.binlog_flush_binlogs_delete_domain : Modified in 10.2.19 -binlog.binlog_killed : MDEV-12925 - Wrong result +binlog.binlog_killed : MDEV-12925 - Wrong result +binlog.binlog_mysqlbinlog_row_frag : Added in 10.2.22 binlog.binlog_xa_recover : MDEV-8517 - Extra checkpoint binlog.load_data_stm_view : MDEV-16948 - Wrong result @@ -172,10 +166,11 @@ binlog_encryption.rpl_skip_replication : MDEV-13571 - Unexpected warning binlog_encryption.rpl_ssl : MDEV-14507 - Timeouts binlog_encryption.rpl_stm_relay_ign_space : MDEV-13278 - Wrong result (test assertion) binlog_encryption.rpl_sync : MDEV-13830 - Assertion failure -binlog_encryption.rpl_typeconv : MDEV-14362 - Lost connection to MySQL server during query; include file modified in 10.2.19 +binlog_encryption.rpl_typeconv : MDEV-14362 - Lost connection to MySQL server during query #---------------------------------------------------------------- +connect.part_table : Modified in 10.2.22 connect.pivot : MDEV-14803 - Failed to discover table connect.vcol : MDEV-12374 - Fails on Windows connect.zip : MDEV-13884 - Wrong result @@ -190,7 +185,7 @@ encryption.innodb-checksum-algorithm : MDEV-12898 - Deadlock of thre encryption.innodb-compressed-blob : MDEV-14728 - Unable to get certificate encryption.innodb_encrypt_log : MDEV-13725 - Wrong result encryption.innodb_encryption : MDEV-15675 - Timeout -encryption.innodb-encryption-alter : MDEV-13566 - Lock wait timeout; modified in 10.2.19 +encryption.innodb-encryption-alter : MDEV-13566 - Lock wait timeout; modified in 10.2.22 encryption.innodb_encryption_discard_import : MDEV-16116 - Wrong result encryption.innodb_encryption-page-compression : MDEV-12630 - crash or assertion failure encryption.innodb_encryption_row_compressed : MDEV-16113 - Crash @@ -206,7 +201,7 @@ encryption.innodb-remove-encryption : MDEV-16493 - Timeout in wait encryption.innodb_scrub : MDEV-8139 - scrubbing tests need fixing encryption.innodb_scrub_background : MDEV-8139 - scrubbing tests need fixing encryption.innodb_scrub_compressed : MDEV-8139 - scrubbing tests need fixing -encryption.innodb-spatial-index : MDEV-13746 - Wrong result +encryption.innodb-spatial-index : MDEV-13746 - Wrong result; modified in 10.2.22 #---------------------------------------------------------------- @@ -225,6 +220,7 @@ federated.federatedx : MDEV-10617 - Wrong checksum #---------------------------------------------------------------- +funcs_1.is_check_constraint : Added in 10.2.22 funcs_1.memory_views : MDEV-11773 - timeout funcs_1.processlist_val_no_prot : MDEV-11223 - Wrong result funcs_1.processlist_val_ps : MDEV-12175 - Wrong plan @@ -241,39 +237,41 @@ galera_3nodes.* : Suite is not stable yet #---------------------------------------------------------------- -gcol.gcol_partition_innodb : Modified in 10.2.19 +gcol.gcol_column_def_options_innodb : Include file modified in 10.2.22 +gcol.gcol_column_def_options_myisam : Include file modified in 10.2.22 +gcol.gcol_keys_innodb : Include file modified in 10.2.22 +gcol.gcol_keys_myisam : Include file modified in 10.2.22 gcol.gcol_rollback : MDEV-16954 - Unknown storage engine 'InnoDB' gcol.innodb_virtual_basic : MDEV-16950 - Failing assertion -gcol.innodb_virtual_debug_purge : MDEV-16952 - Wrong result; modified in 10.2.19 -gcol.innodb_virtual_index : Modifed in 10.2.19 - -#---------------------------------------------------------------- - -heap.heap_btree : Modified in 10.2.19 +gcol.innodb_virtual_debug_purge : MDEV-16952 - Wrong result +gcol.innodb_virtual_fk : Modified in 10.2.22 +gcol.innodb_virtual_fk_restart : Modified in 10.2.22 +gcol.innodb_virtual_index : Modified in 10.2.22 #---------------------------------------------------------------- innodb.101_compatibility : MDEV-13891 - Wrong result -innodb.alter_copy : MDEV-16181 - Assertion failure; modified in 10.2.19 -innodb.alter_crash : MDEV-16944 - The process cannot access the file; modified in 10.2.19 -innodb.alter_inplace_perfschema : MDEV-17748 - Wrong result; added in 10.2.19 -innodb.alter_kill : Modified in 10.2.19 -innodb.auto_increment_dup : Modified in 10.2.19 +innodb.add_constraint : Modified in 10.2.22 +innodb.alter_candidate_key : Added in 10.2.22 +innodb.alter_copy : MDEV-16181 - Assertion failure +innodb.alter_crash : MDEV-16944 - The process cannot access the file +innodb.alter_inplace_perfschema : Modified in 10.2.22 +innodb.alter_varchar_change : Modified in 10.2.22 innodb.autoinc_persist : MDEV-15282 - Assertion failure innodb.binlog_consistent : MDEV-10618 - Server fails to start innodb.data_types : Modified in 10.2.20 innodb.default_row_format_create : Modified in 10.2.20 innodb.doublewrite : MDEV-12905 - Server crash -innodb.drop_table_background : Modified in 10.2.19 -innodb.foreign_key : Modified in 10.2.19 +innodb.foreign_key : Modified in 10.2.22 innodb.group_commit_crash : MDEV-14191 - InnoDB registration failed innodb.group_commit_crash_no_optimize_thread : MDEV-13830 - Assertion failure +innodb.innodb_28867993 : Added in 10.2.22 innodb.innodb-32k-crash : MDEV-16953 - Corrupt log record found innodb.innodb-64k-crash : MDEV-13872 - Failure and crash on startup -innodb.innodb-alter : Modified in 10.2.19 -innodb.innodb-alter-debug : MDEV-13182 - InnoDB: adjusting FSP_SPACE_FLAGS; modified in 10.2.19 +innodb.innodb-alter : Modified in 10.2.22 +innodb.innodb-alter-debug : MDEV-13182 - InnoDB: adjusting FSP_SPACE_FLAGS; modified in 10.2.22 innodb.innodb-alter-table : MDEV-10619 - Testcase timeout -innodb.innodb-alter-tempfile : MDEV-15285 - Table already exists; modified in 10.2.19 +innodb.innodb-alter-tempfile : MDEV-15285 - Table already exists innodb.innodb-blob : MDEV-12053 - Client crash innodb.innodb_buffer_pool_resize_with_chunks : MDEV-16964 - Assertion failure innodb.innodb_bug14147491 : MDEV-11808 - Index is corrupt @@ -282,52 +280,48 @@ innodb.innodb_bug48024 : MDEV-14352 - Assertion failure innodb.innodb_bug59641 : MDEV-13830 - Assertion failure innodb.innodb_bulk_create_index_replication : MDEV-15273 - Slave failed to start innodb.innodb_defrag_stats_many_tables : MDEV-14198 - Table is full -innodb.innodb-fk : MDEV-13832 - Assertion failure on shutdown +innodb.innodb-fk : MDEV-13832 - Assertion failure on shutdown; modified in 10.2.22 +innodb.innodb-fk-warnings : Modified in 10.2.22 +innodb.innodb_force_recovery : Modified in 10.2.22 innodb.innodb-get-fk : MDEV-13276 - Server crash -innodb.innodb-index : Modified in 10.2.20 -innodb.innodb-index-online : MDEV-14809 - Cannot save statistics +innodb.innodb-index : Modified in 10.2.22 +innodb.innodb-index-online : MDEV-14809 - Cannot save statistics; modified in 10.2.22 innodb.innodb_information_schema : MDEV-8851 - Wrong result innodb.innodb_max_recordsize_32k : MDEV-14801 - Operation failed innodb.innodb_max_recordsize_64k : MDEV-15203 - Wrong result innodb.innodb_monitor : MDEV-10939 - Testcase timeout innodb.innodb-page_compression_default : MDEV-13644 - Assertion failure -innodb.innodb-page_compression_lzma : MDEV-14353 - Wrong result -innodb.innodb-page_compression_zip : MDEV-10641 - mutex problem +innodb.innodb-page_compression_lzma : MDEV-14353 - Wrong result +innodb.innodb-page_compression_tables : Modified in 10.2.22 +innodb.innodb-page_compression_zip : MDEV-10641 - mutex problem +innodb.innodb_simulate_comp_failures : MDEV-18417 - ASAN failures innodb.innodb_stats : MDEV-10682 - wrong result innodb.innodb_stats_persistent_debug : MDEV-14801 - Operation failed -innodb.innodb-table-online : MDEV-13894 - Wrong result +innodb.innodb-table-online : MDEV-13894 - Wrong result; modified in 10.2.22 innodb.innodb_sys_semaphore_waits : MDEV-10331 - Semaphore wait +innodb.innodb-virtual-columns : Modified in 10.2.22 innodb.innodb-wl5522-debug : MDEV-14200 - Wrong errno +innodb.innodb_zip_innochecksum2 : MDEV-13882 - Warning: difficult to find free blocks innodb.log_corruption : MDEV-13251 - Wrong result innodb.log_data_file_size : MDEV-14204 - Server failed to start innodb.log_file_name : MDEV-14193 - Exception -innodb.log_file_name_debug : Modified in 10.2.19 -innodb.log_file_size : MDEV-15668 - Not found pattern; modified in 10.2.19 +innodb.log_file_size : MDEV-15668 - Not found pattern innodb.monitor : MDEV-16179 - Wrong result innodb.purge_secondary : MDEV-15681 - Wrong result innodb.purge_thread_shutdown : MDEV-13792 - Wrong result innodb.read_only_recovery : MDEV-13886 - Server crash innodb.recovery_shutdown : MDEV-15671 - Checksum mismatch in datafile -innodb.rename_table_debug : Added in 10.2.19 innodb.row_format_redundant : MDEV-15192 - Trying to access missing tablespace innodb.table_definition_cache_debug : MDEV-14206 - Extra warning innodb.table_flags : MDEV-13572 - Wrong result; modified in 10.2.20 innodb.temp_table_savepoint : MDEV-16182 - Wrong result innodb.temporary_table : MDEV-13265 - Wrong result innodb.truncate : Modified in 10.2.20 -innodb.truncate_crash : Added in 10.2.19 -innodb.truncate_debug : Opt file added in 10.2.19 -innodb.truncate_foreign : Added in 10.2.19 -innodb.truncate_inject : Opt file added in 10.2.19 -innodb.truncate_missing : Added in 10.2.19 -innodb.truncate_purge_debug : Opt file added in 10.2.19 -innodb.truncate_restart : Opt file added in 10.2.19 innodb.update_time : MDEV-14804 - Wrong result -innodb.undo_truncate : MDEV-17340 - Server hung; added in 10.2.19 -innodb.undo_truncate_recover : MDEV-17679 - MySQL server has gone away; added in 10.2.19 +innodb.undo_truncate : MDEV-17340 - Server hung +innodb.undo_truncate_recover : MDEV-17679 - MySQL server has gone away innodb.xa_recovery : MDEV-15279 - mysqld got exception -innodb_fts.crash_recovery : Modified in 10.2.19 innodb_fts.create : Modified in 10.2.20 innodb_fts.innodb-fts-fic : MDEV-14154 - Assertion failure innodb_fts.innodb_fts_misc_debug : MDEV-14156 - Unexpected warning @@ -336,7 +330,8 @@ innodb_fts.innodb_fts_stopword_charset : MDEV-13259 - Table crashed innodb_fts.sync : MDEV-14808 - Wrong result innodb_gis.kill_server : MDEV-16941 - Checksum mismatch -innodb_gis.rtree_concurrent_srch : MDEV-15284 - Wrong result with embedded; modified in 10.2.19 +innodb_gis.point_basic : Modified in 10.2.22 +innodb_gis.rtree_concurrent_srch : MDEV-15284 - Wrong result with embedded innodb_gis.rtree_purge : MDEV-15275 - Timeout innodb_gis.rtree_recovery : MDEV-15274 - Error on check innodb_gis.rtree_split : MDEV-14208 - Too many arguments @@ -346,19 +341,13 @@ innodb_gis.types : MDEV-15679 - Table is marked as crashed innodb_zip.cmp_per_index : MDEV-14490 - Table is marked as crashed innodb_zip.innochecksum : Modified in 10.2.20 innodb_zip.innochecksum_3 : MDEV-13279 - Extra warnings -innodb_zip.restart : Opt file modified in 10.2.19 innodb_zip.wl6470_1 : MDEV-14240 - Assertion failure -innodb_zip.wl6501_1 : MDEV-10891 - Can't create UNIX socket; opt file added in 10.2.19 -innodb_zip.wl6501_crash_3 : Opt file added in 10.2.19 -innodb_zip.wl6501_crash_4 : Opt file added in 10.2.19 -innodb_zip.wl6501_crash_5 : Opt file added in 10.2.19 -innodb_zip.wl6501_scale_1 : Opt file added in 10.2.19 +innodb_zip.wl6501_1 : MDEV-10891 - Can't create UNIX socket innodb_zip.wl5522_debug_zip : MDEV-11600 - Operating system error number 2 innodb_zip.wl6501_scale_1 : MDEV-13254 - Timeout, MDEV-14104 - Error 192 #---------------------------------------------------------------- -maria.fulltext2 : Added in 10.2.19 maria.insert_select : MDEV-12757 - Timeout maria.insert_select-7314 : MDEV-16492 - Timeout maria.maria : MDEV-14430 - Extra warning @@ -371,17 +360,20 @@ mariabackup.apply-log-only-incr : MDEV-14192 - Assertion failure mariabackup.backup_grants : Added in 10.2.20 mariabackup.backup_ssl : MDEV-14192 - Assertion failure mariabackup.data_directory : MDEV-15270 - Error on exec +mariabackup.drop_table_during_backup : Modified in 10.2.22 mariabackup.encrypted_page_compressed : Added in 10.2.20 mariabackup.encrypted_page_corruption : Added in 10.2.20 mariabackup.unencrypted_page_compressed : Added in 10.2.20 mariabackup.full_backup : MDEV-16571 - Wrong result -mariabackup.huge_lsn : MDEV-15662 - Sequence number is in the future +mariabackup.huge_lsn : MDEV-15662 - Sequence number is in the future; opt file modified in 10.2.22 mariabackup.incremental_backup : MDEV-14192 - Assertion failure +mariabackup.incremental_ddl_before_backup : Added in 10.2.22 mariabackup.incremental_encrypted : MDEV-15667 - Timeout; MDEV-14192 - Assertion failure -mariabackup.mdev-14447 : MDEV-15201 - Timeout +mariabackup.innodb_log_optimize_ddl : MDEV-14192 - Assertion failure +mariabackup.mdev-14447 : MDEV-15201 - Timeout; modified in 10.2.22 mariabackup.partial_exclude : MDEV-15270 - Error on exec -mariabackup.rename_during_backup : MDEV-14192 - Assertion failure -mariabackup.truncate_during_backup : Modified in 10.2.19 +mariabackup.partition_partial : Opt file added in 10.2.22 +mariabackup.rename_during_backup : MDEV-14192 - Assertion failure; modified in 10.2.22 mariabackup.xbstream : MDEV-14192 - Crash mariabackup.xb_page_compress : MDEV-14810 - status: 1, errno: 11 mariabackup.xb_partition : MDEV-14192 - Assertion failure; MDEV-17584 - Crash on shutdown @@ -425,11 +417,9 @@ percona.* : MDEV-10997 - Not maintained #---------------------------------------------------------------- -perfschema.bad_option_1 : MDEV-13892 - Timeout -perfschema.bad_option_3 : MDEV-12728 - Timeout on Power -perfschema.bad_option_5 : MDEV-14197 - Timeout perfschema.connect_attrs : MDEV-17283 - Wrong result perfschema.dml_file_instances : MDEV-15179 - Wrong result +perfschema.dml_setup_instruments : Modified in 10.2.22 perfschema.dml_threads : MDEV-17746 - Wrong errno perfschema.func_file_io : MDEV-5708 - fails for s390x perfschema.func_mutex : MDEV-5708 - fails for s390x @@ -452,6 +442,7 @@ perfschema_stress.* : MDEV-10996 - Not maintained #---------------------------------------------------------------- +plugins.audit_null : Modified in 10.2.22 plugins.feedback_plugin_send : MDEV-7932, MDEV-11118 - Connection problems and such plugins.processlist : MDEV-16574 - Wrong result plugins.server_audit : MDEV-9562 - crashes on sol10-sparc @@ -501,7 +492,6 @@ roles.flush_roles-17898 : Added in 10.2.20 #---------------------------------------------------------------- rpl.last_insert_id : MDEV-10625 - warnings in error log -rpl.rpl_15919 : Added in 10.2.19 rpl.rpl_auto_increment : MDEV-10417 - Fails on Mips rpl.rpl_auto_increment_bug45679 : MDEV-10417 - Fails on Mips rpl.rpl_auto_increment_update_failure : MDEV-10625 - warnings in error log @@ -523,6 +513,7 @@ rpl.rpl_gtid_mdev9033 : MDEV-10680 - warnings rpl.rpl_gtid_reconnect : MDEV-14497 - Crash rpl.rpl_gtid_stop_start : MDEV-10629 - Crash on shutdown, MDEV-12629 - Valgrind warnings rpl.rpl_gtid_until : MDEV-10625 - warnings in error log +rpl.rpl_idempotency : Modified in 10.2.22 rpl.rpl_innodb_bug30888 : MDEV-10417 - Fails on Mips rpl.rpl_insert : MDEV-9329 - Fails on Ubuntu/s390x rpl.rpl_insert_delayed : MDEV-9329 - Fails on Ubuntu/s390x @@ -530,19 +521,17 @@ rpl.rpl_insert_id : MDEV-15197 - Wrong result rpl.rpl_insert_id_pk : MDEV-16567 - Assertion failure rpl.rpl_insert_ignore : MDEV-14365 - Lost connection to MySQL server during query rpl.rpl_invoked_features : MDEV-10417 - Fails on Mips -rpl.rpl_lcase_tblnames_rewrite_db : Added in 10.2.19 rpl.rpl_mariadb_slave_capability : MDEV-11018 - Extra lines in binlog rpl.rpl_mdev6020 : MDEV-15272 - Server crash rpl.rpl_mixed_mixing_engines : MDEV-14489 - Sync slave with master failed rpl.rpl_non_direct_row_mixing_engines : MDEV-16561 - Timeout in master_pos_wait rpl.rpl_non_direct_mixed_mixing_engines : MDEV-14489 - Sync slave with master failed rpl.rpl_non_direct_stm_mixing_engines : MDEV-14489 - Failed sync_slave_with_master -rpl.rpl_old_master : Modified in 10.2.19 rpl.rpl_parallel : MDEV-10653 - Timeouts rpl.rpl_parallel_conflicts : MDEV-15272 - Server crash rpl.rpl_parallel_mdev6589 : MDEV-12979 - Assertion failure rpl.rpl_parallel_multilevel2 : MDEV-14723 - Timeout -rpl.rpl_parallel_optimistic : MDEV-15278 - Failed to sync with master; modified in 10.2.19 +rpl.rpl_parallel_optimistic : MDEV-15278 - Failed to sync with master rpl.rpl_parallel_optimistic_nobinlog : MDEV-15278 - Failed to sync with master rpl.rpl_parallel_retry : MDEV-11119 - Crash; MDEV-17109 - Timeout rpl.rpl_parallel_temptable : MDEV-10356 - Crash @@ -551,12 +540,12 @@ rpl.rpl_password_boundaries : MDEV-11534 - Slave IO warnings rpl.rpl_row_001 : MDEV-16653 - Internal check fails rpl.rpl_row_basic_11bugs : MDEV-12171 - Server failed to start rpl.rpl_row_basic_2myisam : MDEV-13875 - command "diff_files" failed +rpl.rpl_row_big_table_id : Added in 10.2.22 rpl.rpl_row_drop_create_temp_table : MDEV-14487 - Wrong result rpl.rpl_row_img_blobs : MDEV-13875 - command "diff_files" failed rpl.rpl_row_img_eng_min : MDEV-13875 - diff_files failed rpl.rpl_row_img_eng_noblob : MDEV-13875 - command "diff_files" failed rpl.rpl_row_index_choice : MDEV-15196 - Slave crash -rpl.rpl_row_lcase_tblnames : Added in 10.2.19 rpl.rpl_row_sp001 : MDEV-9329 - Fails on Ubuntu/s390x rpl.rpl_semi_sync : MDEV-11220 - Wrong result rpl.rpl_semi_sync_after_sync : MDEV-14366 - Wrong result @@ -572,7 +561,6 @@ rpl.rpl_slave_load_tmpdir_not_exist : MDEV-14203 - Extra warning rpl.rpl_slow_query_log : MDEV-13250 - Test abort rpl.rpl_sp_effects : MDEV-13249 - Crash rpl.rpl_start_stop_slave : MDEV-13567 - Sync slave timeout -rpl.rpl_stm_lcase_tblnames : Added in 10.2.19 rpl.rpl_stm_mixing_engines : MDEV-14489 - Sync slave with master failed rpl.rpl_stm_multi_query : MDEV-9501 - Failed registering on master rpl.rpl_stm_relay_ign_space : MDEV-14360 - Test assertion @@ -581,7 +569,7 @@ rpl.rpl_sync : MDEV-13830 - Assertion failure rpl.rpl_temporal_mysql56_to_mariadb53 : MDEV-9501 - Failed registering on master rpl.rpl_temporary_error2 : MDEV-10634 - Wrong number of retries rpl.rpl_trigger : MDEV-18055 - Wrong result -rpl.rpl_typeconv : Include file modified in 10.2.19 +rpl.rpl_user : Modified in 10.2.22 rpl.sec_behind_master-5114 : MDEV-13878 - Wrong result rpl/extra/rpl_tests.* : MDEV-10994 - Not maintained @@ -619,20 +607,18 @@ stress.ddl_innodb : MDEV-10635 - Testcase timeout sys_vars.aria_used_for_temp_tables_basic : Modified in 10.2.20 sys_vars.autocommit_func2 : MDEV-9329 - Fails on Ubuntu/s390x -sys_vars.delayed_insert_limit_func : MDEV-17683 - Wrong result; modified in 10.2.19 +sys_vars.delayed_insert_limit_func : MDEV-17683 - Wrong result sys_vars.innodb_buffer_pool_dump_at_shutdown_basic : MDEV-14280 - Unexpected error -sys_vars.innodb_ft_result_cache_limit_32 : Added in 10.2.19 -sys_vars.innodb_ft_result_cache_limit_64 : Added in 10.2.19 -sys_vars.innodb_ft_result_cache_limit_basic : Modified in 10.2.19 sys_vars.keep_files_on_create_basic : MDEV-10676 - timeout sys_vars.log_slow_admin_statements_func : MDEV-12235 - Server crash sys_vars.rpl_init_slave_func : MDEV-10149 - Test assertion sys_vars.slow_query_log_func : MDEV-14273 - Wrong result -sys_vars.sql_low_priority_updates_func : Modified in 10.2.19 sys_vars.sysvars_aria : Modified in 10.2.20 +sys_vars.table_definition_cache_basic : Modified in 10.2.22 sys_vars.thread_cache_size_func : MDEV-11775 - Wrong result -sys_vars.tmp_disk_table_size_func : Modified in 10.2.20 +sys_vars.tmp_disk_table_size_func : Modified in 10.2.22 sys_vars.wait_timeout_func : MDEV-12896 - Wrong result +sys_vars.wsrep_sst_method_basic : Modified in 10.2.22 #---------------------------------------------------------------- @@ -660,6 +646,7 @@ tokudb.type_datetime : MDEV-15193 - Wrong result tokudb_alter_table.hcad_all_add2 : MDEV-15269 - Timeout +tokudb_bugs.PS-4979 : Added in 10.2.22 tokudb_bugs.checkpoint_lock : MDEV-10637 - Wrong processlist output tokudb_bugs.checkpoint_lock_3 : MDEV-10637 - Wrong processlist output tokudb_bugs.frm_store : MDEV-12823 - Valgrind @@ -681,13 +668,15 @@ rpl-tokudb.* : MDEV-14354 - Tests fail with tcmalloc unit.conc_basic-t : MDEV-15286 - not ok 7 - test_reconnect_maxpackage unit.conc_misc : MDEV-14811 - not ok 12 - test_conc49 unit.conc_ps_bugs : MDEV-13252 - not ok 44 test_bug4236 +unit.lf : MDEV-18416 - object was probably modified after being freed unit.ma_test_loghandler : MDEV-10638 - record read not ok +unit.my_atomic : MDEV-18472 - Signal 11 thrown #---------------------------------------------------------------- vcol.not_supported : MDEV-10639 - Testcase timeout -vcol.races : Added in 10.2.19 vcol.upgrade : Modified in 10.2.20 +vcol.vcol_keys : Modified in 10.2.22 vcol.vcol_keys_innodb : MDEV-10639 - Testcase timeout vcol.vcol_misc : MDEV-16651 - Wrong error message @@ -695,6 +684,7 @@ vcol.vcol_misc : MDEV-16651 - Wrong error message wsrep.foreign_key : MDEV-14725 - WSREP has not yet prepared node wsrep.mdev_6832 : MDEV-14195 - Check testcase failed -wsrep.variables : MDEV-14311 - Wrong result; MDEV-17585 - Deadlock; modified in 10.2.19 +wsrep.variables : MDEV-14311 - Wrong result; MDEV-17585 - Deadlock +wsrep.wsrep-recover-v25 : Added in 10.2.22 wsrep_info.plugin : MDEV-13569 - No nodes coming from prim view From bc50d72604d68e31538ef9519616451763e2d20f Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 8 Feb 2019 16:38:39 +0100 Subject: [PATCH 091/106] C/C again fixes memory leaks in restart_mysqld.inc tests --- libmariadb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmariadb b/libmariadb index 7923e8dadd3..2c5aebb3bc7 160000 --- a/libmariadb +++ b/libmariadb @@ -1 +1 @@ -Subproject commit 7923e8dadd3482ee439e8c5618d6bd1735921634 +Subproject commit 2c5aebb3bc724c1663c481ba2fedde00ab494fa4 From e5a5ae45d18d858e9d83e85c03dfe9428c171059 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Fri, 8 Feb 2019 14:10:44 +0100 Subject: [PATCH 092/106] revert the check changes made in 8f5ea83ff109827748d2f9f5025ed6c6bb91fd80 and in fef9013d43b734ca062d7f9a2e1e320aa512d9d8 --- mysql-test/include/mtr_check.sql | 1 - mysql-test/suite/funcs_1/r/is_routines_embedded.result | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/mysql-test/include/mtr_check.sql b/mysql-test/include/mtr_check.sql index 067df841ce4..d47e7d322b5 100644 --- a/mysql-test/include/mtr_check.sql +++ b/mysql-test/include/mtr_check.sql @@ -35,7 +35,6 @@ BEGIN AND variable_name != 'INNODB_BUFFER_POOL_LOAD_AT_STARTUP' AND variable_name not like 'GTID%POS' AND variable_name != 'GTID_BINLOG_STATE' - AND variable_name != 'AUTO_INCREMENT_INCREMENT' ORDER BY variable_name; -- Dump all databases, there should be none diff --git a/mysql-test/suite/funcs_1/r/is_routines_embedded.result b/mysql-test/suite/funcs_1/r/is_routines_embedded.result index d415ea1da96..1fc9f90ae49 100644 --- a/mysql-test/suite/funcs_1/r/is_routines_embedded.result +++ b/mysql-test/suite/funcs_1/r/is_routines_embedded.result @@ -197,7 +197,7 @@ sp_6_408002_2 def db_datadict_2 sp_6_408002_2 PROCEDURE NULL NULL NULL NULL NUL SELECT * FROM db_datadict_2.res_6_408002_2; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost latin1 latin1_swedish_ci latin1_swedish_ci add_suppression def mtr add_suppression PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN INSERT INTO test_suppressions (pattern) VALUES (pattern); FLUSH NO_WRITE_TO_BINLOG TABLE test_suppressions; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8 utf8_general_ci latin1_swedish_ci -check_testcase def mtr check_testcase PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE variable_name NOT IN ('timestamp', 'innodb_file_format_max') AND variable_name not like "Last_IO_Err*" AND variable_name != 'INNODB_IBUF_MAX_SIZE' AND variable_name != 'INNODB_USE_NATIVE_AIO' AND variable_name != 'INNODB_BUFFER_POOL_LOAD_AT_STARTUP' AND variable_name not like 'GTID%POS' AND variable_name != 'GTID_BINLOG_STATE' AND variable_name != 'AUTO_INCREMENT_INCREMENT' ORDER BY variable_name; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('mtr_wsrep_notify', 'wsrep_schema'); SELECT table_name AS tables_in_test FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='test'; SELECT CONCAT(table_schema, '.', table_name) AS tables_in_mysql FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='mysql' ORDER BY tables_in_mysql; SELECT CONCAT(table_schema, '.', table_name) AS columns_in_mysql, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, character_set_name, collation_name, column_type, column_key, extra, column_comment FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='mysql' ORDER BY columns_in_mysql; SELECT * FROM INFORMATION_SCHEMA.EVENTS; SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME NOT IN ('gs_insert', 'ts_insert'); SELECT * FROM INFORMATION_SCHEMA.ROUTINES; SHOW STATUS LIKE 'slave_open_temp_tables'; checksum table mysql.columns_priv, mysql.db, mysql.func, mysql.help_category, mysql.help_keyword, mysql.help_relation, mysql.host, mysql.plugin, mysql.proc, mysql.procs_priv, mysql.roles_mapping, mysql.tables_priv, mysql.time_zone, mysql.time_zone_leap_second, mysql.time_zone_name, mysql.time_zone_transition, mysql.time_zone_transition_type, mysql.user; SELECT * FROM INFORMATION_SCHEMA.PLUGINS; select * from information_schema.session_variables where variable_name = 'debug_sync'; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8 utf8_general_ci latin1_swedish_ci +check_testcase def mtr check_testcase PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE variable_name NOT IN ('timestamp', 'innodb_file_format_max') AND variable_name not like "Last_IO_Err*" AND variable_name != 'INNODB_IBUF_MAX_SIZE' AND variable_name != 'INNODB_USE_NATIVE_AIO' AND variable_name != 'INNODB_BUFFER_POOL_LOAD_AT_STARTUP' AND variable_name not like 'GTID%POS' AND variable_name != 'GTID_BINLOG_STATE' ORDER BY variable_name; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('mtr_wsrep_notify', 'wsrep_schema'); SELECT table_name AS tables_in_test FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='test'; SELECT CONCAT(table_schema, '.', table_name) AS tables_in_mysql FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='mysql' ORDER BY tables_in_mysql; SELECT CONCAT(table_schema, '.', table_name) AS columns_in_mysql, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, character_set_name, collation_name, column_type, column_key, extra, column_comment FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='mysql' ORDER BY columns_in_mysql; SELECT * FROM INFORMATION_SCHEMA.EVENTS; SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME NOT IN ('gs_insert', 'ts_insert'); SELECT * FROM INFORMATION_SCHEMA.ROUTINES; SHOW STATUS LIKE 'slave_open_temp_tables'; checksum table mysql.columns_priv, mysql.db, mysql.func, mysql.help_category, mysql.help_keyword, mysql.help_relation, mysql.host, mysql.plugin, mysql.proc, mysql.procs_priv, mysql.roles_mapping, mysql.tables_priv, mysql.time_zone, mysql.time_zone_leap_second, mysql.time_zone_name, mysql.time_zone_transition, mysql.time_zone_transition_type, mysql.user; SELECT * FROM INFORMATION_SCHEMA.PLUGINS; select * from information_schema.session_variables where variable_name = 'debug_sync'; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8 utf8_general_ci latin1_swedish_ci check_warnings def mtr check_warnings PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN DECLARE `pos` bigint unsigned; SET SQL_LOG_BIN=0; UPDATE error_log el, global_suppressions gs SET suspicious=0 WHERE el.suspicious=1 AND el.line REGEXP gs.pattern; UPDATE error_log el, test_suppressions ts SET suspicious=0 WHERE el.suspicious=1 AND el.line REGEXP ts.pattern; SELECT COUNT(*) INTO @num_warnings FROM error_log WHERE suspicious=1; IF @num_warnings > 0 THEN SELECT line FROM error_log WHERE suspicious=1; SELECT 2 INTO result; ELSE SELECT 0 INTO RESULT; END IF; TRUNCATE test_suppressions; DROP TABLE error_log; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8 utf8_general_ci latin1_swedish_ci connect testuser2, localhost, testuser2, , db_datadict; SELECT * FROM information_schema.routines; @@ -209,7 +209,7 @@ sp_6_408002_2 def db_datadict_2 sp_6_408002_2 PROCEDURE NULL NULL NULL NULL NUL SELECT * FROM db_datadict_2.res_6_408002_2; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost latin1 latin1_swedish_ci latin1_swedish_ci add_suppression def mtr add_suppression PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN INSERT INTO test_suppressions (pattern) VALUES (pattern); FLUSH NO_WRITE_TO_BINLOG TABLE test_suppressions; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8 utf8_general_ci latin1_swedish_ci -check_testcase def mtr check_testcase PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE variable_name NOT IN ('timestamp', 'innodb_file_format_max') AND variable_name not like "Last_IO_Err*" AND variable_name != 'INNODB_IBUF_MAX_SIZE' AND variable_name != 'INNODB_USE_NATIVE_AIO' AND variable_name != 'INNODB_BUFFER_POOL_LOAD_AT_STARTUP' AND variable_name not like 'GTID%POS' AND variable_name != 'GTID_BINLOG_STATE' AND variable_name != 'AUTO_INCREMENT_INCREMENT' ORDER BY variable_name; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('mtr_wsrep_notify', 'wsrep_schema'); SELECT table_name AS tables_in_test FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='test'; SELECT CONCAT(table_schema, '.', table_name) AS tables_in_mysql FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='mysql' ORDER BY tables_in_mysql; SELECT CONCAT(table_schema, '.', table_name) AS columns_in_mysql, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, character_set_name, collation_name, column_type, column_key, extra, column_comment FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='mysql' ORDER BY columns_in_mysql; SELECT * FROM INFORMATION_SCHEMA.EVENTS; SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME NOT IN ('gs_insert', 'ts_insert'); SELECT * FROM INFORMATION_SCHEMA.ROUTINES; SHOW STATUS LIKE 'slave_open_temp_tables'; checksum table mysql.columns_priv, mysql.db, mysql.func, mysql.help_category, mysql.help_keyword, mysql.help_relation, mysql.host, mysql.plugin, mysql.proc, mysql.procs_priv, mysql.roles_mapping, mysql.tables_priv, mysql.time_zone, mysql.time_zone_leap_second, mysql.time_zone_name, mysql.time_zone_transition, mysql.time_zone_transition_type, mysql.user; SELECT * FROM INFORMATION_SCHEMA.PLUGINS; select * from information_schema.session_variables where variable_name = 'debug_sync'; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8 utf8_general_ci latin1_swedish_ci +check_testcase def mtr check_testcase PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE variable_name NOT IN ('timestamp', 'innodb_file_format_max') AND variable_name not like "Last_IO_Err*" AND variable_name != 'INNODB_IBUF_MAX_SIZE' AND variable_name != 'INNODB_USE_NATIVE_AIO' AND variable_name != 'INNODB_BUFFER_POOL_LOAD_AT_STARTUP' AND variable_name not like 'GTID%POS' AND variable_name != 'GTID_BINLOG_STATE' ORDER BY variable_name; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('mtr_wsrep_notify', 'wsrep_schema'); SELECT table_name AS tables_in_test FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='test'; SELECT CONCAT(table_schema, '.', table_name) AS tables_in_mysql FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='mysql' ORDER BY tables_in_mysql; SELECT CONCAT(table_schema, '.', table_name) AS columns_in_mysql, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, character_set_name, collation_name, column_type, column_key, extra, column_comment FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='mysql' ORDER BY columns_in_mysql; SELECT * FROM INFORMATION_SCHEMA.EVENTS; SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME NOT IN ('gs_insert', 'ts_insert'); SELECT * FROM INFORMATION_SCHEMA.ROUTINES; SHOW STATUS LIKE 'slave_open_temp_tables'; checksum table mysql.columns_priv, mysql.db, mysql.func, mysql.help_category, mysql.help_keyword, mysql.help_relation, mysql.host, mysql.plugin, mysql.proc, mysql.procs_priv, mysql.roles_mapping, mysql.tables_priv, mysql.time_zone, mysql.time_zone_leap_second, mysql.time_zone_name, mysql.time_zone_transition, mysql.time_zone_transition_type, mysql.user; SELECT * FROM INFORMATION_SCHEMA.PLUGINS; select * from information_schema.session_variables where variable_name = 'debug_sync'; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8 utf8_general_ci latin1_swedish_ci check_warnings def mtr check_warnings PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN DECLARE `pos` bigint unsigned; SET SQL_LOG_BIN=0; UPDATE error_log el, global_suppressions gs SET suspicious=0 WHERE el.suspicious=1 AND el.line REGEXP gs.pattern; UPDATE error_log el, test_suppressions ts SET suspicious=0 WHERE el.suspicious=1 AND el.line REGEXP ts.pattern; SELECT COUNT(*) INTO @num_warnings FROM error_log WHERE suspicious=1; IF @num_warnings > 0 THEN SELECT line FROM error_log WHERE suspicious=1; SELECT 2 INTO result; ELSE SELECT 0 INTO RESULT; END IF; TRUNCATE test_suppressions; DROP TABLE error_log; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8 utf8_general_ci latin1_swedish_ci connect testuser3, localhost, testuser3, , test; SELECT * FROM information_schema.routines; @@ -221,7 +221,7 @@ sp_6_408002_2 def db_datadict_2 sp_6_408002_2 PROCEDURE NULL NULL NULL NULL NUL SELECT * FROM db_datadict_2.res_6_408002_2; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost latin1 latin1_swedish_ci latin1_swedish_ci add_suppression def mtr add_suppression PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN INSERT INTO test_suppressions (pattern) VALUES (pattern); FLUSH NO_WRITE_TO_BINLOG TABLE test_suppressions; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8 utf8_general_ci latin1_swedish_ci -check_testcase def mtr check_testcase PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE variable_name NOT IN ('timestamp', 'innodb_file_format_max') AND variable_name not like "Last_IO_Err*" AND variable_name != 'INNODB_IBUF_MAX_SIZE' AND variable_name != 'INNODB_USE_NATIVE_AIO' AND variable_name != 'INNODB_BUFFER_POOL_LOAD_AT_STARTUP' AND variable_name not like 'GTID%POS' AND variable_name != 'GTID_BINLOG_STATE' AND variable_name != 'AUTO_INCREMENT_INCREMENT' ORDER BY variable_name; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('mtr_wsrep_notify', 'wsrep_schema'); SELECT table_name AS tables_in_test FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='test'; SELECT CONCAT(table_schema, '.', table_name) AS tables_in_mysql FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='mysql' ORDER BY tables_in_mysql; SELECT CONCAT(table_schema, '.', table_name) AS columns_in_mysql, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, character_set_name, collation_name, column_type, column_key, extra, column_comment FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='mysql' ORDER BY columns_in_mysql; SELECT * FROM INFORMATION_SCHEMA.EVENTS; SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME NOT IN ('gs_insert', 'ts_insert'); SELECT * FROM INFORMATION_SCHEMA.ROUTINES; SHOW STATUS LIKE 'slave_open_temp_tables'; checksum table mysql.columns_priv, mysql.db, mysql.func, mysql.help_category, mysql.help_keyword, mysql.help_relation, mysql.host, mysql.plugin, mysql.proc, mysql.procs_priv, mysql.roles_mapping, mysql.tables_priv, mysql.time_zone, mysql.time_zone_leap_second, mysql.time_zone_name, mysql.time_zone_transition, mysql.time_zone_transition_type, mysql.user; SELECT * FROM INFORMATION_SCHEMA.PLUGINS; select * from information_schema.session_variables where variable_name = 'debug_sync'; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8 utf8_general_ci latin1_swedish_ci +check_testcase def mtr check_testcase PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE variable_name NOT IN ('timestamp', 'innodb_file_format_max') AND variable_name not like "Last_IO_Err*" AND variable_name != 'INNODB_IBUF_MAX_SIZE' AND variable_name != 'INNODB_USE_NATIVE_AIO' AND variable_name != 'INNODB_BUFFER_POOL_LOAD_AT_STARTUP' AND variable_name not like 'GTID%POS' AND variable_name != 'GTID_BINLOG_STATE' ORDER BY variable_name; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('mtr_wsrep_notify', 'wsrep_schema'); SELECT table_name AS tables_in_test FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='test'; SELECT CONCAT(table_schema, '.', table_name) AS tables_in_mysql FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='mysql' ORDER BY tables_in_mysql; SELECT CONCAT(table_schema, '.', table_name) AS columns_in_mysql, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, character_set_name, collation_name, column_type, column_key, extra, column_comment FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='mysql' ORDER BY columns_in_mysql; SELECT * FROM INFORMATION_SCHEMA.EVENTS; SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME NOT IN ('gs_insert', 'ts_insert'); SELECT * FROM INFORMATION_SCHEMA.ROUTINES; SHOW STATUS LIKE 'slave_open_temp_tables'; checksum table mysql.columns_priv, mysql.db, mysql.func, mysql.help_category, mysql.help_keyword, mysql.help_relation, mysql.host, mysql.plugin, mysql.proc, mysql.procs_priv, mysql.roles_mapping, mysql.tables_priv, mysql.time_zone, mysql.time_zone_leap_second, mysql.time_zone_name, mysql.time_zone_transition, mysql.time_zone_transition_type, mysql.user; SELECT * FROM INFORMATION_SCHEMA.PLUGINS; select * from information_schema.session_variables where variable_name = 'debug_sync'; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8 utf8_general_ci latin1_swedish_ci check_warnings def mtr check_warnings PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN DECLARE `pos` bigint unsigned; SET SQL_LOG_BIN=0; UPDATE error_log el, global_suppressions gs SET suspicious=0 WHERE el.suspicious=1 AND el.line REGEXP gs.pattern; UPDATE error_log el, test_suppressions ts SET suspicious=0 WHERE el.suspicious=1 AND el.line REGEXP ts.pattern; SELECT COUNT(*) INTO @num_warnings FROM error_log WHERE suspicious=1; IF @num_warnings > 0 THEN SELECT line FROM error_log WHERE suspicious=1; SELECT 2 INTO result; ELSE SELECT 0 INTO RESULT; END IF; TRUNCATE test_suppressions; DROP TABLE error_log; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8 utf8_general_ci latin1_swedish_ci connection default; disconnect testuser1; From 894f44b60b2f99a60d10382c3f7869796d59f506 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 9 Feb 2019 22:54:10 +0100 Subject: [PATCH 093/106] CONNECT: Windows paths Followup for db8f0daeb4f --- storage/connect/ha_connect.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index c5fd9483a65..859dc859a09 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -1816,7 +1816,7 @@ PCSZ ha_connect::GetDBName(PCSZ name) const char *ha_connect::GetTableName(void) { const char *path= tshp ? tshp->path.str : table_share->path.str; - const char *name= strrchr(path, '/'); + const char *name= strrchr(path, slash); return name ? name+1 : path; } // end of GetTableName From ca325a46d230438ab06b8fe4455f54538dfa11d4 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 10 Feb 2019 00:21:43 +0100 Subject: [PATCH 094/106] CONNECT: update test results --- storage/connect/mysql-test/connect/r/xml.result | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/connect/mysql-test/connect/r/xml.result b/storage/connect/mysql-test/connect/r/xml.result index 99739b1ec10..6a0c9db27b3 100644 --- a/storage/connect/mysql-test/connect/r/xml.result +++ b/storage/connect/mysql-test/connect/r/xml.result @@ -323,7 +323,7 @@ HEX(c) 3F3F3F3F3F3F3F Warnings: Level Warning Code 1366 -Message Incorrect string value: '\xC3\x81\xC3\x82\xC3\x83...' for column 'c' at row 1 +Message Incorrect string value: '\xC3\x81\xC3\x82\xC3\x83...' for column `test`.`t1`.`c` at row 1 Level Warning Code 1105 Message Out of range value ÁÂÃÄÅÆÇ for column 'c' at row 1 From be25414828958d9cf829f7e8f162377bbfdfb4db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 11 Feb 2019 11:36:00 +0200 Subject: [PATCH 095/106] MDEV-18016: Cover the no-rebuild case, and remove a bogus debug assertion The code path where the table was not being rebuilt during ALTER TABLE was not covered by the test. Add coverage, and remove the debug assertion that could fail in this case. --- mysql-test/suite/innodb/r/foreign_key.result | 10 ++++++++++ mysql-test/suite/innodb/t/foreign_key.test | 9 +++++++++ storage/innobase/handler/handler0alter.cc | 1 - storage/xtradb/handler/handler0alter.cc | 1 - 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/innodb/r/foreign_key.result b/mysql-test/suite/innodb/r/foreign_key.result index 4e253261f2e..d28ade4c543 100644 --- a/mysql-test/suite/innodb/r/foreign_key.result +++ b/mysql-test/suite/innodb/r/foreign_key.result @@ -82,3 +82,13 @@ ALTER TABLE t1 ADD FULLTEXT INDEX ft2 (f); Warnings: Warning 1088 failed to load FOREIGN KEY constraints DROP TABLE t1; +CREATE TABLE t1 (f VARCHAR(256), FTS_DOC_ID BIGINT UNSIGNED PRIMARY KEY) +ENGINE=InnoDB; +SET SESSION FOREIGN_KEY_CHECKS = OFF; +ALTER TABLE t1 ADD FOREIGN KEY (f) REFERENCES non_existing_table (x); +SET SESSION FOREIGN_KEY_CHECKS = ON; +ALTER TABLE t1 ADD FULLTEXT INDEX ft1 (f); +Warnings: +Warning 1088 failed to load FOREIGN KEY constraints +ALTER TABLE t1 ADD FULLTEXT INDEX ft2 (f); +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/foreign_key.test b/mysql-test/suite/innodb/t/foreign_key.test index b4e2ee1bbe7..3fc8449a6b0 100644 --- a/mysql-test/suite/innodb/t/foreign_key.test +++ b/mysql-test/suite/innodb/t/foreign_key.test @@ -104,3 +104,12 @@ SET SESSION FOREIGN_KEY_CHECKS = ON; ALTER TABLE t1 ADD FULLTEXT INDEX ft1 (f); ALTER TABLE t1 ADD FULLTEXT INDEX ft2 (f); DROP TABLE t1; + +CREATE TABLE t1 (f VARCHAR(256), FTS_DOC_ID BIGINT UNSIGNED PRIMARY KEY) +ENGINE=InnoDB; +SET SESSION FOREIGN_KEY_CHECKS = OFF; +ALTER TABLE t1 ADD FOREIGN KEY (f) REFERENCES non_existing_table (x); +SET SESSION FOREIGN_KEY_CHECKS = ON; +ALTER TABLE t1 ADD FULLTEXT INDEX ft1 (f); +ALTER TABLE t1 ADD FULLTEXT INDEX ft2 (f); +DROP TABLE t1; diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 7e8a8334a4d..b3d9faf0680 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -6163,7 +6163,6 @@ foreign_fail: if (!commit_cache_norebuild(ctx, table, trx)) { fk_fail = true; - ut_ad(!prebuilt->trx->check_foreigns); } innobase_rename_columns_cache(ha_alter_info, table, diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc index 3d55ca839cb..43df8b04201 100644 --- a/storage/xtradb/handler/handler0alter.cc +++ b/storage/xtradb/handler/handler0alter.cc @@ -6181,7 +6181,6 @@ foreign_fail: if (!commit_cache_norebuild(ctx, table, trx)) { fk_fail = true; - ut_ad(!prebuilt->trx->check_foreigns); } innobase_rename_columns_cache(ha_alter_info, table, From aae261e96270bd2212feee8ecc5aa2044c46f58f Mon Sep 17 00:00:00 2001 From: Daniel Bartholomew Date: Mon, 11 Feb 2019 10:43:57 -0500 Subject: [PATCH 096/106] bump the VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 976b857053d..43f159b8281 100644 --- a/VERSION +++ b/VERSION @@ -1,3 +1,3 @@ MYSQL_VERSION_MAJOR=10 MYSQL_VERSION_MINOR=2 -MYSQL_VERSION_PATCH=22 +MYSQL_VERSION_PATCH=23 From 5b827511116feb2e3f594cb4e7df816e8704b153 Mon Sep 17 00:00:00 2001 From: Julius Goryavsky Date: Wed, 6 Feb 2019 16:44:36 +0100 Subject: [PATCH 097/106] MDEV-18426: Most of the mtr tests in the galera_3nodes suite fail Most of the mtr tests in the galera_3nodes suite fail for a variety of reasons with a variety of errors. This patch fixes several substantial flaws in the galera_3nodes suite tests and in the mtr framework service files, adapting the tests from galera_3nodes for the current version of MariaDB. This patch also synchronizes some galera_3nodes-related files with the latest changes made for MDEV-17835 (v2 patch) and for MDEV-18379 in other branches (10.2 and 10.3). Closes #1161 --- .../galera => }/include/galera_resume.inc | 2 +- .../include/galera_suspend.inc | 2 +- .../suite/galera_3nodes/galera_2x3nodes.cnf | 1 + .../suite/galera_3nodes/galera_3nodes.cnf | 1 + .../galera_3nodes/r/galera_pc_weight.result | 9 ++++++ .../r/galera_safe_to_bootstrap.result | 10 ++++++ mysql-test/suite/galera_3nodes/suite.pm | 6 ++-- .../suite/galera_3nodes/t/galera_garbd.test | 20 ++++++++++-- .../t/galera_innobackupex_backup.test | 2 +- .../t/galera_ipv6_mariabackup.test | 2 +- .../galera_3nodes/t/galera_ipv6_mysqldump.opt | 1 + .../galera_3nodes/t/galera_ipv6_rsync.opt | 1 + .../t/galera_ist_gcache_rollover.cnf | 6 ++-- .../t/galera_ist_gcache_rollover.test | 13 ++++++++ .../t/galera_safe_to_bootstrap.test | 32 ++++++++++++++++--- .../t/galera_var_dirty_reads2.test | 14 ++++++++ scripts/wsrep_sst_mariabackup.sh | 6 ++-- scripts/wsrep_sst_rsync.sh | 2 +- 18 files changed, 108 insertions(+), 22 deletions(-) rename mysql-test/{suite/galera => }/include/galera_resume.inc (80%) rename mysql-test/{suite/galera_3nodes => }/include/galera_suspend.inc (86%) create mode 100644 mysql-test/suite/galera_3nodes/t/galera_ipv6_mysqldump.opt create mode 100644 mysql-test/suite/galera_3nodes/t/galera_ipv6_rsync.opt diff --git a/mysql-test/suite/galera/include/galera_resume.inc b/mysql-test/include/galera_resume.inc similarity index 80% rename from mysql-test/suite/galera/include/galera_resume.inc rename to mysql-test/include/galera_resume.inc index 232cb46479e..af8f2b956fd 100644 --- a/mysql-test/suite/galera/include/galera_resume.inc +++ b/mysql-test/include/galera_resume.inc @@ -3,7 +3,7 @@ my $pid_filename = $ENV{'_SUSPEND_NODE_PIDFILE'}; my $mysqld_pid = `cat $pid_filename`; chomp($mysqld_pid); - system("kill -18 $mysqld_pid"); + system("kill -SIGCONT $mysqld_pid"); exit(0); EOF diff --git a/mysql-test/suite/galera_3nodes/include/galera_suspend.inc b/mysql-test/include/galera_suspend.inc similarity index 86% rename from mysql-test/suite/galera_3nodes/include/galera_suspend.inc rename to mysql-test/include/galera_suspend.inc index 3495ad2342b..d4037d8958c 100644 --- a/mysql-test/suite/galera_3nodes/include/galera_suspend.inc +++ b/mysql-test/include/galera_suspend.inc @@ -9,6 +9,6 @@ my $pid_filename = $ENV{'_SUSPEND_NODE_PIDFILE'}; my $mysqld_pid = `cat $pid_filename`; chomp($mysqld_pid); - system("kill -19 $mysqld_pid"); + system("kill -SIGSTOP $mysqld_pid"); exit(0); EOF diff --git a/mysql-test/suite/galera_3nodes/galera_2x3nodes.cnf b/mysql-test/suite/galera_3nodes/galera_2x3nodes.cnf index df51920c13c..477789175fb 100644 --- a/mysql-test/suite/galera_3nodes/galera_2x3nodes.cnf +++ b/mysql-test/suite/galera_3nodes/galera_2x3nodes.cnf @@ -9,6 +9,7 @@ innodb-autoinc-lock-mode=2 default-storage-engine=innodb wsrep_gtid_mode=1 gtid_ignore_duplicates +auto_increment_increment=3 wsrep-on=1 wsrep-provider=@ENV.WSREP_PROVIDER diff --git a/mysql-test/suite/galera_3nodes/galera_3nodes.cnf b/mysql-test/suite/galera_3nodes/galera_3nodes.cnf index 7b68d36c04a..e5aa81b8742 100644 --- a/mysql-test/suite/galera_3nodes/galera_3nodes.cnf +++ b/mysql-test/suite/galera_3nodes/galera_3nodes.cnf @@ -5,6 +5,7 @@ binlog-format=row innodb-autoinc-lock-mode=2 default-storage-engine=innodb +auto_increment_increment=3 wsrep-on=1 wsrep-provider=@ENV.WSREP_PROVIDER diff --git a/mysql-test/suite/galera_3nodes/r/galera_pc_weight.result b/mysql-test/suite/galera_3nodes/r/galera_pc_weight.result index 9f845ffe776..572982b76be 100644 --- a/mysql-test/suite/galera_3nodes/r/galera_pc_weight.result +++ b/mysql-test/suite/galera_3nodes/r/galera_pc_weight.result @@ -1,8 +1,10 @@ SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_weight'; VARIABLE_VALUE = 3 +1 SET GLOBAL wsrep_provider_options = 'pc.weight=3'; SELECT VARIABLE_VALUE = 5 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_weight'; VARIABLE_VALUE = 5 +1 SET GLOBAL wsrep_provider_options = 'gmcast.isolate=1'; SET SESSION wsrep_sync_wait=0; SET SESSION wsrep_on=OFF; @@ -12,6 +14,7 @@ Variable_name Value wsrep_cluster_size 2 SHOW STATUS LIKE 'wsrep_cluster_weight'; Variable_name Value +wsrep_cluster_weight 0 SHOW STATUS LIKE 'wsrep_cluster_status'; Variable_name Value wsrep_cluster_status non-Primary @@ -35,6 +38,7 @@ Variable_name Value wsrep_cluster_size 2 SHOW STATUS LIKE 'wsrep_cluster_weight'; Variable_name Value +wsrep_cluster_weight 0 SHOW STATUS LIKE 'wsrep_cluster_status'; Variable_name Value wsrep_cluster_status non-Primary @@ -52,6 +56,7 @@ Variable_name Value wsrep_local_state_comment Initialized SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_weight'; VARIABLE_VALUE = 3 +1 SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; VARIABLE_VALUE = 'Primary' 1 @@ -70,12 +75,14 @@ VARIABLE_VALUE = 'Synced' SET GLOBAL wsrep_provider_options = 'pc.weight=1'; SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_weight'; VARIABLE_VALUE = 1 +1 SET GLOBAL wsrep_provider_options = 'gmcast.isolate=0'; SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; VARIABLE_VALUE = 3 1 SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_weight'; VARIABLE_VALUE = 3 +1 SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; VARIABLE_VALUE = 'Primary' 1 @@ -96,6 +103,7 @@ VARIABLE_VALUE = 3 1 SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_weight'; VARIABLE_VALUE = 3 +1 SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; VARIABLE_VALUE = 'Primary' 1 @@ -116,6 +124,7 @@ VARIABLE_VALUE = 3 1 SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_weight'; VARIABLE_VALUE = 3 +1 SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; VARIABLE_VALUE = 'Primary' 1 diff --git a/mysql-test/suite/galera_3nodes/r/galera_safe_to_bootstrap.result b/mysql-test/suite/galera_3nodes/r/galera_safe_to_bootstrap.result index 21f747d280b..b346a2d6eb6 100644 --- a/mysql-test/suite/galera_3nodes/r/galera_safe_to_bootstrap.result +++ b/mysql-test/suite/galera_3nodes/r/galera_safe_to_bootstrap.result @@ -16,7 +16,17 @@ Killing server ... safe_to_bootstrap: 1 safe_to_bootstrap: 0 safe_to_bootstrap: 0 +CALL mtr.add_suppression("WSREP: no nodes coming from prim view, prim not possible"); +CALL mtr.add_suppression("WSREP: It may not be safe to bootstrap the cluster from this node"); +CALL mtr.add_suppression("WSREP: wsrep::connect(.*) failed: 7"); +CALL mtr.add_suppression("Aborting"); +CALL mtr.add_suppression("WSREP: moving position backwards: [0-9]+ -> 0"); CALL mtr.add_suppression("Failed to prepare for incremental state transfer"); +CALL mtr.add_suppression("WSREP: no nodes coming from prim view, prim not possible"); +CALL mtr.add_suppression("WSREP: It may not be safe to bootstrap the cluster from this node"); +CALL mtr.add_suppression("WSREP: wsrep::connect(.*) failed: 7"); +CALL mtr.add_suppression("Aborting"); +CALL mtr.add_suppression("WSREP: moving position backwards: [0-9]+ -> 0"); CALL mtr.add_suppression("Failed to prepare for incremental state transfer"); SHOW CREATE TABLE t1; Table Create Table diff --git a/mysql-test/suite/galera_3nodes/suite.pm b/mysql-test/suite/galera_3nodes/suite.pm index 66502c00c6b..a7c1bf79c06 100644 --- a/mysql-test/suite/galera_3nodes/suite.pm +++ b/mysql-test/suite/galera_3nodes/suite.pm @@ -81,11 +81,11 @@ sub skip_combinations { my %skip = (); $skip{'include/have_filekeymanagement.inc'} = 'needs file_key_management plugin' unless $ENV{FILE_KEY_MANAGEMENT_SO}; - $skip{'include/have_mariabackup.inc'} = 'Need mariabackup' + $skip{'suite/galera/include/have_mariabackup.inc'} = 'Need mariabackup' unless which(mariabackup); - $skip{'include/have_mariabackup.inc'} = 'Need ss' + $skip{'suite/galera/include/have_mariabackup.inc'} = 'Need ss' unless which(ss); - $skip{'include/have_mariabackup.inc'} = 'Need socat or nc' + $skip{'suite/galera/include/have_mariabackup.inc'} = 'Need socat or nc' unless $ENV{MTR_GALERA_TFMT}; %skip; } diff --git a/mysql-test/suite/galera_3nodes/t/galera_garbd.test b/mysql-test/suite/galera_3nodes/t/galera_garbd.test index a68ba8ce15b..2d03e8897b9 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_garbd.test +++ b/mysql-test/suite/galera_3nodes/t/galera_garbd.test @@ -7,10 +7,20 @@ --source include/have_innodb.inc --source include/big_test.inc ---echo Killing node #3 to free ports for garbd ... --let $galera_connection_name = node_3 --let $galera_server_number = 3 --source include/galera_connect.inc + +# Save original auto_increment_offset values. +--let $node_1=node_1 +--let $node_2=node_2 +--let $node_3=node_3 +--source ../galera/include/auto_increment_offset_save.inc + +--echo Killing node #3 to free ports for garbd ... +--connection node_3 +--let $gp3 = `SELECT SUBSTR(@@wsrep_provider_options, LOCATE('base_port =', @@wsrep_provider_options) + LENGTH('base_port = '))` +--let $galera_port_3 = `SELECT SUBSTR('$gp3', 1, LOCATE(';', '$gp3') - 1)` --source include/shutdown_mysqld.inc --connection node_1 @@ -18,7 +28,9 @@ --source include/wait_condition.inc --echo Starting garbd ... ---exec `dirname $WSREP_PROVIDER`/garb/garbd --address "gcomm://127.0.0.1:$NODE_GALERAPORT_1" --group my_wsrep_cluster --options 'base_port=$NODE_GALERAPORT_3' > $MYSQL_TMP_DIR/garbd.log 2>&1 & +--let $gp1 = `SELECT SUBSTR(@@wsrep_provider_options, LOCATE('base_port =', @@wsrep_provider_options) + LENGTH('base_port = '))` +--let $galera_port_1 = `SELECT SUBSTR('$gp1', 1, LOCATE(';', '$gp1') - 1)` +--exec `dirname $WSREP_PROVIDER`/../../bin/garb/garbd --address "gcomm://127.0.0.1:$galera_port_1" --group my_wsrep_cluster --options 'base_port=$galera_port_3' > $MYSQL_TMP_DIR/garbd.log 2>&1 & --sleep 5 @@ -32,7 +44,7 @@ INSERT INTO t1 VALUES (1); SELECT COUNT(*) = 1 FROM t1; --echo Killing garbd ... ---exec pkill --oldest --full garbd.*$NODE_GALERAPORT_3 +--exec pkill --oldest --full garbd.*$galera_port_3 --sleep 5 @@ -51,6 +63,8 @@ DROP TABLE t1; --connection node_3 --source include/start_mysqld.inc +# Restore original auto_increment_offset values. +--source ../galera/include/auto_increment_offset_restore.inc # Workaround for galera#101 diff --git a/mysql-test/suite/galera_3nodes/t/galera_innobackupex_backup.test b/mysql-test/suite/galera_3nodes/t/galera_innobackupex_backup.test index 8dfb4660f3e..cd5c020ae38 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_innobackupex_backup.test +++ b/mysql-test/suite/galera_3nodes/t/galera_innobackupex_backup.test @@ -4,7 +4,7 @@ --source include/galera_cluster.inc --source include/have_innodb.inc ---source include/have_mariabackup.inc +--source suite/galera/include/have_mariabackup.inc --let $galera_connection_name = node_3 --let $galera_server_number = 3 diff --git a/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup.test b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup.test index 8cbd8cf2454..84c33251c98 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup.test +++ b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup.test @@ -1,6 +1,6 @@ --source include/galera_cluster.inc --source include/check_ipv6.inc ---source include/have_mariabackup.inc +--source suite/galera/include/have_mariabackup.inc # Confirm that initial handshake happened over ipv6 diff --git a/mysql-test/suite/galera_3nodes/t/galera_ipv6_mysqldump.opt b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mysqldump.opt new file mode 100644 index 00000000000..c2bb4d156af --- /dev/null +++ b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mysqldump.opt @@ -0,0 +1 @@ +--bind-address=:: diff --git a/mysql-test/suite/galera_3nodes/t/galera_ipv6_rsync.opt b/mysql-test/suite/galera_3nodes/t/galera_ipv6_rsync.opt new file mode 100644 index 00000000000..c2bb4d156af --- /dev/null +++ b/mysql-test/suite/galera_3nodes/t/galera_ipv6_rsync.opt @@ -0,0 +1 @@ +--bind-address=:: diff --git a/mysql-test/suite/galera_3nodes/t/galera_ist_gcache_rollover.cnf b/mysql-test/suite/galera_3nodes/t/galera_ist_gcache_rollover.cnf index 821175220ac..303087dffbb 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_ist_gcache_rollover.cnf +++ b/mysql-test/suite/galera_3nodes/t/galera_ist_gcache_rollover.cnf @@ -1,11 +1,11 @@ !include ../galera_3nodes.cnf [mysqld.1] -wsrep_provider_options='base_port=@mysqld.1.#galera_port;pc.ignore_sb=true;gcache.size=1M' +wsrep_provider_options='repl.causal_read_timeout=PT90S;base_port=@mysqld.1.#galera_port;evs.suspect_timeout=PT10S;evs.inactive_timeout=PT30S;evs.install_timeout=PT15S;pc.ignore_sb=true;gcache.size=1M' [mysqld.2] -wsrep_provider_options='base_port=@mysqld.2.#galera_port;pc.ignore_sb=true;gcache.size=1M' +wsrep_provider_options='repl.causal_read_timeout=PT90S;base_port=@mysqld.2.#galera_port;evs.suspect_timeout=PT10S;evs.inactive_timeout=PT30S;evs.install_timeout=PT15S;pc.ignore_sb=true;gcache.size=1M' [mysqld.3] -wsrep_provider_options='base_port=@mysqld.3.#galera_port;pc.ignore_sb=true;gcache.size=1M' +wsrep_provider_options='repl.causal_read_timeout=PT90S;base_port=@mysqld.3.#galera_port;evs.suspect_timeout=PT10S;evs.inactive_timeout=PT30S;evs.install_timeout=PT15S;pc.ignore_sb=true;gcache.size=1M' diff --git a/mysql-test/suite/galera_3nodes/t/galera_ist_gcache_rollover.test b/mysql-test/suite/galera_3nodes/t/galera_ist_gcache_rollover.test index 8575d99f066..ebc756d60b1 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_ist_gcache_rollover.test +++ b/mysql-test/suite/galera_3nodes/t/galera_ist_gcache_rollover.test @@ -17,6 +17,13 @@ --let $galera_server_number = 3 --source include/galera_connect.inc +# Save original auto_increment_offset values. +--let $node_1=node_1 +--let $node_2=node_2 +--let $node_3=node_3 +--source ../galera/include/auto_increment_offset_save.inc + +--connection node_1 CREATE TABLE t1 (f1 INTEGER PRIMARY KEY); INSERT INTO t1 VALUES (01), (02), (03), (04), (05); @@ -99,3 +106,9 @@ SELECT LENGTH(f1) = 512 * 1024 FROM t2; CALL mtr.add_suppression("WSREP: Unsupported protocol downgrade: incremental data collection disabled"); DROP TABLE t1, t2; + +# Restore original auto_increment_offset values. +--source ../galera/include/auto_increment_offset_restore.inc + +--let $galera_cluster_size=3 +--source include/galera_end.inc diff --git a/mysql-test/suite/galera_3nodes/t/galera_safe_to_bootstrap.test b/mysql-test/suite/galera_3nodes/t/galera_safe_to_bootstrap.test index 88d0cfba4f4..b7b6c66e5ad 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_safe_to_bootstrap.test +++ b/mysql-test/suite/galera_3nodes/t/galera_safe_to_bootstrap.test @@ -1,8 +1,19 @@ # # Test the safe_to_bootstrap in grastate.dat # - --source include/galera_cluster.inc + +--let $galera_connection_name = node_3 +--let $galera_server_number = 3 +--source include/galera_connect.inc + +# Save original auto_increment_offset values. +--let $node_1=node_1 +--let $node_2=node_2 +--let $node_3=node_3 +--source ../galera/include/auto_increment_offset_save.inc + +--connection node_1 CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; # @@ -47,8 +58,6 @@ CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; # # Shut down one more node # - ---connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3 --connection node_3 --source include/shutdown_mysqld.inc @@ -129,9 +138,9 @@ SET SESSION wsrep_on = OFF; # --error 1 ---exec $MYSQLD --defaults-group-suffix=.2 --defaults-file=$MYSQLTEST_VARDIR/my.cnf --wsrep-new-cluster | grep 'This node is not safe to bootstrap the cluster' +--exec $MYSQLD --defaults-group-suffix=.2 --defaults-file=$MYSQLTEST_VARDIR/my.cnf --wsrep-new-cluster --wsrep-cluster-address='gcomm://' | grep 'This node is not safe to bootstrap the cluster' --error 1 ---exec $MYSQLD --defaults-group-suffix=.3 --defaults-file=$MYSQLTEST_VARDIR/my.cnf --wsrep-new-cluster | grep 'This node is not safe to bootstrap the cluster' +--exec $MYSQLD --defaults-group-suffix=.3 --defaults-file=$MYSQLTEST_VARDIR/my.cnf --wsrep-new-cluster --wsrep-cluster-address='gcomm://' | grep 'This node is not safe to bootstrap the cluster' # # Attempt to bootstrap starting from node #1, should succeed @@ -154,10 +163,23 @@ SET SESSION wsrep_on = OFF; --source include/wait_condition.inc --connection node_2 +CALL mtr.add_suppression("WSREP: no nodes coming from prim view, prim not possible"); +CALL mtr.add_suppression("WSREP: It may not be safe to bootstrap the cluster from this node"); +CALL mtr.add_suppression("WSREP: wsrep::connect(.*) failed: 7"); +CALL mtr.add_suppression("Aborting"); +CALL mtr.add_suppression("WSREP: moving position backwards: [0-9]+ -> 0"); CALL mtr.add_suppression("Failed to prepare for incremental state transfer"); --connection node_3 +CALL mtr.add_suppression("WSREP: no nodes coming from prim view, prim not possible"); +CALL mtr.add_suppression("WSREP: It may not be safe to bootstrap the cluster from this node"); +CALL mtr.add_suppression("WSREP: wsrep::connect(.*) failed: 7"); +CALL mtr.add_suppression("Aborting"); +CALL mtr.add_suppression("WSREP: moving position backwards: [0-9]+ -> 0"); CALL mtr.add_suppression("Failed to prepare for incremental state transfer"); SHOW CREATE TABLE t1; DROP TABLE t1; + +# Restore original auto_increment_offset values. +--source ../galera/include/auto_increment_offset_restore.inc diff --git a/mysql-test/suite/galera_3nodes/t/galera_var_dirty_reads2.test b/mysql-test/suite/galera_3nodes/t/galera_var_dirty_reads2.test index 129ba2e1f38..e3f94a012b8 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_var_dirty_reads2.test +++ b/mysql-test/suite/galera_3nodes/t/galera_var_dirty_reads2.test @@ -5,6 +5,17 @@ --source include/galera_cluster.inc --source include/have_innodb.inc +--let $galera_connection_name = node_3 +--let $galera_server_number = 3 +--source include/galera_connect.inc + +# Save original auto_increment_offset values. +--let $node_1=node_1 +--let $node_2=node_2 +--let $node_3=node_3 +--source ../galera/include/auto_increment_offset_save.inc + +--connection node_1 CREATE TABLE t1 (f1 INTEGER); INSERT INTO t1 VALUES (1); @@ -110,3 +121,6 @@ SET GLOBAL wsrep_provider_options='gmcast.isolate=0'; --source include/wait_condition.inc DROP TABLE t1; + +# Restore original auto_increment_offset values. +--source ../galera/include/auto_increment_offset_restore.inc diff --git a/scripts/wsrep_sst_mariabackup.sh b/scripts/wsrep_sst_mariabackup.sh index 4891ade7c3c..3fd93a90c1e 100644 --- a/scripts/wsrep_sst_mariabackup.sh +++ b/scripts/wsrep_sst_mariabackup.sh @@ -520,7 +520,7 @@ kill_xtrabackup() setup_ports() { if [[ "$WSREP_SST_OPT_ROLE" == "donor" ]];then - if [[ ${WSREP_SST_OPT_ADDR:0:1} == '[' ]];then + if [ "${WSREP_SST_OPT_ADDR#\[}" != "$WSREP_SST_OPT_ADDR" ]; then remain=$(echo $WSREP_SST_OPT_ADDR | awk -F '\\][:/]' '{ print $2 }') REMOTEIP=$(echo $WSREP_SST_OPT_ADDR | awk -F '\\]:' '{ print $1 }')"]" SST_PORT=$(echo $remain | awk -F '[:/]' '{ print $1 }') @@ -533,7 +533,7 @@ setup_ports() sst_ver=$(echo $WSREP_SST_OPT_ADDR | awk -F '[:/]' '{ print $5 }') fi else - if [[ ${WSREP_SST_OPT_ADDR:0:1} == '[' ]];then + if [ "${WSREP_SST_OPT_ADDR#\[}" != "$WSREP_SST_OPT_ADDR" ]; then SST_PORT=$(echo ${WSREP_SST_OPT_ADDR} | awk -F '\\]:' '{ print $2 }') else SST_PORT=$(echo ${WSREP_SST_OPT_ADDR} | awk -F ':' '{ print $2 }') @@ -952,7 +952,7 @@ then if [ -z "${SST_PORT}" ] then SST_PORT=4444 - if [[ ${ADDR:0:1} == '[' ]];then + if [ "${ADDR#\[}" != "$ADDR" ]; then ADDR="$(echo ${WSREP_SST_OPT_ADDR} | awk -F '\\]:' '{ print $1 }')]:${SST_PORT}" else ADDR="$(echo ${WSREP_SST_OPT_ADDR} | awk -F ':' '{ print $1 }'):${SST_PORT}" diff --git a/scripts/wsrep_sst_rsync.sh b/scripts/wsrep_sst_rsync.sh index 1bded37a6b6..6b1a7eb6ee6 100644 --- a/scripts/wsrep_sst_rsync.sh +++ b/scripts/wsrep_sst_rsync.sh @@ -364,7 +364,7 @@ then rm -rf "$RSYNC_PID" ADDR=$WSREP_SST_OPT_ADDR - if [[ ${ADDR:0:1} == '[' ]]; then + if [ "${ADDR#\[}" != "$ADDR" ]; then RSYNC_PORT=$(echo $ADDR | awk -F '\\]:' '{ print $2 }') RSYNC_ADDR=$(echo $ADDR | awk -F '\\]:' '{ print $1 }')"]" else From 17c3f147f82ca6f0ea45fa3807e4e770659fbba6 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 13 Feb 2019 09:03:12 +1100 Subject: [PATCH 098/106] cmake/submodules: notify user about gitconfig for automatic update --- cmake/submodules.cmake | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/cmake/submodules.cmake b/cmake/submodules.cmake index 4181f4cd01e..6e019674c1f 100644 --- a/cmake/submodules.cmake +++ b/cmake/submodules.cmake @@ -10,7 +10,12 @@ IF(GIT_EXECUTABLE AND EXISTS "${CMAKE_SOURCE_DIR}/.git") WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" OUTPUT_VARIABLE cmake_update_submodules RESULT_VARIABLE git_config_get_result) - IF(git_config_get_result EQUAL 128 OR cmake_update_submodules MATCHES no) + IF(cmake_update_submodules MATCHES no) + SET(update_result 0) + SET(SUBMODULE_UPDATE_CONFIG_MESSAGE +"\n\nTo update submodules automaticly, set cmake.update-submodules to 'yes', or 'force' to update automaticly: + ${GIT_EXECUTABLE} config cmake.update-submodules yes") + ELSEIF(git_config_get_result EQUAL 128) SET(update_result 0) ELSEIF (cmake_update_submodules MATCHES force) MESSAGE(STATUS "Updating submodules (forced)") @@ -31,7 +36,6 @@ ENDIF() IF(update_result OR NOT EXISTS ${CMAKE_SOURCE_DIR}/libmariadb/CMakeLists.txt) MESSAGE(FATAL_ERROR "No MariaDB Connector/C! Run - git submodule update --init -Then restart the build. -") + ${GIT_EXECUTABLE} submodule update --init +Then restart the build.${SUBMODULE_UPDATE_CONFIG_MESSAGE}") ENDIF() From 43a7409bb8425b976fd890e725eb85071c3d63b6 Mon Sep 17 00:00:00 2001 From: Laurynas Biveinis Date: Wed, 13 Feb 2019 17:48:12 +1100 Subject: [PATCH 099/106] typo cmake/submodules.cmake Co-Authored-By: grooverdan --- cmake/submodules.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/submodules.cmake b/cmake/submodules.cmake index 6e019674c1f..34d1f37c956 100644 --- a/cmake/submodules.cmake +++ b/cmake/submodules.cmake @@ -13,7 +13,7 @@ IF(GIT_EXECUTABLE AND EXISTS "${CMAKE_SOURCE_DIR}/.git") IF(cmake_update_submodules MATCHES no) SET(update_result 0) SET(SUBMODULE_UPDATE_CONFIG_MESSAGE -"\n\nTo update submodules automaticly, set cmake.update-submodules to 'yes', or 'force' to update automaticly: +"\n\nTo update submodules automatically, set cmake.update-submodules to 'yes', or 'force' to update automatically: ${GIT_EXECUTABLE} config cmake.update-submodules yes") ELSEIF(git_config_get_result EQUAL 128) SET(update_result 0) From 40b4f9c907e58a4b65677cc9e5b3f5deca8b7cb3 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Thu, 14 Feb 2019 11:54:34 +0100 Subject: [PATCH 100/106] MDEV-18575 remove innodb-encrypt-log parameter from mariabackup The variable is obsolete. In mariabackup --backup, encryption plugin loading code sets the value this parameter to the same as in server. In mariabackup --prepare, no new redo log is generated, and xtrabackup_logfile is removed after it anyway. --- extra/mariabackup/xtrabackup.cc | 5 ----- 1 file changed, 5 deletions(-) diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index 38d871d965d..ecbd118aa3b 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -803,7 +803,6 @@ enum options_xtrabackup OPT_INNODB_LOG_CHECKSUMS, OPT_XTRA_INCREMENTAL_FORCE_SCAN, OPT_DEFAULTS_GROUP, - OPT_INNODB_ENCRYPT_LOG, OPT_CLOSE_FILES, OPT_CORE_FILE, @@ -1376,10 +1375,6 @@ struct my_option xb_server_options[] = &xb_plugin_dir, &xb_plugin_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, - { "innodb-encrypt-log", OPT_INNODB_ENCRYPT_LOG, "Whether to encrypt innodb log", - &srv_encrypt_log, &srv_encrypt_log, - 0, GET_BOOL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, - {"innodb-log-checksums", OPT_INNODB_LOG_CHECKSUMS, "Whether to require checksums for InnoDB redo log blocks", &innodb_log_checksums, &innodb_log_checksums, From 3a42926c88f8c3c582a7af7e482f6aded0c74f89 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Mon, 18 Feb 2019 18:56:32 +0100 Subject: [PATCH 101/106] MDEV-18204 Fix rocksdb incremental backup Fix incremental prepare to copy #rocksdb subdirectory from the incremental dir. --- client/mysqltest.cc | 59 +----------------- extra/mariabackup/backup_copy.cc | 13 ++++ include/my_sys.h | 1 + .../suite/mariabackup/incremental_rocksdb.opt | 1 + .../mariabackup/incremental_rocksdb.result | 19 ++++++ .../mariabackup/incremental_rocksdb.test | 38 ++++++++++++ mysys/my_delete.c | 60 +++++++++++++++++++ 7 files changed, 133 insertions(+), 58 deletions(-) create mode 100644 mysql-test/suite/mariabackup/incremental_rocksdb.opt create mode 100644 mysql-test/suite/mariabackup/incremental_rocksdb.result create mode 100644 mysql-test/suite/mariabackup/incremental_rocksdb.test diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 00bea466912..1a6c22573e0 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -4019,63 +4019,6 @@ void do_mkdir(struct st_command *command) } -/* - Remove directory recursively. -*/ -static int rmtree(const char *dir) -{ - char path[FN_REFLEN]; - char sep[]={ FN_LIBCHAR, 0 }; - int err=0; - - MY_DIR *dir_info= my_dir(dir, MYF(MY_DONT_SORT | MY_WANT_STAT)); - if (!dir_info) - return 1; - - for (uint i= 0; i < dir_info->number_of_files; i++) - { - FILEINFO *file= dir_info->dir_entry + i; - /* Skip "." and ".." */ - if (!strcmp(file->name, ".") || !strcmp(file->name, "..")) - continue; - - strxnmov(path, sizeof(path), dir, sep, file->name, NULL); - - if (!MY_S_ISDIR(file->mystat->st_mode)) - { - err= my_delete(path, 0); -#ifdef _WIN32 - /* - On Windows, check and possible reset readonly attribute. - my_delete(), or DeleteFile does not remove theses files. - */ - if (err) - { - DWORD attr= GetFileAttributes(path); - if (attr != INVALID_FILE_ATTRIBUTES && - (attr & FILE_ATTRIBUTE_READONLY)) - { - SetFileAttributes(path, attr &~ FILE_ATTRIBUTE_READONLY); - err= my_delete(path, 0); - } - } -#endif - } - else - err= rmtree(path); - - if(err) - break; - } - - my_dirend(dir_info); - - if (!err) - err= rmdir(dir); - - return err; -} - /* SYNOPSIS @@ -4103,7 +4046,7 @@ void do_rmdir(struct st_command *command) DBUG_VOID_RETURN; DBUG_PRINT("info", ("removing directory: %s", ds_dirname.str)); - if (rmtree(ds_dirname.str)) + if (my_rmtree(ds_dirname.str, MYF(0))) handle_command_error(command, 1, errno); dynstr_free(&ds_dirname); diff --git a/extra/mariabackup/backup_copy.cc b/extra/mariabackup/backup_copy.cc index b0ad000cb90..bd2f28baa92 100644 --- a/extra/mariabackup/backup_copy.cc +++ b/extra/mariabackup/backup_copy.cc @@ -1635,6 +1635,19 @@ ibx_copy_incremental_over_full() } + if (directory_exists(ROCKSDB_BACKUP_DIR, false)) { + if (my_rmtree(ROCKSDB_BACKUP_DIR, MYF(0))) { + die("Can't remove " ROCKSDB_BACKUP_DIR); + } + } + snprintf(path, sizeof(path), "%s/" ROCKSDB_BACKUP_DIR, xtrabackup_incremental_dir); + if (directory_exists(path, false)) { + if (my_mkdir(ROCKSDB_BACKUP_DIR, 0777, MYF(0))) { + die("my_mkdir failed for " ROCKSDB_BACKUP_DIR); + } + copy_or_move_dir(path, ROCKSDB_BACKUP_DIR, true, true); + } + cleanup: if (it != NULL) { datadir_iter_free(it); diff --git a/include/my_sys.h b/include/my_sys.h index 3d233f8b6a6..50a659239b3 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -627,6 +627,7 @@ extern int (*mysys_test_invalid_symlink)(const char *filename); extern int my_copy(const char *from,const char *to,myf MyFlags); extern int my_delete(const char *name,myf MyFlags); +extern int my_rmtree(const char *name, myf Myflags); extern int my_getwd(char * buf,size_t size,myf MyFlags); extern int my_setwd(const char *dir,myf MyFlags); extern int my_lock(File fd,int op,my_off_t start, my_off_t length,myf MyFlags); diff --git a/mysql-test/suite/mariabackup/incremental_rocksdb.opt b/mysql-test/suite/mariabackup/incremental_rocksdb.opt new file mode 100644 index 00000000000..e582413e5b5 --- /dev/null +++ b/mysql-test/suite/mariabackup/incremental_rocksdb.opt @@ -0,0 +1 @@ +--plugin-load=$HA_ROCKSDB_SO \ No newline at end of file diff --git a/mysql-test/suite/mariabackup/incremental_rocksdb.result b/mysql-test/suite/mariabackup/incremental_rocksdb.result new file mode 100644 index 00000000000..4e5b9c43389 --- /dev/null +++ b/mysql-test/suite/mariabackup/incremental_rocksdb.result @@ -0,0 +1,19 @@ +call mtr.add_suppression("InnoDB: New log files created"); +CREATE TABLE t(i INT PRIMARY KEY) ENGINE ROCKSDB; +INSERT INTO t VALUES(1); +# Create full backup , modify table, then create incremental/differential backup +DROP TABLE t; +CREATE TABLE t2(i INT PRIMARY KEY) ENGINE ROCKSDB; +INSERT INTO t2 VALUES(2); +# Prepare full backup, apply incremental one +# Restore and check results +# shutdown server +# remove datadir +# xtrabackup move back +# restart server +SELECT * FROM t2; +i +2 +DROP TABLE t2; +DROP TABLE t; +ERROR 42S02: Unknown table 'test.t' diff --git a/mysql-test/suite/mariabackup/incremental_rocksdb.test b/mysql-test/suite/mariabackup/incremental_rocksdb.test new file mode 100644 index 00000000000..32bce885c32 --- /dev/null +++ b/mysql-test/suite/mariabackup/incremental_rocksdb.test @@ -0,0 +1,38 @@ +--source include/have_rocksdb.inc +call mtr.add_suppression("InnoDB: New log files created"); + +let $basedir=$MYSQLTEST_VARDIR/tmp/backup; +let $incremental_dir=$MYSQLTEST_VARDIR/tmp/backup_inc1; + +CREATE TABLE t(i INT PRIMARY KEY) ENGINE ROCKSDB; +INSERT INTO t VALUES(1); + +echo # Create full backup , modify table, then create incremental/differential backup; +--disable_result_log +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$basedir; +--enable_result_log +DROP TABLE t; +CREATE TABLE t2(i INT PRIMARY KEY) ENGINE ROCKSDB; +INSERT INTO t2 VALUES(2); +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$incremental_dir --incremental-basedir=$basedir; + +--disable_result_log +echo # Prepare full backup, apply incremental one; +exec $XTRABACKUP --prepare --target-dir=$basedir; + +exec $XTRABACKUP --prepare --target-dir=$basedir --incremental-dir=$incremental_dir ; + +echo # Restore and check results; +let $targetdir=$basedir; +-- source include/restart_and_restore.inc +--enable_result_log + +SELECT * FROM t2; +DROP TABLE t2; +--error ER_BAD_TABLE_ERROR +DROP TABLE t; + +# Cleanup +rmdir $basedir; +rmdir $incremental_dir; + diff --git a/mysys/my_delete.c b/mysys/my_delete.c index 0faf6079d98..cff107508d4 100644 --- a/mysys/my_delete.c +++ b/mysys/my_delete.c @@ -18,6 +18,7 @@ #include #ifdef _WIN32 +#include /* rmdir */ static int my_win_unlink(const char *name); #endif @@ -160,3 +161,62 @@ error: DBUG_RETURN(-1); } #endif + +/* + Remove directory recursively. +*/ +int my_rmtree(const char *dir, myf MyFlags) +{ + char path[FN_REFLEN]; + char sep[] = { FN_LIBCHAR, 0 }; + int err = 0; + + MY_DIR *dir_info = my_dir(dir, MYF(MY_DONT_SORT | MY_WANT_STAT)); + if (!dir_info) + return 1; + + for (uint i = 0; i < dir_info->number_of_files; i++) + { + FILEINFO *file = dir_info->dir_entry + i; + /* Skip "." and ".." */ + if (!strcmp(file->name, ".") || !strcmp(file->name, "..")) + continue; + + strxnmov(path, sizeof(path), dir, sep, file->name, NULL); + + if (!MY_S_ISDIR(file->mystat->st_mode)) + { + err = my_delete(path, MyFlags); +#ifdef _WIN32 + /* + On Windows, check and possible reset readonly attribute. + my_delete(), or DeleteFile does not remove theses files. + */ + if (err) + { + DWORD attr = GetFileAttributes(path); + if (attr != INVALID_FILE_ATTRIBUTES && + (attr & FILE_ATTRIBUTE_READONLY)) + { + SetFileAttributes(path, attr &~FILE_ATTRIBUTE_READONLY); + err = my_delete(path, MyFlags); + } + } +#endif + } + else + err = my_rmtree(path, MyFlags); + + if (err) + break; + } + + my_dirend(dir_info); + + if (!err) + err = rmdir(dir); + + return err; +} + + From 98e185ee373310291825fe6ac87f45afe6a3ccf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 18 Feb 2019 21:42:58 +0200 Subject: [PATCH 102/106] MDEV-18630 Uninitialised value in FOREIGN KEY error message dict_create_foreign_constraints_low(): Clean up the way in which the error messages are initialized, and ensure that the table name is always initialized. --- mysql-test/suite/innodb/r/foreign_key.result | 13 ++++++ mysql-test/suite/innodb/t/foreign_key.test | 12 +++++ storage/innobase/dict/dict0dict.cc | 49 +++++++------------- storage/xtradb/dict/dict0dict.cc | 49 +++++++------------- 4 files changed, 59 insertions(+), 64 deletions(-) diff --git a/mysql-test/suite/innodb/r/foreign_key.result b/mysql-test/suite/innodb/r/foreign_key.result index d28ade4c543..3c881b43504 100644 --- a/mysql-test/suite/innodb/r/foreign_key.result +++ b/mysql-test/suite/innodb/r/foreign_key.result @@ -92,3 +92,16 @@ Warnings: Warning 1088 failed to load FOREIGN KEY constraints ALTER TABLE t1 ADD FULLTEXT INDEX ft2 (f); DROP TABLE t1; +# +# MDEV-18630 Conditional jump or move depends on uninitialised value +# in ib_push_warning / dict_create_foreign_constraints_low +# +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +ALTER IGNORE TABLE t1 ADD FOREIGN KEY (a) REFERENCES t2 (b); +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") +SHOW WARNINGS; +Level Code Message +Warning 150 Alter table test/#sql-temporary with foreign key constraint failed. Referenced table `test`.`t2` not found in the data dictionary near 'FOREIGN KEY (a) REFERENCES t2 (b)'. +Error 1005 Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") +Warning 1215 Cannot add foreign key constraint +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/foreign_key.test b/mysql-test/suite/innodb/t/foreign_key.test index 3fc8449a6b0..f4117d2d780 100644 --- a/mysql-test/suite/innodb/t/foreign_key.test +++ b/mysql-test/suite/innodb/t/foreign_key.test @@ -113,3 +113,15 @@ SET SESSION FOREIGN_KEY_CHECKS = ON; ALTER TABLE t1 ADD FULLTEXT INDEX ft1 (f); ALTER TABLE t1 ADD FULLTEXT INDEX ft2 (f); DROP TABLE t1; + +--echo # +--echo # MDEV-18630 Conditional jump or move depends on uninitialised value +--echo # in ib_push_warning / dict_create_foreign_constraints_low +--echo # +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +--replace_regex /#sql-[0-9_a-f-]*/#sql-temporary/ +--error ER_CANT_CREATE_TABLE +ALTER IGNORE TABLE t1 ADD FOREIGN KEY (a) REFERENCES t2 (b); +--replace_regex /#sql-[0-9_a-f-]*/#sql-temporary/ +SHOW WARNINGS; +DROP TABLE t1; diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index 2a37db4e076..06c6c3effab 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -4396,7 +4396,6 @@ dict_create_foreign_constraints_low( const char* create_table_name; const char* orig; char create_name[MAX_TABLE_NAME_LEN + 1]; - char operation[8]; ut_ad(!srv_read_only_mode); ut_ad(mutex_own(&(dict_sys->mutex))); @@ -4407,41 +4406,33 @@ dict_create_foreign_constraints_low( orig = ptr; ptr = dict_accept(cs, ptr, "ALTER", &success); - strcpy((char *)operation, success ? "Alter " : "Create "); + const char* const operation = success ? "Alter " : "Create "; if (!success) { orig = ptr; ptr = dict_scan_to(ptr, "CREATE"); ptr = dict_scan_to(ptr, "TABLE"); ptr = dict_accept(cs, ptr, "TABLE", &success); + create_table_name = NULL; if (success) { ptr = dict_scan_table_name(cs, ptr, &table_to_create, name, - &success, heap, &create_table_name); + &success, heap, &create_table_name); } - if (success) { - char *bufend; - bufend = innobase_convert_name((char *)create_name, MAX_TABLE_NAME_LEN, - create_table_name, strlen(create_table_name), - trx->mysql_thd, TRUE); - create_name[bufend-create_name]='\0'; - ptr = orig; - } else { - char *bufend; - ptr = orig; - bufend = innobase_convert_name((char *)create_name, MAX_TABLE_NAME_LEN, - name, strlen(name), trx->mysql_thd, TRUE); - create_name[bufend-create_name]='\0'; - } - - goto loop; + ptr = orig; + const char* n = create_table_name ? create_table_name : name; + char *bufend = innobase_convert_name(create_name, MAX_TABLE_NAME_LEN, + n, strlen(n), trx->mysql_thd, TRUE); + create_name[bufend-create_name] = '\0'; + } else { + strncpy(create_name, name, sizeof create_name); + create_name[(sizeof create_name) - 1] = '\0'; } if (table == NULL) { mutex_enter(&dict_foreign_err_mutex); dict_foreign_error_report_low(ef, create_name); - dict_foreign_error_report_low(ef, create_name); fprintf(ef, "%s table %s with foreign key constraint" " failed. Table %s not found from data dictionary." " Error close to %s.\n", @@ -4476,19 +4467,13 @@ dict_create_foreign_constraints_low( ptr = dict_scan_table_name(cs, ptr, &table_to_alter, name, &success, heap, &referenced_table_name); - if (table_to_alter) { - char *bufend; - bufend = innobase_convert_name((char *)create_name, MAX_TABLE_NAME_LEN, - table_to_alter->name, strlen(table_to_alter->name), - trx->mysql_thd, TRUE); + { + const char* n = table_to_alter + ? table_to_alter->name : referenced_table_name; + char* bufend = innobase_convert_name( + create_name, MAX_TABLE_NAME_LEN, n, strlen(n), + trx->mysql_thd, TRUE); create_name[bufend-create_name]='\0'; - } else { - char *bufend; - bufend = innobase_convert_name((char *)create_name, MAX_TABLE_NAME_LEN, - referenced_table_name, strlen(referenced_table_name), - trx->mysql_thd, TRUE); - create_name[bufend-create_name]='\0'; - } if (!success) { diff --git a/storage/xtradb/dict/dict0dict.cc b/storage/xtradb/dict/dict0dict.cc index 1eb0a53e0b0..1c489d13f1a 100644 --- a/storage/xtradb/dict/dict0dict.cc +++ b/storage/xtradb/dict/dict0dict.cc @@ -4405,7 +4405,6 @@ dict_create_foreign_constraints_low( const char* create_table_name; const char* orig; char create_name[MAX_TABLE_NAME_LEN + 1]; - char operation[8]; ut_ad(!srv_read_only_mode); ut_ad(mutex_own(&(dict_sys->mutex))); @@ -4416,41 +4415,33 @@ dict_create_foreign_constraints_low( orig = ptr; ptr = dict_accept(cs, ptr, "ALTER", &success); - strcpy((char *)operation, success ? "Alter " : "Create "); + const char* const operation = success ? "Alter " : "Create "; if (!success) { orig = ptr; ptr = dict_scan_to(ptr, "CREATE"); ptr = dict_scan_to(ptr, "TABLE"); ptr = dict_accept(cs, ptr, "TABLE", &success); + create_table_name = NULL; if (success) { ptr = dict_scan_table_name(cs, ptr, &table_to_create, name, - &success, heap, &create_table_name); + &success, heap, &create_table_name); } - if (success) { - char *bufend; - bufend = innobase_convert_name((char *)create_name, MAX_TABLE_NAME_LEN, - create_table_name, strlen(create_table_name), - trx->mysql_thd, TRUE); - create_name[bufend-create_name]='\0'; - ptr = orig; - } else { - char *bufend; - ptr = orig; - bufend = innobase_convert_name((char *)create_name, MAX_TABLE_NAME_LEN, - name, strlen(name), trx->mysql_thd, TRUE); - create_name[bufend-create_name]='\0'; - } - - goto loop; + ptr = orig; + const char* n = create_table_name ? create_table_name : name; + char *bufend = innobase_convert_name(create_name, MAX_TABLE_NAME_LEN, + n, strlen(n), trx->mysql_thd, TRUE); + create_name[bufend-create_name] = '\0'; + } else { + strncpy(create_name, name, sizeof create_name); + create_name[(sizeof create_name) - 1] = '\0'; } if (table == NULL) { mutex_enter(&dict_foreign_err_mutex); dict_foreign_error_report_low(ef, create_name); - dict_foreign_error_report_low(ef, create_name); fprintf(ef, "%s table %s with foreign key constraint" " failed. Table %s not found from data dictionary." " Error close to %s.\n", @@ -4485,19 +4476,13 @@ dict_create_foreign_constraints_low( ptr = dict_scan_table_name(cs, ptr, &table_to_alter, name, &success, heap, &referenced_table_name); - if (table_to_alter) { - char *bufend; - bufend = innobase_convert_name((char *)create_name, MAX_TABLE_NAME_LEN, - table_to_alter->name, strlen(table_to_alter->name), - trx->mysql_thd, TRUE); + { + const char* n = table_to_alter + ? table_to_alter->name : referenced_table_name; + char* bufend = innobase_convert_name( + create_name, MAX_TABLE_NAME_LEN, n, strlen(n), + trx->mysql_thd, TRUE); create_name[bufend-create_name]='\0'; - } else { - char *bufend; - bufend = innobase_convert_name((char *)create_name, MAX_TABLE_NAME_LEN, - referenced_table_name, strlen(referenced_table_name), - trx->mysql_thd, TRUE); - create_name[bufend-create_name]='\0'; - } if (!success) { From d2fc9d09da007d41d83e9e29a9f2911eb7f8feee Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Tue, 19 Feb 2019 07:31:25 +0100 Subject: [PATCH 103/106] MDEV-18204 - fixup --- extra/mariabackup/backup_copy.cc | 24 ++++++++++++------------ mysys/my_delete.c | 3 ++- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/extra/mariabackup/backup_copy.cc b/extra/mariabackup/backup_copy.cc index bd2f28baa92..0059ae5b16a 100644 --- a/extra/mariabackup/backup_copy.cc +++ b/extra/mariabackup/backup_copy.cc @@ -1633,20 +1633,20 @@ ibx_copy_incremental_over_full() } } + if (directory_exists(ROCKSDB_BACKUP_DIR, false)) { + if (my_rmtree(ROCKSDB_BACKUP_DIR, MYF(0))) { + die("Can't remove " ROCKSDB_BACKUP_DIR); + } + } + snprintf(path, sizeof(path), "%s/" ROCKSDB_BACKUP_DIR, xtrabackup_incremental_dir); + if (directory_exists(path, false)) { + if (my_mkdir(ROCKSDB_BACKUP_DIR, 0777, MYF(0))) { + die("my_mkdir failed for " ROCKSDB_BACKUP_DIR); + } + copy_or_move_dir(path, ROCKSDB_BACKUP_DIR, true, true); + } } - if (directory_exists(ROCKSDB_BACKUP_DIR, false)) { - if (my_rmtree(ROCKSDB_BACKUP_DIR, MYF(0))) { - die("Can't remove " ROCKSDB_BACKUP_DIR); - } - } - snprintf(path, sizeof(path), "%s/" ROCKSDB_BACKUP_DIR, xtrabackup_incremental_dir); - if (directory_exists(path, false)) { - if (my_mkdir(ROCKSDB_BACKUP_DIR, 0777, MYF(0))) { - die("my_mkdir failed for " ROCKSDB_BACKUP_DIR); - } - copy_or_move_dir(path, ROCKSDB_BACKUP_DIR, true, true); - } cleanup: if (it != NULL) { diff --git a/mysys/my_delete.c b/mysys/my_delete.c index cff107508d4..a816d972d29 100644 --- a/mysys/my_delete.c +++ b/mysys/my_delete.c @@ -170,12 +170,13 @@ int my_rmtree(const char *dir, myf MyFlags) char path[FN_REFLEN]; char sep[] = { FN_LIBCHAR, 0 }; int err = 0; + uint i; MY_DIR *dir_info = my_dir(dir, MYF(MY_DONT_SORT | MY_WANT_STAT)); if (!dir_info) return 1; - for (uint i = 0; i < dir_info->number_of_files; i++) + for (i = 0; i < dir_info->number_of_files; i++) { FILEINFO *file = dir_info->dir_entry + i; /* Skip "." and ".." */ From 346e46089621e6951e076c82ed5690aa23dcb5fe Mon Sep 17 00:00:00 2001 From: Monty Date: Tue, 19 Feb 2019 10:51:34 +0200 Subject: [PATCH 104/106] Fixed bug in macro _ma_mark_page_with_transid() By pure chance the macro worked in the cases it was used, but better to get this fixed! --- storage/maria/ma_delete.c | 2 -- storage/maria/ma_write.c | 3 +-- storage/maria/maria_def.h | 4 ++-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/storage/maria/ma_delete.c b/storage/maria/ma_delete.c index 7921ab59a8f..5d66015b9ac 100644 --- a/storage/maria/ma_delete.c +++ b/storage/maria/ma_delete.c @@ -695,9 +695,7 @@ static int del(MARIA_HA *info, MARIA_KEY *key, key_start= keypos; if (tmp_key.flag & (SEARCH_USER_KEY_HAS_TRANSID | SEARCH_PAGE_KEY_HAS_TRANSID)) - { _ma_mark_page_with_transid(share, anc_page); - } /* Save pointer to next leaf on parent page */ if (!(*keyinfo->get_key)(&ret_key, page_flag, share->base.key_reflength, diff --git a/storage/maria/ma_write.c b/storage/maria/ma_write.c index 52954aded4f..fde0b3a7afd 100644 --- a/storage/maria/ma_write.c +++ b/storage/maria/ma_write.c @@ -843,9 +843,8 @@ int _ma_insert(register MARIA_HA *info, MARIA_KEY *key, a_length+=t_length; if (key->flag & (SEARCH_USER_KEY_HAS_TRANSID | SEARCH_PAGE_KEY_HAS_TRANSID)) - { _ma_mark_page_with_transid(share, anc_page); - } + anc_page->size= a_length; page_store_size(share, anc_page); diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h index 128e78da32b..eeb5625cb7e 100644 --- a/storage/maria/maria_def.h +++ b/storage/maria/maria_def.h @@ -777,8 +777,8 @@ struct st_maria_handler transid_korr((buff) + LSN_STORE_SIZE) #define _ma_store_keypage_flag(share,x,flag) x[(share)->keypage_header - KEYPAGE_USED_SIZE - KEYPAGE_FLAG_SIZE]= (flag) #define _ma_mark_page_with_transid(share, page) \ - (page)->flag|= KEYPAGE_FLAG_HAS_TRANSID; \ - (page)->buff[(share)->keypage_header - KEYPAGE_USED_SIZE - KEYPAGE_FLAG_SIZE]= (page)->flag; + do { (page)->flag|= KEYPAGE_FLAG_HAS_TRANSID; \ + (page)->buff[(share)->keypage_header - KEYPAGE_USED_SIZE - KEYPAGE_FLAG_SIZE]= (page)->flag; } while (0) #define KEYPAGE_KEY_VERSION(share, x) ((x) + \ (share)->keypage_header - \ From ca76fc4a3a1c5f393e1e34005975582e73e84365 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 19 Feb 2019 11:14:03 +0200 Subject: [PATCH 105/106] MDEV-18611: mariabackup silently ended during xtrabackup_copy_logfile() log_group_read_log_seg(): Always return false when returning before reading end_lsn. xtrabackup_copy_logfile(): On error, indicate whether a corrupt log record was encountered. Only xtrabackup_copy_logfile() in Mariabackup cared about the return value of the function. InnoDB crash recovery was not affected by this bug. --- extra/mariabackup/xtrabackup.cc | 5 ++++- storage/innobase/log/log0recv.cc | 11 +++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index ecbd118aa3b..acd11135289 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -2756,7 +2756,10 @@ static bool xtrabackup_copy_logfile(bool last = false) log_mutex_exit(); if (!start_lsn) { - die("xtrabackup_copy_logfile() failed."); + msg(recv_sys->found_corrupt_log + ? "xtrabackup_copy_logfile() failed: corrupt log." + : "xtrabackup_copy_logfile() failed."); + return true; } } while (start_lsn == end_lsn); diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index bcd6254ebd6..0c0046da989 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -2,7 +2,7 @@ Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. -Copyright (c) 2013, 2018, MariaDB Corporation. +Copyright (c) 2013, 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 @@ -807,7 +807,9 @@ loop: happen when InnoDB was killed while it was writing redo log. We simply treat this as an abrupt end of the redo log. */ +fail: end_lsn = *start_lsn; + success = false; break; } @@ -829,9 +831,7 @@ loop: << log_block_get_checkpoint_no(buf) << " expected: " << crc << " found: " << cksum; - end_lsn = *start_lsn; - success = false; - break; + goto fail; } if (group->is_encrypted()) { @@ -845,8 +845,7 @@ loop: || (dl > OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE && dl != OS_FILE_LOG_BLOCK_SIZE)) { recv_sys->found_corrupt_log = true; - end_lsn = *start_lsn; - break; + goto fail; } } From 88b6dc4db5567951f9c0d0baa6e965d44a7130b1 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Tue, 19 Feb 2019 14:47:10 +0200 Subject: [PATCH 106/106] MDEV-18639 Assertion failure upon attempt to start with lower number of undo tablespaces trx_rseg_t::is_persistent(): Correct a bogus debug assertion. --- mysql-test/suite/innodb/r/undo_truncate_recover.result | 1 + mysql-test/suite/innodb/t/undo_truncate_recover.test | 3 ++- storage/innobase/include/trx0rseg.h | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/innodb/r/undo_truncate_recover.result b/mysql-test/suite/innodb/r/undo_truncate_recover.result index ae33474e00d..e1b6a67368b 100644 --- a/mysql-test/suite/innodb/r/undo_truncate_recover.result +++ b/mysql-test/suite/innodb/r/undo_truncate_recover.result @@ -9,6 +9,7 @@ update t1 set c = 'MariaDB'; update t1 set c = 'InnoDB'; set global debug_dbug = '+d,ib_undo_trunc'; commit; +call mtr.add_suppression("InnoDB: innodb_undo_tablespaces=0 disables dedicated undo log tablespaces"); call mtr.add_suppression("InnoDB: The transaction log size is too large"); SET GLOBAL innodb_fast_shutdown=0; FOUND 1 /ib_undo_trunc/ in mysqld.1.err diff --git a/mysql-test/suite/innodb/t/undo_truncate_recover.test b/mysql-test/suite/innodb/t/undo_truncate_recover.test index fb901bc4259..e6f8afb7857 100644 --- a/mysql-test/suite/innodb/t/undo_truncate_recover.test +++ b/mysql-test/suite/innodb/t/undo_truncate_recover.test @@ -38,13 +38,14 @@ update t1 set c = 'MariaDB'; update t1 set c = 'InnoDB'; eval set global debug_dbug = '+d,$SEARCH_PATTERN'; commit; +call mtr.add_suppression("InnoDB: innodb_undo_tablespaces=0 disables dedicated undo log tablespaces"); # FIXME: remove this work-around, and generate less log! call mtr.add_suppression("InnoDB: The transaction log size is too large"); SET GLOBAL innodb_fast_shutdown=0; --source include/shutdown_mysqld.inc --source include/search_pattern_in_file.inc # FIXME: remove this work-around, and generate less log! ---let $restart_parameters= --innodb-buffer-pool-size=16m +--let $restart_parameters= --innodb-buffer-pool-size=16m --innodb-undo-tablespaces=1 --source include/start_mysqld.inc drop table t1; diff --git a/storage/innobase/include/trx0rseg.h b/storage/innobase/include/trx0rseg.h index 48c5133644c..5df41bde48c 100644 --- a/storage/innobase/include/trx0rseg.h +++ b/storage/innobase/include/trx0rseg.h @@ -213,7 +213,7 @@ struct trx_rseg_t { || (srv_undo_space_id_start > 0 && space >= srv_undo_space_id_start && space <= srv_undo_space_id_start - + srv_undo_tablespaces_active) + + srv_undo_tablespaces_open) || !srv_was_started); return(space != SRV_TMP_SPACE_ID); }