fix tenant_allocator reuse error
This commit is contained in:
		@ -347,9 +347,7 @@ int ObMallocAllocator::add_tenant_allocator(ObTenantCtxAllocator *allocator)
 | 
				
			|||||||
  while ((NULL != *cur) && (*cur)->get_tenant_id() < tenant_id) {
 | 
					  while ((NULL != *cur) && (*cur)->get_tenant_id() < tenant_id) {
 | 
				
			||||||
    cur = &((*cur)->get_next());
 | 
					    cur = &((*cur)->get_next());
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  if (OB_ISNULL(*cur)) {
 | 
					  if (OB_ISNULL(*cur) || (*cur)->get_tenant_id() > tenant_id) {
 | 
				
			||||||
    *cur = allocator;
 | 
					 | 
				
			||||||
  } else if ((*cur)->get_tenant_id() > tenant_id) {
 | 
					 | 
				
			||||||
    ObTenantCtxAllocator *next_allocator = *cur;
 | 
					    ObTenantCtxAllocator *next_allocator = *cur;
 | 
				
			||||||
    *cur = allocator;
 | 
					    *cur = allocator;
 | 
				
			||||||
    ((*cur)->get_next()) = next_allocator;
 | 
					    ((*cur)->get_next()) = next_allocator;
 | 
				
			||||||
 | 
				
			|||||||
@ -18,6 +18,21 @@
 | 
				
			|||||||
using namespace oceanbase::lib;
 | 
					using namespace oceanbase::lib;
 | 
				
			||||||
using namespace oceanbase::common;
 | 
					using namespace oceanbase::common;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TestMallocAllocator : public ::testing::Test
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  virtual void SetUp()
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    // cleanup
 | 
				
			||||||
 | 
					    ObMallocAllocator *malloc_allocator = ObMallocAllocator::get_instance();
 | 
				
			||||||
 | 
					    for (int i = OB_USER_TENANT_ID + 1; i < ObMallocAllocator::PRESERVED_TENANT_COUNT; i++) {
 | 
				
			||||||
 | 
					      malloc_allocator->allocators_[i] = NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    malloc_allocator->unrecycled_allocators_ = NULL;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  virtual void TearDown() {}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int64_t g_ctx_id = ObCtxIds::DEFAULT_CTX_ID;
 | 
					int64_t g_ctx_id = ObCtxIds::DEFAULT_CTX_ID;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TEST(TestMallocAllocator, reserved_tenant)
 | 
					TEST(TestMallocAllocator, reserved_tenant)
 | 
				
			||||||
@ -171,6 +186,60 @@ TEST(TestMallocAllocator, allocator_guard)
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(TestMallocAllocator, bug_47543065)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  std::pair<int, int64_t> flow[] = {
 | 
				
			||||||
 | 
					    std::make_pair(1, 1002),
 | 
				
			||||||
 | 
					    std::make_pair(1, 1001),
 | 
				
			||||||
 | 
					    std::make_pair(1, 1006),
 | 
				
			||||||
 | 
					    std::make_pair(1, 1005),
 | 
				
			||||||
 | 
					    std::make_pair(1, 1004),
 | 
				
			||||||
 | 
					    std::make_pair(1, 1003),
 | 
				
			||||||
 | 
					    std::make_pair(0, 1001),
 | 
				
			||||||
 | 
					    std::make_pair(1, 1008),
 | 
				
			||||||
 | 
					    std::make_pair(1, 1007),
 | 
				
			||||||
 | 
					    std::make_pair(0, 1005),
 | 
				
			||||||
 | 
					    std::make_pair(0, 1007),
 | 
				
			||||||
 | 
					    std::make_pair(0, 1008),
 | 
				
			||||||
 | 
					    std::make_pair(1, 1008),
 | 
				
			||||||
 | 
					    std::make_pair(1, 1007),
 | 
				
			||||||
 | 
					    std::make_pair(0, 1007),
 | 
				
			||||||
 | 
					    std::make_pair(0, 1008),
 | 
				
			||||||
 | 
					    std::make_pair(1, 1008)
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  ObMallocAllocator *malloc_allocator = ObMallocAllocator::get_instance();
 | 
				
			||||||
 | 
					  for (int i = 0; i < sizeof(flow)/sizeof(flow[0]);i++) {
 | 
				
			||||||
 | 
					    int create = flow[i].first;
 | 
				
			||||||
 | 
					    int64_t tenant_id = flow[i].second;
 | 
				
			||||||
 | 
					    if (create) {
 | 
				
			||||||
 | 
					      ASSERT_EQ(OB_SUCCESS, malloc_allocator->create_and_add_tenant_allocator(tenant_id));
 | 
				
			||||||
 | 
					      // make tenant memleak
 | 
				
			||||||
 | 
					      auto ta = malloc_allocator->get_tenant_ctx_allocator(tenant_id, 0);
 | 
				
			||||||
 | 
					      ASSERT_NE(nullptr, ta);
 | 
				
			||||||
 | 
					      ASSERT_NE(nullptr, ta->alloc(8, ObMemAttr(tenant_id)));
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      malloc_allocator->recycle_tenant_allocator(tenant_id);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // check status
 | 
				
			||||||
 | 
					  for (int i = 0; i < ObMallocAllocator::PRESERVED_TENANT_COUNT; i++) {
 | 
				
			||||||
 | 
					    auto ta = malloc_allocator->allocators_[i];
 | 
				
			||||||
 | 
					    uint64_t prev_tenant_id = 0;
 | 
				
			||||||
 | 
					    while (ta != NULL) {
 | 
				
			||||||
 | 
					      ASSERT_EQ(ta->get_tenant_id() % ObMallocAllocator::PRESERVED_TENANT_COUNT, i);
 | 
				
			||||||
 | 
					      ASSERT_GT(ta->get_tenant_id(), prev_tenant_id);
 | 
				
			||||||
 | 
					      auto ta_other = malloc_allocator->unrecycled_allocators_;
 | 
				
			||||||
 | 
					      while (ta_other) {
 | 
				
			||||||
 | 
					        ASSERT_NE(ta, ta_other);
 | 
				
			||||||
 | 
					        ta_other = ta_other->get_next();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      prev_tenant_id = ta->get_tenant_id();
 | 
				
			||||||
 | 
					      ta = ta->get_next();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main(int argc, char *argv[])
 | 
					int main(int argc, char *argv[])
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  signal(49, SIG_IGN);
 | 
					  signal(49, SIG_IGN);
 | 
				
			||||||
 | 
				
			|||||||
@ -844,7 +844,9 @@ int ObMultiTenant::create_tenant(const ObTenantMeta &meta, bool write_slog, cons
 | 
				
			|||||||
      tmp_ret = OB_SUCCESS;
 | 
					      tmp_ret = OB_SUCCESS;
 | 
				
			||||||
      if (create_step >= ObTenantCreateStep::STEP_CTX_MEM_CONFIG_SETTED) {
 | 
					      if (create_step >= ObTenantCreateStep::STEP_CTX_MEM_CONFIG_SETTED) {
 | 
				
			||||||
        for (uint64_t ctx_id = 0; ctx_id < ObCtxIds::MAX_CTX_ID; ctx_id++) {
 | 
					        for (uint64_t ctx_id = 0; ctx_id < ObCtxIds::MAX_CTX_ID; ctx_id++) {
 | 
				
			||||||
          if (OB_SUCCESS != (tmp_ret = malloc_allocator->set_tenant_ctx_idle(tenant_id, ctx_id, 0))) {
 | 
					          if (NULL == malloc_allocator->get_tenant_ctx_allocator(tenant_id, ctx_id)) {
 | 
				
			||||||
 | 
					            // do-nothing
 | 
				
			||||||
 | 
					          } else if (OB_SUCCESS != (tmp_ret = malloc_allocator->set_tenant_ctx_idle(tenant_id, ctx_id, 0))) {
 | 
				
			||||||
            LOG_ERROR("fail to cleanup ctx mem config", K(tmp_ret), K(tenant_id), K(ctx_id));
 | 
					            LOG_ERROR("fail to cleanup ctx mem config", K(tmp_ret), K(tenant_id), K(ctx_id));
 | 
				
			||||||
            SLEEP(1);
 | 
					            SLEEP(1);
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user