summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/lock.cc20
-rw-r--r--sql/lock.h3
-rw-r--r--sql/sql_reload.cc12
3 files changed, 24 insertions, 11 deletions
diff --git a/sql/lock.cc b/sql/lock.cc
index a0796db7367..c9aa49a4057 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -68,10 +68,6 @@
table_handler->external_lock(thd, F_UNLCK) for each table that was locked,
excluding one that caused failure. That means handler must cleanup itself
in case external_lock() fails.
-
- @todo
- Change to use my_malloc() ONLY when using LOCK TABLES command or when
- we are forced to use mysql_lock_merge.
*/
#include <my_global.h>
@@ -266,19 +262,24 @@ void reset_lock_data(MYSQL_LOCK *sql_lock, bool unlock)
MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, uint flags)
{
MYSQL_LOCK *sql_lock;
+ uint gld_flags= GET_LOCK_STORE_LOCKS;
DBUG_ENTER("mysql_lock_tables(tables)");
if (lock_tables_check(thd, tables, count, flags))
DBUG_RETURN(NULL);
- if (! (sql_lock= get_lock_data(thd, tables, count, GET_LOCK_STORE_LOCKS)))
+ if (!(thd->variables.option_bits & OPTION_TABLE_LOCK))
+ gld_flags|= GET_LOCK_ON_THD;
+
+ if (! (sql_lock= get_lock_data(thd, tables, count, gld_flags)))
DBUG_RETURN(NULL);
if (mysql_lock_tables(thd, sql_lock, flags))
{
/* Clear the lock type of all lock data to avoid reusage. */
reset_lock_data(sql_lock, 1);
- my_free(sql_lock);
+ if (!(gld_flags & GET_LOCK_ON_THD))
+ my_free(sql_lock);
sql_lock= 0;
}
DBUG_RETURN(sql_lock);
@@ -382,6 +383,13 @@ static int lock_external(THD *thd, TABLE **tables, uint count)
}
+void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock)
+{
+ mysql_unlock_tables(thd, sql_lock,
+ thd->variables.option_bits & OPTION_TABLE_LOCK);
+}
+
+
void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock, bool free_lock)
{
DBUG_ENTER("mysql_unlock_tables");
diff --git a/sql/lock.h b/sql/lock.h
index ca2f267f3d5..341d7a20f9f 100644
--- a/sql/lock.h
+++ b/sql/lock.h
@@ -28,7 +28,8 @@ typedef struct st_mysql_lock MYSQL_LOCK;
MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **table, uint count, uint flags);
bool mysql_lock_tables(THD *thd, MYSQL_LOCK *sql_lock, uint flags);
-void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock, bool free_lock= 1);
+void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock, bool free_lock);
+void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock);
void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock);
void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count);
void mysql_lock_remove(THD *thd, MYSQL_LOCK *locked,TABLE *table);
diff --git a/sql/sql_reload.cc b/sql/sql_reload.cc
index ca632f4a2fb..fe494c760dc 100644
--- a/sql/sql_reload.cc
+++ b/sql/sql_reload.cc
@@ -521,6 +521,8 @@ bool flush_tables_with_read_lock(THD *thd, TABLE_LIST *all_tables)
}
}
+ thd->variables.option_bits|= OPTION_TABLE_LOCK;
+
/*
Before opening and locking tables the below call also waits
for old shares to go away, so the fact that we don't pass
@@ -534,7 +536,7 @@ bool flush_tables_with_read_lock(THD *thd, TABLE_LIST *all_tables)
if (open_and_lock_tables(thd, all_tables, FALSE,
MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK,
&lock_tables_prelocking_strategy))
- goto error;
+ goto error_reset_bits;
if (thd->lex->type & REFRESH_FOR_EXPORT)
{
@@ -546,15 +548,14 @@ bool flush_tables_with_read_lock(THD *thd, TABLE_LIST *all_tables)
{
my_error(ER_ILLEGAL_HA, MYF(0),table_list->table->file->table_type(),
table_list->db, table_list->table_name);
- return true;
+ goto error_reset_bits;
}
}
}
if (thd->locked_tables_list.init_locked_tables(thd))
- goto error;
+ goto error_reset_bits;
- thd->variables.option_bits|= OPTION_TABLE_LOCK;
/*
We don't downgrade MDL_SHARED_NO_WRITE here as the intended
@@ -565,6 +566,9 @@ bool flush_tables_with_read_lock(THD *thd, TABLE_LIST *all_tables)
return FALSE;
+error_reset_bits:
+ close_thread_tables(thd);
+ thd->variables.option_bits&= ~OPTION_TABLE_LOCK;
error:
return TRUE;
}