Commit 9bc5cec0 authored by Sergey Vojtovich's avatar Sergey Vojtovich

MDEV-7004 - Merge scalability fixes from 10.0-power

Preallocate locks on THD mem_root to avoid expensive malloc.
parent faf169d2
...@@ -404,9 +404,10 @@ void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock, bool free_lock) ...@@ -404,9 +404,10 @@ void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock, bool free_lock)
void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count) void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count)
{ {
MYSQL_LOCK *sql_lock; MYSQL_LOCK *sql_lock=
if ((sql_lock= get_lock_data(thd, table, count, GET_LOCK_UNLOCK))) get_lock_data(thd, table, count, GET_LOCK_UNLOCK | GET_LOCK_ON_THD);
mysql_unlock_tables(thd, sql_lock, 1); if (sql_lock)
mysql_unlock_tables(thd, sql_lock, 0);
} }
...@@ -553,11 +554,10 @@ void mysql_lock_abort(THD *thd, TABLE *table, bool upgrade_lock) ...@@ -553,11 +554,10 @@ void mysql_lock_abort(THD *thd, TABLE *table, bool upgrade_lock)
MYSQL_LOCK *locked; MYSQL_LOCK *locked;
DBUG_ENTER("mysql_lock_abort"); DBUG_ENTER("mysql_lock_abort");
if ((locked= get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK))) if ((locked= get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK | GET_LOCK_ON_THD)))
{ {
for (uint i=0; i < locked->lock_count; i++) for (uint i=0; i < locked->lock_count; i++)
thr_abort_locks(locked->locks[i]->lock, upgrade_lock); thr_abort_locks(locked->locks[i]->lock, upgrade_lock);
my_free(locked);
} }
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
...@@ -581,7 +581,7 @@ bool mysql_lock_abort_for_thread(THD *thd, TABLE *table) ...@@ -581,7 +581,7 @@ bool mysql_lock_abort_for_thread(THD *thd, TABLE *table)
bool result= FALSE; bool result= FALSE;
DBUG_ENTER("mysql_lock_abort_for_thread"); DBUG_ENTER("mysql_lock_abort_for_thread");
if ((locked= get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK))) if ((locked= get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK | GET_LOCK_ON_THD)))
{ {
for (uint i=0; i < locked->lock_count; i++) for (uint i=0; i < locked->lock_count; i++)
{ {
...@@ -589,7 +589,6 @@ bool mysql_lock_abort_for_thread(THD *thd, TABLE *table) ...@@ -589,7 +589,6 @@ bool mysql_lock_abort_for_thread(THD *thd, TABLE *table)
table->in_use->thread_id)) table->in_use->thread_id))
result= TRUE; result= TRUE;
} }
my_free(locked);
} }
DBUG_RETURN(result); DBUG_RETURN(result);
} }
...@@ -707,7 +706,6 @@ MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, uint flags) ...@@ -707,7 +706,6 @@ MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, uint flags)
TABLE **to, **table_buf; TABLE **to, **table_buf;
DBUG_ENTER("get_lock_data"); DBUG_ENTER("get_lock_data");
DBUG_ASSERT((flags == GET_LOCK_UNLOCK) || (flags == GET_LOCK_STORE_LOCKS));
DBUG_PRINT("info", ("count %d", count)); DBUG_PRINT("info", ("count %d", count));
for (i=lock_count=table_count=0 ; i < count ; i++) for (i=lock_count=table_count=0 ; i < count ; i++)
...@@ -728,11 +726,12 @@ MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, uint flags) ...@@ -728,11 +726,12 @@ MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, uint flags)
update the table values. So the second part of the array is copied update the table values. So the second part of the array is copied
from the first part immediately before calling thr_multi_lock(). from the first part immediately before calling thr_multi_lock().
*/ */
if (!(sql_lock= (MYSQL_LOCK*) size_t amount= sizeof(*sql_lock) +
my_malloc(sizeof(*sql_lock) + sizeof(THR_LOCK_DATA*) * lock_count * 2 +
sizeof(THR_LOCK_DATA*) * lock_count * 2 + sizeof(table_ptr) * table_count;
sizeof(table_ptr) * table_count, if (!(sql_lock= (MYSQL_LOCK*) (flags & GET_LOCK_ON_THD ?
MYF(0)))) thd->alloc(amount) :
my_malloc(amount, MYF(0)))))
DBUG_RETURN(0); DBUG_RETURN(0);
locks= locks_buf= sql_lock->locks= (THR_LOCK_DATA**) (sql_lock + 1); locks= locks_buf= sql_lock->locks= (THR_LOCK_DATA**) (sql_lock + 1);
to= table_buf= sql_lock->table= (TABLE**) (locks + lock_count * 2); to= table_buf= sql_lock->table= (TABLE**) (locks + lock_count * 2);
...@@ -751,9 +750,9 @@ MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, uint flags) ...@@ -751,9 +750,9 @@ MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, uint flags)
DBUG_ASSERT(lock_type != TL_WRITE_DEFAULT && lock_type != TL_READ_DEFAULT); DBUG_ASSERT(lock_type != TL_WRITE_DEFAULT && lock_type != TL_READ_DEFAULT);
locks_start= locks; locks_start= locks;
locks= table->file->store_lock(thd, locks, locks= table->file->store_lock(thd, locks,
(flags & GET_LOCK_UNLOCK) ? TL_IGNORE : (flags & GET_LOCK_ACTION_MASK) == GET_LOCK_UNLOCK ? TL_IGNORE :
lock_type); lock_type);
if (flags & GET_LOCK_STORE_LOCKS) if ((flags & GET_LOCK_ACTION_MASK) == GET_LOCK_STORE_LOCKS)
{ {
table->lock_position= (uint) (to - table_buf); table->lock_position= (uint) (to - table_buf);
table->lock_data_start= (uint) (locks_start - locks_buf); table->lock_data_start= (uint) (locks_start - locks_buf);
......
...@@ -42,8 +42,10 @@ bool lock_object_name(THD *thd, MDL_key::enum_mdl_namespace mdl_type, ...@@ -42,8 +42,10 @@ bool lock_object_name(THD *thd, MDL_key::enum_mdl_namespace mdl_type,
const char *db, const char *name); const char *db, const char *name);
/* flags for get_lock_data */ /* flags for get_lock_data */
#define GET_LOCK_UNLOCK 1 #define GET_LOCK_UNLOCK 0
#define GET_LOCK_STORE_LOCKS 2 #define GET_LOCK_STORE_LOCKS 1
#define GET_LOCK_ACTION_MASK 1
#define GET_LOCK_ON_THD (1 << 1)
MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, uint flags); MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, uint flags);
void reset_lock_data(MYSQL_LOCK *sql_lock, bool unlock); void reset_lock_data(MYSQL_LOCK *sql_lock, bool unlock);
......
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