fixed problems when shrink log disk size
This commit is contained in:
@ -171,6 +171,8 @@ public:
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
int update_server_log_disk(const int64_t log_disk_size)
|
||||
{return OB_SUCCESS;}
|
||||
public:
|
||||
int simple_init(const std::string &cluster_name,
|
||||
const common::ObAddr &addr,
|
||||
|
||||
@ -1480,5 +1480,15 @@ int ObSimpleLogClusterTestEnv::wait_until_disk_space_to(const int64_t server_id,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObSimpleLogClusterTestEnv::update_server_log_disk(const int64_t log_disk_size)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
auto cluster = get_cluster();
|
||||
for (auto srv : cluster) {
|
||||
srv->update_server_log_disk(log_disk_size);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // end namespace unittest
|
||||
} // end namespace oceanbase
|
||||
|
||||
@ -249,6 +249,7 @@ public:
|
||||
bool is_degraded(const PalfHandleImplGuard &leader, const int64_t degraded_server_idx);
|
||||
bool is_upgraded(PalfHandleImplGuard &leader, const int64_t palf_id);
|
||||
int wait_until_disk_space_to(const int64_t server_id, const int64_t expect_log_disk_space);
|
||||
int update_server_log_disk(const int64_t log_disk_size);
|
||||
public:
|
||||
static int64_t palf_id_;
|
||||
private:
|
||||
|
||||
79
mittest/logservice/env/ob_simple_log_server.cpp
vendored
79
mittest/logservice/env/ob_simple_log_server.cpp
vendored
@ -163,44 +163,10 @@ int ObSimpleLogServer::simple_init(
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObSimpleLogServer::construct_allowed_new_log_disk_(const uint64_t tenant_id,
|
||||
const int64_t expected_log_disk_size,
|
||||
const int64_t old_log_disk_size,
|
||||
int64_t &allowed_new_log_disk_size)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
bool can_update_log_disk_size_with_expected_log_disk = true;
|
||||
int64_t palf_log_disk_size = 0;
|
||||
MAKE_TENANT_SWITCH_SCOPE_GUARD(guard);
|
||||
if (OB_FAIL(guard.switch_to(tenant_id))) {
|
||||
LOG_WARN("failed to switch tenant", K(ret), K(tenant_id));
|
||||
} else {
|
||||
ObLogService *log_service = MTL(ObLogService*);
|
||||
int64_t used_log_disk_size = 0;
|
||||
if (OB_ISNULL(log_service)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("ObLogService is nullptr", K(ret), KP(log_service));
|
||||
} else if (OB_FAIL(log_service->get_palf_stable_disk_usage(used_log_disk_size, palf_log_disk_size))) {
|
||||
LOG_WARN("failed to update_log_disk_size", K(ret), K(palf_log_disk_size), K(allowed_new_log_disk_size), K(expected_log_disk_size));
|
||||
} else if (FALSE_IT(can_update_log_disk_size_with_expected_log_disk = (expected_log_disk_size >= palf_log_disk_size))) {
|
||||
// For shrinking log disk, we still update log disk size of 'new_unit' to 'old_log_disk_size'.
|
||||
} else if (!can_update_log_disk_size_with_expected_log_disk
|
||||
&& FALSE_IT(allowed_new_log_disk_size = old_log_disk_size)) {
|
||||
// For expanding log disk, we update log disk size of 'new_unit' to 'expected_log_disk_size'.
|
||||
} else if (can_update_log_disk_size_with_expected_log_disk
|
||||
&& FALSE_IT(allowed_new_log_disk_size = expected_log_disk_size)) {
|
||||
} else {
|
||||
LOG_INFO("construct_new_log_disk success", K(ret), K(tenant_id), K(can_update_log_disk_size_with_expected_log_disk),
|
||||
K(old_log_disk_size), K(allowed_new_log_disk_size), K(expected_log_disk_size));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObSimpleLogServer::update_tenant_log_disk_size_(const uint64_t tenant_id,
|
||||
const int64_t expected_log_disk_size,
|
||||
const int64_t old_log_disk_size,
|
||||
const int64_t allowed_new_log_disk_size)
|
||||
const int64_t new_log_disk_size,
|
||||
int64_t &allowed_new_log_disk_size)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
MAKE_TENANT_SWITCH_SCOPE_GUARD(guard);
|
||||
@ -208,15 +174,15 @@ int ObSimpleLogServer::update_tenant_log_disk_size_(const uint64_t tenant_id,
|
||||
ObLogService *log_service = MTL(ObLogService *);
|
||||
if (OB_ISNULL(log_service)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
} else if (OB_FAIL(log_service->update_log_disk_usage_limit_size(expected_log_disk_size))) {
|
||||
LOG_WARN("failed to update_log_disk_usage_limit_size", K(ret), K(tenant_id), K(expected_log_disk_size),
|
||||
} else if (OB_FAIL(log_service->update_log_disk_usage_limit_size(new_log_disk_size))) {
|
||||
LOG_WARN("failed to update_log_disk_usage_limit_size", K(ret), K(tenant_id), K(new_log_disk_size),
|
||||
K(old_log_disk_size), K(allowed_new_log_disk_size));
|
||||
} else if (OB_FAIL(log_block_pool_.update_tenant(old_log_disk_size, allowed_new_log_disk_size))) {
|
||||
LOG_WARN("failed to update teannt int ObServerLogBlockMGR", K(ret), K(tenant_id), K(expected_log_disk_size),
|
||||
} else if (OB_FAIL(log_block_pool_.update_tenant(old_log_disk_size, new_log_disk_size, allowed_new_log_disk_size, log_service))) {
|
||||
LOG_WARN("failed to update teannt int ObServerLogBlockMGR", K(ret), K(tenant_id), K(new_log_disk_size),
|
||||
K(old_log_disk_size), K(allowed_new_log_disk_size));
|
||||
} else {
|
||||
disk_opts_.log_disk_usage_limit_size_ = allowed_new_log_disk_size;
|
||||
LOG_INFO("update_log_disk_usage_limit_size success", K(ret), K(tenant_id), K(expected_log_disk_size),
|
||||
LOG_INFO("update_log_disk_usage_limit_size success", K(ret), K(tenant_id), K(new_log_disk_size),
|
||||
K(old_log_disk_size), K(allowed_new_log_disk_size), K(disk_opts_));
|
||||
}
|
||||
}
|
||||
@ -226,26 +192,26 @@ int ObSimpleLogServer::update_tenant_log_disk_size_(const uint64_t tenant_id,
|
||||
int ObSimpleLogServer::update_disk_opts_no_lock_(const PalfDiskOptions &opts)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
CLOG_LOG(INFO, "begin update_disk_opts_no_lock_", K(opts), K(disk_opts_), K(inner_table_disk_opts_));
|
||||
int64_t old_log_disk_size = disk_opts_.log_disk_usage_limit_size_;
|
||||
int64_t expected_log_disk_size = opts.log_disk_usage_limit_size_;
|
||||
int64_t new_log_disk_size = opts.log_disk_usage_limit_size_;
|
||||
int64_t allowed_new_log_disk_size = 0;
|
||||
// 内部表中的disk_opts立马生效
|
||||
inner_table_disk_opts_ = opts;
|
||||
// disk_opts_表示本地持久化最新的disk_opts,在construct_allowed_new_log_disk_中会修改disk_opts_的log_disk_usage_limit_size_
|
||||
// disk_opts_表示本地持久化最新的disk_opts,log_disk_percentage_延迟生效
|
||||
disk_opts_ = opts;
|
||||
disk_opts_.log_disk_usage_limit_size_ = old_log_disk_size;
|
||||
if (!opts.is_valid()) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
CLOG_LOG(WARN, "invalid argument", K(opts));
|
||||
} else if (OB_FAIL(construct_allowed_new_log_disk_(node_id_, expected_log_disk_size,
|
||||
old_log_disk_size, allowed_new_log_disk_size))) {
|
||||
CLOG_LOG(WARN, "construct_allowed_new_log_disk_ failed", K(expected_log_disk_size), K(old_log_disk_size),
|
||||
K(allowed_new_log_disk_size));
|
||||
} else if (OB_FAIL(update_tenant_log_disk_size_(node_id_, expected_log_disk_size,
|
||||
old_log_disk_size, allowed_new_log_disk_size))) {
|
||||
CLOG_LOG(WARN, "update_tenant_log_disk_size_ failed", K(expected_log_disk_size), K(old_log_disk_size),
|
||||
} else if (OB_FAIL(update_tenant_log_disk_size_(node_id_,
|
||||
old_log_disk_size,
|
||||
new_log_disk_size,
|
||||
allowed_new_log_disk_size))) {
|
||||
CLOG_LOG(WARN, "update_tenant_log_disk_size_ failed", K(new_log_disk_size), K(old_log_disk_size),
|
||||
K(allowed_new_log_disk_size));
|
||||
} else {
|
||||
CLOG_LOG(INFO, "update_disk_opts success", K(opts), K(disk_opts_), K(expected_log_disk_size), K(old_log_disk_size),
|
||||
CLOG_LOG(INFO, "update_disk_opts success", K(opts), K(disk_opts_), K(new_log_disk_size), K(old_log_disk_size),
|
||||
K(allowed_new_log_disk_size));
|
||||
}
|
||||
return ret;
|
||||
@ -272,6 +238,12 @@ int ObSimpleLogServer::try_resize()
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObSimpleLogServer::update_server_log_disk(const int64_t log_disk_size)
|
||||
{
|
||||
ObSpinLockGuard guard(log_disk_lock_);
|
||||
return log_block_pool_.resize_(log_disk_size);
|
||||
}
|
||||
|
||||
int ObSimpleLogServer::init_memory_dump_timer_()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
@ -349,7 +321,8 @@ int ObSimpleLogServer::init_io_(const std::string &cluster_name)
|
||||
storage_env.default_block_size_ = OB_DEFAULT_MACRO_BLOCK_SIZE;
|
||||
storage_env.data_disk_size_ = 1024 * 1024 * 1024;
|
||||
storage_env.data_disk_percentage_ = 0;
|
||||
storage_env.log_disk_size_ = 10LL * 1024 * 1024 * 1024;
|
||||
// 当disk_opts_有效时,使用disk_opts_中记录的log_disk_usage_limit_size_作为log_block_pool_的初始值,否则重启会失败
|
||||
storage_env.log_disk_size_ = disk_opts_.is_valid() ? disk_opts_.log_disk_usage_limit_size_ : 2LL * 1024 * 1024 * 1024;
|
||||
storage_env.log_disk_percentage_ = 0;
|
||||
|
||||
storage_env.log_spec_.log_dir_ = slog_dir.c_str();
|
||||
@ -394,7 +367,7 @@ int ObSimpleLogServer::init_log_service_()
|
||||
if (disk_opts_.is_valid()) {
|
||||
opts.disk_options_ = disk_opts_;
|
||||
} else {
|
||||
opts.disk_options_.log_disk_usage_limit_size_ = 10 * 1024 * 1024 * 1024ul;
|
||||
opts.disk_options_.log_disk_usage_limit_size_ = 2 * 1024 * 1024 * 1024ul;
|
||||
opts.disk_options_.log_disk_utilization_threshold_ = 80;
|
||||
opts.disk_options_.log_disk_utilization_limit_threshold_ = 95;
|
||||
opts.disk_options_.log_disk_throttling_percentage_ = 100;
|
||||
|
||||
15
mittest/logservice/env/ob_simple_log_server.h
vendored
15
mittest/logservice/env/ob_simple_log_server.h
vendored
@ -251,6 +251,7 @@ public:
|
||||
virtual int create_mock_election(const int64_t palf_id, MockElection *&mock_election) = 0;
|
||||
virtual int remove_mock_election(const int64_t palf_id) = 0;
|
||||
virtual int set_leader(const int64_t palf_id, const common::ObAddr &leader, const int64_t new_epoch = 0) = 0;
|
||||
virtual int update_server_log_disk(const int64_t log_disk_size) = 0;
|
||||
DECLARE_PURE_VIRTUAL_TO_STRING;
|
||||
};
|
||||
|
||||
@ -287,6 +288,7 @@ public:
|
||||
virtual int update_disk_opts(const PalfDiskOptions &opts) override final;
|
||||
virtual int get_disk_opts(PalfDiskOptions &opts) override final
|
||||
{
|
||||
ObSpinLockGuard guard(log_disk_lock_);
|
||||
opts = disk_opts_;
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
@ -368,6 +370,7 @@ public:
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
int update_server_log_disk(const int64_t log_disk_size);
|
||||
TO_STRING_KV(K_(node_id), K_(addr), KP(palf_env_));
|
||||
|
||||
protected:
|
||||
@ -375,15 +378,10 @@ protected:
|
||||
int init_network_(const common::ObAddr &addr, const bool is_bootstrap);
|
||||
int init_log_service_();
|
||||
int init_memory_dump_timer_();
|
||||
// 更新log_disk_size的逻辑保持和ObMultiTenant.cpp中维护同名函数一样
|
||||
int construct_allowed_new_log_disk_(const uint64_t tenant_id,
|
||||
const int64_t expected_log_disk_size,
|
||||
const int64_t old_log_disk_size,
|
||||
int64_t &allowed_new_log_disk_size);
|
||||
int update_tenant_log_disk_size_(const uint64_t tenant_id,
|
||||
const int64_t expected_log_disk_size,
|
||||
const int64_t old_log_disk_size,
|
||||
const int64_t allowed_log_disk_size);
|
||||
const int64_t new_log_disk_size,
|
||||
int64_t &allowed_log_disk_size);
|
||||
int update_disk_opts_no_lock_(const PalfDiskOptions &opts);
|
||||
|
||||
private:
|
||||
@ -415,8 +413,11 @@ private:
|
||||
ObSrvRpcProxy srv_proxy_;
|
||||
logservice::coordinator::ObFailureDetector detector_;
|
||||
MockElectionMap mock_election_map_;
|
||||
// ObTenantUnit以及__all_unit_configs
|
||||
ObSpinLock log_disk_lock_;
|
||||
// 本地已生效日志盘规格
|
||||
palf::PalfDiskOptions disk_opts_;
|
||||
// 内部表中记录日志盘规格
|
||||
palf::PalfDiskOptions inner_table_disk_opts_;
|
||||
ObLooper looper_;
|
||||
};
|
||||
|
||||
@ -37,27 +37,27 @@ using namespace logservice;
|
||||
namespace unittest
|
||||
{
|
||||
class TestObSimpleLogDiskMgr : public ObSimpleLogClusterTestEnv
|
||||
{
|
||||
public:
|
||||
TestObSimpleLogDiskMgr() : ObSimpleLogClusterTestEnv()
|
||||
{
|
||||
int ret = init();
|
||||
if (OB_SUCCESS != ret) {
|
||||
throw std::runtime_error("TestObSimpleLogDiskMgr init failed");
|
||||
public:
|
||||
TestObSimpleLogDiskMgr() : ObSimpleLogClusterTestEnv()
|
||||
{
|
||||
int ret = init();
|
||||
if (OB_SUCCESS != ret) {
|
||||
throw std::runtime_error("TestObSimpleLogDiskMgr init failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
~TestObSimpleLogDiskMgr()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
int init()
|
||||
{
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
void destroy()
|
||||
{}
|
||||
int64_t id_;
|
||||
};
|
||||
~TestObSimpleLogDiskMgr()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
int init()
|
||||
{
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
void destroy()
|
||||
{}
|
||||
int64_t id_;
|
||||
};
|
||||
|
||||
int64_t ObSimpleLogClusterTestBase::member_cnt_ = 1;
|
||||
int64_t ObSimpleLogClusterTestBase::node_cnt_ = 1;
|
||||
@ -66,6 +66,8 @@ bool ObSimpleLogClusterTestBase::need_add_arb_server_ = false;
|
||||
|
||||
TEST_F(TestObSimpleLogDiskMgr, out_of_disk_space)
|
||||
{
|
||||
update_server_log_disk(10*1024*1024*1024ul);
|
||||
update_disk_options(10*1024*1024*1024ul/palf::PALF_PHY_BLOCK_SIZE);
|
||||
SET_CASE_LOG_FILE(TEST_NAME, "out_of_disk_space");
|
||||
int64_t id = ATOMIC_AAF(&palf_id_, 1);
|
||||
int server_idx = 0;
|
||||
@ -117,7 +119,8 @@ TEST_F(TestObSimpleLogDiskMgr, update_disk_options_basic)
|
||||
palf_env->palf_env_impl_.disk_options_wrapper_.status_);
|
||||
EXPECT_EQ(palf_env->palf_env_impl_.disk_options_wrapper_.disk_opts_for_recycling_blocks_.log_disk_usage_limit_size_,
|
||||
20*PALF_PHY_BLOCK_SIZE);
|
||||
// 可以在上一次为缩容完成之前,可以继续缩容
|
||||
|
||||
// case1: 在上一次未缩容完成之前,可以继续缩容
|
||||
EXPECT_EQ(OB_SUCCESS, update_disk_options(leader_idx, 10));
|
||||
usleep(1000*1000+palf::BlockGCTimerTask::BLOCK_GC_TIMER_INTERVAL_MS);
|
||||
EXPECT_EQ(PalfDiskOptionsWrapper::Status::SHRINKING_STATUS,
|
||||
@ -130,8 +133,7 @@ TEST_F(TestObSimpleLogDiskMgr, update_disk_options_basic)
|
||||
EXPECT_EQ(OB_SUCCESS, get_disk_options(leader_idx, opts));
|
||||
EXPECT_EQ(opts.log_disk_usage_limit_size_, 10*1024*1024*1024ul);
|
||||
}
|
||||
// 可以在上一次未缩容完成之前,可以继续扩容, 同时由于扩容后日志盘依旧小于第一次缩容
|
||||
// ,因此依旧处于缩容状态.
|
||||
// case2: 在上一次未缩容完成之前,可以继续扩容, 同时由于扩容后日志盘依旧小于第一次缩容,因此依旧处于缩容状态.
|
||||
EXPECT_EQ(OB_SUCCESS, update_disk_options(leader_idx, 11));
|
||||
usleep(1000*1000+palf::BlockGCTimerTask::BLOCK_GC_TIMER_INTERVAL_MS);
|
||||
EXPECT_EQ(PalfDiskOptionsWrapper::Status::SHRINKING_STATUS,
|
||||
@ -171,6 +173,37 @@ TEST_F(TestObSimpleLogDiskMgr, update_disk_options_basic)
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TestObSimpleLogDiskMgr, shrink_log_disk)
|
||||
{
|
||||
SET_CASE_LOG_FILE(TEST_NAME, "shrink_log_disk");
|
||||
OB_LOGGER.set_log_level("INFO");
|
||||
// 验证缩容由于单日志流最少需要512MB日志盘失败
|
||||
// 保证能同时容纳两个日志流
|
||||
PalfEnv *palf_env = NULL;
|
||||
int64_t leader_idx = 0;
|
||||
PalfHandleImplGuard leader;
|
||||
share::SCN create_scn = share::SCN::base_scn();
|
||||
int server_idx = 0;
|
||||
EXPECT_EQ(OB_SUCCESS, get_palf_env(server_idx, palf_env));
|
||||
EXPECT_EQ(OB_SUCCESS, update_disk_options(16));
|
||||
EXPECT_EQ(PalfDiskOptionsWrapper::Status::NORMAL_STATUS,
|
||||
palf_env->palf_env_impl_.disk_options_wrapper_.status_);
|
||||
EXPECT_EQ(palf_env->palf_env_impl_.disk_options_wrapper_.disk_opts_for_stopping_writing_.log_disk_usage_limit_size_,
|
||||
16*PALF_PHY_BLOCK_SIZE);
|
||||
int64_t tmp_id1 = ATOMIC_AAF(&palf_id_, 1);
|
||||
{
|
||||
PalfHandleImplGuard leader;
|
||||
EXPECT_EQ(OB_SUCCESS, create_paxos_group(tmp_id1, leader_idx, leader));
|
||||
}
|
||||
int64_t tmp_id2 = ATOMIC_AAF(&palf_id_, 1);
|
||||
{
|
||||
PalfHandleImplGuard leader;
|
||||
EXPECT_EQ(OB_SUCCESS, create_paxos_group(tmp_id2, leader_idx, leader));
|
||||
}
|
||||
EXPECT_EQ(OB_NOT_SUPPORTED, update_disk_options(9));
|
||||
EXPECT_EQ(OB_SUCCESS, delete_paxos_group(tmp_id1));
|
||||
}
|
||||
|
||||
TEST_F(TestObSimpleLogDiskMgr, update_disk_options_restart)
|
||||
{
|
||||
disable_hot_cache_ = true;
|
||||
|
||||
@ -457,7 +457,8 @@ public:
|
||||
TEST_F(TestObSimpleLogClusterLogEngine, io_reducer_basic_func)
|
||||
{
|
||||
SET_CASE_LOG_FILE(TEST_NAME, "io_reducer_func");
|
||||
|
||||
update_server_log_disk(4*1024*1024*1024ul);
|
||||
update_disk_options(4*1024*1024*1024ul/palf::PALF_PHY_BLOCK_SIZE);
|
||||
OB_LOGGER.set_log_level("TRACE");
|
||||
PALF_LOG(INFO, "begin io_reducer_basic_func");
|
||||
PalfHandleImplGuard leader_1;
|
||||
|
||||
@ -182,14 +182,14 @@ TEST_F(TestObSimpleLogClusterRebuild, test_old_leader_rebuild)
|
||||
EXPECT_EQ(OB_SUCCESS, get_leader(id, new_leader, new_leader_idx));
|
||||
PALF_LOG(INFO, "after get_leader", K(id), K(leader_idx), K(new_leader_idx));
|
||||
// submit logs
|
||||
EXPECT_EQ(OB_SUCCESS, submit_log(new_leader, 64 * 6, id, MB));
|
||||
EXPECT_EQ(OB_SUCCESS, submit_log(new_leader, 64 * 8, id, MB));
|
||||
|
||||
// update new_leader's disk option, only reserves 4 * 80% log blocks,
|
||||
// that means 2 blocks will be recycled
|
||||
PALF_LOG(INFO, "begin advance_base_lsn", K(id), K(leader_idx), K(new_leader_idx));
|
||||
LSN recycle_lsn(2 * PALF_BLOCK_SIZE);
|
||||
EXPECT_EQ(OB_SUCCESS, new_leader.palf_handle_impl_->set_base_lsn(recycle_lsn));
|
||||
update_disk_options(new_leader_idx, 4);
|
||||
update_disk_options(new_leader_idx, 8);
|
||||
// recycle 2 block
|
||||
sleep(5);
|
||||
block_id_t leader_min_block_id;
|
||||
@ -254,7 +254,7 @@ TEST_F(TestObSimpleLogClusterRebuild, test_old_leader_rebuild)
|
||||
revert_cluster_palf_handle_guard(palf_list);
|
||||
EXPECT_EQ(OB_SUCCESS, new_leader.palf_handle_impl_->set_base_lsn(LSN(64*6*MB)));
|
||||
sleep(1);
|
||||
EXPECT_EQ(OB_SUCCESS, update_disk_options(new_leader_idx, 40));
|
||||
EXPECT_EQ(OB_SUCCESS, update_disk_options(new_leader_idx, 30));
|
||||
PALF_LOG(INFO, "end test old_leader_rebuild", K(id));
|
||||
}
|
||||
|
||||
@ -283,11 +283,11 @@ TEST_F(TestObSimpleLogClusterRebuild, test_follower_rebuild)
|
||||
// the follower is empty
|
||||
block_net(leader_idx, follower_idx);
|
||||
EXPECT_EQ(OB_SUCCESS, submit_log(leader, 64, leader_idx, MB));
|
||||
EXPECT_EQ(OB_SUCCESS, submit_log(leader, 64 * 5, leader_idx, MB));
|
||||
EXPECT_EQ(OB_SUCCESS, submit_log(leader, 64 * 7, leader_idx, MB));
|
||||
// recycle one block
|
||||
LSN recycle_lsn(2 * PALF_BLOCK_SIZE);
|
||||
EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->set_base_lsn(recycle_lsn));
|
||||
update_disk_options(leader_idx, 4);
|
||||
update_disk_options(leader_idx, 8);
|
||||
sleep(1);
|
||||
block_id_t leader_min_block_id, follower_min_block_id;
|
||||
share::SCN min_scn;
|
||||
|
||||
@ -97,6 +97,8 @@ void read_padding_entry(PalfHandleImplGuard &leader, SCN padding_scn, LSN paddin
|
||||
|
||||
TEST_F(TestObSimpleLogClusterSingleReplica, delete_paxos_group)
|
||||
{
|
||||
update_server_log_disk(10*1024*1024*1024ul);
|
||||
update_disk_options(10*1024*1024*1024ul/palf::PALF_PHY_BLOCK_SIZE);
|
||||
SET_CASE_LOG_FILE(TEST_NAME, "delete_paxos_group");
|
||||
const int64_t id = ATOMIC_AAF(&palf_id_, 1);
|
||||
PALF_LOG(INFO, "start test delete_paxos_group", K(id));
|
||||
|
||||
@ -158,7 +158,7 @@ int ObServerLogBlockMgr::start(const int64_t new_size_byte)
|
||||
ret = OB_NOT_INIT;
|
||||
CLOG_LOG(WARN, "ObServerLogBlockMGR is not inited", K(ret), KPC(this));
|
||||
} else if (!check_space_is_enough_(new_size_byte)) {
|
||||
ret = OB_LOG_OUTOF_DISK_SPACE;
|
||||
ret = OB_MACHINE_RESOURCE_NOT_ENOUGH;
|
||||
CLOG_LOG(WARN, "server log disk is too small to hold all tenants or the count of tenants"
|
||||
", log disk space is not enough!!!",
|
||||
K(ret), KPC(this), K(min_log_disk_size_for_all_tenants_), K(new_size_byte));
|
||||
@ -189,27 +189,25 @@ int ObServerLogBlockMgr::resize_(const int64_t new_size_byte)
|
||||
ret = OB_NOT_INIT;
|
||||
CLOG_LOG(ERROR, "ObServerLogBlockMgr has not inited", K(ret), KPC(this),
|
||||
K(new_size_byte), K(aligned_new_size_byte));
|
||||
} else if (new_size_byte < share::ObUnitResource::UNIT_MIN_LOG_DISK_SIZE) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
CLOG_LOG(ERROR, "The size of reserved disp space need greater than 1GB!!!", K(ret),
|
||||
KPC(this), K(new_size_byte), K(aligned_new_size_byte));
|
||||
} else if (curr_total_size == aligned_new_size_byte) {
|
||||
CLOG_LOG(TRACE, "no need do resize", K(ret), KPC(this), K(new_size_byte), K(aligned_new_size_byte));
|
||||
} else if (FALSE_IT(new_log_pool_meta.status_ =
|
||||
(aligned_new_size_byte > curr_total_size ? EXPANDING_STATUS
|
||||
: SHRINKING_STATUS))) {
|
||||
} else if (SHRINKING_STATUS == new_log_pool_meta.status_
|
||||
&& free_size_byte < resize_block_cnt * BLOCK_SIZE) {
|
||||
} else if (aligned_new_size_byte < min_log_disk_size_for_all_tenants_) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
CLOG_LOG(ERROR, "shrink_block_cnt is greater than free_block_cnt", K(ret), KPC(this),
|
||||
K(resize_block_cnt), "free_block_cnt:", free_size_byte / BLOCK_SIZE);
|
||||
LOG_DBA_ERROR(OB_NOT_SUPPORTED,
|
||||
"possible reason",
|
||||
"new log_disk_size is not enough to hold all tenants, please check the configuration about log disk",
|
||||
"new log disk size(MB)", (new_size_byte+1024*1024-1)/1024/1024,
|
||||
"min log disk size(MB)", (min_log_disk_size_for_all_tenants_+1024*1024-1)/1024/1024);
|
||||
} else if (OB_FAIL(
|
||||
do_resize_(old_log_pool_meta, resize_block_cnt, new_log_pool_meta))) {
|
||||
if (OB_ALLOCATE_DISK_SPACE_FAILED == ret) {
|
||||
LOG_DBA_ERROR(OB_ALLOCATE_DISK_SPACE_FAILED,
|
||||
"possible reason",
|
||||
"may be diskspace is not enough, please check the configuration about log disk",
|
||||
"expected log disk size(MB)", (new_size_byte+1024*1024-1)/1024/1024);
|
||||
"new log disk size(MB)", (new_size_byte+1024*1024-1)/1024/1024);
|
||||
} else {
|
||||
CLOG_LOG(ERROR, "do_resize_ failed", K(ret), KPC(this), K(old_log_pool_meta),
|
||||
K(new_log_pool_meta));
|
||||
@ -343,40 +341,113 @@ void ObServerLogBlockMgr::abort_create_tenant(const int64_t log_disk_size)
|
||||
}
|
||||
}
|
||||
|
||||
int ObServerLogBlockMgr::update_tenant(const int64_t old_log_disk_size, const int64_t new_log_disk_size)
|
||||
int ObServerLogBlockMgr::update_tenant(const int64_t old_log_disk_size,
|
||||
const int64_t new_log_disk_size,
|
||||
int64_t &allowed_new_log_disk_size,
|
||||
logservice::ObLogService *log_service)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSpinLockGuard guard(resize_lock_);
|
||||
int64_t used_log_disk_size = 0, palf_log_disk_size = 0;
|
||||
bool can_update_log_disk_size_with_expected_log_disk = false;
|
||||
int64_t tmp_log_disk_size = min_log_disk_size_for_all_tenants_;
|
||||
tmp_log_disk_size -= old_log_disk_size;
|
||||
// 'old_log_disk_size' is current log disk size in ObTenant.
|
||||
// 'new_log_disk_size' is the latest log disk size record in __all_unit_config.
|
||||
// 'allowed_new_log_disk_size' is current allowed log disk size when update log disk.
|
||||
//
|
||||
// To avoid overselling, we can not use 'new_log_disk_size' to update unit config which will save in slog.
|
||||
// therefore, we need constuct a virtual log disk size which named with 'allowed_new_log_disk_size'.
|
||||
if (IS_NOT_INIT) {
|
||||
ret = OB_NOT_INIT;
|
||||
CLOG_LOG(WARN, "ObServerLogBlockMGR is not inited", K(old_log_disk_size), K(new_log_disk_size), KPC(this));
|
||||
} else if (old_log_disk_size <= 0 || new_log_disk_size <= 0 || OB_ISNULL(log_service)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
CLOG_LOG(WARN, "invalid argument", K(old_log_disk_size), K(new_log_disk_size), KP(log_service), KPC(this));
|
||||
} else if (OB_FAIL(log_service->get_palf_stable_disk_usage(used_log_disk_size, palf_log_disk_size))) {
|
||||
CLOG_LOG(WARN, "fail to get_palf_stable_disk_usage", K(old_log_disk_size), K(new_log_disk_size));
|
||||
// The standard for determing whether it's in shrinking or expanding status:
|
||||
// 1. If 'palf_log_disk_size' is smaller than or equal to 'new_log_disk_size', it's in expanding status.
|
||||
// 2. If 'palf_log_disk_size' is greater than 'new_log_disk_size', it's in shrinking status.
|
||||
//
|
||||
// For shrinking log disk, we don't update ObTenantConfig of ObTenant to new ObTenantConfig until shrinking successfully.
|
||||
//
|
||||
// NB: All fields of new ObTenantConfig except log_disk_size has been updated in case of shrinking log disk.
|
||||
//
|
||||
// For example:
|
||||
// 1. before shrinkg log disk successfully, and then expand log disk.
|
||||
// - At T1 timestamp, the original log disk is 100G, and update it to 50G, we will construct 'new_unit' with
|
||||
// 100G, but update palf with 50G because original log disk size is greater than new log disk size.
|
||||
// - At T2 timestamp, the log disk size in current ObTenantConfig is 100G, and we update it to 80G, there are
|
||||
// two scenarios:
|
||||
// 1. if 'palf_log_disk_size' which get from palf is 100G, we think palf is still in shrinking status. and we will
|
||||
// construct 'new_unit' with 100G because 'palf_log_disk_size' is greater than new log disk size(80G). but udpate
|
||||
// palf with 80G
|
||||
// 2. if 'palf_log_disk_size' which get from palf is 50G, we think palf has been in normal status. and we will
|
||||
// construct 'new_unit' with 80G because 'palf_log_disk_size' is smaller than new log disk size(80G), but udpate
|
||||
// palf with 80G.
|
||||
} else if (FALSE_IT(can_update_log_disk_size_with_expected_log_disk = (new_log_disk_size >= palf_log_disk_size))) {
|
||||
// For expanding log disk, we can update 'allowed_new_log_disk_size' to 'new_log_disk_size' directlly.
|
||||
} else if (can_update_log_disk_size_with_expected_log_disk && FALSE_IT(allowed_new_log_disk_size = new_log_disk_size)) {
|
||||
// For shrinking log disk, we still update log disk size of 'new_unit' to 'old_log_disk_size'.
|
||||
} else if (!can_update_log_disk_size_with_expected_log_disk && FALSE_IT(allowed_new_log_disk_size = old_log_disk_size)) {
|
||||
} else if ((tmp_log_disk_size += allowed_new_log_disk_size) > get_total_size_guarded_by_lock_()) {
|
||||
ret = OB_MACHINE_RESOURCE_NOT_ENOUGH;
|
||||
CLOG_LOG(WARN, "ObServerLogBlockMGR can not hold any new tenants", KPC(this), K(old_log_disk_size),
|
||||
K(new_log_disk_size), K(allowed_new_log_disk_size), K(tmp_log_disk_size));
|
||||
// case 1: for shrinking log disk, shrinking log disk from 100G to 50G.
|
||||
// - At T1 timestamp, 'new_log_disk_size' is 50G, 'old_log_disk_size' is 100G, 'allowed_new_log_disk_size' is 100G.
|
||||
// the log disk size record in slog is 100G, and we will update log disk size used for palf to 50G, but not update log
|
||||
// disk which has assigned in ObServerLogBlockMGR.
|
||||
// - At T2 timestamp, 'new_log_disk_size' is still 50G, 'old_log_disk_size' is still 100G, however, 'allowed_new_log_disk_size'
|
||||
// is 50G because of shrinking log disk has been successfully, the log disk record in slog is 50G, and then we will update log disk
|
||||
// size used for palf to 50G again but has no effect, log disk assigned in ObServerLogBlockMGR update to 50G(assume there is only one tenant).
|
||||
//
|
||||
// case 2: for expanding log disk, expanding log disk from 100G to 150G.
|
||||
// - At T1 timestamp, 'new_log_disk_size' is 150G, 'old_log_disk_size' is 100G, 'allowed_new_log_disk_size' is 150G.
|
||||
// the log disk size record in slog is 150G, and then, we will update log disk size used for palf to 150G, the log disk
|
||||
// which has assigned in ObServerLogBlockMGR updaet to 150G(assume there is only one tenant).
|
||||
//
|
||||
// case 3: for shrinking log disk, shrinking log disk from 100G to 50G, and then shrinking log disk from 50G to 25G.
|
||||
// - At T1 timestamp, 'new_log_disk_size' is 50G, 'old_log_disk_size' is 100G, 'allowed_new_log_disk_size' is 100G.
|
||||
// the log disk size record in slog is 100G, and we will update log disk size used for palf to 50G, but not update log
|
||||
// disk which has assigned in ObServerLogBlockMGR.
|
||||
// - At T2 timestamp, 'new_log_disk_size' is 25G, 'old_log_disk_size' is still 100G, however, there are two possibility value for
|
||||
// 'allowed_new_log_disk_size':
|
||||
// 1. the value is 100G because of last shrinking log disk has not been successfully, the log disk record in slog is still 100G
|
||||
// and then we will update log disk size used for palf to 25G, but not update log disk assigned in ObServerLogBlockMGR.
|
||||
// At T3 timestamp, 'new_log_disk_size' is 25G, 'old_log_disk_size' is 100G, 'allowed_new_log_disk_size' is 25G,
|
||||
// the log disk record in slog is 25G, the log disk assigned in ObServerLogBlockMGR is 25G.
|
||||
// 2. the value is 50G because of last shrinking log disk has been successfully, the log disk record in slog is 50G
|
||||
// and then we will update log disk size used for palf to 25G, update log disk assigned in ObServerLogBlockMGR to 50G(assume there is only one tenant).
|
||||
// At T3 timestamp, 'new_log_disk_size' is 25G, 'old_log_disk_size' is 100G, 'allowed_new_log_disk_size' is 25G,
|
||||
// the log disk record in slog is 25G, the log disk assigned in ObServerLogBlockMGR is 25G.
|
||||
//
|
||||
// case 4: for shrinking log disk, shrinking log disk from 100G to 50G, and then expanding log disk from 50G to 80G.
|
||||
// - At T1 timestamp, 'new_log_disk_size' is 50G, 'old_log_disk_size' is 100G, 'allowed_new_log_disk_size' is 100G.
|
||||
// the log disk size record in slog is 100G, and we will update log disk size used for palf to 50G, but not update log
|
||||
// disk which has assigned in ObServerLogBlockMGR.
|
||||
// - At T2 timestamp, 'new_log_disk_size' is 80G, 'old_log_disk_size' is still 100G, however, there are two possibility value for
|
||||
// 'allowed_new_log_disk_size':
|
||||
// 1. the value is 100G because of last shrinking log disk has not been successfully, the log disk record in slog is still 100G
|
||||
// and then we will update log disk size used for palf to 80G, but not update log disk assigned in ObServerLogBlockMGR.
|
||||
// At T3 timestamp, 'new_log_disk_size' is 80G, 'old_log_disk_size' is 100G, 'allowed_new_log_disk_size' is 80G,
|
||||
// the log disk record in slog is 80G, the log disk assigned in ObServerLogBlockMGR is 80G.
|
||||
// 2. the value is 80G because of last shrinking log disk has been successfully, the log disk record in slog is 80G
|
||||
// and then we will update log disk size used for palf to 80G, update log disk assigned in ObServerLogBlockMGR to 80G(assume there is only one tenant).
|
||||
// At T3 timestamp, 'new_log_disk_size' is 25G, 'old_log_disk_size' is 100G, 'allowed_new_log_disk_size' is 25G,
|
||||
// the log disk record in slog is 25G, the log disk assigned in ObServerLogBlockMGR is 25G.
|
||||
//
|
||||
} else if (OB_FAIL(log_service->update_log_disk_usage_limit_size(new_log_disk_size))) {
|
||||
CLOG_LOG(WARN, "failed to update_log_disk_usage_limit_size", K(new_log_disk_size), K(old_log_disk_size),
|
||||
K(allowed_new_log_disk_size));
|
||||
} else {
|
||||
ObSpinLockGuard guard(resize_lock_);
|
||||
int64_t tmp_log_disk_size = min_log_disk_size_for_all_tenants_;
|
||||
tmp_log_disk_size -= old_log_disk_size;
|
||||
if ((tmp_log_disk_size +=new_log_disk_size) > get_total_size_guarded_by_lock_()) {
|
||||
ret = OB_MACHINE_RESOURCE_NOT_ENOUGH;
|
||||
CLOG_LOG(ERROR, "ObServerLogBlockMGR can not hold any new tenants",
|
||||
K(ret), KPC(this), K(old_log_disk_size), K(new_log_disk_size));
|
||||
} else {
|
||||
min_log_disk_size_for_all_tenants_ = tmp_log_disk_size;
|
||||
CLOG_LOG(INFO, "ObServerLogBlockMGR update_tenant success", KPC(this), K(old_log_disk_size), K(new_log_disk_size));
|
||||
}
|
||||
min_log_disk_size_for_all_tenants_ = tmp_log_disk_size;
|
||||
CLOG_LOG(INFO, "update_tenant success", KPC(this), K(new_log_disk_size), K(old_log_disk_size),
|
||||
K(allowed_new_log_disk_size));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ObServerLogBlockMgr::abort_update_tenant(const int64_t old_log_disk_size, const int64_t new_log_disk_size)
|
||||
{
|
||||
if (IS_NOT_INIT) {
|
||||
CLOG_LOG_RET(WARN, OB_NOT_INIT, "ObServerLogBlockMGR is not inited", K(old_log_disk_size), K(new_log_disk_size), KPC(this));
|
||||
} else {
|
||||
ObSpinLockGuard guard(resize_lock_);
|
||||
min_log_disk_size_for_all_tenants_ -= old_log_disk_size;
|
||||
min_log_disk_size_for_all_tenants_ += new_log_disk_size;
|
||||
OB_ASSERT(min_log_disk_size_for_all_tenants_ >= 0
|
||||
&& min_log_disk_size_for_all_tenants_ <= get_total_size_guarded_by_lock_());
|
||||
CLOG_LOG(INFO, "ObServerLogBlockMGR abort_update_tenant success", KPC(this), K(old_log_disk_size), K(new_log_disk_size));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObServerLogBlockMgr::remove_tenant(const int64_t log_disk_size)
|
||||
@ -695,17 +766,13 @@ int ObServerLogBlockMgr::try_resize()
|
||||
ret = OB_NOT_RUNNING;
|
||||
CLOG_LOG(WARN, "ObServerLogBlockMgr not running, can not support resize", KPC(this));
|
||||
} else if (OB_FAIL(observer::ObServerUtils::get_log_disk_info_in_config(log_disk_size,
|
||||
log_disk_percentage))) {
|
||||
if (OB_LOG_OUTOF_DISK_SPACE == ret) {
|
||||
CLOG_LOG(ERROR, "log disk size is too large", K(ret), KPC(this),
|
||||
K(log_disk_size), K(log_disk_percentage));
|
||||
log_disk_percentage))) {
|
||||
if (OB_SERVER_OUTOF_DISK_SPACE == ret) {
|
||||
ret = OB_MACHINE_RESOURCE_NOT_ENOUGH;
|
||||
CLOG_LOG(ERROR, "try_resize failed, log disk space is not enough", K(log_disk_size), KPC(this));
|
||||
} else {
|
||||
CLOG_LOG(ERROR, "get_log_disk_info_in_config failed", K(ret), KPC(this),
|
||||
K(log_disk_size), K(log_disk_percentage));
|
||||
CLOG_LOG(ERROR, "get_log_disk_info_in_config failed", K(log_disk_size), KPC(this));
|
||||
}
|
||||
} else if (log_disk_size == get_total_size_guarded_by_lock_()) {
|
||||
} else if (false == check_space_is_enough_(log_disk_size)) {
|
||||
CLOG_LOG(ERROR, "log disk size is not enough to hold all tenants", KPC(this), K(log_disk_size));
|
||||
} else if (OB_FAIL(resize_(log_disk_size))) {
|
||||
CLOG_LOG(ERROR, "ObServerLogBlockMGR resize failed", K(ret), KPC(this));
|
||||
} else {
|
||||
|
||||
@ -29,7 +29,7 @@ namespace oceanbase
|
||||
{
|
||||
namespace logservice
|
||||
{
|
||||
|
||||
class ObLogService;
|
||||
class ObServerLogBlockMgr : public palf::ILogBlockPool
|
||||
{
|
||||
public:
|
||||
@ -187,14 +187,14 @@ public:
|
||||
// @brief before 'update_tenant_log_disk_size' in ObMultiTenant, need update it.
|
||||
// @param[in] the log disk size used by tenant.
|
||||
// @param[in] the log disk size need by tenant.
|
||||
// @param[in] the log disk size allowed by tenant
|
||||
// @param[in] ObLogService*
|
||||
// OB_SUCCESS
|
||||
// OB_MACHINE_RESOURCE_NOT_ENOUGH
|
||||
int update_tenant(const int64_t old_log_disk_size, const int64_t new_log_disk_size);
|
||||
|
||||
// @brief after 'update_tenant_log_disk_size' in ObMultiTenant failed, need rollbakc it.
|
||||
// @param[in] the log disk size need by tenant.
|
||||
// @param[in] the log disk size used by tenant.
|
||||
void abort_update_tenant(const int64_t old_log_disk_size, const int64_t new_log_disk_size);
|
||||
int update_tenant(const int64_t old_log_disk_size,
|
||||
const int64_t new_log_disk_size,
|
||||
int64_t &allowed_log_disk_size,
|
||||
ObLogService *log_service);
|
||||
|
||||
// @brief after 'del_tenant' in ObMultiTenant success, need remove it from ObServerLogBlockMgr
|
||||
// NB: accurately, when tenant not exist in 'omt_', we can remove it from ObServerLogBlockMgr
|
||||
|
||||
@ -169,7 +169,6 @@ int PalfDiskOptionsWrapper::update_disk_options_not_guarded_by_lock_(const PalfD
|
||||
disk_opts_for_stopping_writing_.log_disk_throttling_percentage_ = new_trigger_percentage;
|
||||
disk_opts_for_recycling_blocks_.log_disk_throttling_maximum_duration_ = new_maximum_duration;
|
||||
disk_opts_for_stopping_writing_.log_disk_throttling_maximum_duration_ = new_maximum_duration;
|
||||
|
||||
sequence_++;
|
||||
}
|
||||
return ret;
|
||||
@ -404,7 +403,7 @@ int PalfEnvImpl::create_palf_handle_impl_(const int64_t palf_id,
|
||||
PALF_LOG(WARN, "palf_handle has exist, ignore this request", K(ret), K(palf_id));
|
||||
} else if (false == check_can_create_palf_handle_impl_()) {
|
||||
ret = OB_LOG_OUTOF_DISK_SPACE;
|
||||
PALF_LOG(ERROR, "PalfEnv can not hold more instance", K(ret), KPC(this), K(palf_id));
|
||||
PALF_LOG(WARN, "PalfEnv can not hold more instance", K(ret), KPC(this), K(palf_id));
|
||||
} else if (0 > (pret = snprintf(base_dir, MAX_PATH_SIZE, "%s/%ld", log_dir_, palf_id))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
PALF_LOG(ERROR, "snprinf failed", K(pret), K(palf_id));
|
||||
@ -709,6 +708,11 @@ int PalfEnvImpl::try_recycle_blocks()
|
||||
const bool curr_diskspace_enough =
|
||||
usable_disk_limit_size_to_stop_writing > total_used_size_byte ? true : false;
|
||||
constexpr int64_t MB = 1024 * 1024LL;
|
||||
const int64_t print_error_log_disk_size =
|
||||
disk_opts_for_stopping_writing.log_disk_usage_limit_size_
|
||||
* disk_opts_for_stopping_writing.log_disk_utilization_threshold_;
|
||||
const bool need_print_error_log =
|
||||
print_error_log_disk_size > total_used_size_byte ? false : true;
|
||||
|
||||
// step1. change SHRINKING_STATUS to normal
|
||||
// 1. when there is no possibility to stop writing,
|
||||
@ -736,23 +740,27 @@ int PalfEnvImpl::try_recycle_blocks()
|
||||
if (diskspace_enough_ != curr_diskspace_enough) {
|
||||
ATOMIC_STORE(&diskspace_enough_, curr_diskspace_enough);
|
||||
}
|
||||
if ((true == need_recycle && false == has_recycled && false == is_shrinking) || false == diskspace_enough_) {
|
||||
|
||||
// NB: print error log when:
|
||||
// 1. write-stop.
|
||||
// 2. the used log disk space exceeded the log disk recycle threshold(stop-write PalfDiskOptions) and there is no recycable block.
|
||||
if ((false == diskspace_enough_) || (true == need_print_error_log && false == has_recycled)) {
|
||||
constexpr int64_t INTERVAL = 1*1000*1000;
|
||||
if (palf_reach_time_interval(INTERVAL, disk_not_enough_print_interval_)) {
|
||||
int tmp_ret = OB_LOG_OUTOF_DISK_SPACE;
|
||||
LOG_DBA_ERROR(OB_LOG_OUTOF_DISK_SPACE, "msg", "log disk space is almost full", "ret", tmp_ret,
|
||||
"total_size(MB)", disk_opts_for_recycling_blocks.log_disk_usage_limit_size_/MB,
|
||||
"used_size(MB)", total_used_size_byte/MB,
|
||||
"used_percent(%)", (total_used_size_byte* 100) / (disk_opts_for_stopping_writing.log_disk_usage_limit_size_ + 1),
|
||||
"warn_size(MB)", (total_size_to_recycle_blocks*disk_opts_for_recycling_blocks.log_disk_utilization_threshold_)/100/MB,
|
||||
"warn_percent(%)", disk_opts_for_recycling_blocks.log_disk_utilization_threshold_,
|
||||
"limit_size(MB)", (total_size_to_recycle_blocks*disk_opts_for_recycling_blocks.log_disk_utilization_limit_threshold_)/100/MB,
|
||||
"limit_percent(%)", disk_opts_for_recycling_blocks.log_disk_utilization_limit_threshold_,
|
||||
"total_unrecyclable_size_byte(MB)", total_unrecyclable_size_byte/MB,
|
||||
"maximum_used_size(MB)", maximum_used_size/MB,
|
||||
"maximum_log_stream", palf_id,
|
||||
"oldest_log_stream", oldest_palf_id,
|
||||
"oldest_scn", oldest_scn);
|
||||
int tmp_ret = OB_LOG_OUTOF_DISK_SPACE;
|
||||
LOG_DBA_ERROR(OB_LOG_OUTOF_DISK_SPACE, "msg", "log disk space is almost full", "ret", tmp_ret,
|
||||
"total_size(MB)", disk_opts_for_recycling_blocks.log_disk_usage_limit_size_/MB,
|
||||
"used_size(MB)", total_used_size_byte/MB,
|
||||
"used_percent(%)", (total_used_size_byte* 100) / (disk_opts_for_stopping_writing.log_disk_usage_limit_size_ + 1),
|
||||
"warn_size(MB)", (total_size_to_recycle_blocks*disk_opts_for_recycling_blocks.log_disk_utilization_threshold_)/100/MB,
|
||||
"warn_percent(%)", disk_opts_for_recycling_blocks.log_disk_utilization_threshold_,
|
||||
"limit_size(MB)", (total_size_to_recycle_blocks*disk_opts_for_recycling_blocks.log_disk_utilization_limit_threshold_)/100/MB,
|
||||
"limit_percent(%)", disk_opts_for_recycling_blocks.log_disk_utilization_limit_threshold_,
|
||||
"total_unrecyclable_size_byte(MB)", total_unrecyclable_size_byte/MB,
|
||||
"maximum_used_size(MB)", maximum_used_size/MB,
|
||||
"maximum_log_stream", palf_id,
|
||||
"oldest_log_stream", oldest_palf_id,
|
||||
"oldest_scn", oldest_scn);
|
||||
}
|
||||
} else {
|
||||
if (REACH_TIME_INTERVAL(2 * 1000 * 1000L)) {
|
||||
@ -886,13 +894,15 @@ int PalfEnvImpl::update_options(const PalfOptions &options)
|
||||
} else if (false == options.is_valid()) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
PALF_LOG(WARN, "invalid argument", K(options));
|
||||
} else if (OB_FAIL(disk_options_wrapper_.update_disk_options(options.disk_options_))) {
|
||||
PALF_LOG(WARN, "update_disk_options failed", K(ret), K(options));
|
||||
} else if (OB_FAIL(log_rpc_.update_transport_compress_options(options.compress_options_))) {
|
||||
PALF_LOG(WARN, "update_transport_compress_options failed", K(ret), K(options));
|
||||
} else if (FALSE_IT(rebuild_replica_log_lag_threshold_ = options.rebuild_replica_log_lag_threshold_)) {
|
||||
} else if (OB_FAIL(check_can_update_log_disk_options_(options.disk_options_))) {
|
||||
PALF_LOG(WARN, "check_can_update_log_disk_options_ failed", K(options));
|
||||
} else if (OB_FAIL(disk_options_wrapper_.update_disk_options(options.disk_options_))) {
|
||||
PALF_LOG(WARN, "update_disk_options failed", K(ret), K(options));
|
||||
} else {
|
||||
rebuild_replica_log_lag_threshold_ = options.rebuild_replica_log_lag_threshold_;
|
||||
PALF_LOG(INFO, "update_palf_options success", K(options));
|
||||
PALF_LOG(INFO, "update_options successs", K(options), KPC(this));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -1315,5 +1325,18 @@ int PalfEnvImpl::init_log_io_worker_config_(const int log_writer_parallelism,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int PalfEnvImpl::check_can_update_log_disk_options_(const PalfDiskOptions &disk_opts)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const int64_t curr_palf_instance_num = palf_handle_impl_map_.count();
|
||||
const int64_t curr_min_log_disk_size = curr_palf_instance_num * MIN_DISK_SIZE_PER_PALF_INSTANCE;
|
||||
if (disk_opts.log_disk_usage_limit_size_ < curr_min_log_disk_size) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
PALF_LOG(WARN, "can not hold current palf instance", K(curr_palf_instance_num),
|
||||
K(curr_min_log_disk_size), K(disk_opts));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // end namespace palf
|
||||
} // end namespace oceanbase
|
||||
|
||||
@ -346,6 +346,8 @@ private:
|
||||
const int64_t tenant_id,
|
||||
LogIOWorkerConfig &config);
|
||||
|
||||
int check_can_update_log_disk_options_(const PalfDiskOptions &disk_options);
|
||||
|
||||
private:
|
||||
typedef common::RWLock RWLock;
|
||||
typedef RWLock::RLockGuard RLockGuard;
|
||||
|
||||
@ -51,158 +51,102 @@ int ObServerUtils::get_server_ip(ObIAllocator *allocator, ObString &ipstr)
|
||||
int ObServerUtils::get_log_disk_info_in_config(int64_t& log_disk_size,
|
||||
int64_t& log_disk_percentage)
|
||||
{
|
||||
int64_t data_disk_size = 0;
|
||||
int64_t data_disk_percentage = 0;
|
||||
|
||||
return observer::ObServerUtils::cal_all_part_disk_size(GCONF.datafile_size,
|
||||
GCONF.log_disk_size,
|
||||
GCONF.datafile_disk_percentage,
|
||||
GCONF.log_disk_percentage,
|
||||
data_disk_size,
|
||||
log_disk_size,
|
||||
data_disk_percentage,
|
||||
log_disk_percentage);
|
||||
int ret = OB_SUCCESS;
|
||||
int64_t suggested_data_disk_size = GCONF.datafile_size;
|
||||
int64_t suggested_data_disk_percentage = GCONF.datafile_disk_percentage;
|
||||
int64_t suggested_clog_disk_size = GCONF.log_disk_size;
|
||||
int64_t suggested_clog_disk_percentage = GCONF.log_disk_percentage;
|
||||
int64_t data_default_disk_percentage = 0;
|
||||
int64_t clog_default_disk_percentage = 0;
|
||||
int64_t data_disk_total_size = 0;
|
||||
int64_t clog_disk_total_size = 0;
|
||||
bool shared_mode = false;
|
||||
const char* data_dir = OB_FILE_SYSTEM_ROUTER.get_sstable_dir();
|
||||
const char* clog_dir = OB_FILE_SYSTEM_ROUTER.get_clog_dir();
|
||||
if (OB_FAIL(cal_all_part_disk_default_percentage(data_disk_total_size,
|
||||
data_default_disk_percentage,
|
||||
clog_disk_total_size,
|
||||
clog_default_disk_percentage,
|
||||
shared_mode))) {
|
||||
LOG_ERROR("cal all part disk default percentage failed",
|
||||
KR(ret), K(data_dir), K(suggested_data_disk_size), K(suggested_data_disk_percentage),
|
||||
K(data_default_disk_percentage), K(shared_mode));
|
||||
} else if (OB_FAIL(decide_disk_size(clog_disk_total_size,
|
||||
suggested_clog_disk_size,
|
||||
suggested_clog_disk_percentage,
|
||||
clog_default_disk_percentage,
|
||||
log_disk_size,
|
||||
log_disk_percentage))) {
|
||||
LOG_ERROR("decide disk size failed",
|
||||
KR(ret), K(data_dir), K(suggested_data_disk_size), K(suggested_data_disk_percentage),
|
||||
K(data_default_disk_percentage), K(shared_mode));
|
||||
} else {
|
||||
LOG_INFO("get_log_disk_info_in_config", K(suggested_data_disk_size), K(suggested_clog_disk_size),
|
||||
K(suggested_data_disk_percentage), K(suggested_clog_disk_percentage), K(log_disk_size),
|
||||
K(log_disk_percentage));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObServerUtils::get_data_disk_info_in_config(int64_t& data_disk_size,
|
||||
int64_t& data_disk_percentage)
|
||||
{
|
||||
int64_t log_disk_size = 0;
|
||||
int64_t log_disk_percentage = 0;
|
||||
|
||||
return observer::ObServerUtils::cal_all_part_disk_size(GCONF.datafile_size,
|
||||
GCONF.log_disk_size,
|
||||
GCONF.datafile_disk_percentage,
|
||||
GCONF.log_disk_percentage,
|
||||
data_disk_size,
|
||||
log_disk_size,
|
||||
data_disk_percentage,
|
||||
log_disk_percentage);
|
||||
int ret = OB_SUCCESS;
|
||||
int64_t suggested_data_disk_size = GCONF.datafile_size;
|
||||
int64_t suggested_data_disk_percentage = GCONF.datafile_disk_percentage;
|
||||
int64_t suggested_clog_disk_size = GCONF.log_disk_size;
|
||||
int64_t suggested_clog_disk_percentage = GCONF.log_disk_percentage;
|
||||
int64_t data_default_disk_percentage = 0;
|
||||
int64_t clog_default_disk_percentage = 0;
|
||||
int64_t data_disk_total_size = 0;
|
||||
int64_t clog_disk_total_size = 0;
|
||||
bool shared_mode = false;
|
||||
const char* data_dir = OB_FILE_SYSTEM_ROUTER.get_sstable_dir();
|
||||
const char* clog_dir = OB_FILE_SYSTEM_ROUTER.get_clog_dir();
|
||||
if (OB_FAIL(cal_all_part_disk_default_percentage(data_disk_total_size,
|
||||
data_default_disk_percentage,
|
||||
clog_disk_total_size,
|
||||
clog_default_disk_percentage,
|
||||
shared_mode))) {
|
||||
LOG_ERROR("cal all part disk default percentage failed",
|
||||
KR(ret), K(data_dir), K(suggested_data_disk_size), K(suggested_data_disk_percentage),
|
||||
K(data_default_disk_percentage), K(shared_mode));
|
||||
} else if (OB_FAIL(decide_disk_size(data_disk_total_size,
|
||||
suggested_data_disk_size,
|
||||
suggested_data_disk_percentage,
|
||||
data_default_disk_percentage,
|
||||
data_disk_size,
|
||||
data_disk_percentage))) {
|
||||
LOG_ERROR("decide data disk size failed",
|
||||
KR(ret), K(data_dir), K(suggested_data_disk_size), K(suggested_data_disk_percentage),
|
||||
K(data_default_disk_percentage), K(shared_mode));
|
||||
} else {
|
||||
LOG_INFO("get_data_disk_info_in_config", K(suggested_data_disk_size), K(suggested_clog_disk_size),
|
||||
K(suggested_data_disk_percentage), K(suggested_clog_disk_percentage), K(data_disk_size),
|
||||
K(data_disk_percentage));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObServerUtils::cal_all_part_disk_size(const int64_t suggested_data_disk_size,
|
||||
const int64_t suggested_log_disk_size,
|
||||
const int64_t suggested_clog_disk_size,
|
||||
const int64_t suggested_data_disk_percentage,
|
||||
const int64_t suggested_log_disk_percentage,
|
||||
const int64_t suggested_clog_disk_percentage,
|
||||
int64_t& data_disk_size,
|
||||
int64_t& log_disk_size,
|
||||
int64_t& data_disk_percentage,
|
||||
int64_t& log_disk_percentage)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
||||
// background information about default disk percentage:
|
||||
// If not in shared mode, disk will be used up to 90%.
|
||||
// If in shared mode, data and clog disk usage will be up to 60% and 30%
|
||||
const int64_t DEFAULT_DISK_PERCENTAGE_IN_SEPRATE_MODE = 90;
|
||||
const int64_t DEFAULT_DATA_DISK_PERCENTAGE_IN_SHARED_MODE = 60;
|
||||
const int64_t DEFAULT_CLOG_DISK_PERCENTAGE_IN_SHARED_MODE = 30;
|
||||
|
||||
// We use sstable_dir as the data disk directory to identify whether the log and data are located
|
||||
// on the same file system, and the storage module will ensure that sstable_dir and slog_dir are
|
||||
// located on the same file system;
|
||||
const char* data_dir = OB_FILE_SYSTEM_ROUTER.get_sstable_dir();
|
||||
const char* clog_dir = OB_FILE_SYSTEM_ROUTER.get_clog_dir();
|
||||
|
||||
struct statvfs data_statvfs;
|
||||
struct statvfs clog_statvfs;
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_UNLIKELY(0 != statvfs(data_dir, &data_statvfs))) {
|
||||
LOG_ERROR("Failed to get data disk space ", KR(ret), K(data_dir), K(errno));
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
} else if (OB_UNLIKELY(0 != statvfs(clog_dir, &clog_statvfs))) {
|
||||
LOG_ERROR("Failed to get clog disk space ", KR(ret), K(clog_dir), K(errno));
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
}
|
||||
}
|
||||
|
||||
bool shared_mode = true;
|
||||
int64_t data_default_disk_percentage = 0;
|
||||
int64_t clog_default_disk_percentage = 0;
|
||||
|
||||
if (OB_SUCC(ret)) {
|
||||
if (data_statvfs.f_fsid == clog_statvfs.f_fsid) {
|
||||
shared_mode = true;
|
||||
data_default_disk_percentage = DEFAULT_DATA_DISK_PERCENTAGE_IN_SHARED_MODE;
|
||||
clog_default_disk_percentage = DEFAULT_CLOG_DISK_PERCENTAGE_IN_SHARED_MODE;
|
||||
} else {
|
||||
shared_mode = false;
|
||||
data_default_disk_percentage = DEFAULT_DISK_PERCENTAGE_IN_SEPRATE_MODE;
|
||||
clog_default_disk_percentage = DEFAULT_DISK_PERCENTAGE_IN_SEPRATE_MODE;
|
||||
}
|
||||
if (OB_FAIL(decide_disk_size(data_statvfs,
|
||||
suggested_data_disk_size,
|
||||
suggested_data_disk_percentage,
|
||||
data_default_disk_percentage,
|
||||
data_dir,
|
||||
data_disk_size,
|
||||
data_disk_percentage))) {
|
||||
LOG_ERROR("decide data disk size failed",
|
||||
KR(ret), K(data_dir), K(suggested_data_disk_size), K(suggested_data_disk_percentage),
|
||||
K(data_default_disk_percentage), K(shared_mode));
|
||||
} else if (OB_FAIL(decide_disk_size(clog_statvfs,
|
||||
suggested_log_disk_size,
|
||||
suggested_log_disk_percentage,
|
||||
clog_default_disk_percentage,
|
||||
clog_dir,
|
||||
log_disk_size,
|
||||
log_disk_percentage))) {
|
||||
LOG_ERROR("decide clog disk size failed",
|
||||
KR(ret), K(clog_dir), K(suggested_data_disk_size), K(suggested_data_disk_percentage),
|
||||
K(clog_default_disk_percentage), K(shared_mode));
|
||||
}
|
||||
}
|
||||
|
||||
if (OB_FAIL(ret)) {
|
||||
LOG_ERROR("decide_all_disk_size failed",
|
||||
KR(ret), K(data_dir), K(clog_dir),
|
||||
K(suggested_data_disk_size), K(suggested_data_disk_percentage),
|
||||
K(data_default_disk_percentage), K(clog_default_disk_percentage),
|
||||
K(shared_mode), K(data_disk_size), K(log_disk_size));
|
||||
if (OB_FAIL(get_data_disk_info_in_config(data_disk_size, data_disk_percentage))) {
|
||||
LOG_ERROR("get_data_disk_info_in_config failed", K(data_disk_size), K(data_disk_percentage));
|
||||
} else if (OB_FAIL(get_log_disk_info_in_config(log_disk_size, log_disk_percentage))) {
|
||||
LOG_ERROR("get_log_disk_info_in_config failed", K(log_disk_size), K(log_disk_percentage));
|
||||
} else {
|
||||
LOG_INFO("decide_all_disk_size succ",
|
||||
K(data_dir), K(clog_dir),
|
||||
K(suggested_data_disk_size), K(suggested_data_disk_percentage),
|
||||
K(data_default_disk_percentage), K(clog_default_disk_percentage),
|
||||
K(shared_mode), K(data_disk_size), K(log_disk_size));
|
||||
LOG_INFO("cal_all_part_disk_size success", K(suggested_data_disk_size), K(suggested_clog_disk_size),
|
||||
K(suggested_data_disk_percentage), K(suggested_clog_disk_percentage), K(data_disk_size),
|
||||
K(log_disk_size), K(data_disk_percentage), K(log_disk_percentage));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObServerUtils::decide_disk_size(const struct statvfs& svfs,
|
||||
const int64_t suggested_disk_size,
|
||||
const int64_t suggested_disk_percentage,
|
||||
const int64_t default_disk_percentage,
|
||||
const char* dir,
|
||||
int64_t& disk_size,
|
||||
int64_t& disk_percentage)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
||||
int64_t total_space = (svfs.f_blocks + svfs.f_bavail - svfs.f_bfree) * svfs.f_bsize;
|
||||
int64_t free_space = svfs.f_bavail * svfs.f_bsize;
|
||||
|
||||
if (suggested_disk_size <= 0) {
|
||||
int64_t disk_percentage = 0;
|
||||
if (suggested_disk_percentage <= 0) {
|
||||
disk_percentage = default_disk_percentage;
|
||||
} else {
|
||||
disk_percentage = suggested_disk_percentage;
|
||||
}
|
||||
disk_size = total_space * disk_percentage / 100;
|
||||
} else {
|
||||
disk_size = suggested_disk_size;
|
||||
}
|
||||
|
||||
if (disk_size > total_space) {
|
||||
ret = OB_SERVER_OUTOF_DISK_SPACE;
|
||||
}
|
||||
LOG_INFO("decide disk size finished",
|
||||
K(dir),
|
||||
K(suggested_disk_size), K(suggested_disk_percentage),
|
||||
K(default_disk_percentage),
|
||||
K(total_space), K(free_space), K(disk_size));
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -327,6 +271,91 @@ int ObServerUtils::calc_auto_extend_size(int64_t &actual_extend_size)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObServerUtils::cal_all_part_disk_default_percentage(int64_t& data_disk_total_size,
|
||||
int64_t& data_disk_default_percentage,
|
||||
int64_t& clog_disk_total_size,
|
||||
int64_t& clog_disk_default_percentage,
|
||||
bool &shared_mode)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
||||
// background information about default disk percentage:
|
||||
// If not in shared mode, disk will be used up to 90%.
|
||||
// If in shared mode, data and clog disk usage will be up to 60% and 30%
|
||||
const int64_t DEFAULT_DISK_PERCENTAGE_IN_SEPRATE_MODE = 90;
|
||||
const int64_t DEFAULT_DATA_DISK_PERCENTAGE_IN_SHARED_MODE = 60;
|
||||
const int64_t DEFAULT_CLOG_DISK_PERCENTAGE_IN_SHARED_MODE = 30;
|
||||
|
||||
// We use sstable_dir as the data disk directory to identify whether the log and data are located
|
||||
// on the same file system, and the storage module will ensure that sstable_dir and slog_dir are
|
||||
// located on the same file system;
|
||||
const char* data_dir = OB_FILE_SYSTEM_ROUTER.get_sstable_dir();
|
||||
const char* clog_dir = OB_FILE_SYSTEM_ROUTER.get_clog_dir();
|
||||
|
||||
struct statvfs data_statvfs;
|
||||
struct statvfs clog_statvfs;
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_UNLIKELY(0 != statvfs(data_dir, &data_statvfs))) {
|
||||
LOG_ERROR("Failed to get data disk space ", KR(ret), K(data_dir), K(errno));
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
} else if (OB_UNLIKELY(0 != statvfs(clog_dir, &clog_statvfs))) {
|
||||
LOG_ERROR("Failed to get clog disk space ", KR(ret), K(clog_dir), K(errno));
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
}
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret)) {
|
||||
if (data_statvfs.f_fsid == clog_statvfs.f_fsid) {
|
||||
shared_mode = true;
|
||||
data_disk_default_percentage = DEFAULT_DATA_DISK_PERCENTAGE_IN_SHARED_MODE;
|
||||
clog_disk_default_percentage = DEFAULT_CLOG_DISK_PERCENTAGE_IN_SHARED_MODE;
|
||||
} else {
|
||||
shared_mode = false;
|
||||
data_disk_default_percentage = DEFAULT_DISK_PERCENTAGE_IN_SEPRATE_MODE;
|
||||
clog_disk_default_percentage = DEFAULT_DISK_PERCENTAGE_IN_SEPRATE_MODE;
|
||||
}
|
||||
data_disk_total_size = (data_statvfs.f_blocks + data_statvfs.f_bavail - data_statvfs.f_bfree) * data_statvfs.f_bsize;
|
||||
clog_disk_total_size = (clog_statvfs.f_blocks + clog_statvfs.f_bavail - clog_statvfs.f_bfree) * clog_statvfs.f_bsize;
|
||||
LOG_INFO("cal_all_part_disk_default_percentage succ",
|
||||
K(data_dir), K(clog_dir),
|
||||
K(shared_mode), K(data_disk_total_size), K(data_disk_default_percentage),
|
||||
K(clog_disk_total_size), K(clog_disk_default_percentage));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObServerUtils::decide_disk_size(const int64_t total_space,
|
||||
const int64_t suggested_disk_size,
|
||||
const int64_t suggested_disk_percentage,
|
||||
const int64_t default_disk_percentage,
|
||||
int64_t& disk_size,
|
||||
int64_t& disk_percentage)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
||||
if (suggested_disk_size <= 0) {
|
||||
int64_t disk_percentage = 0;
|
||||
if (suggested_disk_percentage <= 0) {
|
||||
disk_percentage = default_disk_percentage;
|
||||
} else {
|
||||
disk_percentage = suggested_disk_percentage;
|
||||
}
|
||||
disk_size = total_space * disk_percentage / 100;
|
||||
} else {
|
||||
disk_size = suggested_disk_size;
|
||||
}
|
||||
|
||||
if (disk_size > total_space) {
|
||||
ret = OB_SERVER_OUTOF_DISK_SPACE;
|
||||
}
|
||||
LOG_INFO("decide disk size finished",
|
||||
K(suggested_disk_size), K(suggested_disk_percentage),
|
||||
K(default_disk_percentage),
|
||||
K(total_space), K(disk_size));
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace observer
|
||||
} // namespace oceanbase
|
||||
|
||||
|
||||
@ -71,6 +71,17 @@ private:
|
||||
const char* dir,
|
||||
int64_t& disk_size,
|
||||
int64_t& disk_percentage);
|
||||
static int decide_disk_size(const int64_t disk_total_size,
|
||||
const int64_t suggested_disk_size,
|
||||
const int64_t suggested_disk_percentage,
|
||||
const int64_t default_disk_percentage,
|
||||
int64_t& disk_size,
|
||||
int64_t& disk_percentage);
|
||||
static int cal_all_part_disk_default_percentage(int64_t &data_disk_total_size,
|
||||
int64_t& data_disk_percentage,
|
||||
int64_t &log_disk_total_size,
|
||||
int64_t& log_disk_percentage,
|
||||
bool &shared_mode);
|
||||
DISALLOW_COPY_AND_ASSIGN(ObServerUtils);
|
||||
};
|
||||
} // namespace observer
|
||||
|
||||
@ -1019,8 +1019,8 @@ int ObMultiTenant::update_tenant_unit_no_lock(const ObUnitInfoGetter::ObTenantCo
|
||||
} else if (OB_FAIL(update_tenant_memory(tenant_id, unit.config_.memory_size(), allowed_mem_limit))) {
|
||||
LOG_WARN("fail to update tenant memory", K(ret), K(tenant_id));
|
||||
} else if (OB_FAIL(update_tenant_log_disk_size(tenant_id,
|
||||
unit.config_.log_disk_size(),
|
||||
old_unit.config_.log_disk_size(),
|
||||
unit.config_.log_disk_size(),
|
||||
allowed_new_log_disk_size))) {
|
||||
LOG_WARN("fail to update tenant log disk size", K(ret), K(tenant_id));
|
||||
} else if (OB_FAIL(construct_allowed_unit_config(allowed_new_log_disk_size,
|
||||
@ -1154,104 +1154,23 @@ int ObMultiTenant::update_tenant_memory(const uint64_t tenant_id, const int64_t
|
||||
}
|
||||
|
||||
int ObMultiTenant::update_tenant_log_disk_size(const uint64_t tenant_id,
|
||||
const int64_t expected_log_disk_size,
|
||||
const int64_t old_log_disk_size,
|
||||
const int64_t new_log_disk_size,
|
||||
int64_t &allowed_new_log_disk_size)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int64_t used_log_disk_size = 0, palf_log_disk_size = 0;
|
||||
bool can_update_log_disk_size_with_expected_log_disk = false;
|
||||
// 'expected_log_disk_size' is the latest log disk size record in __all_unit_config.
|
||||
// 'old_log_disk_size' is current log disk size in ObTenant.
|
||||
// 'allowed_new_log_disk_size' is current allowed log disk size when update log disk.
|
||||
//
|
||||
// To avoid overselling, we can not use 'expected_log_disk_size' to update unit config which will save in slog.
|
||||
// therefore, we need constuct a virtual log disk size which named with 'allowed_new_log_disk_size'.
|
||||
MAKE_TENANT_SWITCH_SCOPE_GUARD(guard);
|
||||
if (OB_SUCC(guard.switch_to(tenant_id))) {
|
||||
ObLogService *log_service = MTL(ObLogService *);
|
||||
if (OB_ISNULL(log_service)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
} else if (OB_FAIL(log_service->get_palf_stable_disk_usage(used_log_disk_size, palf_log_disk_size))) {
|
||||
LOG_WARN("fail to get_palf_stable_disk_usage", K(tenant_id), K(old_log_disk_size), K(expected_log_disk_size));
|
||||
// The standard for determing whether it's in shrinking or expanding status:
|
||||
// 1. If 'palf_log_disk_size' is smaller than or equal to 'expected_log_disk_size', it's in expanding status.
|
||||
// 2. If 'palf_log_disk_size' is greater than 'expected_log_disk_size', it's in shrinking status.
|
||||
//
|
||||
// For shrinking log disk, we don't update ObTenantConfig of ObTenant to new ObTenantConfig until shrinking successfully.
|
||||
//
|
||||
// NB: All fields of new ObTenantConfig except log_disk_size has been updated in case of shrinking log disk.
|
||||
//
|
||||
// For example:
|
||||
// 1. before shrinkg log disk successfully, and then expand log disk.
|
||||
// - At T1 timestamp, the original log disk is 100G, and update it to 50G, we will construct 'new_unit' with
|
||||
// 100G, but update palf with 50G because original log disk size is greater than new log disk size.
|
||||
// - At T2 timestamp, the log disk size in current ObTenantConfig is 100G, and we update it to 80G, there are
|
||||
// two scenarios:
|
||||
// 1. if 'palf_log_disk_size' which get from palf is 100G, we think palf is still in shrinking status. and we will
|
||||
// construct 'new_unit' with 100G because 'palf_log_disk_size' is greater than new log disk size(80G). but udpate
|
||||
// palf with 80G
|
||||
// 2. if 'palf_log_disk_size' which get from palf is 50G, we think palf has been in normal status. and we will
|
||||
// construct 'new_unit' with 80G because 'palf_log_disk_size' is smaller than new log disk size(80G), but udpate
|
||||
// palf with 80G.
|
||||
} else if (FALSE_IT(can_update_log_disk_size_with_expected_log_disk = (expected_log_disk_size >= palf_log_disk_size))) {
|
||||
// For expanding log disk, we can update 'allowed_new_log_disk_size' to 'expected_log_disk_size' directlly.
|
||||
} else if (can_update_log_disk_size_with_expected_log_disk && FALSE_IT(allowed_new_log_disk_size = expected_log_disk_size)) {
|
||||
// For shrinking log disk, we still update log disk size of 'new_unit' to 'old_log_disk_size'.
|
||||
} else if (!can_update_log_disk_size_with_expected_log_disk && FALSE_IT(allowed_new_log_disk_size = old_log_disk_size)) {
|
||||
// case 1: for shrinking log disk, shrinking log disk from 100G to 50G.
|
||||
// - At T1 timestamp, 'expected_log_disk_size' is 50G, 'old_log_disk_size' is 100G, 'allowed_new_log_disk_size' is 100G.
|
||||
// the log disk size record in slog is 100G, and we will update log disk size used for palf to 50G, but not update log
|
||||
// disk which has assigned in ObServerLogBlockMGR.
|
||||
// - At T2 timestamp, 'expected_log_disk_size' is still 50G, 'old_log_disk_size' is still 100G, however, 'allowed_new_log_disk_size'
|
||||
// is 50G because of shrinking log disk has been successfully, the log disk record in slog is 50G, and then we will update log disk
|
||||
// size used for palf to 50G again but has no effect, log disk assigned in ObServerLogBlockMGR update to 50G(assume there is only one tenant).
|
||||
//
|
||||
// case 2: for expanding log disk, expanding log disk from 100G to 150G.
|
||||
// - At T1 timestamp, 'expected_log_disk_size' is 150G, 'old_log_disk_size' is 100G, 'allowed_new_log_disk_size' is 150G.
|
||||
// the log disk size record in slog is 150G, and then, we will update log disk size used for palf to 150G, the log disk
|
||||
// which has assigned in ObServerLogBlockMGR updaet to 150G(assume there is only one tenant).
|
||||
//
|
||||
// case 3: for shrinking log disk, shrinking log disk from 100G to 50G, and then shrinking log disk from 50G to 25G.
|
||||
// - At T1 timestamp, 'expected_log_disk_size' is 50G, 'old_log_disk_size' is 100G, 'allowed_new_log_disk_size' is 100G.
|
||||
// the log disk size record in slog is 100G, and we will update log disk size used for palf to 50G, but not update log
|
||||
// disk which has assigned in ObServerLogBlockMGR.
|
||||
// - At T2 timestamp, 'expected_log_disk_size' is 25G, 'old_log_disk_size' is still 100G, however, there are two possibility value for
|
||||
// 'allowed_new_log_disk_size':
|
||||
// 1. the value is 100G because of last shrinking log disk has not been successfully, the log disk record in slog is still 100G
|
||||
// and then we will update log disk size used for palf to 25G, but not update log disk assigned in ObServerLogBlockMGR.
|
||||
// At T3 timestamp, 'expected_log_disk_size' is 25G, 'old_log_disk_size' is 100G, 'allowed_new_log_disk_size' is 25G,
|
||||
// the log disk record in slog is 25G, the log disk assigned in ObServerLogBlockMGR is 25G.
|
||||
// 2. the value is 50G because of last shrinking log disk has been successfully, the log disk record in slog is 50G
|
||||
// and then we will update log disk size used for palf to 25G, update log disk assigned in ObServerLogBlockMGR to 50G(assume there is only one tenant).
|
||||
// At T3 timestamp, 'expected_log_disk_size' is 25G, 'old_log_disk_size' is 100G, 'allowed_new_log_disk_size' is 25G,
|
||||
// the log disk record in slog is 25G, the log disk assigned in ObServerLogBlockMGR is 25G.
|
||||
//
|
||||
// case 4: for shrinking log disk, shrinking log disk from 100G to 50G, and then expanding log disk from 50G to 80G.
|
||||
// - At T1 timestamp, 'expected_log_disk_size' is 50G, 'old_log_disk_size' is 100G, 'allowed_new_log_disk_size' is 100G.
|
||||
// the log disk size record in slog is 100G, and we will update log disk size used for palf to 50G, but not update log
|
||||
// disk which has assigned in ObServerLogBlockMGR.
|
||||
// - At T2 timestamp, 'expected_log_disk_size' is 80G, 'old_log_disk_size' is still 100G, however, there are two possibility value for
|
||||
// 'allowed_new_log_disk_size':
|
||||
// 1. the value is 100G because of last shrinking log disk has not been successfully, the log disk record in slog is still 100G
|
||||
// and then we will update log disk size used for palf to 80G, but not update log disk assigned in ObServerLogBlockMGR.
|
||||
// At T3 timestamp, 'expected_log_disk_size' is 80G, 'old_log_disk_size' is 100G, 'allowed_new_log_disk_size' is 80G,
|
||||
// the log disk record in slog is 80G, the log disk assigned in ObServerLogBlockMGR is 80G.
|
||||
// 2. the value is 80G because of last shrinking log disk has been successfully, the log disk record in slog is 80G
|
||||
// and then we will update log disk size used for palf to 80G, update log disk assigned in ObServerLogBlockMGR to 80G(assume there is only one tenant).
|
||||
// At T3 timestamp, 'expected_log_disk_size' is 25G, 'old_log_disk_size' is 100G, 'allowed_new_log_disk_size' is 25G,
|
||||
// the log disk record in slog is 25G, the log disk assigned in ObServerLogBlockMGR is 25G.
|
||||
//
|
||||
} else if (OB_FAIL(GCTX.log_block_mgr_->update_tenant(old_log_disk_size, allowed_new_log_disk_size))) {
|
||||
LOG_WARN("failed to update teannt int ObServerLogBlockMGR", K(ret), K(tenant_id), K(expected_log_disk_size),
|
||||
K(old_log_disk_size), K(allowed_new_log_disk_size));
|
||||
} else if (OB_FAIL(log_service->update_log_disk_usage_limit_size(expected_log_disk_size))) {
|
||||
LOG_WARN("failed to update_log_disk_usage_limit_size", K(ret), K(tenant_id), K(expected_log_disk_size),
|
||||
K(old_log_disk_size), K(allowed_new_log_disk_size));
|
||||
GCTX.log_block_mgr_->abort_update_tenant(allowed_new_log_disk_size, old_log_disk_size);
|
||||
} else if (OB_FAIL(GCTX.log_block_mgr_->update_tenant(old_log_disk_size, new_log_disk_size,
|
||||
allowed_new_log_disk_size, log_service))) {
|
||||
LOG_WARN("fail to update_tenant", K(tenant_id), K(old_log_disk_size), K(new_log_disk_size),
|
||||
K(allowed_new_log_disk_size));
|
||||
} else {
|
||||
LOG_INFO("update_log_disk_usage_limit_size success", K(ret), K(tenant_id), K(expected_log_disk_size),
|
||||
K(old_log_disk_size), K(allowed_new_log_disk_size));
|
||||
LOG_INFO("update_tenant_log_disk_size success", K(tenant_id), K(old_log_disk_size),
|
||||
K(new_log_disk_size), K(allowed_new_log_disk_size));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
||||
@ -112,8 +112,8 @@ public:
|
||||
int update_tenant_memory(const uint64_t tenant_id, const int64_t mem_limit, int64_t &allowed_mem_limit);
|
||||
int update_tenant_memory(const share::ObUnitInfoGetter::ObTenantConfig &unit);
|
||||
int update_tenant_log_disk_size(const uint64_t tenant_id,
|
||||
const int64_t expected_log_disk_size,
|
||||
const int64_t old_log_disk_size,
|
||||
const int64_t new_log_disk_size,
|
||||
int64_t &allowed_log_disk_size);
|
||||
int modify_tenant_io(const uint64_t tenant_id, const share::ObUnitConfig &unit_config);
|
||||
int update_tenant_config(uint64_t tenant_id);
|
||||
|
||||
@ -16,12 +16,14 @@
|
||||
#include "observer/omt/ob_multi_tenant.h"
|
||||
#include "observer/omt/ob_tenant.h"
|
||||
#include "share/ob_unit_getter.h"
|
||||
#include "logservice/ob_log_service.h"
|
||||
|
||||
using namespace oceanbase;
|
||||
using namespace oceanbase::common;
|
||||
using namespace oceanbase::storage;
|
||||
using namespace oceanbase::observer;
|
||||
using namespace oceanbase::omt;
|
||||
using namespace logservice;
|
||||
|
||||
ObAllVirtualUnit::ObAllVirtualUnit()
|
||||
: ObVirtualTableScannerIterator(),
|
||||
@ -244,9 +246,9 @@ int ObAllVirtualUnit::inner_get_next_row(ObNewRow *&row)
|
||||
break;
|
||||
case LOG_DISK_IN_USE: {
|
||||
int64_t clog_disk_in_use = 0;
|
||||
if (OB_FAIL(static_cast<ObDiskUsageReportTask*>(GCTX.disk_reporter_)
|
||||
->get_clog_disk_used_size(tenant_meta.unit_.tenant_id_, clog_disk_in_use))) {
|
||||
SERVER_LOG(WARN, "fail to get data disk in use", K(ret), K(tenant_meta));
|
||||
const uint64_t tenant_id = tenant_meta.unit_.tenant_id_;
|
||||
if (OB_FAIL(get_clog_disk_used_size_(tenant_id, clog_disk_in_use))) {
|
||||
SERVER_LOG(WARN, "fail to get clog disk in use", K(ret), K(tenant_meta));
|
||||
} else {
|
||||
cur_row_.cells_[i].set_int(clog_disk_in_use);
|
||||
}
|
||||
@ -284,5 +286,25 @@ int ObAllVirtualUnit::inner_get_next_row(ObNewRow *&row)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObAllVirtualUnit::get_clog_disk_used_size_(const uint64_t tenant_id,
|
||||
int64_t &log_used_size)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
log_used_size = 0;
|
||||
MAKE_TENANT_SWITCH_SCOPE_GUARD(guard);
|
||||
if (OB_SUCC(guard.switch_to(tenant_id))) {
|
||||
ObLogService *log_service = MTL(ObLogService*);
|
||||
int64_t unused_log_disk_total_size = 0;
|
||||
if (OB_ISNULL(log_service)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SERVER_LOG(WARN, "ObLogService is nullptr", KP(log_service), K(tenant_id));
|
||||
} else if (OB_FAIL(log_service->get_palf_stable_disk_usage(log_used_size,
|
||||
unused_log_disk_total_size))) {
|
||||
SERVER_LOG(WARN, "get_palf_stable_disk_usage failed", KP(log_service), K(tenant_id));
|
||||
}
|
||||
}
|
||||
// return OB_SUCCESS whatever.
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -53,7 +53,8 @@ public:
|
||||
virtual int inner_open();
|
||||
virtual void reset();
|
||||
virtual int inner_get_next_row(common::ObNewRow *&row);
|
||||
|
||||
private:
|
||||
int get_clog_disk_used_size_(const uint64_t tenant_id, int64_t &log_used_size);
|
||||
private:
|
||||
char ip_buf_[common::OB_IP_STR_BUFF];
|
||||
common::ObAddr addr_;
|
||||
|
||||
@ -153,10 +153,16 @@ public:
|
||||
ret = OB_ENTRY_NOT_EXIST;
|
||||
} else {
|
||||
int64_t old_size = map_[key];
|
||||
ret = this->log_block_mgr_.update_tenant(old_size, new_size);
|
||||
int64_t tmp_min_log_disk_size_for_all_tenants = this->log_block_mgr_.min_log_disk_size_for_all_tenants_;
|
||||
tmp_min_log_disk_size_for_all_tenants -= old_size;
|
||||
tmp_min_log_disk_size_for_all_tenants += new_size;
|
||||
if (tmp_min_log_disk_size_for_all_tenants > this->log_block_mgr_.get_total_size_guarded_by_lock_()) {
|
||||
ret = OB_MACHINE_RESOURCE_NOT_ENOUGH;
|
||||
}
|
||||
if (OB_SUCCESS != ret) {
|
||||
map_[key] = old_size;
|
||||
} else {
|
||||
this->log_block_mgr_.min_log_disk_size_for_all_tenants_ = tmp_min_log_disk_size_for_all_tenants;
|
||||
map_[key] = new_size;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user