1 /* Copyright (C) 2014 InfiniDB, Inc. 2 3 This program is free software; you can redistribute it and/or 4 modify it under the terms of the GNU General Public License 5 as published by the Free Software Foundation; version 2 of 6 the License. 7 8 This program is distributed in the hope that it will be useful, 9 but WITHOUT ANY WARRANTY; without even the implied warranty of 10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 GNU General Public License for more details. 12 13 You should have received a copy of the GNU General Public License 14 along with this program; if not, write to the Free Software 15 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 16 MA 02110-1301, USA. */ 17 18 /****************************************************************************** 19 * $Id: sessionmanagerserver.h 1906 2013-06-14 19:15:32Z rdempsey $ 20 * 21 *****************************************************************************/ 22 23 /** @file 24 * class SessionManagerServer interface 25 */ 26 27 #ifndef _SESSIONMANAGERSERVER_H 28 #define _SESSIONMANAGERSERVER_H 29 30 #include <map> 31 32 #include <boost/shared_array.hpp> 33 #include <boost/thread/mutex.hpp> 34 #include <boost/thread/condition_variable.hpp> 35 36 #include "calpontsystemcatalog.h" 37 #include "brmtypes.h" 38 39 #include "atomicops.h" 40 41 #if defined(_MSC_VER) && defined(xxxSESSIONMANAGERSERVER_DLLEXPORT) 42 #define EXPORT __declspec(dllexport) 43 #else 44 #define EXPORT 45 #endif 46 47 #ifdef _MSC_VER 48 #pragma warning (push) 49 #pragma warning (disable : 4200) 50 #endif 51 52 namespace BRM 53 { 54 55 /** @brief Issues transaction IDs and keeps track of the current system-wide version ID. 56 * 57 * This class's primary purpose is to keep track of the current system-wide version ID and issue transaction IDs. 58 * It can be used simultaneously by multiple threads and processes. 59 * 60 * It uses system-wide semaphores and shared memory segments for IPC. 61 * It allocates both if they don't already exist, but it only deallocates 62 * the shmseg (saves it to a file so state isn't lost). It may be a waste of 63 * CPU time to deallocate either while the system is running. It may be more 64 * appropriate to do that in the DB shut down script. 65 * 66 * Note: Added a macro 'DESTROYSHMSEG' which enables/disables the code to load/save 67 * and deallocate the shared memory segment. 68 * 69 * This class uses 3 parameters from the Columnstore.xml file: 70 * SessionManager/MaxConcurrentTransactions: defines how many active transactions the 71 * system should support. When a new request comes in and there are already 72 * MaxConcurrentTransactions active, the new request blocks by default. The 73 * default value is 1000. 74 * SessionManager/SharedMemoryTmpFile: the file to store the shared memory segment 75 * data in between invocations if DESTROYSHMSEG is defined below. The 76 * default is /tmp/ColumnstoreShm. 77 * SessionManager/TxnIDFile: the file to store the last transaction ID issued 78 */ 79 80 /* 81 * Define DESTROYSHMSEG if the SM should deallocate the shared memory segment 82 * after the last reference has died. This also enables the load/save 83 * operations. If it is undefined, the segment is never deallocated 84 * by SM, and is therefore more efficient between instances. 85 * NOTE: It seems that valgrind doesn't work well with shared memory segments. 86 * Specifically, when the code executes shmctl(IPC_RMID), which normally means 87 * "destroy the segment when refcount == 0", the segment is destroyed 88 * immediately, causing all subsequent references to fail. This only affects 89 * 'leakcheck'. 90 */ 91 //#define DESTROYSHMSEG 92 93 class SessionManagerServer 94 { 95 public: 96 /** @brief SID = Session ID */ 97 typedef uint32_t SID; 98 99 // State flags. These bit values are stored in Overlay::state and reflect the current state of the system 100 static const uint32_t SS_READY; /// bit 0 => Set by dmlProc one time when dmlProc is ready 101 static const uint32_t SS_SUSPENDED; /// bit 1 => Set by console when the system has been suspended by user. 102 static const uint32_t SS_SUSPEND_PENDING; /// bit 2 => Set by console when user wants to suspend, but writing is occuring. 103 static const uint32_t SS_SHUTDOWN_PENDING; /// bit 3 => Set by console when user wants to shutdown, but writing is occuring. 104 static const uint32_t SS_ROLLBACK; /// bit 4 => In combination with a PENDING flag, force a rollback as soom as possible. 105 static const uint32_t SS_FORCE; /// bit 5 => In combination with a PENDING flag, force a shutdown without rollback. 106 static const uint32_t SS_QUERY_READY; /// bit 6 => Set by ProcManager when system is ready for queries 107 108 /** @brief Constructor 109 * 110 * This sets up the shared memory segment & semaphores used by this 111 * instance. No additional set-up calls are necessary. 112 * @note throws ios_base::failure on file IO error, runtime_error for 113 * other types of errors. It might be worthwhile to define additional 114 * exceptions for all the different types of failures that can happen 115 * here. 116 */ 117 EXPORT SessionManagerServer(); 118 119 /** @brief Destructor 120 * 121 * This detaches the shared memory segment. If DESTROYSHMSEG is defined and this 122 * is the last reference to it, it will be saved to disk and destroyed. 123 * It does not destroy the semaphores. Those persist until the system 124 * is shut down. 125 */ 126 virtual ~SessionManagerServer(); 127 128 /** @brief Gets the current version ID 129 * 130 * Gets the current version ID. 131 */ 132 EXPORT const QueryContext verID(); 133 134 /** @brief Gets the current version ID 135 * 136 * Gets the current version ID. 137 */ 138 EXPORT const QueryContext sysCatVerID(); 139 140 /** @brief Gets a new Transaction ID 141 * 142 * Makes a new Transaction ID, associates it with the given session 143 * and increments the system-wide version ID 144 * @note This blocks until (# active transactions) \< MaxTxns unless block == false 145 * @note Throws runtime_error on semaphore-related error 146 * @note This will always return a valid TxnID unless block == false, in which case 147 * it will return a valid TxnID iff it doesn't have to block. 148 * @param session The session ID to associate with the transaction ID 149 * @param block If true, this will block until there is an available slot, otherwise 150 * it will return a TxnID marked invalid, signifying that it could not start a new transaction 151 * @return The new transaction ID. 152 */ 153 EXPORT const TxnID newTxnID(const SID session, bool block = true, bool isDDL = false); 154 155 /** @brief Record that a transaction has been committed 156 * 157 * Record that a transaction has been committed. 158 * @note Throws runtime_error on a semaphore-related error, invalid_argument 159 * when txnid can't be found 160 * @param txnid The committed transaction ID. This is marked invalid 161 * on return. 162 */ committed(TxnID & txn)163 void committed(TxnID& txn) 164 { 165 finishTransaction(txn); 166 } 167 168 /** @brief Record that a transaction has been rolled back 169 * 170 * Record that a transaction has been rolled back. 171 * @note Throws runtime_error on a semaphore-related error, invalid_argument 172 * when txnid can't be found 173 * @param txnid The rolled back transaction ID. This is marked invalid 174 * on return. 175 */ rolledback(TxnID & txn)176 void rolledback(TxnID& txn) 177 { 178 finishTransaction(txn); 179 } 180 181 /** @brief Gets the transaction ID associated with a given session ID 182 * 183 * Gets the transaction ID associated with a given session ID. 184 * @note Throws runtime_error on a semaphore-related error 185 * @param session The session ID 186 * @return A valid transaction ID if there's an association; an invalid 187 * one if there isn't. 188 */ 189 EXPORT const TxnID getTxnID(const SID session); 190 191 /** @brief Gets an array containing all active SID-TID associations 192 * 193 * Gets an array containing the SID-TID associations of all active 194 * transactions. This is intended to be used by another object 195 * that can determine which sessions are still live and which 196 * transactions need to go away. 197 * @note Throws runtime_error on a semaphore-related error 198 * @param len (out) the length of the array 199 * @return A pointer to the array. Note: The caller is responsible for 200 * deallocating it. Use delete[]. 201 */ 202 EXPORT boost::shared_array<SIDTIDEntry> SIDTIDMap(int& len); 203 204 /** 205 * get a unique 32-bit number 206 */ getUnique32()207 uint32_t getUnique32() 208 { 209 return atomicops::atomicInc(&unique32); 210 } 211 212 /** 213 * get a unique 64-bit number 214 */ getUnique64()215 uint64_t getUnique64() 216 { 217 return atomicops::atomicInc(&unique64); 218 } 219 220 /** @brief Resets the semaphores to their original state. For testing only. 221 * 222 * Resets the semaphores to their original state. For testing only. 223 */ 224 EXPORT void reset(); 225 226 /** 227 * get the Txn ID filename 228 */ getTxnIDFilename()229 std::string getTxnIDFilename() const 230 { 231 return txnidFilename; 232 } 233 234 /** @brief set system state info 235 * 236 * Sets the bits on in Overlay::systemState that are found on in 237 * state. That is Overlay::systemState | state. 238 */ 239 EXPORT void setSystemState(uint32_t state); 240 241 /** @brief set system state info 242 * 243 * Clears the bits on in Overlay::systemState that are found on 244 * in state. That is Overlay::systemState & ~state. 245 */ 246 EXPORT void clearSystemState(uint32_t state); 247 248 /** @brief get system state info 249 * 250 * Returns the Overlay::systemState flags 251 */ getSystemState(uint32_t & state)252 void getSystemState(uint32_t& state) 253 { 254 state = systemState; 255 } 256 257 /** 258 * get the number of active txn's 259 */ 260 EXPORT uint32_t getTxnCount(); 261 262 private: 263 SessionManagerServer(const SessionManagerServer&); 264 SessionManagerServer& operator=(const SessionManagerServer&); 265 266 void loadState(); 267 void saveSystemState(); 268 void finishTransaction(TxnID& txn); 269 void saveSMTxnIDAndState(); 270 271 volatile uint32_t unique32; 272 volatile uint64_t unique64; 273 274 int maxTxns; // the maximum number of concurrent transactions 275 std::string txnidFilename; 276 execplan::CalpontSystemCatalog::SCN _verID; 277 execplan::CalpontSystemCatalog::SCN _sysCatVerID; 278 uint32_t systemState; 279 280 std::map<SID, execplan::CalpontSystemCatalog::SCN> activeTxns; 281 typedef std::map<SID, execplan::CalpontSystemCatalog::SCN>::iterator iterator; 282 283 boost::mutex mutex; 284 boost::condition_variable condvar; // used to synthesize a semaphore 285 uint32_t semValue; 286 }; 287 288 } //namespace 289 290 #ifdef _MSC_VER 291 #pragma warning (pop) 292 #endif 293 294 #undef EXPORT 295 296 #endif 297