1 #ifndef SESSION_TRACKER_INCLUDED 2 #define SESSION_TRACKER_INCLUDED 3 4 /* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License, version 2.0, 8 as published by the Free Software Foundation. 9 10 This program is also distributed with certain software (including 11 but not limited to OpenSSL) that is licensed under separate terms, 12 as designated in a particular file or component or in included license 13 documentation. The authors of MySQL hereby grant you an additional 14 permission to link the program and your derivative works with the 15 separately licensed software that they have included with MySQL. 16 17 This program is distributed in the hope that it will be useful, 18 but WITHOUT ANY WARRANTY; without even the implied warranty of 19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 GNU General Public License, version 2.0, for more details. 21 22 You should have received a copy of the GNU General Public License 23 along with this program; if not, write to the Free Software 24 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 25 26 #include "m_string.h" 27 #include "thr_lock.h" 28 29 /* forward declarations */ 30 class THD; 31 class set_var; 32 class String; 33 typedef struct charset_info_st CHARSET_INFO; 34 35 36 enum enum_session_tracker 37 { 38 SESSION_SYSVARS_TRACKER, /* Session system variables */ 39 CURRENT_SCHEMA_TRACKER, /* Current schema */ 40 SESSION_STATE_CHANGE_TRACKER, 41 SESSION_GTIDS_TRACKER, /* Tracks GTIDs */ 42 TRANSACTION_INFO_TRACKER /* Transaction state */ 43 }; 44 45 #define SESSION_TRACKER_END TRANSACTION_INFO_TRACKER 46 47 48 /** 49 State_tracker 50 ------------- 51 An abstract class that defines the interface for any of the server's 52 'session state change tracker'. A tracker, however, is a sub- class of 53 this class which takes care of tracking the change in value of a part- 54 icular session state type and thus defines various methods listed in this 55 interface. The change information is later serialized and transmitted to 56 the client through protocol's OK packet. 57 58 Tracker system variables :- 59 A tracker is normally mapped to a system variable. So in order to enable, 60 disable or modify the sub-entities of a tracker, the user needs to modify 61 the respective system variable either through SET command or via command 62 line option. As required in system variable handling, this interface also 63 includes two functions to help in the verification of the supplied value 64 (ON_CHECK) and the updation (ON_UPDATE) of the tracker system variable, 65 namely - check() and update(). 66 */ 67 68 class State_tracker 69 { 70 protected: 71 /** Is tracking enabled for a particular session state type ? */ 72 bool m_enabled; 73 74 /** Has the session state type changed ? */ 75 bool m_changed; 76 77 public: 78 /** Constructor */ State_tracker()79 State_tracker() : m_enabled(false), m_changed(false) 80 {} 81 82 /** Destructor */ ~State_tracker()83 virtual ~State_tracker() 84 {} 85 86 /** Getters */ is_enabled()87 bool is_enabled() const 88 { return m_enabled; } 89 is_changed()90 bool is_changed() const 91 { return m_changed; } 92 93 /** Called in the constructor of THD*/ 94 virtual bool enable(THD *thd)= 0; 95 96 /** To be invoked when the tracker's system variable is checked (ON_CHECK). */ 97 virtual bool check(THD *thd, set_var *var)= 0; 98 99 /** To be invoked when the tracker's system variable is updated (ON_UPDATE).*/ 100 virtual bool update(THD *thd)= 0; 101 102 /** Store changed data into the given buffer. */ 103 virtual bool store(THD *thd, String &buf)= 0; 104 105 /** Mark the entity as changed. */ 106 virtual void mark_as_changed(THD *thd, LEX_CSTRING *name)= 0; 107 claim_memory_ownership()108 virtual void claim_memory_ownership() 109 {} 110 }; 111 112 113 /** 114 Session_tracker 115 --------------- 116 This class holds an object each for all tracker classes and provides 117 methods necessary for systematic detection and generation of session 118 state change information. 119 */ 120 121 class Session_tracker 122 { 123 private: 124 State_tracker *m_trackers[SESSION_TRACKER_END + 1]; 125 126 /* The following two functions are private to disable copying. */ 127 /** Copy constructor */ Session_tracker(Session_tracker const & other)128 Session_tracker(Session_tracker const &other) 129 { 130 DBUG_ASSERT(FALSE); 131 } 132 133 /** Copy assignment operator */ 134 Session_tracker& operator= (Session_tracker const &rhs) 135 { 136 DBUG_ASSERT(FALSE); 137 return *this; 138 } 139 140 public: 141 142 /** Constructor */ Session_tracker()143 Session_tracker() 144 {} 145 146 /** Destructor */ ~Session_tracker()147 ~Session_tracker() 148 { 149 } 150 /** 151 Initialize Session_tracker objects and enable them based on the 152 tracker_xxx variables' value that the session inherit from global 153 variables at the time of session initialization (see plugin_thdvar_init). 154 */ 155 void init(const CHARSET_INFO *char_set); 156 void enable(THD *thd); 157 bool server_boot_verify(const CHARSET_INFO *char_set, LEX_STRING var_list); 158 159 /** Returns the pointer to the tracker object for the specified tracker. */ 160 State_tracker *get_tracker(enum_session_tracker tracker) const; 161 162 /** Checks if m_enabled flag is set for any of the tracker objects. */ 163 bool enabled_any(); 164 165 /** Checks if m_changed flag is set for any of the tracker objects. */ 166 bool changed_any(); 167 168 /** 169 Stores the session state change information of all changes session state 170 type entities into the specified buffer. 171 */ 172 void store(THD *thd, String &main_buf); deinit()173 void deinit() 174 { 175 for (int i= 0; i <= SESSION_TRACKER_END; i ++) 176 delete m_trackers[i]; 177 } 178 179 void claim_memory_ownership(); 180 }; 181 182 /* 183 Session_state_change_tracker 184 ---------------------------- 185 This is a boolean tracker class that will monitor any change that contributes 186 to a session state change. 187 Attributes that contribute to session state change include: 188 - Successful change to System variables 189 - User defined variables assignments 190 - temporary tables created, altered or deleted 191 - prepared statements added or removed 192 - change in current database 193 */ 194 195 class Session_state_change_tracker : public State_tracker 196 { 197 private: 198 199 void reset(); 200 201 public: 202 Session_state_change_tracker(); 203 bool enable(THD *thd); check(THD * thd,set_var * var)204 bool check(THD *thd, set_var *var) 205 { return false; } 206 bool update(THD *thd); 207 bool store(THD *thd, String &buf); 208 void mark_as_changed(THD *thd, LEX_CSTRING *tracked_item_name); 209 bool is_state_changed(THD*); ensure_enabled(THD * thd)210 void ensure_enabled(THD *thd) 211 {} 212 }; 213 214 215 /** 216 Transaction_state_tracker 217 ---------------------- 218 This is a tracker class that enables & manages the tracking of 219 current transaction info for a particular connection. 220 */ 221 222 /** 223 Transaction state (no transaction, transaction active, work attached, etc.) 224 */ 225 enum enum_tx_state { 226 TX_EMPTY = 0, ///< "none of the below" 227 TX_EXPLICIT = 1, ///< an explicit transaction is active 228 TX_IMPLICIT = 2, ///< an implicit transaction is active 229 TX_READ_TRX = 4, ///< transactional reads were done 230 TX_READ_UNSAFE = 8, ///< non-transaction reads were done 231 TX_WRITE_TRX = 16, ///< transactional writes were done 232 TX_WRITE_UNSAFE = 32, ///< non-transactional writes were done 233 TX_STMT_UNSAFE = 64, ///< "unsafe" (non-deterministic like UUID()) stmts 234 TX_RESULT_SET = 128, ///< result-set was sent 235 TX_WITH_SNAPSHOT= 256, ///< WITH CONSISTENT SNAPSHOT was used 236 TX_LOCKED_TABLES= 512 ///< LOCK TABLES is active 237 }; 238 239 /** 240 Transaction access mode 241 */ 242 enum enum_tx_read_flags { 243 TX_READ_INHERIT = 0, ///< not explicitly set, inherit session.tx_read_only 244 TX_READ_ONLY = 1, ///< START TRANSACTION READ ONLY, or tx_read_only=1 245 TX_READ_WRITE = 2, ///< START TRANSACTION READ WRITE, or tx_read_only=0 246 }; 247 248 /** 249 Transaction isolation level 250 */ 251 enum enum_tx_isol_level { 252 TX_ISOL_INHERIT = 0, ///< not explicitly set, inherit session.tx_isolation 253 TX_ISOL_UNCOMMITTED = 1, 254 TX_ISOL_COMMITTED = 2, 255 TX_ISOL_REPEATABLE = 3, 256 TX_ISOL_SERIALIZABLE= 4 257 }; 258 259 /** 260 Transaction tracking level 261 */ 262 enum enum_session_track_transaction_info { 263 TX_TRACK_NONE = 0, ///< do not send tracker items on transaction info 264 TX_TRACK_STATE = 1, ///< track transaction status 265 TX_TRACK_CHISTICS = 2 ///< track status and characteristics 266 }; 267 268 class Transaction_state_tracker : public State_tracker 269 { 270 public: 271 /** Constructor */ 272 Transaction_state_tracker(); enable(THD * thd)273 bool enable(THD *thd) 274 { return update(thd); } check(THD * thd,set_var * var)275 bool check(THD *thd, set_var *var) 276 { return false; } 277 bool update(THD *thd); 278 bool store(THD *thd, String &buf); 279 void mark_as_changed(THD *thd, LEX_CSTRING *tracked_item_name); 280 281 /** Change transaction characteristics */ 282 void set_read_flags(THD *thd, enum enum_tx_read_flags flags); 283 void set_isol_level(THD *thd, enum enum_tx_isol_level level); 284 285 /** Change transaction state */ 286 void clear_trx_state(THD *thd, uint clear); 287 void add_trx_state(THD *thd, uint add); 288 void add_trx_state_from_thd(THD *thd); 289 void end_trx(THD *thd); 290 291 /** Helper function: turn table info into table access flag */ 292 enum_tx_state calc_trx_state(THD *thd, thr_lock_type l, bool has_trx); 293 294 private: 295 enum enum_tx_changed { 296 TX_CHG_NONE = 0, ///< no changes from previous stmt 297 TX_CHG_STATE = 1, ///< state has changed from previous stmt 298 TX_CHG_CHISTICS = 2 ///< characteristics have changed from previous stmt 299 }; 300 301 /** any trackable changes caused by this statement? */ 302 uint tx_changed; 303 304 /** transaction state */ 305 uint tx_curr_state, tx_reported_state; 306 307 /** r/w or r/o set? session default? */ 308 enum enum_tx_read_flags tx_read_flags; 309 310 /** isolation level */ 311 enum enum_tx_isol_level tx_isol_level; 312 313 void reset(); 314 update_change_flags(THD * thd)315 inline void update_change_flags(THD *thd) 316 { 317 tx_changed &= ~TX_CHG_STATE; 318 tx_changed |= (tx_curr_state != tx_reported_state) ? TX_CHG_STATE : 0; 319 if (tx_changed != TX_CHG_NONE) 320 mark_as_changed(thd, NULL); 321 } 322 }; 323 324 325 #endif /* SESSION_TRACKER_INCLUDED */ 326