diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2022-05-25 09:15:08 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2022-05-25 09:15:08 +0300 |
commit | 3cc8539d84f569f4829874bf36f4b44b0ceb030c (patch) | |
tree | cc4cf6561f81b4d6b33af1dc5da888e6baff59af /sql/sql_class.cc | |
parent | 956d93b581b704fa56b0b6469ae35a2e79850ef4 (diff) | |
parent | 1ace1075dc6bb02fe19802334f9d47446a17a79a (diff) | |
download | mariadb-git-3cc8539d84f569f4829874bf36f4b44b0ceb030c.tar.gz |
Merge 10.9 into 10.10
Diffstat (limited to 'sql/sql_class.cc')
-rw-r--r-- | sql/sql_class.cc | 136 |
1 files changed, 94 insertions, 42 deletions
diff --git a/sql/sql_class.cc b/sql/sql_class.cc index f902f12481e..a0ba1d7e5a3 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1,6 +1,6 @@ /* Copyright (c) 2000, 2015, Oracle and/or its affiliates. - Copyright (c) 2008, 2021, MariaDB Corporation. + Copyright (c) 2008, 2022, 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 @@ -56,6 +56,7 @@ #include "sp_rcontext.h" #include "sp_cache.h" #include "sql_show.h" // append_identifier +#include "sql_db.h" // get_default_db_collation #include "transaction.h" #include "sql_select.h" /* declares create_tmp_table() */ #include "debug_sync.h" @@ -679,7 +680,8 @@ THD::THD(my_thread_id id, bool is_wsrep_applier) #ifdef HAVE_REPLICATION , current_linfo(0), - slave_info(0) + slave_info(0), + is_awaiting_semisync_ack(0) #endif #ifdef WITH_WSREP , @@ -861,11 +863,6 @@ THD::THD(my_thread_id id, bool is_wsrep_applier) get_sequence_last_key, (my_hash_free_key) free_sequence_last, HASH_THREAD_SPECIFIC); - sp_proc_cache= NULL; - sp_func_cache= NULL; - sp_package_spec_cache= NULL; - sp_package_body_cache= NULL; - /* For user vars replication*/ if (opt_bin_log) my_init_dynamic_array(key_memory_user_var_entry, &user_var_events, @@ -1439,10 +1436,7 @@ void THD::change_user(void) SEQUENCES_HASH_SIZE, 0, 0, (my_hash_get_key) get_sequence_last_key, (my_hash_free_key) free_sequence_last, HASH_THREAD_SPECIFIC); - sp_cache_clear(&sp_proc_cache); - sp_cache_clear(&sp_func_cache); - sp_cache_clear(&sp_package_spec_cache); - sp_cache_clear(&sp_package_body_cache); + sp_caches_clear(); opt_trace.delete_traces(); } @@ -1569,10 +1563,7 @@ void THD::cleanup(void) my_hash_free(&user_vars); my_hash_free(&sequences); - sp_cache_clear(&sp_proc_cache); - sp_cache_clear(&sp_func_cache); - sp_cache_clear(&sp_package_spec_cache); - sp_cache_clear(&sp_package_body_cache); + sp_caches_clear(); auto_inc_intervals_forced.empty(); auto_inc_intervals_in_cur_stmt_for_binlog.empty(); @@ -6741,49 +6732,86 @@ int THD::decide_logging_format(TABLE_LIST *tables) DBUG_RETURN(0); } -int THD::decide_logging_format_low(TABLE *table) + +/* + Reconsider logging format in case of INSERT...ON DUPLICATE KEY UPDATE + for tables with more than one unique keys in case of MIXED binlog format. + + Unsafe means that a master could execute the statement differently than + the slave. + This could can happen in the following cases: + - The unique check are done in different order on master or slave + (different engine or different key order). + - There is a conflict on another key than the first and before the + statement is committed, another connection commits a row that conflicts + on an earlier unique key. Example follows: + + Below a and b are unique keys, the table has a row (1,1,0) + connection 1: + INSERT INTO t1 set a=2,b=1,c=0 ON DUPLICATE KEY UPDATE c=1; + connection 2: + INSERT INTO t1 set a=2,b=2,c=0; + + If 2 commits after 1 has been executed but before 1 has committed + (and are thus put before the other in the binary log), one will + get different data on the slave: + (1,1,1),(2,2,1) instead of (1,1,1),(2,2,0) +*/ + +void THD::reconsider_logging_format_for_iodup(TABLE *table) { - DBUG_ENTER("decide_logging_format_low"); - /* - INSERT...ON DUPLICATE KEY UPDATE on a table with more than one unique keys - can be unsafe. - */ - if (wsrep_binlog_format() <= BINLOG_FORMAT_STMT && - !is_current_stmt_binlog_format_row() && - !lex->is_stmt_unsafe() && - lex->duplicates == DUP_UPDATE) + DBUG_ENTER("reconsider_logging_format_for_iodup"); + enum_binlog_format bf= (enum_binlog_format) wsrep_binlog_format(); + + DBUG_ASSERT(lex->duplicates == DUP_UPDATE); + + if (bf <= BINLOG_FORMAT_STMT && + !is_current_stmt_binlog_format_row()) { + KEY *end= table->s->key_info + table->s->keys; uint unique_keys= 0; - uint keys= table->s->keys, i= 0; - Field *field; - for (KEY* keyinfo= table->s->key_info; - i < keys && unique_keys <= 1; i++, keyinfo++) - if (keyinfo->flags & HA_NOSAME && - !(keyinfo->key_part->field->flags & AUTO_INCREMENT_FLAG && - //User given auto inc can be unsafe - !keyinfo->key_part->field->val_int())) + + for (KEY *keyinfo= table->s->key_info; keyinfo < end ; keyinfo++) + { + if (keyinfo->flags & HA_NOSAME) { + /* + We assume that the following cases will guarantee that the + key is unique if a key part is not set: + - The key part is an autoincrement (autogenerated) + - The key part has a default value that is null and it not + a virtual field that will be calculated later. + */ for (uint j= 0; j < keyinfo->user_defined_key_parts; j++) { - field= keyinfo->key_part[j].field; - if(!bitmap_is_set(table->write_set,field->field_index)) - goto exit; + Field *field= keyinfo->key_part[j].field; + if (!bitmap_is_set(table->write_set, field->field_index)) + { + /* Check auto_increment */ + if (field == table->next_number_field) + goto exit; + if (field->is_real_null() && !field->default_value) + goto exit; + } } - unique_keys++; + if (unique_keys++) + break; exit:; } - + } if (unique_keys > 1) { - lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_INSERT_TWO_KEYS); - binlog_unsafe_warning_flags|= lex->get_stmt_unsafe_flags(); + if (bf == BINLOG_FORMAT_STMT && !lex->is_stmt_unsafe()) + { + lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_INSERT_TWO_KEYS); + binlog_unsafe_warning_flags|= lex->get_stmt_unsafe_flags(); + } set_current_stmt_binlog_format_row_if_mixed(); if (is_current_stmt_binlog_format_row()) binlog_prepare_for_row_logging(); - DBUG_RETURN(1); } } - DBUG_RETURN(0); + DBUG_VOID_RETURN; } #ifndef MYSQL_CLIENT @@ -8269,3 +8297,27 @@ THD_list_iterator *THD_list_iterator::iterator() { return &server_threads; } + + +Charset_collation_context +THD::charset_collation_context_alter_db(const char *db) +{ + return Charset_collation_context(variables.collation_server, + get_default_db_collation(this, db)); +} + + +Charset_collation_context +THD::charset_collation_context_create_table_in_db(const char *db) +{ + CHARSET_INFO *cs= get_default_db_collation(this, db); + return Charset_collation_context(cs, cs); +} + + +Charset_collation_context +THD::charset_collation_context_alter_table(const TABLE_SHARE *s) +{ + return Charset_collation_context(get_default_db_collation(this, s->db.str), + s->table_charset); +} |