diff options
author | unknown <dlenev@mysql.com> | 2005-07-13 13:48:13 +0400 |
---|---|---|
committer | unknown <dlenev@mysql.com> | 2005-07-13 13:48:13 +0400 |
commit | 11f9e513d7080c9965e13211d88840960d5ffebb (patch) | |
tree | eb4e973833841f07d83fdb7e830b02e46a90b56a /sql/sql_class.cc | |
parent | 98a3bae33d5d960aa045d82c02ec68312ec7d379 (diff) | |
download | mariadb-git-11f9e513d7080c9965e13211d88840960d5ffebb.tar.gz |
Implementation of Monty's idea: Now we can open mysql.proc table for lookup
of stored routines definitions even if we already have some tables open and
locked. To avoid deadlocks in this case we have to put certain restrictions
on locking of mysql.proc table.
This allows to use stored routines safely under LOCK TABLES without explicitly
mentioning mysql.proc in the list of locked tables. It also fixes bug #11554
"Server crashes on statement indirectly using non-cached function".
mysql-test/r/sp-error.result:
Added test which checks that now we can read stored routines definitions
under LOCK TABLES even if we have not locked mysql.proc explicitly. Also
added check for restrictions which this ability puts on mysql.proc locking.
Updated test for bug #9566 to correspond this new situation.
mysql-test/r/sp-threads.result:
Added test for bug #11554 "Server crashes on statement indirectly using
non-cached function".
mysql-test/t/sp-error.test:
Added test which checks that now we can read stored routines definitions
under LOCK TABLES even if we have not locked mysql.proc explicitly. Also
added check for restrictions which this ability puts on mysql.proc locking.
Updated test for bug #9566 to correspond this new situation.
mysql-test/t/sp-threads.test:
Added test for bug #11554 "Server crashes on statement indirectly using
non-cached function".
sql/lock.cc:
get_lock_data():
To be able to open and lock for reading system tables like 'mysql.proc',
when we already have some tables opened and locked, and avoid deadlocks
we have to disallow write-locking of these tables with any other tables.
sql/mysql_priv.h:
open_table() has new parameter which allows to open table even if some-one
has done a flush or holding namelock on it.
sql/share/errmsg.txt:
Added error message saying that one cannot write-lock some of system tables
with any other tables.
sql/sp.cc:
open_proc_table_for_read()/close_proc_table():
Added functions to be able open and close mysql.proc table when we already
have some tables open and locked.
open_proc_table_for_update():
Added function to simplify opening of mysql.proc for updates.
db_find_routine_aux()/db_find_routine()/db_update_routine()/...
Moved responsibility for opening mysql.proc table from db_find_routine_aux()
one level up, since this level knows better which type of table access for
reading of for update it needs.
sp_function_exists():
Removed unused function.
sql/sp.h:
sp_function_exists():
Removed unused function.
sql/sql_base.cc:
open_table():
Added new parameter which allows to open table even if some-one has done a
flush or holding namelock on it.
open_unireg_entry():
Mark 'mysql.proc' as a system table which has special restrictions on its
locking, but thanks to them can be open and locked even if we already have
some open and locked.
sql/sql_class.cc:
Moved THD members holding information about open and locked tables to separate
Open_tables_state class to be able to save/restore this state easier.
Added THD::push_open_tables_state()/pop_open_tables_state() methods for
saving/restoring this state.
sql/sql_class.h:
Moved THD members holding information about open and locked tables to separate
Open_tables_state class to be able to save/restore this state easier.
Added THD::push_open_tables_state()/pop_open_tables_state() methods for
saving/restoring this state.
sql/sql_lex.cc:
Removed LEX::proc_table member which was not really used.
sql/sql_lex.h:
Removed LEX::proc_table member which was not really used.
sql/sql_table.cc:
open_table() has new parameter which allows to open table even if some-one
has done a flush or holding namelock on it.
sql/table.h:
Added TABLE_SHARE::system_table indicating that this table is system table
like 'mysql.proc' and we want to be able to open and read-lock it even when
we already have some tables open and locked (and because of this we have
to put some restrictions on write locking it).
Diffstat (limited to 'sql/sql_class.cc')
-rw-r--r-- | sql/sql_class.cc | 50 |
1 files changed, 46 insertions, 4 deletions
diff --git a/sql/sql_class.cc b/sql/sql_class.cc index bf6f41d00ed..d0ac1a16f6b 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -156,6 +156,14 @@ bool foreign_key_prefix(Key *a, Key *b) /**************************************************************************** ** Thread specific functions ****************************************************************************/ + +Open_tables_state::Open_tables_state() + :version(refresh_version) +{ + reset_open_tables_state(); +} + + /* Pass nominal parameters to Statement constructor only to ensure that the destructor works OK in case of error. The main_mem_root will be @@ -164,6 +172,7 @@ bool foreign_key_prefix(Key *a, Key *b) THD::THD() :Statement(CONVENTIONAL_EXECUTION, 0, ALLOC_ROOT_MIN_BLOCK_SIZE, 0), + Open_tables_state(), user_time(0), global_read_lock(0), is_fatal_error(0), rand_used(0), time_zone_used(0), last_insert_id_used(0), insert_id_used(0), clear_next_insert_id(0), @@ -181,10 +190,8 @@ THD::THD() db_length= col_access=0; query_error= tmp_table_used= 0; next_insert_id=last_insert_id=0; - open_tables= temporary_tables= handler_tables= derived_tables= 0; hash_clear(&handler_tables_hash); tmp_table=0; - lock=locked_tables=0; used_tables=0; cuted_fields= sent_row_count= 0L; limit_found_rows= 0; @@ -230,7 +237,6 @@ THD::THD() #ifndef NO_EMBEDDED_ACCESS_CHECKS db_access=NO_ACCESS; #endif - version=refresh_version; // For boot *scramble= '\0'; init(); @@ -259,7 +265,6 @@ THD::THD() tablespace_op=FALSE; ulong tmp=sql_rnd_with_mutex(); randominit(&rand, tmp + (ulong) &rand, tmp + (ulong) ::query_id); - prelocked_mode= NON_PRELOCKED; } @@ -1775,3 +1780,40 @@ void THD::set_status_var_init() { bzero((char*) &status_var, sizeof(status_var)); } + +/**************************************************************************** + Handling of open and locked tables states. + + This is used when we want to open/lock (and then close) some tables when + we already have a set of tables open and locked. We use these methods for + access to mysql.proc table to find definitions of stored routines. +****************************************************************************/ + +bool THD::push_open_tables_state() +{ + Open_tables_state *state; + DBUG_ENTER("push_open_table_state"); + /* Currently we only push things one level */ + DBUG_ASSERT(open_state_list.elements == 0); + + if (!(state= (Open_tables_state*) alloc(sizeof(*state)))) + DBUG_RETURN(1); // Fatal error is set + /* Store state for currently open tables */ + state->set_open_tables_state(this); + if (open_state_list.push_back(state, mem_root)) + DBUG_RETURN(1); // Fatal error is set + reset_open_tables_state(); + DBUG_RETURN(0); +} + +void THD::pop_open_tables_state() +{ + Open_tables_state *state; + DBUG_ENTER("pop_open_table_state"); + /* Currently we only push things one level */ + DBUG_ASSERT(open_state_list.elements == 1); + + state= open_state_list.pop(); + set_open_tables_state(state); + DBUG_VOID_RETURN; +} |