You've already forked mariadb-columnstore-engine
							
							
				mirror of
				https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
				synced 2025-10-30 07:25:34 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			339 lines
		
	
	
		
			9.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			339 lines
		
	
	
		
			9.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* Copyright (C) 2014 InfiniDB, Inc.
 | |
| 
 | |
|    This program is free software; you can redistribute it and/or
 | |
|    modify it under the terms of the GNU General Public License
 | |
|    as published by the Free Software Foundation; version 2 of
 | |
|    the License.
 | |
| 
 | |
|    This program is distributed in the hope that it will be useful,
 | |
|    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
|    GNU General Public License for more details.
 | |
| 
 | |
|    You should have received a copy of the GNU General Public License
 | |
|    along with this program; if not, write to the Free Software
 | |
|    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 | |
|    MA 02110-1301, USA. */
 | |
| 
 | |
| /******************************************************************************
 | |
|  * $Id: sessionmonitor.h 9210 2013-01-21 14:10:42Z rdempsey $
 | |
|  *
 | |
|  *****************************************************************************/
 | |
| 
 | |
| /** @file
 | |
|  * class SessionMonitor interface
 | |
|  */
 | |
| 
 | |
| #pragma once
 | |
| 
 | |
| #include <vector>
 | |
| #include <exception>
 | |
| #include <sys/types.h>
 | |
| #include <unistd.h>
 | |
| 
 | |
| #include "calpontsystemcatalog.h"
 | |
| #include "sessionmanager.h"
 | |
| #include "shmkeys.h"
 | |
| #include "brmtypes.h"
 | |
| 
 | |
| // #define SM_DEBUG
 | |
| 
 | |
| namespace execplan
 | |
| {
 | |
| /** @brief Identifies stale and orphaned transaction IDs.
 | |
|  *
 | |
|  *
 | |
|  * This class uses 2 parameters from the Columnstore.xml file:
 | |
|  * SessionManager/MaxConcurrentTransactions: defines how many active transactions the
 | |
|  *		system should support.	When a new request comes in and there are already
 | |
|  *		MaxConcurrentTransactions active, the new request blocks by default.  The
 | |
|  *		default value is 1000.
 | |
|  *
 | |
|  * SessionMonitor/SharedMemoryTmpFile: the file to store the shared memory segment
 | |
|  *		data in.  This needs to be a different file than
 | |
|  *		file used for the SessionManager/SharedMemoryTmpFile.
 | |
|  */
 | |
| 
 | |
| /*
 | |
|  * NOTE: It seems that valgrind doesn't work well with shared memory segments.
 | |
|  * Specifically, when the code executes shmctl(IPC_RMID), which normally means
 | |
|  * "destroy the segment when refcount == 0", the segment is destroyed
 | |
|  * immediately, causing all subsequent references to fail.	This only affects
 | |
|  * 'leakcheck'.
 | |
|  * This comment is originally from SessionManager.h. I am assuming we will see
 | |
|  * the same behavior here.
 | |
|  */
 | |
| 
 | |
| class SessionMonitor
 | |
| {
 | |
|  public:
 | |
|   /** @brief A type describing a single transaction ID */
 | |
|   struct MonTxnID
 | |
|   {
 | |
|     /// The TransactionID number
 | |
|     CalpontSystemCatalog::SCN id;
 | |
|     /// True if the id is valid.
 | |
|     bool valid;
 | |
|     /// timestamp of firstrecord of this TID
 | |
|     time_t firstrecord;
 | |
|     MonTxnID()
 | |
|     {
 | |
|       id = 0;
 | |
|       valid = false;
 | |
|       firstrecord = 0;
 | |
|     };
 | |
|   };
 | |
| 
 | |
|   /** @brief A type describing a single transaction ID */
 | |
|   typedef struct MonTxnID MonTxnID;
 | |
| 
 | |
|   /** @brief A type associating a session with a transaction */
 | |
|   struct MonSIDTIDEntry
 | |
|   {
 | |
|     /// The Transaction ID.  txnid.valid determines whether or not this SIDTIDEntry is valid
 | |
|     MonTxnID txnid;
 | |
|     /// The session doing the transaction
 | |
|     SessionManager::SID sessionid;
 | |
|     MonSIDTIDEntry()
 | |
|     {
 | |
|       txnid = MonTxnID();
 | |
|       sessionid = 0;
 | |
|     };
 | |
|   };
 | |
| 
 | |
|   /** @brief A type associating a session with a transaction */
 | |
|   typedef struct MonSIDTIDEntry MonSIDTIDEntry_t;
 | |
| 
 | |
|   /** @brief Vector of MonSIDTIDEntry structures */
 | |
|   typedef std::vector<MonSIDTIDEntry_t*> MonSIDTIDEntryVector_t;
 | |
| 
 | |
|   /** @brief needed to sort txns list in find timedOutTnxs()*/
 | |
|   struct lessMonSIDTIDEntry
 | |
|   {
 | |
|     bool operator()(MonSIDTIDEntry const* p1, MonSIDTIDEntry const* p2)
 | |
|     {
 | |
|       if (!p1)
 | |
|         return true;
 | |
| 
 | |
|       if (!p2)
 | |
|         return false;
 | |
| 
 | |
|       return p1->txnid.firstrecord < p2->txnid.firstrecord;
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   /** @brief monitor version of the SessionManagerData */
 | |
|   struct SessionMonitorData_struct
 | |
|   {
 | |
|     int txnCount;
 | |
|     CalpontSystemCatalog::SCN verID;
 | |
|     MonSIDTIDEntry_t* activeTxns;
 | |
|     SessionMonitorData_struct()
 | |
|     {
 | |
|       txnCount = 0;
 | |
|       verID = 0;
 | |
|       activeTxns = nullptr;
 | |
|     };
 | |
|   };
 | |
|   typedef struct SessionMonitorData_struct SessionMonitorData_t;
 | |
| 
 | |
|   /** @brief typedef if SessionManager struct SIDTIDEntry. For convenience.*/
 | |
|   typedef BRM::SIDTIDEntry SIDTIDEntry_t;
 | |
|   /** @brief This struct describes the layout of the shared memory segment copied from SessionManager.h */
 | |
|   struct SessionManagerData_struct
 | |
|   {
 | |
|     int txnCount;
 | |
|     CalpontSystemCatalog::SCN verID;
 | |
|     CalpontSystemCatalog::SCN syscatVerID;
 | |
|     int systemstate;
 | |
|     boost::interprocess::interprocess_semaphore sems[2];
 | |
|     SIDTIDEntry_t activeTxns[];
 | |
|   };
 | |
|   typedef SessionManagerData_struct SessionManagerData_t;
 | |
| 
 | |
|   /** @brief Constructor
 | |
|    *
 | |
|    * This attaches to existing shared memory segments.
 | |
|    * @note throws ios_base::failure on file IO error, runtime_error for
 | |
|    * other types of errors.  It might be worthwhile to define additional
 | |
|    * exceptions for all the different types of failures that can happen
 | |
|    * here.
 | |
|    */
 | |
|   SessionMonitor();
 | |
| 
 | |
|   /** @brief Destructor
 | |
|    *
 | |
|    * This detaches the shared memory segment then saves it
 | |
|    * to disk and destroyed. It does not destroy the semaphores
 | |
|    * or the shared memory segment. Deletes the local copies
 | |
|    * of the SessionManager data and SessionMonitor data.
 | |
|    */
 | |
|   virtual ~SessionMonitor();
 | |
| 
 | |
|   const int maxTxns() const
 | |
|   {
 | |
|     return fMaxTxns;
 | |
|   }
 | |
|   const int txnCount() const;
 | |
| 
 | |
|   /**
 | |
|    * @brief identifies timed out SessionManager structures
 | |
|    * @param
 | |
|    * @return
 | |
|    */
 | |
|   MonSIDTIDEntryVector_t timedOutTxns();
 | |
| 
 | |
|   const SessionMonitorData_t* previousManagerData()
 | |
|   {
 | |
|     return &fPrevSegment;
 | |
|   }
 | |
|   SessionManagerData_t* currentManagerData()
 | |
|   {
 | |
|     return fCurrentSegment;
 | |
|   }
 | |
|   const SessionManagerData_t* sessionManagerData()
 | |
|   {
 | |
|     return fSessionManagerData;
 | |
|   }
 | |
| 
 | |
|   void printTxns(const MonSIDTIDEntry_t& txn) const;
 | |
| #ifdef SM_DEBUG
 | |
|   void printSegment(const SessionManagerData_t* seg, const int l = 1000) const;
 | |
|   void printMonitorData(const int l = 1000) const;
 | |
|   void printTxns(const SIDTIDEntry_t& txn) const;
 | |
| #endif
 | |
|   const int AgeLimit() const
 | |
|   {
 | |
|     return fAgeLimit;  // to speed up testing
 | |
|   }
 | |
|   void AgeLimit(const int& age)
 | |
|   {
 | |
|     fAgeLimit = age;
 | |
|   }
 | |
|   const char* segmentFilename() const
 | |
|   {
 | |
|     return fSegmentFilename.c_str();
 | |
|   }
 | |
|   bool haveSemaphores() const
 | |
|   {
 | |
|     return fHaveSemaphores;
 | |
|   }
 | |
|   bool haveSharedMemory() const
 | |
|   {
 | |
|     return fIsAttached;
 | |
|   }
 | |
| 
 | |
|  private:
 | |
|   int fMaxTxns;                       // the maximum number of concurrent transactions
 | |
|   static const int fMaxRetries = 10;  // the max number of retries on file IO
 | |
|   std::string fSegmentFilename;       // filename used to store the image of the SessionManager data
 | |
|   time_t fDefaultAgeLimit;
 | |
|   time_t fAgeLimit;  // age limit in seconds used to timeout/orpan a transaction
 | |
| 
 | |
|   SessionMonitorData_t fSessionMonitorData;   // pointer to in memory copy of the Monitor data
 | |
|   SessionMonitorData_t fPrevSegment;          // in memory copy of SessionManager data from backup file
 | |
|   SessionManagerData_t* fCurrentSegment;      // in memory of SessionManager data
 | |
|   SessionManagerData_t* fSessionManagerData;  // current shared memory SessionManager data
 | |
| 
 | |
|   // refers to 2 semaphores; the first is a mutex that guards the shmseg
 | |
|   // the second is used to block processes when there are too many concurrent txns
 | |
|   int fsems;
 | |
|   int fshmid;     // shared memory segment id
 | |
|   uint32_t fuid;  // user id used to create the shared memory key
 | |
| 
 | |
|   SessionManager sm;
 | |
| 
 | |
|   bool isStaleSIDTID(const SIDTIDEntry_t& src, const MonSIDTIDEntry_t& dest) const;
 | |
|   bool isEqualSIDTID(const SIDTIDEntry_t& src, const MonSIDTIDEntry_t& dest) const;
 | |
|   bool isUsedSIDTID(const SIDTIDEntry_t& e) const;
 | |
|   bool isUsed(const MonSIDTIDEntry_t& e) const;
 | |
| 
 | |
|   /**
 | |
|    * @brief attached to SessionManagerData shared memory
 | |
|    * @param
 | |
|    * @return void
 | |
|    */
 | |
|   void getSharedData(void);
 | |
| 
 | |
|   bool fIsAttached;
 | |
| 
 | |
|   /**
 | |
|    * @brief unattached from SessionManagerData shared memory
 | |
|    * @param
 | |
|    * @return void
 | |
|    */
 | |
|   void detachSegment(void);
 | |
| 
 | |
|   /**
 | |
|    * @brief initialize SessionMonitorData
 | |
|    * @param
 | |
|    * @return void
 | |
|    */
 | |
|   void initSegment(SessionMonitorData_t* seg);
 | |
| 
 | |
|   /**
 | |
|    * @brief initialize SessionManagerData
 | |
|    * @param
 | |
|    * @return void
 | |
|    */
 | |
|   void initSegment(SessionManagerData_t* seg);
 | |
| 
 | |
|   const key_t IPCKey() const
 | |
|   {
 | |
|     return fShmKeys.SESSIONMANAGER_SYSVKEY;
 | |
|   };
 | |
| 
 | |
|   /**
 | |
|    * @brief copies the SessionMonitor data from a file into memory
 | |
|    * @param
 | |
|    * @return void
 | |
|    */
 | |
|   void copyPreviousSegment();
 | |
| 
 | |
|   /**
 | |
|    * @brief copies the SessionManager data from shared memory into an SessionMonitor memory
 | |
|    * @param
 | |
|    * @return void
 | |
|    */
 | |
|   void copyCurrentSegment();
 | |
| 
 | |
|   /**
 | |
|    * @brief Reads the SM data from file into memory. Used by copyPreviousSegment().
 | |
|    * @param
 | |
|    * @return bool
 | |
|    */
 | |
|   bool readMonitorDataFromFile(const std::string);
 | |
| 
 | |
|   /**
 | |
|    * @brief write the current SessionManagerData as SessionMonitorData to a file.
 | |
|    * @param
 | |
|    * @return void
 | |
|    */
 | |
|   void saveAsMonitorData(const std::string);
 | |
| 
 | |
|   bool fHaveSemaphores;
 | |
| 
 | |
|   /**
 | |
|    * @brief get the SessionManager semaphores
 | |
|    * @param
 | |
|    * @return void
 | |
|    */
 | |
|   int getSems(void);
 | |
| 
 | |
|   void lock(void);
 | |
| 
 | |
|   void unlock(void);
 | |
| 
 | |
|   /**
 | |
|    * @brief do not use the copy constructor.
 | |
|    * @param
 | |
|    * @return
 | |
|    */
 | |
|   SessionMonitor(const SessionMonitor&);
 | |
| 
 | |
|  private:
 | |
|   BRM::ShmKeys fShmKeys;
 | |
| };
 | |
| 
 | |
| }  // namespace execplan
 |