1 /*****************************************************************************
2 
3 Copyright (c) 2013, 2019, Oracle and/or its affiliates. All Rights Reserved.
4 
5 This program is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License, version 2.0, as published by the
7 Free Software Foundation.
8 
9 This program is also distributed with certain software (including but not
10 limited to OpenSSL) that is licensed under separate terms, as designated in a
11 particular file or component or in included license documentation. The authors
12 of MySQL hereby grant you an additional permission to link the program and
13 your derivative works with the separately licensed software that they have
14 included with MySQL.
15 
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
19 for more details.
20 
21 You should have received a copy of the GNU General Public License along with
22 this program; if not, write to the Free Software Foundation, Inc.,
23 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
24 
25 *****************************************************************************/
26 
27 /** @file include/sess0sess.h
28  InnoDB session state tracker.
29  Multi file, shared, system tablespace implementation.
30 
31  Created 2014-04-30 by Krunal Bauskar
32  *******************************************************/
33 
34 #ifndef sess0sess_h
35 #define sess0sess_h
36 
37 #include <sql_thd_internal_api.h>
38 #include "dict0mem.h"
39 #include "log0meb.h"
40 #include "srv0tmp.h"
41 #include "trx0trx.h"
42 #include "univ.i"
43 #include "ut0new.h"
44 
45 #include <map>
46 
47 class dict_intrinsic_table_t {
48  public:
49   /** Constructor
50   @param[in,out]	handler		table handler. */
dict_intrinsic_table_t(dict_table_t * handler)51   dict_intrinsic_table_t(dict_table_t *handler) : m_handler(handler) {
52     /* Do nothing. */
53   }
54 
55   /** Destructor */
~dict_intrinsic_table_t()56   ~dict_intrinsic_table_t() { m_handler = nullptr; }
57 
58  public:
59   /* Table Handler holding other metadata information commonly needed
60   for any table. */
61   dict_table_t *m_handler;
62 };
63 
64 /** InnoDB private data that is cached in THD */
65 typedef std::map<
66     std::string, dict_intrinsic_table_t *, std::less<std::string>,
67     ut_allocator<std::pair<const std::string, dict_intrinsic_table_t *>>>
68     table_cache_t;
69 
70 class innodb_session_t {
71  public:
72   /** Constructor */
innodb_session_t()73   innodb_session_t()
74       : m_trx(), m_open_tables(), m_usr_temp_tblsp(), m_intrinsic_temp_tblsp() {
75     /* Do nothing. */
76   }
77 
78   /** Destructor */
~innodb_session_t()79   ~innodb_session_t() {
80     m_trx = nullptr;
81 
82     for (table_cache_t::iterator it = m_open_tables.begin();
83          it != m_open_tables.end(); ++it) {
84       delete (it->second);
85     }
86 
87     meb::redo_log_archive_session_end(this);
88 
89     if (m_usr_temp_tblsp != nullptr) {
90       ibt::free_tmp(m_usr_temp_tblsp);
91     }
92 
93     if (m_intrinsic_temp_tblsp != nullptr) {
94       ibt::free_tmp(m_intrinsic_temp_tblsp);
95     }
96   }
97 
98   /** Cache table handler.
99   @param[in]	table_name	name of the table
100   @param[in,out]	table		table handler to register */
register_table_handler(const char * table_name,dict_table_t * table)101   void register_table_handler(const char *table_name, dict_table_t *table) {
102     ut_ad(lookup_table_handler(table_name) == nullptr);
103     m_open_tables.insert(table_cache_t::value_type(
104         table_name, new dict_intrinsic_table_t(table)));
105   }
106 
107   /** Lookup for table handler given table_name.
108   @param[in]	table_name	name of the table to lookup */
lookup_table_handler(const char * table_name)109   dict_table_t *lookup_table_handler(const char *table_name) {
110     table_cache_t::iterator it = m_open_tables.find(table_name);
111     return ((it == m_open_tables.end()) ? nullptr : it->second->m_handler);
112   }
113 
114   /** Remove table handler entry.
115   @param[in]	table_name	name of the table to remove */
unregister_table_handler(const char * table_name)116   void unregister_table_handler(const char *table_name) {
117     table_cache_t::iterator it = m_open_tables.find(table_name);
118     if (it == m_open_tables.end()) {
119       return;
120     }
121 
122     delete (it->second);
123     m_open_tables.erase(table_name);
124   }
125 
126   /** Count of register table handler.
127   @return number of register table handlers */
count_register_table_handler()128   uint count_register_table_handler() const {
129     return (static_cast<uint>(m_open_tables.size()));
130   }
131 
get_usr_temp_tblsp()132   ibt::Tablespace *get_usr_temp_tblsp() {
133     if (m_usr_temp_tblsp == nullptr) {
134       my_thread_id id = thd_thread_id(m_trx->mysql_thd);
135       m_usr_temp_tblsp = ibt::tbsp_pool->get(id, ibt::TBSP_USER);
136     }
137 
138     return (m_usr_temp_tblsp);
139   }
140 
get_instrinsic_temp_tblsp()141   ibt::Tablespace *get_instrinsic_temp_tblsp() {
142     if (m_intrinsic_temp_tblsp == nullptr) {
143       my_thread_id id = thd_thread_id(m_trx->mysql_thd);
144       m_intrinsic_temp_tblsp = ibt::tbsp_pool->get(id, ibt::TBSP_INTRINSIC);
145     }
146 
147     return (m_intrinsic_temp_tblsp);
148   }
149 
150  public:
151   /** transaction handler. */
152   trx_t *m_trx;
153 
154   /** Handler of tables that are created or open but not added
155   to InnoDB dictionary as they are session specific.
156   Currently, limited to intrinsic temporary tables only. */
157   table_cache_t m_open_tables;
158 
159  private:
160   /** Current session's user temp tablespace */
161   ibt::Tablespace *m_usr_temp_tblsp;
162 
163   /** Current session's optimizer temp tablespace */
164   ibt::Tablespace *m_intrinsic_temp_tblsp;
165 };
166 
167 #endif /* sess0sess_h */
168