mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-04-18 21:44:02 +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
|