[FEAT MERGE] instant ddl commit

Co-authored-by: hiddenbomb <bwgui203@gmail.com>
Co-authored-by: Charles0429 <xiezhenjiang@gmail.com>
Co-authored-by: rolandqi <qikai456@126.com>
This commit is contained in:
simonjoylet
2023-01-28 20:34:20 +08:00
committed by ob-robot
parent 5dbb8ee1a2
commit 0f14606391
112 changed files with 2988 additions and 1757 deletions

View File

@ -16,11 +16,13 @@
#include "share/scn.h"
#include "share/ob_force_print_log.h"
#include "storage/ddl/ob_ddl_struct.h"
#include "storage/ddl/ob_tablet_ddl_kv.h"
#include "storage/ddl/ob_ddl_merge_task.h"
#include "storage/blocksstable/ob_sstable_sec_meta_iterator.h"
#include "storage/compaction/ob_schedule_dag_func.h"
#include "storage/tx_storage/ob_ls_service.h"
#include "storage/tx_storage/ob_ls_handle.h"
#include "storage/meta_mem/ob_tenant_meta_mem_mgr.h"
using namespace oceanbase::common;
using namespace oceanbase::blocksstable;
@ -29,10 +31,10 @@ using namespace oceanbase::storage;
ObTabletDDLKvMgr::ObTabletDDLKvMgr()
: is_inited_(false), success_start_scn_(SCN::min_scn()), ls_id_(), tablet_id_(), table_key_(), cluster_version_(0),
start_scn_(SCN::min_scn()), max_freeze_scn_(SCN::min_scn()),
table_id_(0), execution_id_(-1), head_(0), tail_(0), lock_(ObLatchIds::TABLET_DDL_KV_MGR_LOCK), ref_cnt_(0)
start_scn_(SCN::min_scn()), commit_scn_(SCN::min_scn()), max_freeze_scn_(SCN::min_scn()),
table_id_(0), execution_id_(-1), head_(0), tail_(0), lock_(ObLatchIds::TABLET_DDL_KV_MGR_LOCK), ref_cnt_(0),
can_schedule_major_compaction_(false)
{
MEMSET(ddl_kvs_, 0, MAX_DDL_KV_CNT_IN_STORAGE * sizeof(ddl_kvs_[0]));
}
ObTabletDDLKvMgr::~ObTabletDDLKvMgr()
@ -53,17 +55,21 @@ void ObTabletDDLKvMgr::destroy()
}
head_ = 0;
tail_ = 0;
MEMSET(ddl_kvs_, 0, sizeof(ddl_kvs_));
for (int64_t i = 0; i < MAX_DDL_KV_CNT_IN_STORAGE; ++i) {
ddl_kv_handles_[i].reset();
}
ls_id_.reset();
tablet_id_.reset();
table_key_.reset();
cluster_version_ = 0;
start_scn_.set_min();
commit_scn_.set_min();
max_freeze_scn_.set_min();
table_id_ = 0;
execution_id_ = -1;
success_start_scn_.set_min();
is_inited_ = false;
can_schedule_major_compaction_ = false;
}
int ObTabletDDLKvMgr::init(const share::ObLSID &ls_id, const common::ObTabletID &tablet_id)
@ -148,14 +154,12 @@ int ObTabletDDLKvMgr::ddl_start(const ObITable::TableKey &table_key,
return ret;
}
int ObTabletDDLKvMgr::ddl_prepare(
const SCN &start_scn,
const SCN &prepare_scn,
const uint64_t table_id,
const int64_t ddl_task_id)
int ObTabletDDLKvMgr::ddl_commit(const SCN &start_scn,
const SCN &commit_scn,
const uint64_t table_id,
const int64_t ddl_task_id)
{
int ret = OB_SUCCESS;
ObDDLKVHandle kv_handle;
if (OB_UNLIKELY(!is_inited_)) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret), K(is_inited_));
@ -164,17 +168,27 @@ int ObTabletDDLKvMgr::ddl_prepare(
LOG_WARN("ddl not started", K(ret));
} else if (start_scn < start_scn_) {
ret = OB_TASK_EXPIRED;
LOG_INFO("skip ddl prepare log", K(start_scn), K(*this));
} else if (OB_FAIL(freeze_ddl_kv(prepare_scn))) {
LOG_WARN("freeze ddl kv failed", K(ret), K(prepare_scn));
LOG_INFO("skip ddl commit log", K(start_scn), K(*this));
} else if (OB_FAIL(freeze_ddl_kv(commit_scn))) {
LOG_WARN("freeze ddl kv failed", K(ret), K(commit_scn));
} else {
ret = OB_EAGAIN;
while (OB_EAGAIN == ret) {
if (OB_FAIL(update_ddl_major_sstable())) {
LOG_WARN("update ddl major sstable failed", K(ret));
}
if (OB_EAGAIN == ret) {
usleep(1000L);
}
}
table_id_ = table_id;
ddl_task_id_ = ddl_task_id;
commit_scn_ = commit_scn;
ObDDLTableMergeDagParam param;
param.ls_id_ = ls_id_;
param.tablet_id_ = tablet_id_;
param.rec_scn_ = prepare_scn;
param.rec_scn_ = commit_scn;
param.is_commit_ = true;
param.start_scn_ = start_scn;
param.table_id_ = table_id;
@ -191,12 +205,12 @@ int ObTabletDDLKvMgr::ddl_prepare(
ob_usleep(10L * 1000L);
if (REACH_TIME_INTERVAL(10L * 1000L * 1000L)) {
LOG_INFO("retry schedule ddl commit task",
K(start_scn), K(prepare_scn), K(table_id), K(ddl_task_id), K(*this),
K(start_scn), K(commit_scn), K(table_id), K(ddl_task_id), K(*this),
"wait_elpased_s", (ObTimeUtility::fast_current_time() - start_ts) / 1000000L);
}
}
} else {
LOG_INFO("schedule ddl commit task success", K(start_scn), K(prepare_scn), K(table_id), K(ddl_task_id), K(*this));
LOG_INFO("schedule ddl commit task success", K(start_scn), K(commit_scn), K(table_id), K(ddl_task_id), K(*this));
break;
}
}
@ -204,10 +218,7 @@ int ObTabletDDLKvMgr::ddl_prepare(
return ret;
}
int ObTabletDDLKvMgr::ddl_commit(
const SCN &start_scn,
const SCN &prepare_scn,
const bool is_replay)
int ObTabletDDLKvMgr::schedule_ddl_merge_task(const SCN &start_scn, const SCN &commit_scn, const bool is_replay)
{
int ret = OB_SUCCESS;
ObLSHandle ls_handle;
@ -215,10 +226,10 @@ int ObTabletDDLKvMgr::ddl_commit(
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret), K(is_inited_));
} else if (is_commit_success()) {
FLOG_INFO("ddl commit already succeed", K(start_scn), K(prepare_scn), K(*this));
FLOG_INFO("ddl commit already succeed", K(start_scn), K(commit_scn), K(*this));
} else if (start_scn < start_scn_) {
ret = OB_TASK_EXPIRED;
LOG_INFO("skip ddl commit log", K(start_scn), K(prepare_scn), K(*this));
LOG_INFO("skip ddl commit log", K(start_scn), K(commit_scn), K(*this));
} else if (OB_FAIL(MTL(ObLSService *)->get_ls(ls_id_, ls_handle, ObLSGetMod::DDL_MOD))) {
LOG_WARN("failed to get log stream", K(ret), K(ls_id_));
} else {
@ -226,7 +237,7 @@ int ObTabletDDLKvMgr::ddl_commit(
ObDDLTableMergeDagParam param;
param.ls_id_ = ls_id_;
param.tablet_id_ = tablet_id_;
param.rec_scn_ = prepare_scn;
param.rec_scn_ = commit_scn;
param.is_commit_ = true;
param.start_scn_ = start_scn;
param.table_id_ = table_id_;
@ -248,7 +259,7 @@ int ObTabletDDLKvMgr::ddl_commit(
ret = OB_SUCCESS; // think as succcess for replay
} else {
if (REACH_TIME_INTERVAL(10L * 1000L * 1000L)) {
LOG_INFO("replay ddl commit", K(ret), K(start_scn), K(prepare_scn), K(*this));
LOG_INFO("replay ddl commit", K(ret), K(start_scn), K(commit_scn), K(*this));
}
ret = OB_EAGAIN; // retry by replay service
}
@ -256,17 +267,15 @@ int ObTabletDDLKvMgr::ddl_commit(
return ret;
}
int ObTabletDDLKvMgr::wait_ddl_commit(
const SCN &start_scn,
const SCN &prepare_scn)
int ObTabletDDLKvMgr::wait_ddl_merge_success(const SCN &start_scn, const SCN &commit_scn)
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(!is_inited_)) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret), K(is_inited_));
} else if (OB_UNLIKELY(!start_scn.is_valid_and_not_min() || !prepare_scn.is_valid_and_not_min())) {
} else if (OB_UNLIKELY(!start_scn.is_valid_and_not_min() || !commit_scn.is_valid_and_not_min())) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid argument", K(ret), K(start_scn), K(prepare_scn));
LOG_WARN("invalid argument", K(ret), K(start_scn), K(commit_scn));
} else if (!is_started()) {
ret = OB_STATE_NOT_MATCH;
LOG_WARN("ddl not started", K(ret));
@ -276,18 +285,18 @@ int ObTabletDDLKvMgr::wait_ddl_commit(
} else {
const int64_t wait_start_ts = ObTimeUtility::fast_current_time();
while (OB_SUCC(ret)) {
if (OB_FAIL(ddl_commit(start_scn, prepare_scn, false/*is_replay*/ ))) {
if (OB_FAIL(schedule_ddl_merge_task(start_scn, commit_scn, false/*is_replay*/))) {
if (OB_EAGAIN == ret) {
ob_usleep(10L * 1000L);
ret = OB_SUCCESS; // retry
} else {
LOG_WARN("commit ddl log failed", K(ret), K(start_scn), K(prepare_scn), K(ls_id_), K(tablet_id_));
LOG_WARN("commit ddl log failed", K(ret), K(start_scn), K(commit_scn), K(ls_id_), K(tablet_id_));
}
} else {
break;
}
if (REACH_TIME_INTERVAL(10L * 1000L * 1000L)) {
LOG_INFO("wait build ddl sstable", K(ret), K(ls_id_), K(tablet_id_), K(start_scn_), K(prepare_scn), K(max_freeze_scn_),
LOG_INFO("wait build ddl sstable", K(ret), K(ls_id_), K(tablet_id_), K(start_scn_), K(commit_scn), K(max_freeze_scn_),
"wait_elpased_s", (ObTimeUtility::fast_current_time() - wait_start_ts) / 1000000L);
}
}
@ -295,6 +304,20 @@ int ObTabletDDLKvMgr::wait_ddl_commit(
return ret;
}
int ObTabletDDLKvMgr::get_ddl_major_merge_param(ObDDLTableMergeDagParam &param)
{
int ret = OB_SUCCESS;
param.ls_id_ = ls_id_;
param.tablet_id_ = tablet_id_;
param.rec_scn_ = commit_scn_;
param.is_commit_ = true;
param.start_scn_ = start_scn_;
param.table_id_ = table_id_;
param.execution_id_ = execution_id_;
param.ddl_task_id_ = ddl_task_id_;
return ret;
}
int ObTabletDDLKvMgr::set_commit_success(const SCN &start_scn)
{
int ret = OB_SUCCESS;
@ -329,9 +352,20 @@ int ObTabletDDLKvMgr::set_commit_success(const SCN &start_scn)
bool ObTabletDDLKvMgr::is_commit_success() const
{
TCRLockGuard guard(lock_);
return is_commit_success_unlock();
}
bool ObTabletDDLKvMgr::is_commit_success_unlock() const
{
return success_start_scn_ > SCN::min_scn() && success_start_scn_ == start_scn_;
}
bool ObTabletDDLKvMgr::can_schedule_major_compaction() const
{
TCRLockGuard guard(lock_);
return can_schedule_major_compaction_ && !is_commit_success_unlock();
}
int ObTabletDDLKvMgr::cleanup()
{
int ret = OB_SUCCESS;
@ -354,14 +388,18 @@ void ObTabletDDLKvMgr::cleanup_unlock()
}
head_ = 0;
tail_ = 0;
MEMSET(ddl_kvs_, 0, sizeof(ddl_kvs_));
for (int64_t i = 0; i < MAX_DDL_KV_CNT_IN_STORAGE; ++i) {
ddl_kv_handles_[i].reset();
}
table_key_.reset();
cluster_version_ = 0;
start_scn_.set_min();
commit_scn_.set_min();
max_freeze_scn_.set_min();
table_id_ = 0;
execution_id_ = -1;
success_start_scn_.set_min();
can_schedule_major_compaction_ = false;
}
bool ObTabletDDLKvMgr::is_execution_id_older(const int64_t execution_id)
@ -511,13 +549,16 @@ int ObTabletDDLKvMgr::update_tablet(const SCN &start_scn, const int64_t snapshot
ObVersionRange::MIN_VERSION, // multi_version_start
&tablet_handle.get_obj()->get_storage_schema(),
rebuild_seq);
param.keep_old_ddl_sstable_ = false;
param.ddl_start_scn_ = start_scn;
param.ddl_snapshot_version_ = snapshot_version;
param.ddl_checkpoint_scn_ = ddl_checkpoint_scn;
param.ddl_execution_id_ = execution_id_;
param.ddl_cluster_version_ = cluster_version_;
if (OB_FAIL(ls_handle.get_ls()->update_tablet_table_store(tablet_id_, param, new_tablet_handle))) {
param.ddl_info_.keep_old_ddl_sstable_ = false;
param.ddl_info_.ddl_start_scn_ = start_scn;
param.ddl_info_.ddl_snapshot_version_ = snapshot_version;
param.ddl_info_.ddl_checkpoint_scn_ = ddl_checkpoint_scn;
param.ddl_info_.ddl_execution_id_ = execution_id_;
param.ddl_info_.ddl_cluster_version_ = cluster_version_;
if (OB_FAIL(create_empty_ddl_sstable(table_handle))) {
LOG_WARN("create empty ddl sstable failed", K(ret));
} else if (FALSE_IT(param.table_handle_ = table_handle)) {
} else if (OB_FAIL(ls_handle.get_ls()->update_tablet_table_store(tablet_id_, param, new_tablet_handle))) {
LOG_WARN("failed to update tablet table store", K(ret), K(ls_id_), K(tablet_id_), K(param));
} else {
LOG_INFO("update tablet success", K(ls_id_), K(tablet_id_), K(param), K(start_scn), K(snapshot_version), K(ddl_checkpoint_scn));
@ -526,6 +567,76 @@ int ObTabletDDLKvMgr::update_tablet(const SCN &start_scn, const int64_t snapshot
return ret;
}
int ObTabletDDLKvMgr::create_empty_ddl_sstable(ObTableHandleV2 &table_handle)
{
int ret = OB_SUCCESS;
table_handle.reset();
ObArenaAllocator arena;
ObSSTableIndexBuilder *sstable_index_builder = nullptr;
ObIndexBlockRebuilder *index_block_rebuilder = nullptr;
const ObSSTableIndexBuilder::ObSpaceOptimizationMode mode = ObSSTableIndexBuilder::DISABLE;
ObTabletDDLParam ddl_param;
if (OB_FAIL(get_ddl_param(ddl_param))) {
LOG_WARN("get ddl param failed", K(ret));
} else {
ddl_param.table_key_.table_type_ = ObITable::DDL_DUMP_SSTABLE;
ddl_param.table_key_.scn_range_.start_scn_ = SCN::scn_dec(start_scn_);
ddl_param.table_key_.scn_range_.end_scn_ = start_scn_;
}
if (OB_FAIL(ret)) {
} else if (OB_FAIL(ObTabletDDLUtil::prepare_index_builder(ddl_param, arena, mode, nullptr/*first_ddl_sstable*/,
sstable_index_builder, index_block_rebuilder))) {
LOG_WARN("prepare sstable index builder failed", K(ret), K(ddl_param));
} else if (OB_FAIL(ObTabletDDLUtil::create_ddl_sstable(sstable_index_builder, ddl_param, nullptr/*first_ddl_sstable*/, table_handle))) {
LOG_WARN("create ddl sstable failed", K(ret), K(ddl_param));
}
if (nullptr != index_block_rebuilder) {
index_block_rebuilder->~ObIndexBlockRebuilder();
arena.free(index_block_rebuilder);
index_block_rebuilder = nullptr;
}
if (nullptr != sstable_index_builder) {
sstable_index_builder->~ObSSTableIndexBuilder();
arena.free(sstable_index_builder);
sstable_index_builder = nullptr;
}
return ret;
}
int ObTabletDDLKvMgr::update_ddl_major_sstable()
{
int ret = OB_SUCCESS;
ObLSHandle ls_handle;
ObTabletHandle tablet_handle;
if (OB_UNLIKELY(!is_inited_)) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else if (OB_FAIL(MTL(ObLSService *)->get_ls(ls_id_, ls_handle, ObLSGetMod::DDL_MOD))) {
LOG_WARN("failed to get log stream", K(ret), K(ls_id_));
} else if (OB_FAIL(ObDDLUtil::ddl_get_tablet(ls_handle,
tablet_id_,
tablet_handle,
ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) {
LOG_WARN("get tablet handle failed", K(ret), K(ls_id_), K(tablet_id_));
} else {
{
TCWLockGuard guard(lock_);
can_schedule_major_compaction_ = true;
}
ObTabletHandle new_tablet_handle;
ObUpdateTableStoreParam param(tablet_handle.get_obj()->get_snapshot_version(),
ObVersionRange::MIN_VERSION, // multi_version_start
&tablet_handle.get_obj()->get_storage_schema(),
ls_handle.get_ls()->get_rebuild_seq());
param.ddl_info_.keep_old_ddl_sstable_ = true;
if (OB_FAIL(ls_handle.get_ls()->update_tablet_table_store(tablet_id_, param, new_tablet_handle))) {
LOG_WARN("failed to update tablet table store", K(ret), K(ls_id_), K(tablet_id_), K(param));
}
}
return ret;
}
int ObTabletDDLKvMgr::get_ddl_param(ObTabletDDLParam &ddl_param)
{
int ret = OB_SUCCESS;
@ -547,7 +658,7 @@ int ObTabletDDLKvMgr::get_ddl_param(ObTabletDDLParam &ddl_param)
return ret;
}
int ObTabletDDLKvMgr::get_freezed_ddl_kv(const SCN &freeze_scn, ObDDLKVHandle &kv_handle)
int ObTabletDDLKvMgr::get_freezed_ddl_kv(const SCN &freeze_scn, ObTableHandleV2 &kv_handle)
{
int ret = OB_SUCCESS;
kv_handle.reset();
@ -559,15 +670,14 @@ int ObTabletDDLKvMgr::get_freezed_ddl_kv(const SCN &freeze_scn, ObDDLKVHandle &k
TCRLockGuard guard(lock_);
for (int64_t i = head_; OB_SUCC(ret) && !found && i < tail_; ++i) {
const int64_t idx = get_idx(i);
ObDDLKV *cur_kv = ddl_kvs_[idx];
ObTableHandleV2 &cur_kv_handle = ddl_kv_handles_[idx];
ObDDLKV *cur_kv = static_cast<ObDDLKV *>(cur_kv_handle.get_table());
if (OB_ISNULL(cur_kv)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("ddl kv is null", K(ret), K(ls_id_), K(tablet_id_), KP(cur_kv), K(i), K(head_), K(tail_));
} else if (freeze_scn == cur_kv->get_freeze_scn()) {
found = true;
if (OB_FAIL(kv_handle.set_ddl_kv(cur_kv))) {
LOG_WARN("hold ddl kv failed", K(ret));
}
kv_handle = cur_kv_handle;
}
}
if (OB_SUCC(ret) && !found) {
@ -588,32 +698,32 @@ int64_t ObTabletDDLKvMgr::get_idx(const int64_t pos) const
return pos & (MAX_DDL_KV_CNT_IN_STORAGE - 1);
}
int ObTabletDDLKvMgr::get_active_ddl_kv_impl(ObDDLKVHandle &kv_handle)
int ObTabletDDLKvMgr::get_active_ddl_kv_impl(ObTableHandleV2 &kv_handle)
{
int ret = OB_SUCCESS;
ObDDLKV *kv = nullptr;
kv_handle.reset();
if (get_count() == 0) {
ret = OB_ENTRY_NOT_EXIST;
} else {
kv = ddl_kvs_[get_idx(tail_ - 1)];
ObTableHandleV2 &tail_kv_handle = ddl_kv_handles_[get_idx(tail_ - 1)];
ObDDLKV *kv = static_cast<ObDDLKV *>(tail_kv_handle.get_table());
if (nullptr == kv) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("error unexpected, kv must not be nullptr", K(ret));
} else if (kv->is_freezed()) {
kv = nullptr;
ret = OB_SUCCESS;
} else if (OB_FAIL(kv_handle.set_ddl_kv(kv))) {
LOG_WARN("fail to set ddl kv", K(ret));
} else {
kv_handle = tail_kv_handle;
}
}
return ret;
}
int ObTabletDDLKvMgr::get_or_create_ddl_kv(const SCN &scn, ObDDLKVHandle &kv_handle)
int ObTabletDDLKvMgr::get_or_create_ddl_kv(const SCN &scn, ObTableHandleV2 &kv_handle)
{
int ret = OB_SUCCESS;
kv_handle.reset();
ObDDLKV *kv = nullptr;
if (IS_NOT_INIT) {
ret = OB_NOT_INIT;
LOG_WARN("ObTabletDDLKvMgr is not inited", K(ret));
@ -621,44 +731,35 @@ int ObTabletDDLKvMgr::get_or_create_ddl_kv(const SCN &scn, ObDDLKVHandle &kv_han
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid argument", K(ret), K(scn));
} else {
ObTableHandleV2 tmp_kv_handle;
TCRLockGuard guard(lock_);
try_get_ddl_kv_unlock(scn, kv);
if (nullptr != kv) {
// increase or decrease the reference count must be under the lock
if (OB_FAIL(kv_handle.set_ddl_kv(kv))) {
LOG_WARN("fail to set ddl kv", K(ret));
}
}
try_get_ddl_kv_unlock(scn, kv_handle);
}
if (OB_SUCC(ret) && nullptr == kv) {
if (OB_SUCC(ret) && !kv_handle.is_valid()) {
TCWLockGuard guard(lock_);
try_get_ddl_kv_unlock(scn, kv);
if (nullptr != kv) {
try_get_ddl_kv_unlock(scn, kv_handle);
if (kv_handle.is_valid()) {
// do nothing
} else if (OB_FAIL(alloc_ddl_kv(kv))) {
} else if (OB_FAIL(alloc_ddl_kv(kv_handle))) {
LOG_WARN("create ddl kv failed", K(ret));
}
if (OB_SUCC(ret) && nullptr != kv) {
// increase or decrease the reference count must be under the lock
if (OB_FAIL(kv_handle.set_ddl_kv(kv))) {
LOG_WARN("fail to set ddl kv", K(ret));
}
}
}
return ret;
}
void ObTabletDDLKvMgr::try_get_ddl_kv_unlock(const SCN &scn, ObDDLKV *&kv)
void ObTabletDDLKvMgr::try_get_ddl_kv_unlock(const SCN &scn, ObTableHandleV2 &kv_handle)
{
int ret = OB_SUCCESS;
kv_handle.reset();
if (get_count() > 0) {
for (int64_t i = tail_ - 1; OB_SUCC(ret) && i >= head_ && nullptr == kv; ++i) {
ObDDLKV *tmp_kv = ddl_kvs_[get_idx(i)];
for (int64_t i = tail_ - 1; OB_SUCC(ret) && i >= head_ && !kv_handle.is_valid(); ++i) {
ObTableHandleV2 &tmp_kv_handle = ddl_kv_handles_[get_idx(i)];
ObDDLKV *tmp_kv = static_cast<ObDDLKV *>(tmp_kv_handle.get_table());
if (OB_ISNULL(tmp_kv)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("ddl kv is null", K(ret), K(ls_id_), K(tablet_id_), KP(tmp_kv), K(i), K(head_), K(tail_));
} else if (scn <= tmp_kv->get_freeze_scn()) {
kv = tmp_kv;
kv_handle = tmp_kv_handle;
break;
}
}
@ -668,8 +769,7 @@ void ObTabletDDLKvMgr::try_get_ddl_kv_unlock(const SCN &scn, ObDDLKV *&kv)
int ObTabletDDLKvMgr::freeze_ddl_kv(const SCN &freeze_scn)
{
int ret = OB_SUCCESS;
ObDDLKVHandle kv_handle;
ObDDLKV *kv = nullptr;
ObTableHandleV2 kv_handle;
TCWLockGuard guard(lock_);
if (IS_NOT_INIT) {
ret = OB_NOT_INIT;
@ -678,22 +778,20 @@ int ObTabletDDLKvMgr::freeze_ddl_kv(const SCN &freeze_scn)
// do nothing
} else if (OB_FAIL(get_active_ddl_kv_impl(kv_handle))) {
LOG_WARN("fail to get active ddl kv", K(ret));
} else if (OB_FAIL(kv_handle.get_ddl_kv(kv))) {
if (OB_ENTRY_NOT_EXIST != ret) {
LOG_WARN("fail to get ddl kv", K(ret));
} else {
ret = OB_SUCCESS;
}
}
if (OB_SUCC(ret) && nullptr == kv && freeze_scn > max_freeze_scn_) {
// freeze_scn > 0 only occured when ddl prepare
if (OB_SUCC(ret) && !kv_handle.is_valid() && freeze_scn > max_freeze_scn_) {
// freeze_scn > 0 only occured when ddl commit
// assure there is an alive ddl kv, for waiting pre-logs
if (OB_FAIL(alloc_ddl_kv(kv))) {
if (OB_FAIL(alloc_ddl_kv(kv_handle))) {
LOG_WARN("create ddl kv failed", K(ret));
}
}
if (OB_SUCC(ret) && nullptr != kv) {
if (OB_FAIL(kv->freeze(freeze_scn))) {
if (OB_SUCC(ret) && kv_handle.is_valid()) {
ObDDLKV *kv = static_cast<ObDDLKV *>(kv_handle.get_table());
if (OB_ISNULL(kv)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("ddl kv is null", K(ret), KP(kv), K(kv_handle));
} else if (OB_FAIL(kv->freeze(freeze_scn))) {
if (OB_EAGAIN != ret) {
LOG_WARN("fail to freeze active ddl kv", K(ret));
} else {
@ -718,7 +816,7 @@ int ObTabletDDLKvMgr::release_ddl_kvs(const SCN &end_scn)
} else {
for (int64_t i = head_; OB_SUCC(ret) && i < tail_; ++i) {
const int64_t idx = get_idx(head_);
ObDDLKV *kv = ddl_kvs_[idx];
ObDDLKV *kv = static_cast<ObDDLKV *>(ddl_kv_handles_[idx].get_table());
LOG_INFO("try release ddl kv", K(end_scn), KPC(kv));
#ifdef ERRSIM
if (OB_SUCC(ret)) {
@ -754,7 +852,7 @@ int ObTabletDDLKvMgr::get_ddl_kv_min_scn(SCN &min_scn)
} else {
for (int64_t i = head_; OB_SUCC(ret) && i < tail_; ++i) {
const int64_t idx = get_idx(head_);
ObDDLKV *kv = ddl_kvs_[idx];
ObDDLKV *kv = static_cast<ObDDLKV *>(ddl_kv_handles_[idx].get_table());
if (OB_ISNULL(kv)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("ddl kv is null", K(ret), K(ls_id_), K(tablet_id_), KP(kv), K(i), K(head_), K(tail_));
@ -766,23 +864,23 @@ int ObTabletDDLKvMgr::get_ddl_kv_min_scn(SCN &min_scn)
return ret;
}
int ObTabletDDLKvMgr::get_ddl_kvs(const bool frozen_only, ObDDLKVsHandle &ddl_kvs_handle)
int ObTabletDDLKvMgr::get_ddl_kvs_unlock(const bool frozen_only, ObTablesHandleArray &kv_handle_array)
{
int ret = OB_SUCCESS;
ddl_kvs_handle.reset();
TCRLockGuard guard(lock_);
kv_handle_array.reset();
if (IS_NOT_INIT) {
ret = OB_NOT_INIT;
LOG_WARN("ObTabletDDLKvMgr is not inited", K(ret));
} else {
for (int64_t pos = head_; OB_SUCC(ret) && pos < tail_; ++pos) {
const int64_t idx = get_idx(pos);
ObDDLKV *cur_kv = ddl_kvs_[idx];
ObTableHandleV2 &cur_kv_handle = ddl_kv_handles_[idx];
ObDDLKV *cur_kv = static_cast<ObDDLKV *>(cur_kv_handle.get_table());
if (OB_ISNULL(cur_kv)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("ddl kv is null", K(ret), K(ls_id_), K(tablet_id_), KP(cur_kv), K(pos), K(head_), K(tail_));
} else if (!frozen_only || cur_kv->is_freezed()) {
if (OB_FAIL(ddl_kvs_handle.add_ddl_kv(cur_kv))) {
if (OB_FAIL(kv_handle_array.add_table(cur_kv_handle))) {
LOG_WARN("fail to push back ddl kv", K(ret));
}
}
@ -791,6 +889,36 @@ int ObTabletDDLKvMgr::get_ddl_kvs(const bool frozen_only, ObDDLKVsHandle &ddl_kv
return ret;
}
int ObTabletDDLKvMgr::get_ddl_kvs(const bool frozen_only, ObTablesHandleArray &kv_handle_array)
{
int ret = OB_SUCCESS;
kv_handle_array.reset();
TCRLockGuard guard(lock_);
if (IS_NOT_INIT) {
ret = OB_NOT_INIT;
LOG_WARN("ObTabletDDLKvMgr is not inited", K(ret));
} else if (OB_FAIL(get_ddl_kvs_unlock(frozen_only, kv_handle_array))) {
LOG_WARN("get ddl kv unlock failed", K(ret));
}
return ret;
}
int ObTabletDDLKvMgr::get_ddl_kvs_for_query(ObTablesHandleArray &kv_handle_array)
{
int ret = OB_SUCCESS;
kv_handle_array.reset();
TCRLockGuard guard(lock_);
if (IS_NOT_INIT) {
ret = OB_NOT_INIT;
LOG_WARN("ObTabletDDLKvMgr is not inited", K(ret));
} else if (!can_schedule_major_compaction_) {
// do nothing
} else if (OB_FAIL(get_ddl_kvs_unlock(true/*frozen_only*/, kv_handle_array))) {
LOG_WARN("get ddl kv unlock failed", K(ret));
}
return ret;
}
int ObTabletDDLKvMgr::check_has_effective_ddl_kv(bool &has_ddl_kv)
{
int ret = OB_SUCCESS;
@ -804,10 +932,13 @@ int ObTabletDDLKvMgr::check_has_effective_ddl_kv(bool &has_ddl_kv)
return ret;
}
int ObTabletDDLKvMgr::alloc_ddl_kv(ObDDLKV *&kv)
int ObTabletDDLKvMgr::alloc_ddl_kv(ObTableHandleV2 &kv_handle)
{
int ret = OB_SUCCESS;
kv = nullptr;
kv_handle.reset();
ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr *);
ObTableHandleV2 tmp_kv_handle;
ObDDLKV *kv = nullptr;
if (OB_UNLIKELY(!is_inited_)) {
ret = OB_NOT_INIT;
LOG_WARN("ddl kv manager not init", K(ret));
@ -817,9 +948,11 @@ int ObTabletDDLKvMgr::alloc_ddl_kv(ObDDLKV *&kv)
} else if (get_count() == MAX_DDL_KV_CNT_IN_STORAGE) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("error unexpected, too much ddl kv count", K(ret));
} else if (OB_ISNULL(kv = op_alloc(ObDDLKV))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("fail to allocate memory", K(ret));
} else if (OB_FAIL(t3m->acquire_ddl_kv(tmp_kv_handle))) {
LOG_WARN("acquire ddl kv failed", K(ret));
} else if (OB_ISNULL(kv = static_cast<ObDDLKV *>(tmp_kv_handle.get_table()))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("ddl kv is null", K(ret));
} else if (OB_FAIL(kv->init(ls_id_,
tablet_id_,
start_scn_,
@ -831,14 +964,10 @@ int ObTabletDDLKvMgr::alloc_ddl_kv(ObDDLKV *&kv)
} else {
const int64_t idx = get_idx(tail_);
tail_++;
ddl_kvs_[idx] = kv;
kv->inc_ref();
ddl_kv_handles_[idx] = tmp_kv_handle;
kv_handle = tmp_kv_handle;
FLOG_INFO("succeed to add ddl kv", K(ls_id_), K(tablet_id_), K(head_), K(tail_), "ddl_kv_cnt", get_count(), KP(kv));
}
if (OB_FAIL(ret) && nullptr != kv) {
op_free(kv);
kv = nullptr;
}
return ret;
}
@ -852,14 +981,8 @@ void ObTabletDDLKvMgr::free_ddl_kv(const int64_t idx)
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid argument", K(ret), K(idx));
} else {
ObDDLKV *kv = ddl_kvs_[idx];
ddl_kvs_[idx] = nullptr;
if (nullptr != kv) {
if (0 == kv->dec_ref()) {
op_free(kv);
FLOG_INFO("free ddl kv", K(ls_id_), K(tablet_id_), KP(kv));
}
}
FLOG_INFO("free ddl kv", K(ls_id_), K(tablet_id_), KPC(ddl_kv_handles_[idx].get_table()));
ddl_kv_handles_[idx].reset();
}
}