diff options
-rw-r--r-- | cmake/wsrep.cmake | 2 | ||||
-rw-r--r-- | sql/mysqld.cc | 9 | ||||
-rw-r--r-- | sql/sys_vars.cc | 4 | ||||
-rw-r--r-- | sql/wsrep_mysqld.cc | 41 | ||||
-rw-r--r-- | sql/wsrep_mysqld.h | 4 | ||||
-rw-r--r-- | sql/wsrep_var.cc | 6 | ||||
-rw-r--r-- | storage/innobase/handler/ha_innodb.cc | 11 | ||||
-rw-r--r-- | storage/innobase/rem/rem0rec.c | 5 | ||||
-rw-r--r-- | storage/innobase/row/row0upd.c | 179 |
9 files changed, 202 insertions, 59 deletions
diff --git a/cmake/wsrep.cmake b/cmake/wsrep.cmake index c1dc5a54958..69a8c19ab1d 100644 --- a/cmake/wsrep.cmake +++ b/cmake/wsrep.cmake @@ -17,7 +17,7 @@ # so WSREP_VERSION is produced regardless # Set the patch version -SET(WSREP_PATCH_VERSION "7a") +SET(WSREP_PATCH_VERSION "7.1") # Obtain patch revision number SET(WSREP_PATCH_REVNO $ENV{WSREP_REV}) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 7d413fe737a..47082f6bb18 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2363,6 +2363,9 @@ static my_socket activate_tcp_port(uint port) socket_errno); unireg_abort(1); } +#if defined(WITH_WSREP) && defined(HAVE_FCNTL) + (void) fcntl(ip_sock, F_SETFD, FD_CLOEXEC); +#endif /* WITH_WSREP */ DBUG_RETURN(ip_sock); } @@ -2484,6 +2487,9 @@ static void network_init(void) if (listen(unix_sock,(int) back_log) < 0) sql_print_warning("listen() on Unix socket failed with error %d", socket_errno); +#if defined(WITH_WSREP) && defined(HAVE_FCNTL) + (void) fcntl(unix_sock, F_SETFD, FD_CLOEXEC); +#endif /* WITH_WSREP */ } #endif DBUG_PRINT("info",("server started")); @@ -6366,6 +6372,9 @@ void handle_connections_sockets() sleep(1); // Give other threads some time continue; } +#if defined(WITH_WSREP) && defined(HAVE_FCNTL) + (void) fcntl(new_sock, F_SETFD, FD_CLOEXEC); +#endif /* WITH_WSREP */ #ifdef HAVE_LIBWRAP { diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index e3df253f873..81ad091cca6 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -3677,9 +3677,7 @@ static Sys_var_charptr Sys_wsrep_node_incoming_address( "wsrep_node_incoming_address", "Client connection address", GLOBAL_VAR(wsrep_node_incoming_address),CMD_LINE(REQUIRED_ARG), IN_FS_CHARSET, DEFAULT(wsrep_node_incoming_address), - NO_MUTEX_GUARD, NOT_IN_BINLOG, - ON_CHECK(wsrep_node_name_check), - ON_UPDATE(wsrep_node_name_update)); + NO_MUTEX_GUARD, NOT_IN_BINLOG); static Sys_var_ulong Sys_wsrep_slave_threads( "wsrep_slave_threads", "Number of slave appliers to launch", diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index 62397c58a6e..9e1c84b897e 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -30,9 +30,6 @@ my_bool wsrep_emulate_bin_log = FALSE; // activating parts of binlog interface */ const char* wsrep_data_home_dir = NULL; - -#define WSREP_NODE_INCOMING_AUTO "AUTO" -const char* wsrep_node_incoming_address = WSREP_NODE_INCOMING_AUTO; const char* wsrep_dbug_option = ""; long wsrep_slave_threads = 1; // # of slave action appliers wanted @@ -463,9 +460,9 @@ int wsrep_init() wsrep_data_home_dir = mysql_real_data_home; char node_addr[512]= { 0, }; + size_t const node_addr_max= sizeof(node_addr) - 1; if (!wsrep_node_address || !strcmp(wsrep_node_address, "")) { - size_t const node_addr_max= sizeof(node_addr); size_t const ret= guess_ip(node_addr, node_addr_max); if (!(ret > 0 && ret < node_addr_max)) { @@ -476,11 +473,11 @@ int wsrep_init() } else { - strncpy(node_addr, wsrep_node_address, sizeof(node_addr) - 1); + strncpy(node_addr, wsrep_node_address, node_addr_max); } - static char inc_addr[512]= { 0, }; - + char inc_addr[512]= { 0, }; + size_t const inc_addr_max= sizeof (inc_addr); if ((!wsrep_node_incoming_address || !strcmp (wsrep_node_incoming_address, WSREP_NODE_INCOMING_AUTO))) { @@ -490,7 +487,6 @@ int wsrep_init() const char* const colon= strrchr(node_addr, ':'); if (strchr(node_addr, ':') == colon) // 1 or 0 ':' { - size_t const inc_addr_max= sizeof (inc_addr); size_t const ip_len= colon ? colon - node_addr : node_addr_len; if (ip_len + 7 /* :55555\0 */ < inc_addr_max) { @@ -512,22 +508,41 @@ int wsrep_init() } } - // this is to display detected address on SHOW VARIABLES... - wsrep_node_incoming_address = inc_addr; - - if (!strlen(wsrep_node_incoming_address)) + if (!strlen(inc_addr)) { WSREP_WARN("Guessing address for incoming client connections failed. " "Try setting wsrep_node_incoming_address explicitly."); } } + else if (!strchr(wsrep_node_incoming_address, ':')) // no port included + { + if ((int)inc_addr_max <= + snprintf(inc_addr, inc_addr_max, "%s:%u", + wsrep_node_incoming_address,(int)mysqld_port)) + { + WSREP_WARN("Guessing address for incoming client connections: " + "address too long."); + inc_addr[0]= '\0'; + } + } + else + { + size_t const need = strlen (wsrep_node_incoming_address); + if (need >= inc_addr_max) { + WSREP_WARN("wsrep_node_incoming_address too long: %zu", need); + inc_addr[0]= '\0'; + } + else { + memcpy (inc_addr, wsrep_node_incoming_address, need); + } + } struct wsrep_init_args wsrep_args; wsrep_args.data_dir = wsrep_data_home_dir; wsrep_args.node_name = (wsrep_node_name) ? wsrep_node_name : ""; wsrep_args.node_address = node_addr; - wsrep_args.node_incoming = wsrep_node_incoming_address; + wsrep_args.node_incoming = inc_addr; wsrep_args.options = (wsrep_provider_options) ? wsrep_provider_options : ""; wsrep_args.proto_ver = wsrep_max_protocol_version; diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h index e9cd227efcf..0709a2c1f34 100644 --- a/sql/wsrep_mysqld.h +++ b/sql/wsrep_mysqld.h @@ -114,7 +114,9 @@ extern const char* wsrep_provider_vendor; extern int wsrep_show_status(THD *thd, SHOW_VAR *var, char *buff); extern void wsrep_free_status(THD *thd); -#define WSREP_SST_ADDRESS_AUTO "AUTO" +#define WSREP_SST_ADDRESS_AUTO "AUTO" +#define WSREP_NODE_INCOMING_AUTO "AUTO" + // MySQL variables funcs #define CHECK_ARGS (sys_var *self, THD* thd, set_var *var) diff --git a/sql/wsrep_var.cc b/sql/wsrep_var.cc index 36d73369c7d..c79c0a6a19f 100644 --- a/sql/wsrep_var.cc +++ b/sql/wsrep_var.cc @@ -31,8 +31,8 @@ const char* wsrep_provider_options = 0; const char* wsrep_cluster_address = 0; const char* wsrep_cluster_name = 0; const char* wsrep_node_name = 0; -static char node_address[256] = { 0, }; -const char* wsrep_node_address = node_address; // ??? +const char* wsrep_node_address = 0; +const char* wsrep_node_incoming_address = 0; const char* wsrep_start_position = 0; ulong wsrep_OSU_method_options; static int wsrep_thread_change = 0; @@ -44,6 +44,8 @@ int wsrep_init_vars() wsrep_cluster_address = my_strdup("", MYF(MY_WME)); wsrep_cluster_name = my_strdup(WSREP_CLUSTER_NAME, MYF(MY_WME)); wsrep_node_name = my_strdup("", MYF(MY_WME)); + wsrep_node_address = my_strdup("", MYF(MY_WME)); + wsrep_node_incoming_address= my_strdup(WSREP_NODE_INCOMING_AUTO, MYF(MY_WME)); wsrep_start_position = my_strdup(WSREP_START_POSITION_ZERO, MYF(MY_WME)); global_system_variables.binlog_format=BINLOG_FORMAT_ROW; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 42150429078..f0f889cad86 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -4978,6 +4978,7 @@ wsrep_store_key_val_for_row( /* Pad the unused space with spaces. */ +#ifdef REMOVED if (true_len < key_len) { ulint pad_len = key_len - true_len; ut_a(!(pad_len % cs->mbminlen)); @@ -4986,6 +4987,7 @@ wsrep_store_key_val_for_row( 0x20 /* space */); buff += pad_len; } +#endif /* REMOVED */ } } @@ -7281,6 +7283,15 @@ ha_innobase::wsrep_append_keys( DBUG_ENTER("wsrep_append_keys"); trx_t *trx = thd_to_trx(thd); + if (table_share && table_share->tmp_table != NO_TMP_TABLE) { + WSREP_DEBUG("skipping tmp table DML: THD: %lu tmp: %d SQL: %s", + wsrep_thd_thread_id(thd), + table_share->tmp_table, + (wsrep_thd_query(thd)) ? + wsrep_thd_query(thd) : "void"); + DBUG_RETURN(0); + } + /* if no PK, calculate hash of full row, to be the key value */ if (prebuilt->clust_index_was_generated && wsrep_certify_nonPK) { uchar digest[16]; diff --git a/storage/innobase/rem/rem0rec.c b/storage/innobase/rem/rem0rec.c index d921889aaef..0e8f606c311 100644 --- a/storage/innobase/rem/rem0rec.c +++ b/storage/innobase/rem/rem0rec.c @@ -1865,7 +1865,8 @@ wsrep_rec_get_foreign_key( } case DATA_VARCHAR: case DATA_VARMYSQL: - case DATA_BINARY: + case DATA_CHAR: + case DATA_MYSQL: /* Copy the actual data */ ut_memcpy(buf, data, len); wsrep_innobase_mysql_sort( @@ -1876,7 +1877,7 @@ wsrep_rec_get_foreign_key( buf, len); break; case DATA_BLOB: - case DATA_MYSQL: + case DATA_BINARY: memcpy(buf, data, len); break; default: diff --git a/storage/innobase/row/row0upd.c b/storage/innobase/row/row0upd.c index 8469d688c5c..c5c51d8283d 100644 --- a/storage/innobase/row/row0upd.c +++ b/storage/innobase/row/row0upd.c @@ -51,6 +51,9 @@ Created 12/27/1996 Heikki Tuuri #include "pars0sym.h" #include "eval0eval.h" #include "buf0lru.h" +#ifdef WITH_WSREP +extern my_bool wsrep_debug; +#endif /* What kind of latch and lock can we assume when the control comes to @@ -178,36 +181,6 @@ ulint wsrep_append_foreign_key(trx_t *trx, ibool referenced, ibool shared); -static -void -wsrep_append_fk_reference( -/*=================================*/ - upd_node_t* node, /*!< in: row update node */ - dict_table_t* table, /*!< in: table in question */ - dict_index_t* index, /*!< in: index of the cursor */ - que_thr_t* thr, /*!< in: query thread */ - const rec_t* rec -) { - dict_foreign_t *foreign = UT_LIST_GET_FIRST(table->foreign_list); - - while (foreign) { - if (foreign->foreign_index == index - && node->is_delete) - { - if (DB_SUCCESS != wsrep_append_foreign_key( - thr_get_trx(thr), - foreign, - rec, - index, - TRUE, TRUE) - ) { - fprintf(stderr, - "WSREP: FK key append failed\n"); - } - } - foreign = UT_LIST_GET_NEXT(foreign_list, foreign); - } -} #endif /* WITH_WSREP */ /*********************************************************************//** @@ -332,6 +305,122 @@ func_exit: return(err); } +#ifdef WITH_WSREP +static +ulint +wsrep_row_upd_check_foreign_constraints( +/*=================================*/ + upd_node_t* node, /*!< in: row update node */ + btr_pcur_t* pcur, /*!< in: cursor positioned on a record; NOTE: the + cursor position is lost in this function! */ + dict_table_t* table, /*!< in: table in question */ + dict_index_t* index, /*!< in: index of the cursor */ + ulint* offsets,/*!< in/out: rec_get_offsets(pcur.rec, index) */ + que_thr_t* thr, /*!< in: query thread */ + mtr_t* mtr) /*!< in: mtr */ +{ + dict_foreign_t* foreign; + mem_heap_t* heap; + dtuple_t* entry; + trx_t* trx; + const rec_t* rec; + ulint n_ext; + ulint err; + ibool got_s_lock = FALSE; + + if (UT_LIST_GET_FIRST(table->foreign_list) == NULL) { + + return(DB_SUCCESS); + } + + trx = thr_get_trx(thr); + + rec = btr_pcur_get_rec(pcur); + ut_ad(rec_offs_validate(rec, index, offsets)); + + heap = mem_heap_create(500); + + entry = row_rec_to_index_entry(ROW_COPY_DATA, rec, index, offsets, + &n_ext, heap); + + mtr_commit(mtr); + + mtr_start(mtr); + + if (trx->dict_operation_lock_mode == 0) { + got_s_lock = TRUE; + + row_mysql_freeze_data_dictionary(trx); + } + + foreign = UT_LIST_GET_FIRST(table->foreign_list); + + while (foreign) { + /* Note that we may have an update which updates the index + record, but does NOT update the first fields which are + referenced in a foreign key constraint. Then the update does + NOT break the constraint. */ + + if (foreign->foreign_index == index + && (node->is_delete + || row_upd_changes_first_fields_binary( + entry, index, node->update, + foreign->n_fields))) { + + if (foreign->referenced_table == NULL) { + dict_table_get(foreign->referenced_table_name_lookup, + FALSE); + } + + if (foreign->referenced_table) { + mutex_enter(&(dict_sys->mutex)); + + (foreign->referenced_table + ->n_foreign_key_checks_running)++; + + mutex_exit(&(dict_sys->mutex)); + } + + /* NOTE that if the thread ends up waiting for a lock + we will release dict_operation_lock temporarily! + But the counter on the table protects 'foreign' from + being dropped while the check is running. */ + + err = row_ins_check_foreign_constraint( + TRUE, foreign, table, entry, thr); + + if (foreign->referenced_table) { + mutex_enter(&(dict_sys->mutex)); + + ut_a(foreign->referenced_table + ->n_foreign_key_checks_running > 0); + + (foreign->referenced_table + ->n_foreign_key_checks_running)--; + + mutex_exit(&(dict_sys->mutex)); + } + + if (err != DB_SUCCESS) { + + goto func_exit; + } + } + + foreign = UT_LIST_GET_NEXT(foreign_list, foreign); + } + + err = DB_SUCCESS; +func_exit: + if (got_s_lock) { + row_mysql_unfreeze_data_dictionary(trx); + } + + mem_heap_free(heap); + + return(err); +} +#endif /* WITH_WSREP */ /*********************************************************************//** Creates an update node for a query graph. @@ -1687,8 +1776,18 @@ row_upd_sec_index_entry( } #ifdef WITH_WSREP if (err == DB_SUCCESS && !referenced) { - wsrep_append_fk_reference(node, index->table, - index, thr, rec); + ulint* offsets = + rec_get_offsets( + rec, index, NULL, ULINT_UNDEFINED, + &heap); + uint werr = wsrep_row_upd_check_foreign_constraints( + node, &pcur, index->table, + index, offsets, thr, &mtr); + + if (wsrep_debug && werr != DB_SUCCESS) + fprintf (stderr, + "WSREP: FK check fail: %u", + werr); } #endif /* WITH_WSREP */ } @@ -1934,8 +2033,12 @@ err_exit: } #ifdef WITH_WSREP if (!referenced) { - wsrep_append_fk_reference(node, index->table, - index, thr, rec); + uint werr = wsrep_row_upd_check_foreign_constraints( + node, pcur, table, index, offsets, thr, mtr); + if (wsrep_debug && werr != DB_SUCCESS) + fprintf (stderr, + "WSREP: FK check fail: %u", + werr); } #endif /* WITH_WSREP */ } @@ -2173,13 +2276,15 @@ row_upd_del_mark_clust_rec( if (err == DB_SUCCESS && referenced) { /* NOTE that the following call loses the position of pcur ! */ - err = row_upd_check_references_constraints( + err = wsrep_row_upd_check_foreign_constraints( node, pcur, index->table, index, offsets, thr, mtr); } #ifdef WITH_WSREP if (err == DB_SUCCESS && !referenced) { - wsrep_append_fk_reference(node, index->table, - index, thr, rec); + uint werr = row_upd_check_references_constraints( + node, pcur, index->table, index, offsets, thr, mtr); + if (wsrep_debug && werr != DB_SUCCESS) + fprintf (stderr, "WSREP: FK check fail: %u", werr); } #endif /* WITH_WSREP */ |