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

Merge 10.0.14 into 10.1

This commit is contained in:
Sergei Golubchik
2014-10-15 12:59:13 +02:00
2115 changed files with 87968 additions and 80173 deletions

View File

@ -2085,7 +2085,10 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
DBUG_RETURN(TRUE);
if (!(flags & MYSQL_OPEN_IGNORE_KILLED) && thd->killed)
{
thd->send_kill_message();
DBUG_RETURN(TRUE);
}
/*
Check if we're trying to take a write lock in a read only transaction.
@ -2923,6 +2926,7 @@ Locked_tables_list::reopen_tables(THD *thd)
size_t reopen_count= 0;
MYSQL_LOCK *lock;
MYSQL_LOCK *merged_lock;
DBUG_ENTER("Locked_tables_list::reopen_tables");
for (TABLE_LIST *table_list= m_locked_tables;
table_list; table_list= table_list->next_global)
@ -2934,7 +2938,7 @@ Locked_tables_list::reopen_tables(THD *thd)
if (open_table(thd, table_list, thd->mem_root, &ot_ctx))
{
unlink_all_closed_tables(thd, 0, reopen_count);
return TRUE;
DBUG_RETURN(TRUE);
}
table_list->table->pos_in_locked_tables= table_list;
/* See also the comment on lock type in init_locked_tables(). */
@ -2966,11 +2970,11 @@ Locked_tables_list::reopen_tables(THD *thd)
unlink_all_closed_tables(thd, lock, reopen_count);
if (! thd->killed)
my_error(ER_LOCK_DEADLOCK, MYF(0));
return TRUE;
DBUG_RETURN(TRUE);
}
thd->lock= merged_lock;
}
return FALSE;
DBUG_RETURN(FALSE);
}
/**
@ -3515,9 +3519,12 @@ Open_table_context::recover_from_failed_open()
/*
Return a appropriate read lock type given a table object.
@param thd Thread context
@param prelocking_ctx Prelocking context.
@param table_list Table list element for table to be locked.
@param thd Thread context
@param prelocking_ctx Prelocking context.
@param table_list Table list element for table to be locked.
@param routine_modifies_data
Some routine that is invoked by statement
modifies data.
@remark Due to a statement-based replication limitation, statements such as
INSERT INTO .. SELECT FROM .. and CREATE TABLE .. SELECT FROM need
@ -3530,9 +3537,13 @@ Open_table_context::recover_from_failed_open()
This also applies to SELECT/SET/DO statements which use stored
functions. Calls to such functions are going to be logged as a
whole and thus should be serialized against concurrent changes
to tables used by those functions. This can be avoided if functions
only read data but doing so requires more complex analysis than it
is done now.
to tables used by those functions. This is avoided when functions
do not modify data but only read it, since in this case nothing is
written to the binary log. Argument routine_modifies_data
denotes the same. So effectively, if the statement is not a
update query and routine_modifies_data is false, then
prelocking_placeholder does not take importance.
Furthermore, this does not apply to I_S and log tables as it's
always unsafe to replicate such tables under statement-based
replication as the table on the slave might contain other data
@ -3547,7 +3558,8 @@ Open_table_context::recover_from_failed_open()
thr_lock_type read_lock_type_for_table(THD *thd,
Query_tables_list *prelocking_ctx,
TABLE_LIST *table_list)
TABLE_LIST *table_list,
bool routine_modifies_data)
{
/*
In cases when this function is called for a sub-statement executed in
@ -3561,7 +3573,7 @@ thr_lock_type read_lock_type_for_table(THD *thd,
(table_list->table->s->table_category == TABLE_CATEGORY_LOG) ||
(table_list->table->s->table_category == TABLE_CATEGORY_PERFORMANCE) ||
!(is_update_query(prelocking_ctx->sql_command) ||
table_list->prelocking_placeholder ||
(routine_modifies_data && table_list->prelocking_placeholder) ||
(thd->locked_tables_mode > LTM_LOCK_TABLES)))
return TL_READ;
else
@ -3574,19 +3586,21 @@ thr_lock_type read_lock_type_for_table(THD *thd,
and, if prelocking strategy prescribes so, extend the prelocking set
with tables and routines used by it.
@param[in] thd Thread context.
@param[in] prelocking_ctx Prelocking context.
@param[in] rt Element of prelocking set to be processed.
@param[in] prelocking_strategy Strategy which specifies how the
prelocking set should be extended when
one of its elements is processed.
@param[in] has_prelocking_list Indicates that prelocking set/list for
this statement has already been built.
@param[in] ot_ctx Context of open_table used to recover from
locking failures.
@param[out] need_prelocking Set to TRUE if it was detected that this
statement will require prelocked mode for
its execution, not touched otherwise.
@param[in] thd Thread context.
@param[in] prelocking_ctx Prelocking context.
@param[in] rt Element of prelocking set to be processed.
@param[in] prelocking_strategy Strategy which specifies how the
prelocking set should be extended when
one of its elements is processed.
@param[in] has_prelocking_list Indicates that prelocking set/list for
this statement has already been built.
@param[in] ot_ctx Context of open_table used to recover from
locking failures.
@param[out] need_prelocking Set to TRUE if it was detected that this
statement will require prelocked mode for
its execution, not touched otherwise.
@param[out] routine_modifies_data Set to TRUE if it was detected that this
routine does modify table data.
@retval FALSE Success.
@retval TRUE Failure (Conflicting metadata lock, OOM, other errors).
@ -3598,11 +3612,13 @@ open_and_process_routine(THD *thd, Query_tables_list *prelocking_ctx,
Prelocking_strategy *prelocking_strategy,
bool has_prelocking_list,
Open_table_context *ot_ctx,
bool *need_prelocking)
bool *need_prelocking, bool *routine_modifies_data)
{
MDL_key::enum_mdl_namespace mdl_type= rt->mdl_request.key.mdl_namespace();
DBUG_ENTER("open_and_process_routine");
*routine_modifies_data= false;
switch (mdl_type)
{
case MDL_key::FUNCTION:
@ -3655,10 +3671,13 @@ open_and_process_routine(THD *thd, Query_tables_list *prelocking_ctx,
DBUG_RETURN(TRUE);
/* 'sp' is NULL when there is no such routine. */
if (sp && !has_prelocking_list)
if (sp)
{
prelocking_strategy->handle_routine(thd, prelocking_ctx, rt, sp,
need_prelocking);
*routine_modifies_data= sp->modifies_data();
if (!has_prelocking_list)
prelocking_strategy->handle_routine(thd, prelocking_ctx, rt, sp,
need_prelocking);
}
}
else
@ -4003,16 +4022,7 @@ open_and_process_table(THD *thd, LEX *lex, TABLE_LIST *tables,
goto end;
}
if (tables->lock_type != TL_UNLOCK && ! thd->locked_tables_mode)
{
if (tables->lock_type == TL_WRITE_DEFAULT)
tables->table->reginfo.lock_type= thd->update_lock_default;
else if (tables->lock_type == TL_READ_DEFAULT)
tables->table->reginfo.lock_type=
read_lock_type_for_table(thd, lex, tables);
else
tables->table->reginfo.lock_type= tables->lock_type;
}
/* Copy grant information from TABLE_LIST instance to TABLE one. */
tables->table->grant= tables->grant;
/* Check and update metadata version of a base table. */
@ -4351,6 +4361,7 @@ bool open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags,
Open_table_context ot_ctx(thd, flags);
bool error= FALSE;
MEM_ROOT new_frm_mem;
bool some_routine_modifies_data= FALSE;
bool has_prelocking_list;
DBUG_ENTER("open_tables");
@ -4523,11 +4534,16 @@ restart:
sroutine_to_open= &rt->next, rt= rt->next)
{
bool need_prelocking= false;
bool routine_modifies_data;
TABLE_LIST **save_query_tables_last= thd->lex->query_tables_last;
error= open_and_process_routine(thd, thd->lex, rt, prelocking_strategy,
has_prelocking_list, &ot_ctx,
&need_prelocking);
&need_prelocking,
&routine_modifies_data);
// Remember if any of SF modifies data.
some_routine_modifies_data|= routine_modifies_data;
if (need_prelocking && ! thd->lex->requires_prelocking())
thd->lex->mark_as_requiring_prelocking(save_query_tables_last);
@ -4568,6 +4584,10 @@ restart:
the children are detached. Attaching and detaching are always done,
even under LOCK TABLES.
We also convert all TL_WRITE_DEFAULT and TL_READ_DEFAULT locks to
appropriate "real" lock types to be used for locking and to be passed
to storage engine.
And start wsrep TOI if needed.
*/
for (tables= *start; tables; tables= tables->next_global)
@ -4595,6 +4615,19 @@ restart:
goto error;
}
}
/* Set appropriate TABLE::lock_type. */
if (tbl && tables->lock_type != TL_UNLOCK && !thd->locked_tables_mode)
{
if (tables->lock_type == TL_WRITE_DEFAULT)
tbl->reginfo.lock_type= thd->update_lock_default;
else if (tables->lock_type == TL_READ_DEFAULT)
tbl->reginfo.lock_type=
read_lock_type_for_table(thd, thd->lex, tables,
some_routine_modifies_data);
else
tbl->reginfo.lock_type= tables->lock_type;
}
}
error:
@ -4858,11 +4891,15 @@ static bool check_lock_and_start_stmt(THD *thd,
engine is important as, for example, InnoDB uses it to determine
what kind of row locks should be acquired when executing statement
in prelocked mode or under LOCK TABLES with @@innodb_table_locks = 0.
Last argument routine_modifies_data for read_lock_type_for_table()
is ignored, as prelocking placeholder will never be set here.
*/
DBUG_ASSERT(table_list->prelocking_placeholder == false);
if (table_list->lock_type == TL_WRITE_DEFAULT)
lock_type= thd->update_lock_default;
else if (table_list->lock_type == TL_READ_DEFAULT)
lock_type= read_lock_type_for_table(thd, prelocking_ctx, table_list);
lock_type= read_lock_type_for_table(thd, prelocking_ctx, table_list, true);
else
lock_type= table_list->lock_type;
@ -5283,6 +5320,7 @@ bool lock_tables(THD *thd, TABLE_LIST *tables, uint count,
thd->lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_AUTOINC_NOT_FIRST);
}
#ifdef NOT_USED_IN_MARIADB
/*
INSERT...ON DUPLICATE KEY UPDATE on a table with more than one unique keys
can be unsafe.
@ -5308,6 +5346,7 @@ bool lock_tables(THD *thd, TABLE_LIST *tables, uint count,
thd->lex->duplicates == DUP_UPDATE)
thd->lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_INSERT_TWO_KEYS);
}
#endif
/* We have to emulate LOCK TABLES if we are statement needs prelocking. */
if (thd->lex->requires_prelocking())