1
0
mirror of https://github.com/MariaDB/server.git synced 2025-12-24 11:21:21 +03:00

Backport of revno: 2617.68.13

Introduce a counter for protection against global read lock on thread level.

The functions for protection against global read lock sometimes need a local
variable to signal when the protection is set, and hence need to be released.
It would be better to control this behaviour via a counter on the THD struct,
telling how many times the protection has been claimed by the current thread.
A side-effect of the fix is that if protection is claimed twice for a thread,
only a simple increment is required for the second claim, instead of a
mutex-protected increment of the global variable protect_against_global_read_lock.
This commit is contained in:
Jon Olav Hauglid
2009-12-09 15:25:48 +01:00
parent 1642f67b40
commit 17252c3258
6 changed files with 115 additions and 32 deletions

View File

@@ -1762,7 +1762,6 @@ int
mysql_execute_command(THD *thd)
{
int res= FALSE;
bool need_start_waiting= FALSE; // have protection against global read lock
int up_result= 0;
LEX *lex= thd->lex;
/* first SELECT_LEX (have special meaning for many of non-SELECTcommands) */
@@ -2039,7 +2038,7 @@ mysql_execute_command(THD *thd)
break;
if (!thd->locked_tables_mode && lex->protect_against_global_read_lock &&
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
wait_if_global_read_lock(thd, 0, 1))
break;
res= execute_sqlcom_select(thd, all_tables);
@@ -2309,10 +2308,9 @@ case SQLCOM_PREPARE:
read lock when it succeeds. This needs to be released by
start_waiting_global_read_lock(). We protect the normal CREATE
TABLE in the same way. That way we avoid that a new table is
created during a gobal read lock.
created during a global read lock.
*/
if (!thd->locked_tables_mode &&
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
if (!thd->locked_tables_mode && wait_if_global_read_lock(thd, 0, 1))
{
res= 1;
goto end_with_restore_list;
@@ -2617,8 +2615,7 @@ end_with_restore_list:
"INDEX DIRECTORY");
create_info.data_file_name= create_info.index_file_name= NULL;
if (!thd->locked_tables_mode &&
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
if (!thd->locked_tables_mode && wait_if_global_read_lock(thd, 0, 1))
{
res= 1;
break;
@@ -2852,8 +2849,7 @@ end_with_restore_list:
DBUG_ASSERT(first_table == all_tables && first_table != 0);
if (update_precheck(thd, all_tables))
break;
if (!thd->locked_tables_mode &&
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
if (!thd->locked_tables_mode && wait_if_global_read_lock(thd, 0, 1))
goto error;
DBUG_ASSERT(select_lex->offset_limit == 0);
unit->set_limit(select_lex);
@@ -2891,7 +2887,7 @@ end_with_restore_list:
*/
if (!thd->locked_tables_mode &&
lex->sql_command == SQLCOM_UPDATE_MULTI &&
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
wait_if_global_read_lock(thd, 0, 1))
goto error;
res= mysql_multi_update_prepare(thd);
@@ -2993,8 +2989,7 @@ end_with_restore_list:
if ((res= insert_precheck(thd, all_tables)))
break;
if (!thd->locked_tables_mode &&
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
if (!thd->locked_tables_mode && wait_if_global_read_lock(thd, 0, 1))
{
res= 1;
break;
@@ -3033,8 +3028,7 @@ end_with_restore_list:
unit->set_limit(select_lex);
if (! thd->locked_tables_mode &&
! (need_start_waiting= ! wait_if_global_read_lock(thd, 0, 1)))
if (!thd->locked_tables_mode && wait_if_global_read_lock(thd, 0, 1))
{
res= 1;
break;
@@ -3104,7 +3098,7 @@ end_with_restore_list:
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
goto error;
}
if (!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
if (wait_if_global_read_lock(thd, 0, 1))
goto error;
res= mysql_truncate(thd, first_table, 0);
break;
@@ -3116,8 +3110,7 @@ end_with_restore_list:
DBUG_ASSERT(select_lex->offset_limit == 0);
unit->set_limit(select_lex);
if (!thd->locked_tables_mode &&
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
if (!thd->locked_tables_mode && wait_if_global_read_lock(thd, 0, 1))
{
res= 1;
break;
@@ -3137,8 +3130,7 @@ end_with_restore_list:
(TABLE_LIST *)thd->lex->auxiliary_table_list.first;
multi_delete *del_result;
if (!thd->locked_tables_mode &&
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
if (!thd->locked_tables_mode && wait_if_global_read_lock(thd, 0, 1))
{
res= 1;
break;
@@ -3282,8 +3274,7 @@ end_with_restore_list:
if (check_one_table_access(thd, privilege, all_tables))
goto error;
if (!thd->locked_tables_mode &&
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
if (!thd->locked_tables_mode && wait_if_global_read_lock(thd, 0, 1))
goto error;
res= mysql_load(thd, lex->exchange, first_table, lex->field_list,
@@ -3357,7 +3348,7 @@ end_with_restore_list:
FALSE, UINT_MAX, FALSE))
goto error;
if (lex->protect_against_global_read_lock &&
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
wait_if_global_read_lock(thd, 0, 1))
goto error;
init_mdl_requests(all_tables);
@@ -4575,7 +4566,7 @@ error:
res= TRUE;
finish:
if (need_start_waiting)
if (thd->global_read_lock_protection > 0)
{
/*
Release the protection against the global read lock and wake