summaryrefslogtreecommitdiff
path: root/sql/sql_class.h
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_class.h')
-rw-r--r--sql/sql_class.h174
1 files changed, 146 insertions, 28 deletions
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 36ee298caed..783f8b9df11 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1264,6 +1264,61 @@ enum enum_locked_tables_mode
LTM_PRELOCKED_UNDER_LOCK_TABLES
};
+/**
+ The following structure is an extension to TABLE_SHARE and is
+ exclusively for temporary tables.
+
+ @note:
+ Although, TDC_element has data members (like next, prev &
+ all_tables) to store the list of TABLE_SHARE & TABLE objects
+ related to a particular TABLE_SHARE, they cannot be moved to
+ TABLE_SHARE in order to be reused for temporary tables. This
+ is because, as concurrent threads iterating through hash of
+ TDC_element's may need access to all_tables, but if all_tables
+ is made part of TABLE_SHARE, then TDC_element->share->all_tables
+ is not always guaranteed to be valid, as TDC_element can live
+ longer than TABLE_SHARE.
+*/
+struct TMP_TABLE_SHARE : public TABLE_SHARE
+{
+private:
+ /*
+ Link to all temporary table shares. Declared as private to
+ avoid direct manipulation with those objects. One should
+ use methods of I_P_List template instead.
+ */
+ TMP_TABLE_SHARE *tmp_next;
+ TMP_TABLE_SHARE **tmp_prev;
+
+ friend struct All_tmp_table_shares;
+
+public:
+ /*
+ Doubly-linked (back-linked) lists of used and unused TABLE objects
+ for this share.
+ */
+ All_share_tables_list all_tmp_tables;
+};
+
+/**
+ Helper class which specifies which members of TMP_TABLE_SHARE are
+ used for participation in the list of temporary tables.
+*/
+
+struct All_tmp_table_shares
+{
+ static inline TMP_TABLE_SHARE **next_ptr(TMP_TABLE_SHARE *l)
+ {
+ return &l->tmp_next;
+ }
+ static inline TMP_TABLE_SHARE ***prev_ptr(TMP_TABLE_SHARE *l)
+ {
+ return &l->tmp_prev;
+ }
+};
+
+/* Also used in rpl_rli.h. */
+typedef I_P_List <TMP_TABLE_SHARE, All_tmp_table_shares> All_tmp_tables_list;
/**
Class that holds information about tables which were opened and locked
@@ -1293,15 +1348,20 @@ public:
base tables that were opened with @see open_tables().
*/
TABLE *open_tables;
+
/**
- List of temporary tables used by this thread. Contains user-level
- temporary tables, created with CREATE TEMPORARY TABLE, and
- internal temporary tables, created, e.g., to resolve a SELECT,
+ A list of temporary tables used by this thread. This includes
+ user-level temporary tables, created with CREATE TEMPORARY TABLE,
+ and internal temporary tables, created, e.g., to resolve a SELECT,
or for an intermediate table used in ALTER.
- XXX Why are internal temporary tables added to this list?
*/
- TABLE *temporary_tables;
+ All_tmp_tables_list *temporary_tables;
+
+ /*
+ Derived tables.
+ */
TABLE *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
@@ -1379,8 +1439,11 @@ public:
void reset_open_tables_state(THD *thd)
{
- open_tables= temporary_tables= derived_tables= 0;
- extra_lock= lock= 0;
+ open_tables= 0;
+ temporary_tables= 0;
+ derived_tables= 0;
+ extra_lock= 0;
+ lock= 0;
locked_tables_mode= LTM_NONE;
state_flags= 0U;
m_reprepare_observer= NULL;
@@ -3544,13 +3607,13 @@ public:
*/
DBUG_PRINT("debug",
("temporary_tables: %s, in_sub_stmt: %s, system_thread: %s",
- YESNO(temporary_tables), YESNO(in_sub_stmt),
+ YESNO(has_thd_temporary_tables()), YESNO(in_sub_stmt),
show_system_thread(system_thread)));
if (in_sub_stmt == 0)
{
if (wsrep_binlog_format() == BINLOG_FORMAT_ROW)
set_current_stmt_binlog_format_row();
- else if (temporary_tables == NULL)
+ else if (!has_thd_temporary_tables())
set_current_stmt_binlog_format_stmt();
}
DBUG_VOID_RETURN;
@@ -3950,10 +4013,6 @@ private:
LEX_STRING invoker_user;
LEX_STRING invoker_host;
- /* Protect against add/delete of temporary tables in parallel replication */
- void rgi_lock_temporary_tables();
- void rgi_unlock_temporary_tables();
- bool rgi_have_temporary_tables();
public:
/*
Flag, mutex and condition for a thread to wait for a signal from another
@@ -3971,26 +4030,85 @@ public:
*/
rpl_gtid last_commit_gtid;
- inline void lock_temporary_tables()
+ LF_PINS *tdc_hash_pins;
+ LF_PINS *xid_hash_pins;
+ bool fix_xid_hash_pins();
+
+/* Members related to temporary tables. */
+public:
+ bool has_thd_temporary_tables();
+
+ TABLE *create_and_open_tmp_table(handlerton *hton,
+ LEX_CUSTRING *frm,
+ const char *path,
+ const char *db,
+ const char *table_name,
+ bool open_in_engine);
+
+ TABLE *find_temporary_table(const char *db, const char *table_name);
+ TABLE *find_temporary_table(const TABLE_LIST *tl);
+
+ TMP_TABLE_SHARE *find_tmp_table_share_w_base_key(const char *key,
+ uint key_length);
+ TMP_TABLE_SHARE *find_tmp_table_share(const char *db,
+ const char *table_name);
+ TMP_TABLE_SHARE *find_tmp_table_share(const TABLE_LIST *tl);
+ TMP_TABLE_SHARE *find_tmp_table_share(const char *key, uint key_length);
+
+ bool open_temporary_table(TABLE_LIST *tl);
+ bool open_temporary_tables(TABLE_LIST *tl);
+
+ bool close_temporary_tables();
+ bool rename_temporary_table(TABLE *table, const char *db,
+ const char *table_name);
+ bool drop_temporary_table(TABLE *table, bool *is_trans, bool delete_table);
+ bool rm_temporary_table(handlerton *hton, const char *path);
+ void mark_tmp_tables_as_free_for_reuse();
+ void mark_tmp_table_as_free_for_reuse(TABLE *table);
+
+private:
+ /* Whether a lock has been acquired? */
+ bool m_tmp_tables_locked;
+
+ /* Opened table states. */
+ enum Temporary_table_state {
+ TMP_TABLE_IN_USE,
+ TMP_TABLE_NOT_IN_USE,
+ TMP_TABLE_ANY
+ };
+
+ bool has_temporary_tables();
+ uint create_tmp_table_def_key(char *key, const char *db,
+ const char *table_name);
+ TMP_TABLE_SHARE *create_temporary_table(handlerton *hton, LEX_CUSTRING *frm,
+ const char *path, const char *db,
+ const char *table_name);
+ TABLE *find_temporary_table(const char *key, uint key_length,
+ Temporary_table_state state);
+ TABLE *open_temporary_table(TMP_TABLE_SHARE *share, const char *alias,
+ bool open_in_engine);
+ bool find_and_use_tmp_table(const TABLE_LIST *tl, TABLE **out_table);
+ bool use_temporary_table(TABLE *table, TABLE **out_table);
+ void close_temporary_table(TABLE *table);
+ bool log_events_and_free_tmp_shares();
+ void free_tmp_table_share(TMP_TABLE_SHARE *share, bool delete_table);
+ void free_temporary_table(TABLE *table);
+ bool lock_temporary_tables();
+ void unlock_temporary_tables();
+
+ inline uint tmpkeyval(TMP_TABLE_SHARE *share)
{
- if (rgi_slave)
- rgi_lock_temporary_tables();
+ return uint4korr(share->table_cache_key.str +
+ share->table_cache_key.length - 4);
}
- inline void unlock_temporary_tables()
- {
- if (rgi_slave)
- rgi_unlock_temporary_tables();
- }
- inline bool have_temporary_tables()
+
+ inline TMP_TABLE_SHARE *tmp_table_share(TABLE *table)
{
- return (temporary_tables ||
- (rgi_slave && rgi_have_temporary_tables()));
+ DBUG_ASSERT(table->s->tmp_table);
+ return static_cast<TMP_TABLE_SHARE *>(table->s);
}
- LF_PINS *tdc_hash_pins;
- LF_PINS *xid_hash_pins;
- bool fix_xid_hash_pins();
-
+public:
inline ulong wsrep_binlog_format() const
{
return WSREP_FORMAT(variables.binlog_format);