summaryrefslogtreecommitdiff
path: root/sql/sql_class.h
diff options
context:
space:
mode:
authorunknown <dlenev@mysql.com>2005-07-13 13:48:13 +0400
committerunknown <dlenev@mysql.com>2005-07-13 13:48:13 +0400
commit11f9e513d7080c9965e13211d88840960d5ffebb (patch)
treeeb4e973833841f07d83fdb7e830b02e46a90b56a /sql/sql_class.h
parent98a3bae33d5d960aa045d82c02ec68312ec7d379 (diff)
downloadmariadb-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.h')
-rw-r--r--sql/sql_class.h144
1 files changed, 88 insertions, 56 deletions
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 5642fa0d6af..625b9c27b44 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -933,12 +933,93 @@ enum prelocked_mode_type {NON_PRELOCKED= 0, PRELOCKED= 1,
/*
+ Class that holds information about tables which were open and locked
+ by the thread. It is also used to save/restore this information in
+ push_open_tables_state()/pop_open_tables_state().
+*/
+
+class Open_tables_state
+{
+public:
+ /*
+ open_tables - list of regular tables in use by this thread
+ temporary_tables - list of temp tables in use by this thread
+ handler_tables - list of tables that were opened with HANDLER OPEN
+ and are still in use by this thread
+ */
+ TABLE *open_tables, *temporary_tables, *handler_tables, *derived_tables;
+ /*
+ During a MySQL session, one can lock tables in two modes: automatic
+ or manual. In automatic mode all necessary tables are locked just before
+ statement execution, and all acquired locks are stored in 'lock'
+ member. Unlocking takes place automatically as well, when the
+ statement ends.
+ Manual mode comes into play when a user issues a 'LOCK TABLES'
+ statement. In this mode the user can only use the locked tables.
+ Trying to use any other tables will give an error. The locked tables are
+ stored in 'locked_tables' member. Manual locking is described in
+ the 'LOCK_TABLES' chapter of the MySQL manual.
+ See also lock_tables() for details.
+ */
+ MYSQL_LOCK *lock;
+ /*
+ Tables that were locked with explicit or implicit LOCK TABLES.
+ (Implicit LOCK TABLES happens when we are prelocking tables for
+ execution of statement which uses stored routines. See description
+ THD::prelocked_mode for more info.)
+ */
+ MYSQL_LOCK *locked_tables;
+ /*
+ prelocked_mode_type enum and prelocked_mode member are used for
+ indicating whenever "prelocked mode" is on, and what type of
+ "prelocked mode" is it.
+
+ Prelocked mode is used for execution of queries which explicitly
+ or implicitly (via views or triggers) use functions, thus may need
+ some additional tables (mentioned in query table list) for their
+ execution.
+
+ First open_tables() call for such query will analyse all functions
+ used by it and add all additional tables to table its list. It will
+ also mark this query as requiring prelocking. After that lock_tables()
+ will issue implicit LOCK TABLES for the whole table list and change
+ thd::prelocked_mode to non-0. All queries called in functions invoked
+ by the main query will use prelocked tables. Non-0 prelocked_mode
+ will also surpress mentioned analysys in those queries thus saving
+ cycles. Prelocked mode will be turned off once close_thread_tables()
+ for the main query will be called.
+
+ Note: Since not all "tables" present in table list are really locked
+ thd::prelocked_mode does not imply thd::locked_tables.
+ */
+ prelocked_mode_type prelocked_mode;
+ ulong version;
+ uint current_tablenr;
+
+ Open_tables_state();
+
+ void set_open_tables_state(Open_tables_state *state)
+ {
+ *this= *state;
+ }
+
+ void reset_open_tables_state()
+ {
+ open_tables= temporary_tables= handler_tables= derived_tables= 0;
+ lock= locked_tables= 0;
+ prelocked_mode= NON_PRELOCKED;
+ }
+};
+
+
+/*
For each client connection we create a separate thread with THD serving as
a thread/connection descriptor
*/
class THD :public ilink,
- public Statement
+ public Statement,
+ public Open_tables_state
{
public:
#ifdef EMBEDDED_LIBRARY
@@ -1006,34 +1087,6 @@ public:
ulong master_access; /* Global privileges from mysql.user */
ulong db_access; /* Privileges for current db */
- /*
- open_tables - list of regular tables in use by this thread
- temporary_tables - list of temp tables in use by this thread
- handler_tables - list of tables that were opened with HANDLER OPEN
- and are still in use by this thread
- */
- TABLE *open_tables,*temporary_tables, *handler_tables, *derived_tables;
- /*
- During a MySQL session, one can lock tables in two modes: automatic
- or manual. In automatic mode all necessary tables are locked just before
- statement execution, and all acquired locks are stored in 'lock'
- member. Unlocking takes place automatically as well, when the
- statement ends.
- Manual mode comes into play when a user issues a 'LOCK TABLES'
- statement. In this mode the user can only use the locked tables.
- Trying to use any other tables will give an error. The locked tables are
- stored in 'locked_tables' member. Manual locking is described in
- the 'LOCK_TABLES' chapter of the MySQL manual.
- See also lock_tables() for details.
- */
- MYSQL_LOCK *lock; /* Current locks */
- /*
- Tables that were locked with explicit or implicit LOCK TABLES.
- (Implicit LOCK TABLES happens when we are prelocking tables for
- execution of statement which uses stored routines. See description
- THD::prelocked_mode for more info.)
- */
- MYSQL_LOCK *locked_tables;
HASH handler_tables_hash;
/*
One thread can hold up to one named user-level lock. This variable
@@ -1150,6 +1203,7 @@ public:
List <MYSQL_ERROR> warn_list;
uint warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_END];
uint total_warn_count;
+ List <Open_tables_state> open_state_list;
/*
Id of current query. Statement can be reused to execute several queries
query_id is global in context of the whole MySQL server.
@@ -1159,7 +1213,7 @@ public:
update auto-updatable fields (like auto_increment and timestamp).
*/
query_id_t query_id, warn_id;
- ulong version, options, thread_id, col_access;
+ ulong options, thread_id, col_access;
/* Statement id is thread-wide. This counter is used to generate ids */
ulong statement_id_counter;
@@ -1167,7 +1221,7 @@ public:
ulong row_count; // Row counter, mainly for errors and warnings
long dbug_thread_id;
pthread_t real_id;
- uint current_tablenr,tmp_table,global_read_lock;
+ uint tmp_table, global_read_lock;
uint server_status,open_options,system_thread;
uint32 db_length;
uint select_number; //number of select (used for EXPLAIN)
@@ -1218,31 +1272,6 @@ public:
long long_value;
} sys_var_tmp;
- /*
- prelocked_mode_type enum and prelocked_mode member are used for
- indicating whenever "prelocked mode" is on, and what type of
- "prelocked mode" is it.
-
- Prelocked mode is used for execution of queries which explicitly
- or implicitly (via views or triggers) use functions, thus may need
- some additional tables (mentioned in query table list) for their
- execution.
-
- First open_tables() call for such query will analyse all functions
- used by it and add all additional tables to table its list. It will
- also mark this query as requiring prelocking. After that lock_tables()
- will issue implicit LOCK TABLES for the whole table list and change
- thd::prelocked_mode to non-0. All queries called in functions invoked
- by the main query will use prelocked tables. Non-0 prelocked_mode
- will also surpress mentioned analysys in those queries thus saving
- cycles. Prelocked mode will be turned off once close_thread_tables()
- for the main query will be called.
-
- Note: Since not all "tables" present in table list are really locked
- thd::relocked_mode does not imply thd::locked_tables.
- */
- prelocked_mode_type prelocked_mode;
-
THD();
~THD();
@@ -1428,8 +1457,11 @@ public:
(variables.sql_mode & MODE_STRICT_ALL_TABLES)));
}
void set_status_var_init();
+ bool push_open_tables_state();
+ void pop_open_tables_state();
};
+
#define tmp_disable_binlog(A) \
{ulong tmp_disable_binlog__save_options= (A)->options; \
(A)->options&= ~OPTION_BIN_LOG