Add free logic for tenant_mutil_allocator_mgr.
This commit is contained in:
committed by
ob-robot
parent
30f03df840
commit
2bf2d711da
@ -28,7 +28,7 @@ int ObTenantMutilAllocatorMgr::init()
|
||||
if (is_inited_) {
|
||||
ret = OB_INIT_TWICE;
|
||||
} else {
|
||||
for (int64_t i = 0; i < PRESERVED_TENANT_COUNT; ++i) {
|
||||
for (int64_t i = 0; i < ARRAY_SIZE; ++i) {
|
||||
tma_array_[i] = NULL;
|
||||
}
|
||||
is_inited_ = true;
|
||||
@ -42,15 +42,31 @@ int ObTenantMutilAllocatorMgr::get_tenant_log_allocator(const uint64_t tenant_id
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTenantMutilAllocator *allocator = NULL;
|
||||
if (OB_FAIL(get_tenant_mutil_allocator(tenant_id, allocator))) {
|
||||
if (OB_FAIL(get_tenant_mutil_allocator_(tenant_id, allocator))) {
|
||||
} else {
|
||||
out_allocator = allocator;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObTenantMutilAllocatorMgr::get_tenant_mutil_allocator(const uint64_t tenant_id,
|
||||
ObTenantMutilAllocator *&out_allocator)
|
||||
int ObTenantMutilAllocatorMgr::delete_tenant_log_allocator(const uint64_t tenant_id)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_FAIL(delete_tenant_mutil_allocator_(tenant_id))) {
|
||||
OB_LOG(WARN, "delete_tenant_mutil_allocator_ failed", K(ret), K(tenant_id));
|
||||
} else {
|
||||
OB_LOG(INFO, "delete_tenant_mutil_allocator_ success", K(tenant_id));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int64_t ObTenantMutilAllocatorMgr::get_slot_(const int64_t tenant_id) const
|
||||
{
|
||||
// The first slot by idx==0 won't be used.
|
||||
return (tenant_id % PRESERVED_TENANT_COUNT) + 1;
|
||||
}
|
||||
int ObTenantMutilAllocatorMgr::get_tenant_mutil_allocator_(const uint64_t tenant_id,
|
||||
TMA *&out_allocator)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
||||
@ -59,16 +75,23 @@ int ObTenantMutilAllocatorMgr::get_tenant_mutil_allocator(const uint64_t tenant_
|
||||
} else if (OB_UNLIKELY(tenant_id <= 0)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
OB_LOG(WARN, "invalid arguments", K(ret), K(tenant_id));
|
||||
} else if (tenant_id < PRESERVED_TENANT_COUNT) {
|
||||
// Don't need lock
|
||||
if (NULL == (out_allocator = ATOMIC_LOAD(&tma_array_[tenant_id]))) {
|
||||
} else if (tenant_id <= PRESERVED_TENANT_COUNT) {
|
||||
// Need rlock
|
||||
do {
|
||||
obsys::ObRLockGuard guard(locks_[tenant_id]);
|
||||
out_allocator = ATOMIC_LOAD(&tma_array_[tenant_id]);
|
||||
} while(0);
|
||||
|
||||
if (NULL == out_allocator) {
|
||||
// Need create new allocator
|
||||
if (OB_FAIL(create_tenant_mutil_allocator_(tenant_id, out_allocator))) {
|
||||
OB_LOG(WARN, "fail to create_tenant_mutil_allocator_", K(ret), K(tenant_id));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Need lock
|
||||
const int64_t slot = tenant_id % PRESERVED_TENANT_COUNT;
|
||||
// slot must be > 0.
|
||||
const int64_t slot = get_slot_(tenant_id);
|
||||
bool is_need_create = false;
|
||||
do {
|
||||
// rdlock
|
||||
@ -131,13 +154,14 @@ int ObTenantMutilAllocatorMgr::create_tenant_mutil_allocator_(const uint64_t ten
|
||||
TMA *&out_allocator)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
||||
if (!is_inited_) {
|
||||
ret = OB_NOT_INIT;
|
||||
} else if (OB_UNLIKELY(tenant_id <= 0)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
OB_LOG(WARN, "invalid arguments", K(ret), K(tenant_id));
|
||||
} else if (tenant_id < PRESERVED_TENANT_COUNT) {
|
||||
} else if (tenant_id <= PRESERVED_TENANT_COUNT) {
|
||||
// wlock
|
||||
obsys::ObWLockGuard guard(locks_[tenant_id]);
|
||||
if (NULL != (out_allocator = ATOMIC_LOAD(&tma_array_[tenant_id]))) {
|
||||
} else {
|
||||
TMA *tmp_tma = NULL;
|
||||
@ -154,26 +178,30 @@ int ObTenantMutilAllocatorMgr::create_tenant_mutil_allocator_(const uint64_t ten
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const int64_t slot = tenant_id % PRESERVED_TENANT_COUNT;
|
||||
if (NULL == ATOMIC_LOAD(&tma_array_[slot])) {
|
||||
// slot's head node is NULL, need construct
|
||||
TMA *tmp_tma = NULL;
|
||||
if (OB_FAIL(construct_allocator_(slot, tmp_tma))) {
|
||||
OB_LOG(WARN, "fail to construct_allocator_", K(ret), K(slot));
|
||||
} else if (!ATOMIC_BCAS(&tma_array_[slot], NULL, tmp_tma)) {
|
||||
if (NULL != tmp_tma) {
|
||||
tmp_tma->~TMA();
|
||||
ob_free(tmp_tma);
|
||||
}
|
||||
} else {}
|
||||
}
|
||||
// slot must be > 0.
|
||||
const int64_t slot = get_slot_(tenant_id);
|
||||
do {
|
||||
// Need lock when modify slog list
|
||||
obsys::ObWLockGuard guard(locks_[slot]);
|
||||
if (NULL == ATOMIC_LOAD(&tma_array_[slot])) {
|
||||
// slot's head node is NULL, need construct
|
||||
TMA *tmp_tma = NULL;
|
||||
if (OB_FAIL(construct_allocator_(slot, tmp_tma))) {
|
||||
OB_LOG(WARN, "fail to construct_allocator_", K(ret), K(slot));
|
||||
} else if (!ATOMIC_BCAS(&tma_array_[slot], NULL, tmp_tma)) {
|
||||
if (NULL != tmp_tma) {
|
||||
tmp_tma->~TMA();
|
||||
ob_free(tmp_tma);
|
||||
}
|
||||
} else {}
|
||||
}
|
||||
// create tenant's allocator
|
||||
if (OB_SUCC(ret)) {
|
||||
bool is_need_create = false;
|
||||
TMA **prev = NULL;
|
||||
TMA **cur = &tma_array_[slot];
|
||||
while ((NULL != cur) && (NULL != *cur) && (*cur)->get_tenant_id() < tenant_id) {
|
||||
prev = cur;
|
||||
cur = &((*cur)->get_next());
|
||||
}
|
||||
if (NULL != cur) {
|
||||
@ -188,9 +216,17 @@ int ObTenantMutilAllocatorMgr::create_tenant_mutil_allocator_(const uint64_t ten
|
||||
if (OB_FAIL(construct_allocator_(tenant_id, tmp_tma))) {
|
||||
OB_LOG(WARN, "fail to construct_allocator_", K(ret), K(tenant_id));
|
||||
} else {
|
||||
OB_ASSERT(NULL != prev);
|
||||
OB_ASSERT(NULL != (*prev));
|
||||
OB_ASSERT(prev != cur);
|
||||
// record cur's value(new next tma ptr)
|
||||
TMA *next_allocator = *cur;
|
||||
*cur = tmp_tma;
|
||||
((*cur)->get_next()) = next_allocator;
|
||||
// set cur to NULL
|
||||
cur = NULL;
|
||||
// Let prev->next_ points to new tma.
|
||||
((*prev)->get_next()) = tmp_tma;
|
||||
// Let tmp_tma->next_ points to old cur.
|
||||
(tmp_tma->get_next()) = next_allocator;
|
||||
out_allocator = tmp_tma;
|
||||
}
|
||||
}
|
||||
@ -201,12 +237,60 @@ int ObTenantMutilAllocatorMgr::create_tenant_mutil_allocator_(const uint64_t ten
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObTenantMutilAllocatorMgr::delete_tenant_mutil_allocator_(const uint64_t tenant_id)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (!is_inited_) {
|
||||
ret = OB_NOT_INIT;
|
||||
} else if (OB_UNLIKELY(tenant_id <= 0)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
OB_LOG(WARN, "invalid arguments", K(ret), K(tenant_id));
|
||||
} else if (tenant_id <= PRESERVED_TENANT_COUNT) {
|
||||
// Need wlock
|
||||
obsys::ObWLockGuard guard(locks_[tenant_id]);
|
||||
TMA *tma_allocator = NULL;
|
||||
if (NULL != (tma_allocator = ATOMIC_LOAD(&tma_array_[tenant_id]))) {
|
||||
if (NULL != tma_allocator->get_next()) {
|
||||
OB_LOG(INFO, "next_ ptr is not NULL, skip deleting this allocator", K(ret), K(tenant_id));
|
||||
} else {
|
||||
tma_array_[tenant_id] = NULL;
|
||||
tma_allocator->~TMA();
|
||||
ob_free(tma_allocator);
|
||||
tma_allocator = NULL;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// slot must be > 0.
|
||||
const int64_t slot = get_slot_(tenant_id);
|
||||
do {
|
||||
// wlock
|
||||
obsys::ObWLockGuard guard(locks_[slot]);
|
||||
TMA *prev = NULL;
|
||||
TMA *cur = tma_array_[slot];
|
||||
while ((NULL != cur) && cur->get_tenant_id() < tenant_id) {
|
||||
prev = cur;
|
||||
cur = cur->get_next();
|
||||
}
|
||||
if (NULL != cur && cur->get_tenant_id() == tenant_id) {
|
||||
OB_ASSERT(NULL != prev);
|
||||
OB_ASSERT(prev != cur);
|
||||
prev->get_next() = cur->get_next();
|
||||
cur->get_next() = NULL;
|
||||
ob_free(cur);
|
||||
cur = NULL;
|
||||
}
|
||||
} while (0);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ObTenantMutilAllocatorMgr &ObTenantMutilAllocatorMgr::get_instance()
|
||||
{
|
||||
static ObTenantMutilAllocatorMgr instance_;
|
||||
return instance_;
|
||||
}
|
||||
|
||||
/*
|
||||
int ObTenantMutilAllocatorMgr::get_tenant_limit(const uint64_t tenant_id,
|
||||
int64_t &limit)
|
||||
{
|
||||
@ -217,7 +301,7 @@ int ObTenantMutilAllocatorMgr::get_tenant_limit(const uint64_t tenant_id,
|
||||
ret = OB_NOT_INIT;
|
||||
} else if (OB_UNLIKELY(tenant_id <= 0)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
} else if (OB_FAIL(get_tenant_mutil_allocator(tenant_id, allocator))) {
|
||||
} else if (OB_FAIL(get_tenant_mutil_allocator_(tenant_id, allocator))) {
|
||||
ret = OB_TENANT_NOT_EXIST;
|
||||
} else {
|
||||
limit = allocator->get_limit();
|
||||
@ -236,7 +320,7 @@ int ObTenantMutilAllocatorMgr::set_tenant_limit(const uint64_t tenant_id,
|
||||
ret = OB_NOT_INIT;
|
||||
} else if (OB_UNLIKELY(tenant_id <= 0) || OB_UNLIKELY(new_limit <= 0)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
} else if (OB_FAIL(get_tenant_mutil_allocator(tenant_id, allocator))) {
|
||||
} else if (OB_FAIL(get_tenant_mutil_allocator_(tenant_id, allocator))) {
|
||||
} else if (OB_ISNULL(allocator)) {
|
||||
ret = OB_TENANT_NOT_EXIST;
|
||||
} else {
|
||||
@ -245,6 +329,7 @@ int ObTenantMutilAllocatorMgr::set_tenant_limit(const uint64_t tenant_id,
|
||||
|
||||
return ret;
|
||||
}
|
||||
*/
|
||||
int ObTenantMutilAllocatorMgr::update_tenant_mem_limit(const share::TenantUnits &all_tenant_units)
|
||||
{
|
||||
// Update mem_limit for each tenant, called when the chane unit specifications or
|
||||
@ -276,10 +361,10 @@ int ObTenantMutilAllocatorMgr::update_tenant_mem_limit(const share::TenantUnits
|
||||
}
|
||||
int tmp_ret = OB_SUCCESS;
|
||||
ObTenantMutilAllocator *tma= NULL;
|
||||
if (OB_SUCCESS != (tmp_ret = get_tenant_mutil_allocator(tenant_id, tma))) {
|
||||
OB_LOG(WARN, "get_tenant_mutil_allocator failed", K(tmp_ret), K(tenant_id));
|
||||
if (OB_SUCCESS != (tmp_ret = get_tenant_mutil_allocator_(tenant_id, tma))) {
|
||||
OB_LOG(WARN, "get_tenant_mutil_allocator_ failed", K(tmp_ret), K(tenant_id));
|
||||
} else if (NULL == tma) {
|
||||
OB_LOG(WARN, "get_tenant_mutil_allocator failed", K(tenant_id));
|
||||
OB_LOG(WARN, "get_tenant_mutil_allocator_ failed", K(tenant_id));
|
||||
} else {
|
||||
tma->set_nway(nway);
|
||||
int64_t pre_tma_limit = tma->get_limit();
|
||||
@ -294,7 +379,7 @@ int ObTenantMutilAllocatorMgr::update_tenant_mem_limit(const share::TenantUnits
|
||||
ObGMemstoreAllocator* memstore_allocator = NULL;
|
||||
if (OB_SUCCESS != (tmp_ret = ObMemstoreAllocatorMgr::get_instance().get_tenant_memstore_allocator(tenant_id, memstore_allocator))) {
|
||||
} else if (OB_ISNULL(memstore_allocator)) {
|
||||
OB_LOG(WARN, "get_tenant_mutil_allocator failed", K(tenant_id));
|
||||
OB_LOG(WARN, "get_tenant_memstore_allocator failed", K(tenant_id));
|
||||
} else if (OB_FAIL(memstore_allocator->set_memstore_threshold(tenant_id))) {
|
||||
OB_LOG(WARN, "failed to set_memstore_threshold of memstore allocator", K(tenant_id), K(ret));
|
||||
} else {
|
||||
|
||||
@ -37,37 +37,36 @@ public:
|
||||
~ObTenantMutilAllocatorMgr()
|
||||
{}
|
||||
int init();
|
||||
int get_tenant_mutil_allocator(const uint64_t tenant_id,
|
||||
ObTenantMutilAllocator *&out_allocator);
|
||||
|
||||
// This interface is used by logservice module only.
|
||||
int get_tenant_log_allocator(const uint64_t tenant_id,
|
||||
ObILogAllocator *&out_allocator);
|
||||
int get_tenant_limit(const uint64_t tenant_id, int64_t &limit);
|
||||
int set_tenant_limit(const uint64_t tenant_id, const int64_t new_limit);
|
||||
void *alloc_log_entry_buf(const int64_t size)
|
||||
{
|
||||
return clog_entry_alloc_.alloc(size);
|
||||
}
|
||||
void free_log_entry_buf(void *ptr)
|
||||
{
|
||||
if (NULL != ptr) {
|
||||
clog_entry_alloc_.free(ptr);
|
||||
}
|
||||
}
|
||||
// This interface is used by logservice module only.
|
||||
int delete_tenant_log_allocator(const uint64_t tenant_id);
|
||||
// int get_tenant_limit(const uint64_t tenant_id, int64_t &limit);
|
||||
// int set_tenant_limit(const uint64_t tenant_id, const int64_t new_limit);
|
||||
// a tricky interface, ugly but save memory
|
||||
int update_tenant_mem_limit(const share::TenantUnits &all_tenant_units);
|
||||
public:
|
||||
static ObTenantMutilAllocatorMgr &get_instance();
|
||||
private:
|
||||
int64_t get_slot_(const int64_t tenant_id) const;
|
||||
int get_tenant_mutil_allocator_(const uint64_t tenant_id, TMA *&out_allocator);
|
||||
int delete_tenant_mutil_allocator_(const uint64_t tenant_id);
|
||||
int construct_allocator_(const uint64_t tenant_id,
|
||||
TMA *&out_allocator);
|
||||
int create_tenant_mutil_allocator_(const uint64_t tenant_id,
|
||||
TMA *&out_allocator);
|
||||
private:
|
||||
static const uint64_t PRESERVED_TENANT_COUNT = 10000;
|
||||
// The sizeof(TMA) is about 130KB, so if the total number of tenants(including deleted ones)
|
||||
// exceeds 1500, the memory used by TMA_MGR will be at least 65MB.
|
||||
static const uint64_t PRESERVED_TENANT_COUNT = 1500;
|
||||
static const uint64_t ARRAY_SIZE = PRESERVED_TENANT_COUNT + 1;
|
||||
|
||||
private:
|
||||
bool is_inited_;
|
||||
obsys::ObRWLock locks_[PRESERVED_TENANT_COUNT];
|
||||
ObTenantMutilAllocator *tma_array_[PRESERVED_TENANT_COUNT];
|
||||
obsys::ObRWLock locks_[ARRAY_SIZE];
|
||||
ObTenantMutilAllocator *tma_array_[ARRAY_SIZE];
|
||||
ObBlockAllocMgr clog_body_blk_alloc_;
|
||||
ObVSliceAlloc clog_entry_alloc_;
|
||||
private:
|
||||
|
||||
Reference in New Issue
Block a user