1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

Added Non-prelocked SP execution: Now a PROCEDURE doesn't enter/leave prelocked mode for

its body, but lets each statement to get/release its own locks. This allows a broader set
of statements to be executed inside PROCEDUREs (but breaks replication)
This patch should fix BUG#8072, BUG#8766, BUG#9563, BUG#11126


mysql-test/r/sp-security.result:
  Drop tables this test attempts to create
mysql-test/r/sp-threads.result:
  Update test results
mysql-test/r/sp.result:
  Disabled a test that triggers BUG#11986, cleanup used tables when tests start.
mysql-test/r/view.result:
  Enabled a test case that now works with prelocking-free SPs
mysql-test/t/sp-security.test:
  Drop tables this test attempts to create
mysql-test/t/sp.test:
  Disabled a test that triggers BUG#11986, cleanup used tables when tests start.
mysql-test/t/view.test:
  Enabled a test case that now works with prelocking-free SPs
sql/handler.cc:
  Rename: thd->transaction.in_sub_stmt -> thd->in_sub_stmt
sql/item_func.cc:
  Rename: thd->transaction.in_sub_stmt -> thd->in_sub_stmt
sql/sp.cc:
  Non-prelocked SP execution: Added support for skipping prelocking of procedure body for
  "CALL proc(...)" statements.
sql/sp.h:
  Non-prelocked SP execution: Added support for skipping prelocking of procedure body for
  "CALL proc(...)" statements.
sql/sp_cache.h:
  Added comments
sql/sp_head.cc:
  Non-prelocked SP execution:
  * Try to unlock tables after PROCEDURE arguments have been evaluated.
  * Make sp_lex_keeper be able to execute in 2 modes: A) when already in prelocked mode
    B) when its statement enters/leaves prelocked mode itself.
sql/sp_head.h:
  Non-prelocked SP execution:  Make sp_lex_keeper to additionally keep list of tables it 
  needs to prelock when its statement enters/leaves prelocked mode on its own.
sql/sql_base.cc:
  Non-prelocked SP execution: Make open_tables() to
   * detect 'CALL proc(...)' and not to do prelocking for procedure body statements.
   * Make lex->query_tables_last to point precisely to a boundary in lex->query_tables 
     list where 'own' tables and views' tables end and added-for-prelocking tables begin.
     (it was not true before - view's tables could end up after query_tables_own_last)
sql/sql_class.cc:
  Rename: thd->transaction.in_sub_stmt -> thd->in_sub_stmt
sql/sql_class.h:
  Rename: thd->transaction.in_sub_stmt -> thd->in_sub_stmt
sql/sql_lex.cc:
  Non-prelocked SP execution: More rigourous cleanup in st_lex::cleanup_after_one_table_open()
sql/sql_parse.cc:
  Rename: thd->transaction.in_sub_stmt -> thd->in_sub_stmt, remove outdated comments
sql/sql_trigger.h:
  Rename: thd->transaction.in_sub_stmt -> thd->in_sub_stmt
This commit is contained in:
unknown
2005-07-30 08:19:57 +00:00
parent 482cf550f9
commit 11abe15eab
22 changed files with 736 additions and 128 deletions

View File

@ -391,6 +391,8 @@ static void mark_used_tables_as_free_for_reuse(THD *thd, TABLE *table)
LOCK_open
skip_derived Set to 1 (0 = default) if we should not free derived
tables.
stopper When closing tables from thd->open_tables(->next)*,
don't close/remove tables starting from stopper.
IMPLEMENTATION
Unlocks tables and frees derived tables.
@ -474,6 +476,7 @@ void close_thread_tables(THD *thd, bool lock_in_use, bool skip_derived,
We are in prelocked mode, so we have to leave it now with doing
implicit UNLOCK TABLES if need.
*/
DBUG_PRINT("info",("thd->prelocked_mode= NON_PRELOCKED"));
thd->prelocked_mode= NON_PRELOCKED;
if (prelocked_mode == PRELOCKED_UNDER_LOCK_TABLES)
@ -1792,6 +1795,7 @@ err:
DBUG_RETURN(1);
}
/*
Open all tables in list
@ -1843,10 +1847,6 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter)
statement for which table list for prelocking is already built, let
us cache routines and try to build such table list.
NOTE: If we want queries with functions to work under explicit
LOCK TABLES we have to additionaly lock mysql.proc table in it.
At least until Monty will fix SP loading :)
NOTE: We can't delay prelocking until we will met some sub-statement
which really uses tables, since this will imply that we have to restore
its table list to be able execute it in some other context.
@ -1860,19 +1860,28 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter)
mode we will have some locked tables, because queries which use only
derived/information schema tables and views possible. Thus "counter"
may be still zero for prelocked statement...
NOTE: The above notes may be out of date. Please wait for psergey to
document new prelocked behavior.
*/
if (!thd->prelocked_mode && !thd->lex->requires_prelocking() &&
thd->lex->sroutines.records)
if (!thd->prelocked_mode && !thd->lex->requires_prelocking())
{
TABLE_LIST **save_query_tables_last= thd->lex->query_tables_last;
DBUG_ASSERT(thd->lex->query_tables == *start);
if (sp_cache_routines_and_add_tables(thd, thd->lex) ||
*start)
bool first_no_prelocking;
if (sp_need_cache_routines(thd, &thd->lex->sroutines_list,
&first_no_prelocking))
{
query_tables_last_own= save_query_tables_last;
*start= thd->lex->query_tables;
TABLE_LIST **save_query_tables_last= thd->lex->query_tables_last;
DBUG_ASSERT(thd->lex->query_tables == *start);
if (sp_cache_routines_and_add_tables(thd, thd->lex,
first_no_prelocking) ||
*start)
{
query_tables_last_own= save_query_tables_last;
*start= thd->lex->query_tables;
}
}
}
@ -1891,14 +1900,31 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter)
DBUG_RETURN(-1);
}
(*counter)++;
if (!tables->table &&
!(tables->table= open_table(thd, tables, &new_frm_mem, &refresh, 0)))
{
free_root(&new_frm_mem, MYF(MY_KEEP_PREALLOC));
if (tables->view)
{
/* VIEW placeholder */
(*counter)--;
/*
tables->next_global list consists of two parts:
1) Query tables and underlying tables of views.
2) Tables used by all stored routines that this statement invokes on
execution.
We need to know where the bound between these two parts is. If we've
just opened the last table in part #1, and it added tables after
itself, adjust the boundary pointer accordingly.
*/
if (query_tables_last_own &&
query_tables_last_own == &(tables->next_global) &&
tables->view->query_tables)
query_tables_last_own= tables->view->query_tables_last;
/*
Again if needed we have to get cache all routines used by this view
and add tables used by them to table list.
@ -2323,6 +2349,7 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count)
and was marked as occupied during open_tables() as free for reuse.
*/
mark_real_tables_as_free_for_reuse(first_not_own);
DBUG_PRINT("info",("prelocked_mode= PRELOCKED"));
thd->prelocked_mode= PRELOCKED;
}
}
@ -2346,6 +2373,7 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count)
if (thd->lex->requires_prelocking())
{
mark_real_tables_as_free_for_reuse(first_not_own);
DBUG_PRINT("info", ("thd->prelocked_mode= PRELOCKED_UNDER_LOCK_TABLES"));
thd->prelocked_mode= PRELOCKED_UNDER_LOCK_TABLES;
}
}