patch 4.0
This commit is contained in:
@ -17,48 +17,53 @@
|
||||
#include "lib/container/ob_concurrent_bitset.h"
|
||||
#include "sql/session/ob_sql_session_info.h"
|
||||
#include "sql/ob_end_trans_callback.h"
|
||||
namespace oceanbase {
|
||||
namespace storage {
|
||||
class ObPartitionService;
|
||||
namespace oceanbase
|
||||
{
|
||||
namespace observer
|
||||
{
|
||||
struct ObSMConnection;
|
||||
}
|
||||
namespace observer {
|
||||
class ObSMConnection;
|
||||
}
|
||||
namespace sql {
|
||||
namespace sql
|
||||
{
|
||||
|
||||
class ObFreeSessionCtx {
|
||||
class ObFreeSessionCtx
|
||||
{
|
||||
public:
|
||||
ObFreeSessionCtx()
|
||||
: has_inc_active_num_(false), tenant_id_(common::OB_INVALID_ID), version_(0), sessid_(0), proxy_sessid_(0)
|
||||
{}
|
||||
~ObFreeSessionCtx()
|
||||
{}
|
||||
VIRTUAL_TO_STRING_KV(K_(has_inc_active_num), K_(tenant_id), K_(version), K_(sessid), K_(proxy_sessid));
|
||||
ObFreeSessionCtx() :
|
||||
has_inc_active_num_(false),
|
||||
tenant_id_(common::OB_INVALID_ID),
|
||||
sessid_(0),
|
||||
proxy_sessid_(0)
|
||||
{
|
||||
}
|
||||
~ObFreeSessionCtx() {}
|
||||
VIRTUAL_TO_STRING_KV(K_(has_inc_active_num), K_(tenant_id), K_(sessid), K_(proxy_sessid));
|
||||
bool has_inc_active_num_;
|
||||
uint64_t tenant_id_;
|
||||
uint32_t version_;
|
||||
uint32_t sessid_;
|
||||
uint64_t proxy_sessid_;
|
||||
};
|
||||
|
||||
class ObSQLSessionMgr : public common::ObTimerTask {
|
||||
class ObSQLSessionMgr : public common::ObTimerTask
|
||||
{
|
||||
public:
|
||||
static const int64_t SCHEDULE_PERIOD = 1000 * 1000 * 5; // 5s
|
||||
static const int64_t SCHEDULE_PERIOD = 1000*1000*5; //5s
|
||||
static const uint32_t NON_DURABLE_VALUE = 0;
|
||||
static const uint32_t MAX_VERSION = UINT8_MAX; // 255
|
||||
static const uint32_t MAX_VERSION = UINT8_MAX;//255
|
||||
static const uint32_t SERVER_SESSID_TAG = 1ULL << 31;
|
||||
static const uint32_t LOCAL_SESSID_TAG = 0; // used for sessions overflow
|
||||
static const uint32_t LOCAL_SESSID_TAG = 0; // used for sessions overflow
|
||||
static const int64_t BUCKET_COUNT = 1024;
|
||||
typedef SessionInfoKey Key;
|
||||
explicit ObSQLSessionMgr(storage::ObPartitionService* partition_service)
|
||||
: // null_callback_(),
|
||||
sessinfo_map_(),
|
||||
sessid_sequence_(),
|
||||
partition_service_(partition_service),
|
||||
first_seq_(NON_DURABLE_VALUE),
|
||||
increment_sessid_(NON_DURABLE_VALUE)
|
||||
{}
|
||||
virtual ~ObSQLSessionMgr()
|
||||
{}
|
||||
typedef common::hash::ObHashMap<uint64_t, ObSQLSessionInfo*> SessionMap;
|
||||
explicit ObSQLSessionMgr():
|
||||
//null_callback_(),
|
||||
sessinfo_map_(),
|
||||
sessid_sequence_(),
|
||||
first_seq_(NON_DURABLE_VALUE),
|
||||
increment_sessid_(NON_DURABLE_VALUE)
|
||||
{
|
||||
}
|
||||
virtual ~ObSQLSessionMgr(){}
|
||||
|
||||
int init();
|
||||
|
||||
@ -67,22 +72,22 @@ public:
|
||||
* @param conn : connection information
|
||||
* @param sess_info : point to the ObSQLSessionInfo that the function created; used as value
|
||||
*/
|
||||
int create_session(observer::ObSMConnection* conn, ObSQLSessionInfo*& sess_info);
|
||||
int create_session(observer::ObSMConnection *conn, ObSQLSessionInfo *&sess_info);
|
||||
// create session by session id and proxy session id.
|
||||
// need call revert_session if return success.
|
||||
int create_session(const uint64_t tenant_id, const uint32_t sessid, const uint64_t proxy_sessid,
|
||||
const int64_t create_time, ObSQLSessionInfo*& session_info);
|
||||
const int64_t create_time, ObSQLSessionInfo *&session_info);
|
||||
|
||||
/**
|
||||
* @brief get the ObSQLSessioninfo
|
||||
* @param sessid : session id; used as key
|
||||
* @param sess_info : point to the ObSQLSessionInfo that the function get; used as value
|
||||
*/
|
||||
int get_session(uint32_t version, uint32_t sessid, ObSQLSessionInfo*& sess_info);
|
||||
int inc_session_ref(const ObSQLSessionInfo* my_session);
|
||||
int free_session(const ObFreeSessionCtx& ctx);
|
||||
int get_session(uint32_t sessid, ObSQLSessionInfo *&sess_info);
|
||||
int inc_session_ref(const ObSQLSessionInfo *my_session);
|
||||
int free_session(const ObFreeSessionCtx &ctx);
|
||||
|
||||
int get_session_count(int64_t& sess_cnt);
|
||||
int get_session_count(int64_t &sess_cnt);
|
||||
|
||||
/**
|
||||
* @brief if you create or get session successfully, you must call
|
||||
@ -90,20 +95,26 @@ public:
|
||||
*
|
||||
* @param sess_info : the session that you want to revert
|
||||
*/
|
||||
int revert_session(ObSQLSessionInfo* sess_info);
|
||||
void revert_session(ObSQLSessionInfo *sess_info);
|
||||
|
||||
/**
|
||||
* @brief use the function to traverse all session
|
||||
* @param fn : it can be a pointer of the function or function object
|
||||
*/
|
||||
template <typename Function>
|
||||
int for_each_session(Function& fn);
|
||||
int for_each_session(Function &fn);
|
||||
|
||||
int kill_query(ObSQLSessionInfo& session);
|
||||
static int kill_query(ObSQLSessionInfo& session, storage::ObPartitionService* partition_service);
|
||||
int kill_active_trx(ObSQLSessionInfo* session);
|
||||
int kill_session(ObSQLSessionInfo& session);
|
||||
int disconnect_session(ObSQLSessionInfo& session);
|
||||
template <typename Function>
|
||||
int for_each_hold_session(Function &fn);
|
||||
|
||||
int kill_query(ObSQLSessionInfo &session);
|
||||
int set_query_deadlocked(ObSQLSessionInfo &session);
|
||||
static int kill_query(ObSQLSessionInfo &session,
|
||||
const ObSQLSessionState status);
|
||||
int kill_idle_timeout_tx(ObSQLSessionInfo *session);
|
||||
int kill_deadlock_tx(ObSQLSessionInfo *session);
|
||||
int kill_session(ObSQLSessionInfo &session);
|
||||
int disconnect_session(ObSQLSessionInfo &session);
|
||||
|
||||
// kill all sessions from this tenant.
|
||||
int kill_tenant(const uint64_t tenant_id);
|
||||
@ -114,81 +125,81 @@ public:
|
||||
virtual void runTimerTask();
|
||||
void try_check_session();
|
||||
|
||||
// used for guarantee the unique sessid when observer generates sessid
|
||||
//used for guarantee the unique sessid when observer generates sessid
|
||||
static uint64_t extract_server_id(uint32_t sessid);
|
||||
static bool is_server_sessid(uint32_t sessid)
|
||||
{
|
||||
return SERVER_SESSID_TAG & sessid;
|
||||
}
|
||||
static int is_need_clear_sessid(const observer::ObSMConnection* conn, bool& is_need);
|
||||
static bool is_server_sessid(uint32_t sessid) {return SERVER_SESSID_TAG & sessid;}
|
||||
static int is_need_clear_sessid(const observer::ObSMConnection *conn, bool &is_need);
|
||||
int fetch_first_sessid();
|
||||
// in_mgr = false means fail back to local session allocating, avoid remote/distribute executing fail
|
||||
int create_sessid(uint32_t& sessid, bool in_mgr = true);
|
||||
int create_sessid(uint32_t &sessid, bool in_mgr = true);
|
||||
int mark_sessid_used(uint32_t sess_id);
|
||||
int mark_sessid_unused(uint32_t sess_id);
|
||||
// inline ObNullEndTransCallback &get_null_callback() { return null_callback_; }
|
||||
int create_session_by_version(
|
||||
uint64_t tenant_id, uint32_t sessid, uint64_t proxy_sessid, ObSQLSessionInfo*& sess_info, uint32_t& out_version);
|
||||
int get_avaiable_local_seq(uint32_t& local_seq);
|
||||
//inline ObNullEndTransCallback &get_null_callback() { return null_callback_; }
|
||||
SessionMap &get_sess_hold_map() { return sess_hold_map_; }
|
||||
private:
|
||||
int check_session_leak();
|
||||
int get_avaiable_local_seq(uint32_t &local_seq);
|
||||
int set_first_seq(int64_t first_seq);
|
||||
|
||||
class SessionPool {
|
||||
class SessionPool
|
||||
{
|
||||
public:
|
||||
SessionPool();
|
||||
|
||||
public:
|
||||
int init();
|
||||
int pop_session(uint64_t tenant_id, ObSQLSessionInfo*& session);
|
||||
int push_session(uint64_t tenant_id, ObSQLSessionInfo*& session);
|
||||
int pop_session(uint64_t tenant_id, ObSQLSessionInfo *&session);
|
||||
int push_session(uint64_t tenant_id, ObSQLSessionInfo *&session);
|
||||
int64_t count() const;
|
||||
TO_STRING_KV(K(session_pool_.capacity()), K(session_pool_.get_total()), K(session_pool_.get_free()));
|
||||
|
||||
TO_STRING_KV(K(session_pool_.capacity()),
|
||||
K(session_pool_.get_total()),
|
||||
K(session_pool_.get_free()));
|
||||
private:
|
||||
static const int64_t POOL_CAPACIPY = 512;
|
||||
static const uint64_t POOL_INITED = 0;
|
||||
common::ObFixedQueue<ObSQLSessionInfo> session_pool_;
|
||||
ObSQLSessionInfo* session_array[POOL_CAPACIPY];
|
||||
ObSQLSessionInfo *session_array[POOL_CAPACIPY];
|
||||
};
|
||||
|
||||
class SessionPoolMap {
|
||||
class SessionPoolMap
|
||||
{
|
||||
public:
|
||||
SessionPoolMap(ObIAllocator& alloc) : pool_blocks_(ObWrapperAllocator(alloc)), alloc_(alloc), lock_()
|
||||
SessionPoolMap(ObIAllocator &alloc)
|
||||
: pool_blocks_(ObWrapperAllocator(alloc)),
|
||||
alloc_(alloc),
|
||||
lock_()
|
||||
{}
|
||||
int get_session_pool(uint64_t tenant_id, SessionPool*& session_pool);
|
||||
|
||||
int get_session_pool(uint64_t tenant_id, SessionPool *&session_pool);
|
||||
private:
|
||||
static const uint64_t BLOCK_ID_SHIFT = 10;
|
||||
static const uint64_t SLOT_ID_MASK = 0x3FF;
|
||||
static const uint64_t SLOT_PER_BLOCK = 1ULL << BLOCK_ID_SHIFT;
|
||||
typedef SessionPool* SessionPoolBlock[SLOT_PER_BLOCK];
|
||||
typedef Ob2DArray<SessionPoolBlock*, 1024, ObWrapperAllocator> SessionPoolBlocks;
|
||||
|
||||
typedef SessionPool *SessionPoolBlock[SLOT_PER_BLOCK];
|
||||
typedef Ob2DArray<SessionPoolBlock *, 1024, ObWrapperAllocator> SessionPoolBlocks;
|
||||
private:
|
||||
int create_pool_block(uint64_t block_id, SessionPoolBlock*& pool_block);
|
||||
int create_session_pool(SessionPoolBlock& pool_block, uint64_t slot_id, SessionPool*& session_pool);
|
||||
int create_pool_block(uint64_t block_id, SessionPoolBlock *&pool_block);
|
||||
int create_session_pool(SessionPoolBlock &pool_block, uint64_t slot_id, SessionPool *&session_pool);
|
||||
uint64_t get_block_id(uint64_t tenant_id) const;
|
||||
uint64_t get_slot_id(uint64_t tenant_id) const;
|
||||
|
||||
private:
|
||||
SessionPoolBlocks pool_blocks_;
|
||||
ObIAllocator& alloc_;
|
||||
ObIAllocator &alloc_;
|
||||
ObSpinLock lock_;
|
||||
};
|
||||
|
||||
class ValueAlloc {
|
||||
class ValueAlloc
|
||||
{
|
||||
public:
|
||||
ValueAlloc()
|
||||
: session_pool_map_(allocator_),
|
||||
alloc_total_count_(0),
|
||||
alloc_from_pool_count_(0),
|
||||
free_total_count_(0),
|
||||
free_to_pool_count_(0)
|
||||
{}
|
||||
~ValueAlloc()
|
||||
: session_pool_map_(allocator_),
|
||||
alloc_total_count_(0),
|
||||
alloc_from_pool_count_(0),
|
||||
free_total_count_(0),
|
||||
free_to_pool_count_(0)
|
||||
{}
|
||||
~ValueAlloc() {}
|
||||
int clean_tenant(uint64_t tenant_id);
|
||||
ObSQLSessionInfo* alloc_value(uint64_t tenant_id);
|
||||
void free_value(ObSQLSessionInfo* sess);
|
||||
void free_value(ObSQLSessionInfo *sess);
|
||||
SessionInfoHashNode* alloc_node(ObSQLSessionInfo* value)
|
||||
{
|
||||
UNUSED(value);
|
||||
@ -201,10 +212,8 @@ public:
|
||||
node = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool is_valid_tenant_id(uint64_t tenant_id) const;
|
||||
|
||||
private:
|
||||
SessionPoolMap session_pool_map_;
|
||||
ObArenaAllocator allocator_;
|
||||
@ -217,37 +226,47 @@ public:
|
||||
static const int64_t MAX_SYS_VAR_MEM = 256 * 1024;
|
||||
};
|
||||
|
||||
#ifdef OB_USE_ASAN
|
||||
typedef common::ObTenantLinkHashMap<Key, ObSQLSessionInfo, ValueAlloc, ZeroRefHandle> HashMap;
|
||||
#else
|
||||
typedef common::ObTenantLinkHashMap<Key, ObSQLSessionInfo, ValueAlloc> HashMap;
|
||||
#endif
|
||||
|
||||
class CheckSessionFunctor {
|
||||
public:
|
||||
CheckSessionFunctor() : sess_mgr_(NULL)
|
||||
{}
|
||||
explicit CheckSessionFunctor(ObSQLSessionMgr* sess_mgr) : sess_mgr_(sess_mgr)
|
||||
{}
|
||||
virtual ~CheckSessionFunctor()
|
||||
{}
|
||||
bool operator()(sql::ObSQLSessionMgr::Key key, ObSQLSessionInfo* sess_info);
|
||||
|
||||
private:
|
||||
ObSQLSessionMgr* sess_mgr_;
|
||||
struct DumpHoldSession
|
||||
{
|
||||
DumpHoldSession() {}
|
||||
int operator()(common::hash::HashMapPair<uint64_t, ObSQLSessionInfo *> &entry);
|
||||
};
|
||||
|
||||
class KillTenant {
|
||||
class CheckSessionFunctor
|
||||
{
|
||||
public:
|
||||
KillTenant(ObSQLSessionMgr* mgr, const uint64_t tenant_id) : mgr_(mgr), tenant_id_(tenant_id)
|
||||
{}
|
||||
bool operator()(sql::ObSQLSessionMgr::Key key, ObSQLSessionInfo* sess_info);
|
||||
|
||||
CheckSessionFunctor() : sess_mgr_(NULL) {}
|
||||
explicit CheckSessionFunctor(ObSQLSessionMgr *sess_mgr): sess_mgr_(sess_mgr) {}
|
||||
virtual ~CheckSessionFunctor(){}
|
||||
bool operator()(sql::ObSQLSessionMgr::Key key, ObSQLSessionInfo *sess_info);
|
||||
private:
|
||||
ObSQLSessionMgr* mgr_;
|
||||
ObSQLSessionMgr *sess_mgr_;
|
||||
};
|
||||
|
||||
class KillTenant
|
||||
{
|
||||
public:
|
||||
KillTenant(ObSQLSessionMgr *mgr, const uint64_t tenant_id)
|
||||
: mgr_(mgr), tenant_id_(tenant_id)
|
||||
{}
|
||||
bool operator() (sql::ObSQLSessionMgr::Key key, ObSQLSessionInfo* sess_info);
|
||||
private:
|
||||
ObSQLSessionMgr *mgr_;
|
||||
const uint64_t tenant_id_;
|
||||
};
|
||||
|
||||
private:
|
||||
// ObNullEndTransCallback null_callback_;
|
||||
//注:必须在session_map_之前定义,依赖于析构的顺序。
|
||||
//ObNullEndTransCallback null_callback_;
|
||||
// used for manage ObSQLSessionInfo
|
||||
HashMap sessinfo_map_;
|
||||
// design doc: https://yuque.antfin-inc.com/docs/share/820fa006-f85a-4530-8e2b-fe3c90271404
|
||||
// |<---------------------------------32bit---------------------------->|
|
||||
// 31b 30b 29b 18b 16b 0b
|
||||
// +----+------------------------------+--------------------------------+
|
||||
@ -259,36 +278,71 @@ private:
|
||||
static const uint32_t MAX_LOCAL_SEQ = (1ULL << LOCAL_SEQ_LEN) - 1;
|
||||
static const uint64_t MAX_SERVER_ID = (1ULL << SERVER_ID_LEN) - 1;
|
||||
common::ObFixedQueue<void> sessid_sequence_;
|
||||
storage::ObPartitionService* partition_service_;
|
||||
uint32_t first_seq_;
|
||||
uint32_t increment_sessid_;
|
||||
SessionMap sess_hold_map_;
|
||||
DISALLOW_COPY_AND_ASSIGN(ObSQLSessionMgr);
|
||||
}; // end of class ObSQLSessionMgr
|
||||
}; // end of class ObSQLSessionMgr
|
||||
|
||||
template <typename Function>
|
||||
int ObSQLSessionMgr::for_each_session(Function& fn)
|
||||
int ObSQLSessionMgr::for_each_session(Function &fn)
|
||||
{
|
||||
return sessinfo_map_.for_each(fn);
|
||||
}
|
||||
|
||||
inline int ObSQLSessionMgr::get_session(uint32_t version, uint32_t sessid, ObSQLSessionInfo*& sess_info)
|
||||
template <typename Function>
|
||||
int ObSQLSessionMgr::for_each_hold_session(Function &fn)
|
||||
{
|
||||
return sessinfo_map_.get(Key(version, sessid), sess_info);
|
||||
return get_sess_hold_map().foreach_refactored(fn);
|
||||
}
|
||||
|
||||
inline int ObSQLSessionMgr::revert_session(ObSQLSessionInfo* sess_info)
|
||||
inline int ObSQLSessionMgr::get_session(uint32_t sessid, ObSQLSessionInfo *&sess_info)
|
||||
{
|
||||
int ret = sessinfo_map_.get(Key(sessid), sess_info);
|
||||
const bool v = GCONF._enable_trace_session_leak;
|
||||
if (OB_UNLIKELY(v)) {
|
||||
if (OB_LIKELY(sess_info)) {
|
||||
sess_info->on_get_session();
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline void ObSQLSessionMgr::revert_session(ObSQLSessionInfo *sess_info)
|
||||
{
|
||||
const bool v = GCONF._enable_trace_session_leak;
|
||||
if (OB_UNLIKELY(v)) {
|
||||
if (OB_LIKELY(nullptr != sess_info)) {
|
||||
sess_info->on_revert_session();
|
||||
}
|
||||
}
|
||||
sessinfo_map_.revert(sess_info);
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int ObSQLSessionMgr::get_session_count(int64_t& sess_cnt)
|
||||
inline int ObSQLSessionMgr::get_session_count(int64_t &sess_cnt)
|
||||
{
|
||||
sess_cnt = sessinfo_map_.count();
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // end of namespace sql
|
||||
} // end of namespace oceanbase
|
||||
|
||||
class ObSessionGetterGuard
|
||||
{
|
||||
public:
|
||||
explicit ObSessionGetterGuard(ObSQLSessionMgr &sess_mgr, uint32_t sessid);
|
||||
~ObSessionGetterGuard();
|
||||
inline int get_session(ObSQLSessionInfo *&session)
|
||||
{
|
||||
session = session_;
|
||||
return ret_;
|
||||
}
|
||||
private:
|
||||
int ret_;
|
||||
ObSQLSessionMgr &mgr_;
|
||||
ObSQLSessionInfo *session_;
|
||||
};
|
||||
|
||||
} // end of namespace sql
|
||||
} // end of namespace oceanbase
|
||||
|
||||
#endif /* _OCEABASE_SQL_SESSION_OB_SQL_SESSION_MGR_H_ */
|
||||
|
||||
Reference in New Issue
Block a user