diff options
author | Sergei Golubchik <serg@mariadb.org> | 2018-09-07 15:25:27 +0200 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2018-09-07 15:25:27 +0200 |
commit | db947b75997248ca4b0a6b6600df993bf84cd601 (patch) | |
tree | b6c16037931b17f645d4b71b0db8c4ebf3479435 /sql | |
parent | f95d26b4d3ec0e4b039e80439f85e4f22bd79fe7 (diff) | |
parent | 2482306861ca107adfb6c8823cd9f6e413912ebe (diff) | |
download | mariadb-git-db947b75997248ca4b0a6b6600df993bf84cd601.tar.gz |
Merge branch '10.0-galera' into 10.1
Diffstat (limited to 'sql')
-rw-r--r-- | sql/events.cc | 2 | ||||
-rw-r--r-- | sql/handler.cc | 1 | ||||
-rw-r--r-- | sql/log_event.cc | 5 | ||||
-rw-r--r-- | sql/sql_alter.cc | 20 | ||||
-rw-r--r-- | sql/sql_parse.cc | 2 | ||||
-rw-r--r-- | sql/sql_trigger.cc | 6 | ||||
-rw-r--r-- | sql/wsrep_hton.cc | 9 | ||||
-rw-r--r-- | sql/wsrep_mysqld.cc | 289 | ||||
-rw-r--r-- | sql/wsrep_mysqld.h | 4 | ||||
-rw-r--r-- | sql/wsrep_var.cc | 2 |
10 files changed, 232 insertions, 108 deletions
diff --git a/sql/events.cc b/sql/events.cc index b7b263971b3..3fdb432cba6 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -462,6 +462,7 @@ Events::update_event(THD *thd, Event_parse_data *parse_data, if (check_access(thd, EVENT_ACL, parse_data->dbname.str, NULL, NULL, 0, 0)) DBUG_RETURN(TRUE); + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL); if (lock_object_name(thd, MDL_key::EVENT, @@ -591,6 +592,7 @@ Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists) if (check_access(thd, EVENT_ACL, dbname.str, NULL, NULL, 0, 0)) DBUG_RETURN(TRUE); + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL); /* diff --git a/sql/handler.cc b/sql/handler.cc index dbe3c5a7a67..497409d0f53 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -4376,6 +4376,7 @@ handler::ha_create_partitioning_metadata(const char *name, (!old_name && strcmp(name, table_share->path.str))); + mark_trx_read_write(); return create_partitioning_metadata(name, old_name, action_flag); } diff --git a/sql/log_event.cc b/sql/log_event.cc index 9ccbb45d01c..e1912ad4620 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -7912,11 +7912,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/sql/sql_alter.cc b/sql/sql_alter.cc index f17931ae919..0accc04c10d 100644 --- a/sql/sql_alter.cc +++ b/sql/sql_alter.cc @@ -307,12 +307,17 @@ bool Sql_cmd_alter_table::execute(THD *thd) #ifdef WITH_WSREP TABLE *find_temporary_table(THD *thd, const TABLE_LIST *tl); - if ((!thd->is_current_stmt_binlog_format_row() || + if (WSREP(thd) && + (!thd->is_current_stmt_binlog_format_row() || !find_temporary_table(thd, first_table))) { - WSREP_TO_ISOLATION_BEGIN(((lex->name.str) ? select_lex->db : NULL), - ((lex->name.str) ? lex->name.str : NULL), - first_table); + WSREP_TO_ISOLATION_BEGIN_ALTER(((lex->name.str) ? select_lex->db : NULL), + ((lex->name.str) ? lex->name.str : NULL), + first_table, + &alter_info); + + thd->variables.auto_increment_offset = 1; + thd->variables.auto_increment_increment = 1; } #endif /* WITH_WSREP */ @@ -325,11 +330,12 @@ bool Sql_cmd_alter_table::execute(THD *thd) lex->ignore); DBUG_RETURN(result); - #ifdef WITH_WSREP error: - WSREP_WARN("ALTER TABLE isolation failure"); - DBUG_RETURN(TRUE); + { + WSREP_WARN("ALTER TABLE isolation failure"); + DBUG_RETURN(TRUE); + } #endif /* WITH_WSREP */ } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 1d57e8f54fa..add059340c9 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -7262,7 +7262,9 @@ static void wsrep_mysql_parse(THD *thd, char *rawbuf, uint length, "WAIT_FOR wsrep_retry_autocommit_continue"; DBUG_ASSERT(!debug_sync_set_action(thd, STRING_WITH_LEN(act))); }); + WSREP_DEBUG("Retry autocommit query: %s", thd->query()); } + mysql_parse(thd, rawbuf, length, parser_state); if (WSREP(thd)) { diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 91ecbe0cb7e..4a484723f02 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -503,7 +503,11 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) if (err_status) goto end; } - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL); + +#ifdef WITH_WSREP + if (thd->wsrep_exec_mode == LOCAL_STATE) + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL); +#endif /* We should have only one table in table list. */ DBUG_ASSERT(tables->next_global == 0); diff --git a/sql/wsrep_hton.cc b/sql/wsrep_hton.cc index e5c754a9d41..a935f8c69b8 100644 --- a/sql/wsrep_hton.cc +++ b/sql/wsrep_hton.cc @@ -24,6 +24,8 @@ #include <cstdlib> #include "debug_sync.h" +extern handlerton *binlog_hton; +extern int binlog_close_connection(handlerton *hton, THD *thd); extern ulonglong thd_to_trx_id(THD *thd); extern "C" int thd_binlog_format(const MYSQL_THD thd); @@ -171,7 +173,10 @@ wsrep_close_connection(handlerton* hton, THD* thd) { DBUG_RETURN(0); } - DBUG_RETURN(wsrep_binlog_close_connection (thd)); + + if (wsrep_emulate_bin_log && thd_get_ha_data(thd, binlog_hton) != NULL) + binlog_hton->close_connection (binlog_hton, thd); + DBUG_RETURN(0); } /* @@ -262,7 +267,7 @@ static int wsrep_rollback(handlerton *hton, THD *thd, bool all) } if ((all || !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) && - (thd->variables.wsrep_on && thd->wsrep_conflict_state != MUST_REPLAY)) + thd->variables.wsrep_on && thd->wsrep_conflict_state != MUST_REPLAY) { if (wsrep && wsrep->post_rollback(wsrep, &thd->wsrep_ws_handle)) { diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index a88713652ed..1b2d7fe04e6 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -627,6 +627,9 @@ int wsrep_init() wsrep->provider_vendor, sizeof(provider_vendor) - 1); } + if (!wsrep_data_home_dir || strlen(wsrep_data_home_dir) == 0) + wsrep_data_home_dir = mysql_real_data_home; + /* Initialize node address */ char node_addr[512]= { 0, }; size_t const node_addr_max= sizeof(node_addr) - 1; @@ -1045,114 +1048,151 @@ static bool wsrep_prepare_key_for_isolation(const char* db, wsrep_buf_t* key, size_t* key_len) { - if (*key_len < 2) return false; + if (*key_len < 2) return false; - switch (wsrep_protocol_version) - { - case 0: - *key_len= 0; - break; - case 1: - case 2: - case 3: + switch (wsrep_protocol_version) + { + case 0: + *key_len= 0; + break; + case 1: + case 2: + case 3: + { + *key_len= 0; + if (db) { - *key_len= 0; - if (db) - { - // sql_print_information("%s.%s", db, table); - if (db) - { - key[*key_len].ptr= db; - key[*key_len].len= strlen(db); - ++(*key_len); - if (table) - { - key[*key_len].ptr= table; - key[*key_len].len= strlen(table); - ++(*key_len); - } - } - } - break; + // sql_print_information("%s.%s", db, table); + key[*key_len].ptr= db; + key[*key_len].len= strlen(db); + ++(*key_len); + if (table) + { + key[*key_len].ptr= table; + key[*key_len].len= strlen(table); + ++(*key_len); + } } - default: + break; + } + default: + return false; + } + return true; +} + + +static bool wsrep_prepare_key_for_isolation(const char* db, + const char* table, + wsrep_key_arr_t* ka) +{ + wsrep_key_t* tmp; + + if (!ka->keys) + tmp= (wsrep_key_t*)my_malloc((ka->keys_len + 1) * sizeof(wsrep_key_t), + MYF(0)); + else + tmp= (wsrep_key_t*)my_realloc(ka->keys, + (ka->keys_len + 1) * sizeof(wsrep_key_t), + MYF(0)); + + if (!tmp) + { + WSREP_ERROR("Can't allocate memory for key_array"); + return false; + } + ka->keys= tmp; + if (!(ka->keys[ka->keys_len].key_parts= (wsrep_buf_t*) + my_malloc(sizeof(wsrep_buf_t)*2, MYF(0)))) + { + WSREP_ERROR("Can't allocate memory for key_parts"); + return false; + } + ka->keys[ka->keys_len].key_parts_num= 2; + ++ka->keys_len; + if (!wsrep_prepare_key_for_isolation(db, table, + (wsrep_buf_t*)ka->keys[ka->keys_len - 1].key_parts, + &ka->keys[ka->keys_len - 1].key_parts_num)) + { + WSREP_ERROR("Preparing keys for isolation failed"); + return false; + } + + return true; +} + + +static bool wsrep_prepare_keys_for_alter_add_fk(char* child_table_db, + Alter_info* alter_info, + wsrep_key_arr_t* ka) +{ + Key *key; + List_iterator<Key> key_iterator(alter_info->key_list); + while ((key= key_iterator++)) + { + if (key->type == Key::FOREIGN_KEY) + { + Foreign_key *fk_key= (Foreign_key *)key; + const char *db_name= fk_key->ref_db.str; + const char *table_name= fk_key->ref_table.str; + if (!db_name) + { + db_name= child_table_db; + } + if (!wsrep_prepare_key_for_isolation(db_name, table_name, ka)) + { return false; + } } - - return true; + } + return true; } -/* Prepare key list from db/table and table_list */ -bool wsrep_prepare_keys_for_isolation(THD* thd, - const char* db, - const char* table, - const TABLE_LIST* table_list, - wsrep_key_arr_t* ka) + +static bool wsrep_prepare_keys_for_isolation(THD* thd, + const char* db, + const char* table, + const TABLE_LIST* table_list, + Alter_info* alter_info, + wsrep_key_arr_t* ka) { ka->keys= 0; ka->keys_len= 0; if (db || table) { - if (!(ka->keys= (wsrep_key_t*)my_malloc(sizeof(wsrep_key_t), MYF(0)))) - { - WSREP_ERROR("Can't allocate memory for key_array"); + if (!wsrep_prepare_key_for_isolation(db, table, ka)) goto err; - } - ka->keys_len= 1; - if (!(ka->keys[0].key_parts= (wsrep_buf_t*) - my_malloc(sizeof(wsrep_buf_t)*2, MYF(0)))) - { - WSREP_ERROR("Can't allocate memory for key_parts"); - goto err; - } - ka->keys[0].key_parts_num= 2; - if (!wsrep_prepare_key_for_isolation( - db, table, - (wsrep_buf_t*)ka->keys[0].key_parts, - &ka->keys[0].key_parts_num)) - { - WSREP_ERROR("Preparing keys for isolation failed (1)"); - goto err; - } } for (const TABLE_LIST* table= table_list; table; table= table->next_global) { - wsrep_key_t* tmp; - if (ka->keys) - tmp= (wsrep_key_t*)my_realloc(ka->keys, - (ka->keys_len + 1) * sizeof(wsrep_key_t), - MYF(0)); - else - tmp= (wsrep_key_t*)my_malloc((ka->keys_len + 1) * sizeof(wsrep_key_t), MYF(0)); - - if (!tmp) - { - WSREP_ERROR("Can't allocate memory for key_array"); + if (!wsrep_prepare_key_for_isolation(table->db, table->table_name, ka)) goto err; - } - ka->keys= tmp; - if (!(ka->keys[ka->keys_len].key_parts= (wsrep_buf_t*) - my_malloc(sizeof(wsrep_buf_t)*2, MYF(0)))) - { - WSREP_ERROR("Can't allocate memory for key_parts"); - goto err; - } - ka->keys[ka->keys_len].key_parts_num= 2; - ++ka->keys_len; - if (!wsrep_prepare_key_for_isolation(table->db, table->table_name, - (wsrep_buf_t*)ka->keys[ka->keys_len - 1].key_parts, - &ka->keys[ka->keys_len - 1].key_parts_num)) - { - WSREP_ERROR("Preparing keys for isolation failed (2)"); + } + + if (alter_info && (alter_info->flags & (Alter_info::ADD_FOREIGN_KEY))) + { + if (!wsrep_prepare_keys_for_alter_add_fk(table_list->db, alter_info, ka)) goto err; - } } - return 0; + + return false; + err: - wsrep_keys_free(ka); - return 1; + wsrep_keys_free(ka); + return true; +} + + +/* Prepare key list from db/table and table_list */ +bool wsrep_prepare_keys_for_isolation(THD* thd, + const char* db, + const char* table, + const TABLE_LIST* table_list, + wsrep_key_arr_t* ka) +{ + return wsrep_prepare_keys_for_isolation(thd, db, table, table_list, NULL, ka); } @@ -1368,6 +1408,67 @@ create_view_query(THD *thd, uchar** buf, size_t* buf_len) return wsrep_to_buf_helper(thd, buff.ptr(), buff.length(), buf, buf_len); } +/* + Rewrite DROP TABLE for TOI. Temporary tables are eliminated from + the query as they are visible only to client connection. + + TODO: See comments for sql_base.cc:drop_temporary_table() and refine + the function to deal with transactional locked tables. + */ +static int wsrep_drop_table_query(THD* thd, uchar** buf, size_t* buf_len) +{ + + LEX* lex= thd->lex; + SELECT_LEX* select_lex= &lex->select_lex; + TABLE_LIST* first_table= select_lex->table_list.first; + String buff; + + DBUG_ASSERT(!lex->create_info.tmp_table()); + + bool found_temp_table= false; + for (TABLE_LIST* table= first_table; table; table= table->next_global) + { + if (find_temporary_table(thd, table->db, table->table_name)) + { + found_temp_table= true; + break; + } + } + + if (found_temp_table) + { + buff.append("DROP TABLE "); + if (lex->check_exists) + buff.append("IF EXISTS "); + + for (TABLE_LIST* table= first_table; table; table= table->next_global) + { + if (!find_temporary_table(thd, table->db, table->table_name)) + { + append_identifier(thd, &buff, table->db, strlen(table->db)); + buff.append("."); + append_identifier(thd, &buff, table->table_name, + strlen(table->table_name)); + buff.append(","); + } + } + + /* Chop the last comma */ + buff.chop(); + buff.append(" /* generated by wsrep */"); + + WSREP_DEBUG("Rewrote '%s' as '%s'", thd->query(), buff.ptr()); + + return wsrep_to_buf_helper(thd, buff.ptr(), buff.length(), buf, buf_len); + } + else + { + return wsrep_to_buf_helper(thd, thd->query(), thd->query_length(), + buf, buf_len); + } +} + + /* Forward declarations. */ static int wsrep_create_sp(THD *thd, uchar** buf, size_t* buf_len); static int wsrep_create_trigger_query(THD *thd, uchar** buf, size_t* buf_len); @@ -1476,7 +1577,8 @@ static const char* wsrep_get_query_or_msg(const THD* thd) -1: TOI replication failed */ static int wsrep_TOI_begin(THD *thd, char *db_, char *table_, - const TABLE_LIST* table_list) + const TABLE_LIST* table_list, + Alter_info* alter_info) { wsrep_status_t ret(WSREP_WARNING); uchar* buf(0); @@ -1511,6 +1613,9 @@ static int wsrep_TOI_begin(THD *thd, char *db_, char *table_, case SQLCOM_ALTER_EVENT: buf_err= wsrep_alter_event_query(thd, &buf, &buf_len); break; + case SQLCOM_DROP_TABLE: + buf_err= wsrep_drop_table_query(thd, &buf, &buf_len); + break; case SQLCOM_CREATE_ROLE: if (sp_process_definer(thd)) { @@ -1526,7 +1631,8 @@ static int wsrep_TOI_begin(THD *thd, char *db_, char *table_, wsrep_key_arr_t key_arr= {0, 0}; struct wsrep_buf buff = { buf, buf_len }; if (!buf_err && - !wsrep_prepare_keys_for_isolation(thd, db_, table_, table_list, &key_arr) && + !wsrep_prepare_keys_for_isolation(thd, db_, table_, + table_list, alter_info, &key_arr) && key_arr.keys_len > 0 && WSREP_OK == (ret = wsrep->to_execute_start(wsrep, thd->thread_id, key_arr.keys, key_arr.keys_len, @@ -1669,7 +1775,8 @@ static void wsrep_RSU_end(THD *thd) } int wsrep_to_isolation_begin(THD *thd, char *db_, char *table_, - const TABLE_LIST* table_list) + const TABLE_LIST* table_list, + Alter_info* alter_info) { int ret= 0; @@ -1725,10 +1832,10 @@ int wsrep_to_isolation_begin(THD *thd, char *db_, char *table_, { switch (thd->variables.wsrep_OSU_method) { case WSREP_OSU_TOI: - ret = wsrep_TOI_begin(thd, db_, table_, table_list); + ret= wsrep_TOI_begin(thd, db_, table_, table_list, alter_info); break; case WSREP_OSU_RSU: - ret = wsrep_RSU_begin(thd, db_, table_); + ret= wsrep_RSU_begin(thd, db_, table_); break; default: WSREP_ERROR("Unsupported OSU method: %lu", diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h index 272e4ac4984..43f0d53393d 100644 --- a/sql/wsrep_mysqld.h +++ b/sql/wsrep_mysqld.h @@ -291,8 +291,10 @@ extern PSI_mutex_key key_LOCK_wsrep_desync; extern PSI_file_key key_file_wsrep_gra_log; #endif /* HAVE_PSI_INTERFACE */ struct TABLE_LIST; +class Alter_info; int wsrep_to_isolation_begin(THD *thd, char *db_, char *table_, - const TABLE_LIST* table_list); + const TABLE_LIST* table_list, + Alter_info* alter_info = NULL); void wsrep_to_isolation_end(THD *thd); void wsrep_cleanup_transaction(THD *thd); int wsrep_to_buf_helper( diff --git a/sql/wsrep_var.cc b/sql/wsrep_var.cc index eea1da1d46c..718676025f9 100644 --- a/sql/wsrep_var.cc +++ b/sql/wsrep_var.cc @@ -565,7 +565,7 @@ void wsrep_node_address_init (const char* value) static void wsrep_slave_count_change_update () { wsrep_slave_count_change = (wsrep_slave_threads - wsrep_prev_slave_threads); - WSREP_DEBUG("Change on slave threads: New %lu old %lu difference %lu", + WSREP_DEBUG("Change on slave threads: New %lu old %lu difference %d", wsrep_slave_threads, wsrep_prev_slave_threads, wsrep_slave_count_change); wsrep_prev_slave_threads = wsrep_slave_threads; } |