1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

Merge branch '10.5' into 10.6

This commit is contained in:
Sergei Golubchik
2022-05-10 11:53:59 +02:00
249 changed files with 7080 additions and 1864 deletions

View File

@ -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
@ -679,7 +679,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
,
@ -862,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,
@ -1452,10 +1448,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();
}
@ -1582,10 +1575,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();
@ -6744,49 +6734,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