Commit d6d90b73 authored by Jon Olav Hauglid's avatar Jon Olav Hauglid

Merge from mysql-5.5-bugfixing to mysql-5.5-runtime.

parents b3713993 664833fa
......@@ -5,7 +5,7 @@
--source include/not_windows.inc
--source include/not_embedded.inc
if ($MYSQLHOTCOPY)
if (!$MYSQLHOTCOPY)
{
die due to missing mysqlhotcopy tool;
}
......
......@@ -2158,7 +2158,10 @@ sub environment_setup {
mtr_pl_maybe_exists("$bindir/scripts/mysqlhotcopy");
# Since mysqltest interprets the real path as "false" in an if,
# use 1 ("true") to indicate "not exists" so it can be tested for
$ENV{'MYSQLHOTCOPY'}= $mysqlhotcopy || 1;
if ($mysqlhotcopy)
{
$ENV{'MYSQLHOTCOPY'}= $mysqlhotcopy;
}
# ----------------------------------------------------
# perror
......
This diff is collapsed.
......@@ -674,7 +674,8 @@ const char* Log_event::get_type_str()
#ifndef MYSQL_CLIENT
Log_event::Log_event(THD* thd_arg, uint16 flags_arg, bool using_trans)
:log_pos(0), temp_buf(0), exec_time(0), flags(flags_arg), thd(thd_arg)
:log_pos(0), temp_buf(0), exec_time(0), flags(flags_arg),
cache_type(Log_event::EVENT_INVALID_CACHE), thd(thd_arg)
{
server_id= thd->server_id;
when= thd->start_time;
......
......@@ -563,15 +563,6 @@ bool open_and_lock_for_insert_delayed(THD *thd, TABLE_LIST *table_list)
*/
DBUG_RETURN(TRUE);
/*
If a lock was acquired above, we should release it after delayed_get_table()
has cloned the ticket for the handler thread. Note that acquire_lock() can
succeed because of a lock already held by the connection. In this case we
should not release it here.
*/
MDL_ticket *table_ticket = mdl_savepoint == thd->mdl_context.mdl_savepoint() ?
NULL: thd->mdl_context.mdl_savepoint();
bool error= FALSE;
if (delayed_get_table(thd, table_list))
error= TRUE;
......@@ -597,12 +588,18 @@ bool open_and_lock_for_insert_delayed(THD *thd, TABLE_LIST *table_list)
}
}
if (table_ticket)
thd->mdl_context.release_lock(table_ticket);
/*
Clone_ticket() in delayed_get_table() causes TABLE_LIST::MDL_REQUEST::ticket
to be overwritten with the cloned ticket. Reset the ticket here in case
we end up having to use normal insert.
If a lock was acquired above, we should release it after
handle_delayed_insert() has cloned the ticket. Note that acquire_lock() can
succeed because the connection already has the lock. In this case the ticket
will be before the mdl_savepoint and we should not release it here.
*/
if (!thd->mdl_context.has_lock(mdl_savepoint, table_list->mdl_request.ticket))
thd->mdl_context.release_lock(table_list->mdl_request.ticket);
/*
Reset the ticket in case we end up having to use normal insert and
therefore will reopen the table and reacquire the metadata lock.
*/
table_list->mdl_request.ticket= NULL;
......@@ -1839,14 +1836,25 @@ public:
mysql_cond_t cond, cond_client;
volatile uint tables_in_use,stacked_inserts;
volatile bool status;
/*
When the handler thread starts, it clones a metadata lock ticket
for the table to be inserted. This is done to allow the deadlock
detector to detect deadlocks resulting from this lock.
Before this is done, the connection thread cannot safely exit
without causing problems for clone_ticket().
Once handler_thread_initialized has been set, it is safe for the
connection thread to exit.
Access to handler_thread_initialized is protected by di->mutex.
*/
bool handler_thread_initialized;
COPY_INFO info;
I_List<delayed_row> rows;
ulong group_count;
TABLE_LIST table_list; // Argument
Delayed_insert()
:locks_in_memory(0),
table(0),tables_in_use(0),stacked_inserts(0), status(0), group_count(0)
:locks_in_memory(0), table(0),tables_in_use(0),stacked_inserts(0),
status(0), handler_thread_initialized(FALSE), group_count(0)
{
DBUG_ENTER("Delayed_insert constructor");
thd.security_ctx->user=thd.security_ctx->priv_user=(char*) delayed_user;
......@@ -2063,19 +2071,9 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list)
/* Replace volatile strings with local copies */
di->table_list.alias= di->table_list.table_name= di->thd.query();
di->table_list.db= di->thd.db;
/*
Clone the ticket representing the lock on the target table for
the insert and add it to the list of granted metadata locks held by
the handler thread. This is safe since the handler thread is
not holding nor waiting on any metadata locks.
*/
if (di->thd.mdl_context.clone_ticket(&table_list->mdl_request))
{
delete di;
my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
goto end_create;
}
/* We need the ticket so that it can be cloned in handle_delayed_insert */
init_mdl_requests(&di->table_list);
di->table_list.mdl_request.ticket= table_list->mdl_request.ticket;
di->lock();
mysql_mutex_lock(&di->mutex);
......@@ -2088,15 +2086,20 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list)
error));
mysql_mutex_unlock(&di->mutex);
di->unlock();
di->thd.mdl_context.release_lock(table_list->mdl_request.ticket);
delete di;
my_error(ER_CANT_CREATE_THREAD, MYF(ME_FATALERROR), error);
goto end_create;
}
/* Wait until table is open */
/*
Wait until table is open unless the handler thread or the connection
thread has been killed. Note that we in all cases must wait until the
handler thread has been properly initialized before exiting. Otherwise
we risk doing clone_ticket() on a ticket that is no longer valid.
*/
thd_proc_info(thd, "waiting for handler open");
while (!di->thd.killed && !di->table && !thd->killed)
while (!di->handler_thread_initialized ||
(!di->thd.killed && !di->table && !thd->killed))
{
mysql_cond_wait(&di->cond_client, &di->mutex);
}
......@@ -2524,6 +2527,7 @@ pthread_handler_t handle_delayed_insert(void *arg)
/* Can't use my_error since store_globals has not yet been called */
thd->stmt_da->set_error_status(thd, ER_OUT_OF_RESOURCES,
ER(ER_OUT_OF_RESOURCES), NULL);
di->handler_thread_initialized= TRUE;
}
else
{
......@@ -2534,6 +2538,7 @@ pthread_handler_t handle_delayed_insert(void *arg)
/* Can't use my_error since store_globals has perhaps failed */
thd->stmt_da->set_error_status(thd, ER_OUT_OF_RESOURCES,
ER(ER_OUT_OF_RESOURCES), NULL);
di->handler_thread_initialized= TRUE;
thd->fatal_error();
goto err;
}
......@@ -2546,7 +2551,24 @@ pthread_handler_t handle_delayed_insert(void *arg)
thd->lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_INSERT_DELAYED);
thd->set_current_stmt_binlog_format_row_if_mixed();
init_mdl_requests(&di->table_list);
/*
Clone the ticket representing the lock on the target table for
the insert and add it to the list of granted metadata locks held by
the handler thread. This is safe since the handler thread is
not holding nor waiting on any metadata locks.
*/
if (thd->mdl_context.clone_ticket(&di->table_list.mdl_request))
{
di->handler_thread_initialized= TRUE;
goto err;
}
/*
Now that the ticket has been cloned, it is safe for the connection
thread to exit.
*/
di->handler_thread_initialized= TRUE;
di->table_list.mdl_request.ticket= NULL;
if (di->open_and_lock_table())
goto err;
......
......@@ -4268,6 +4268,7 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table,
Alter_info *alter_info)
{
bool result;
bool is_trans= FALSE;
DBUG_ENTER("mysql_create_table");
/*
......@@ -4282,7 +4283,6 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table,
/* Got lock. */
DEBUG_SYNC(thd, "locked_table_name");
bool is_trans;
result= mysql_create_table_no_lock(thd, create_table->db,
create_table->table_name, create_info,
alter_info, FALSE, 0, &is_trans);
......@@ -4454,6 +4454,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table,
HA_CREATE_INFO local_create_info;
Alter_info local_alter_info;
bool res= TRUE;
bool is_trans= FALSE;
uint not_used;
DBUG_ENTER("mysql_create_like_table");
......@@ -4503,7 +4504,6 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table,
/* Reset auto-increment counter for the new table. */
local_create_info.auto_increment_value= 0;
bool is_trans;
if ((res= mysql_create_table_no_lock(thd, table->db, table->table_name,
&local_create_info, &local_alter_info,
FALSE, 0, &is_trans)))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment