This is an automated email from the ASF dual-hosted git repository.

morrysnow pushed a commit to branch branch-3.1
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-3.1 by this push:
     new 72eeccf01bc branch-3.1: pick 5 mow lock prs #49716 #49223 #50242 
#50281 #50062 (#52038)
72eeccf01bc is described below

commit 72eeccf01bc0c452be8b4d78fcbec313d85ee80e
Author: meiyi <[email protected]>
AuthorDate: Fri Jun 20 23:45:05 2025 +0800

    branch-3.1: pick 5 mow lock prs #49716 #49223 #50242 #50281 #50062 (#52038)
    
    pick
    #49716
    #49223
    #50242
    #50281
    #50062
    
    ---------
    
    Co-authored-by: huanghaibin <[email protected]>
---
 cloud/src/common/config.h                   |   9 +
 cloud/src/meta-service/keys.cpp             |  20 +-
 cloud/src/meta-service/keys.h               |   1 +
 cloud/src/meta-service/meta_service.cpp     | 341 ++++++++++-
 cloud/src/meta-service/meta_service.h       |  20 +
 cloud/src/meta-service/meta_service_job.cpp | 187 +++---
 cloud/src/recycler/checker.cpp              |  78 +++
 cloud/src/recycler/checker.h                |   2 +
 cloud/test/meta_service_job_test.cpp        | 903 ++++++++++++++++++++++++++++
 cloud/test/recycler_test.cpp                | 124 ++++
 10 files changed, 1590 insertions(+), 95 deletions(-)

diff --git a/cloud/src/common/config.h b/cloud/src/common/config.h
index 84d889a059e..5963adea3aa 100644
--- a/cloud/src/common/config.h
+++ b/cloud/src/common/config.h
@@ -104,6 +104,9 @@ CONF_mInt64(recycle_task_threshold_seconds, "10800"); // 3h
 // **just for TEST**
 CONF_Bool(force_immediate_recycle, "false");
 
+CONF_mBool(enable_mow_compaction_key_check, "false");
+CONF_mInt64(compaction_key_check_expiration_diff_seconds, "600"); // 10min
+
 CONF_String(test_s3_ak, "");
 CONF_String(test_s3_sk, "");
 CONF_String(test_s3_endpoint, "");
@@ -273,6 +276,12 @@ CONF_Bool(enable_check_instance_id, "true");
 
 // Check if ip eq 127.0.0.1, ms/recycler exit
 CONF_Bool(enable_loopback_address_for_ms, "false");
+
+// delete_bitmap_lock version config
+CONF_mString(use_delete_bitmap_lock_version, "v1");
+// FOR DEBUGGING
+CONF_mBool(use_delete_bitmap_lock_random_version, "false");
+
 // Which vaults should be recycled. If empty, recycle all vaults.
 // Comma seprated list: recycler_storage_vault_white_list="aaa,bbb,ccc"
 CONF_Strings(recycler_storage_vault_white_list, "");
diff --git a/cloud/src/meta-service/keys.cpp b/cloud/src/meta-service/keys.cpp
index e089e0a1f0b..b00988b7a77 100644
--- a/cloud/src/meta-service/keys.cpp
+++ b/cloud/src/meta-service/keys.cpp
@@ -33,7 +33,6 @@ static const char* STATS_KEY_PREFIX    = "stats";
 static const char* JOB_KEY_PREFIX      = "job";
 static const char* COPY_KEY_PREFIX     = "copy";
 static const char* VAULT_KEY_PREFIX    = "storage_vault";
-static const char* MOW_KEY_PREFIX      = "mow";
 
 // Infix
 static const char* TXN_KEY_INFIX_LABEL                  = "txn_label";
@@ -137,7 +136,8 @@ static void encode_prefix(const T& t, std::string* key) {
                       || std::is_same_v<T, MetaSchemaPBDictionaryInfo>
                       || std::is_same_v<T, MetaDeleteBitmapInfo>
                       || std::is_same_v<T, MetaDeleteBitmapUpdateLockInfo>
-                      || std::is_same_v<T, MetaPendingDeleteBitmapInfo>) {
+                      || std::is_same_v<T, MetaPendingDeleteBitmapInfo>
+                      || std::is_same_v<T, MowTabletCompactionInfo>) {
         encode_bytes(META_KEY_PREFIX, key);
     } else if constexpr (std::is_same_v<T, PartitionVersionKeyInfo>
                       || std::is_same_v<T, TableVersionKeyInfo>) {
@@ -159,8 +159,6 @@ static void encode_prefix(const T& t, std::string* key) {
         encode_bytes(COPY_KEY_PREFIX, key);
     } else if constexpr (std::is_same_v<T, StorageVaultKeyInfo>) {
         encode_bytes(VAULT_KEY_PREFIX, key);
-    } else if constexpr(std::is_same_v<T, MowTabletCompactionInfo>) {
-        encode_bytes(MOW_KEY_PREFIX, key);
     } else {
         // This branch mean to be unreachable, add an assert(false) here to
         // prevent missing branch match.
@@ -304,6 +302,13 @@ void meta_delete_bitmap_update_lock_key(const 
MetaDeleteBitmapUpdateLockInfo& in
     encode_int64(std::get<2>(in), out);                   // partition_id
 }
 
+void mow_tablet_compaction_key(const MowTabletCompactionInfo& in, std::string* 
out) {
+    encode_prefix(in, out);                                  // 0x01 "meta" 
${instance_id}
+    encode_bytes(META_KEY_INFIX_MOW_TABLET_COMPACTION, out); // 
"mow_tablet_comp"
+    encode_int64(std::get<1>(in), out);                      // table_id
+    encode_int64(std::get<2>(in), out);                      // initiator
+}
+
 void meta_pending_delete_bitmap_key(const MetaPendingDeleteBitmapInfo& in, 
std::string* out) {
     encode_prefix(in, out);                                  // 0x01 "meta" 
${instance_id}
     encode_bytes(META_KEY_INFIX_DELETE_BITMAP_PENDING, out); // 
"delete_bitmap_pending"
@@ -502,13 +507,6 @@ std::string system_meta_service_encryption_key_info_key() {
 // Other keys
 
//==============================================================================
 
-void mow_tablet_compaction_key(const MowTabletCompactionInfo& in, std::string* 
out) {
-    encode_prefix(in, out);                                  // 0x01 "mow" 
${instance_id}
-    encode_bytes(META_KEY_INFIX_MOW_TABLET_COMPACTION, out); // 
"mow_tablet_comp"
-    encode_int64(std::get<1>(in), out);                      // table_id
-    encode_int64(std::get<2>(in), out);                      // initiator
-}
-
 
//==============================================================================
 // Decode keys
 
//==============================================================================
diff --git a/cloud/src/meta-service/keys.h b/cloud/src/meta-service/keys.h
index 9ff51374927..b819d8e2608 100644
--- a/cloud/src/meta-service/keys.h
+++ b/cloud/src/meta-service/keys.h
@@ -45,6 +45,7 @@
 // 0x01 "meta" ${instance_id} "delete_bitmap_pending" ${table_id}              
                  -> PendingDeleteBitmapPB 
 // 0x01 "meta" ${instance_id} "delete_bitmap" ${tablet_id} ${rowset_id} 
${version} ${segment_id} -> roaringbitmap
 // 0x01 "meta" ${instance_id} "tablet_schema_pb_dict" ${index_id}              
                  -> SchemaCloudDictionary
+// 0x01 "meta" ${instance_id} "mow_tablet_comp" ${table_id} ${initiator_id}    
                  -> MowTabletCompactionPB
 //
 // 0x01 "stats" ${instance_id} "tablet" ${table_id} ${index_id} 
${partition_id} ${tablet_id}               -> TabletStatsPB
 // 0x01 "stats" ${instance_id} "tablet" ${table_id} ${index_id} 
${partition_id} ${tablet_id} "data_size"   -> int64
diff --git a/cloud/src/meta-service/meta_service.cpp 
b/cloud/src/meta-service/meta_service.cpp
index a280bc53303..bac1b90dea0 100644
--- a/cloud/src/meta-service/meta_service.cpp
+++ b/cloud/src/meta-service/meta_service.cpp
@@ -1845,10 +1845,11 @@ static bool check_delete_bitmap_lock(MetaServiceCode& 
code, std::string& msg, st
                                      std::unique_ptr<Transaction>& txn, 
std::string& instance_id,
                                      int64_t table_id, int64_t lock_id, 
int64_t lock_initiator,
                                      std::string& lock_key, 
DeleteBitmapUpdateLockPB& lock_info,
-                                     std::string log = "") {
+                                     std::string use_version, std::string log 
= "") {
     std::string lock_val;
     LOG(INFO) << "check_delete_bitmap_lock, table_id=" << table_id << " 
lock_id=" << lock_id
-              << " initiator=" << lock_initiator << " key=" << hex(lock_key) 
<< log;
+              << " initiator=" << lock_initiator << " key=" << hex(lock_key) 
<< log
+              << " use_version=" << use_version;
     auto err = txn->get(lock_key, &lock_val);
     
TEST_SYNC_POINT_CALLBACK("check_delete_bitmap_lock.inject_get_lock_key_err", 
&err);
     if (err == TxnErrorCode::TXN_KEY_NOT_FOUND) {
@@ -1874,7 +1875,7 @@ static bool check_delete_bitmap_lock(MetaServiceCode& 
code, std::string& msg, st
         code = MetaServiceCode::LOCK_EXPIRED;
         return false;
     }
-    if (lock_id == COMPACTION_DELETE_BITMAP_LOCK_ID) {
+    if (use_version == "v2" && lock_id == COMPACTION_DELETE_BITMAP_LOCK_ID) {
         std::string tablet_compaction_key =
                 mow_tablet_compaction_key({instance_id, table_id, 
lock_initiator});
         std::string tablet_compaction_val;
@@ -1910,6 +1911,15 @@ static bool check_delete_bitmap_lock(MetaServiceCode& 
code, std::string& msg, st
     }
     return true;
 }
+static bool use_new_version_random() {
+    std::mt19937 gen {std::random_device {}()};
+    auto p = 0.5;
+    std::bernoulli_distribution inject_fault {p};
+    if (inject_fault(gen)) {
+        return true;
+    }
+    return false;
+}
 
 static bool process_pending_delete_bitmap(MetaServiceCode& code, std::string& 
msg,
                                           std::stringstream& ss, 
std::unique_ptr<Transaction>& txn,
@@ -2052,6 +2062,10 @@ void 
MetaServiceImpl::update_delete_bitmap(google::protobuf::RpcController* cont
                                            const UpdateDeleteBitmapRequest* 
request,
                                            UpdateDeleteBitmapResponse* 
response,
                                            ::google::protobuf::Closure* done) {
+    std::string use_version = config::use_delete_bitmap_lock_version;
+    if (config::use_delete_bitmap_lock_random_version && 
!use_new_version_random()) {
+        use_version = "v1";
+    }
     RPC_PREPROCESS(update_delete_bitmap);
     std::string cloud_unique_id = request->has_cloud_unique_id() ? 
request->cloud_unique_id() : "";
     if (cloud_unique_id.empty()) {
@@ -2088,7 +2102,8 @@ void 
MetaServiceImpl::update_delete_bitmap(google::protobuf::RpcController* cont
         std::string lock_key = 
meta_delete_bitmap_update_lock_key({instance_id, table_id, -1});
         DeleteBitmapUpdateLockPB lock_info;
         if (!check_delete_bitmap_lock(code, msg, ss, txn, instance_id, 
table_id, request->lock_id(),
-                                      request->initiator(), lock_key, 
lock_info, log)) {
+                                      request->initiator(), lock_key, 
lock_info, use_version,
+                                      log)) {
             LOG(WARNING) << "failed to check delete bitmap lock, table_id=" << 
table_id
                          << " request lock_id=" << request->lock_id()
                          << " request initiator=" << request->initiator() << " 
msg " << msg;
@@ -2200,7 +2215,7 @@ void 
MetaServiceImpl::update_delete_bitmap(google::protobuf::RpcController* cont
                 DeleteBitmapUpdateLockPB lock_info;
                 if (!check_delete_bitmap_lock(code, msg, ss, txn, instance_id, 
table_id,
                                               request->lock_id(), 
request->initiator(), lock_key,
-                                              lock_info, log)) {
+                                              lock_info, use_version, log)) {
                     LOG(WARNING) << "failed to check delete bitmap lock, 
table_id=" << table_id
                                  << " request lock_id=" << request->lock_id()
                                  << " request initiator=" << 
request->initiator() << " msg " << msg;
@@ -2473,10 +2488,12 @@ static bool 
put_delete_bitmap_update_lock_key(MetaServiceCode& code, std::string
     return true;
 }
 
-void 
MetaServiceImpl::get_delete_bitmap_update_lock(google::protobuf::RpcController* 
controller,
-                                                    const 
GetDeleteBitmapUpdateLockRequest* request,
-                                                    
GetDeleteBitmapUpdateLockResponse* response,
-                                                    
::google::protobuf::Closure* done) {
+void MetaServiceImpl::get_delete_bitmap_update_lock_v2(
+        google::protobuf::RpcController* controller,
+        const GetDeleteBitmapUpdateLockRequest* request,
+        GetDeleteBitmapUpdateLockResponse* response, 
::google::protobuf::Closure* done) {
+    VLOG_DEBUG << "get delete bitmap update lock in v2 for table=" << 
request->table_id()
+               << ",lock id=" << request->lock_id() << ",initiator=" << 
request->initiator();
     RPC_PREPROCESS(get_delete_bitmap_update_lock);
     std::string cloud_unique_id = request->has_cloud_unique_id() ? 
request->cloud_unique_id() : "";
     if (cloud_unique_id.empty()) {
@@ -2804,7 +2821,7 @@ void 
MetaServiceImpl::get_delete_bitmap_update_lock(google::protobuf::RpcControl
 
     DeleteBitmapUpdateLockPB lock_info_tmp;
     if (!check_delete_bitmap_lock(code, msg, ss, txn, instance_id, table_id, 
request->lock_id(),
-                                  request->initiator(), lock_key, 
lock_info_tmp)) {
+                                  request->initiator(), lock_key, 
lock_info_tmp, "v2")) {
         LOG(WARNING) << "failed to check delete bitmap lock after get tablet 
stats and tablet "
                         "states, table_id="
                      << table_id << " request lock_id=" << request->lock_id()
@@ -2813,10 +2830,200 @@ void 
MetaServiceImpl::get_delete_bitmap_update_lock(google::protobuf::RpcControl
     }
 }
 
-void MetaServiceImpl::remove_delete_bitmap_update_lock(
+void MetaServiceImpl::get_delete_bitmap_update_lock_v1(
+        google::protobuf::RpcController* controller,
+        const GetDeleteBitmapUpdateLockRequest* request,
+        GetDeleteBitmapUpdateLockResponse* response, 
::google::protobuf::Closure* done) {
+    VLOG_DEBUG << "get delete bitmap update lock in v1 for table=" << 
request->table_id()
+               << ",lock id=" << request->lock_id() << ",initiator=" << 
request->initiator();
+    RPC_PREPROCESS(get_delete_bitmap_update_lock);
+    std::string cloud_unique_id = request->has_cloud_unique_id() ? 
request->cloud_unique_id() : "";
+    if (cloud_unique_id.empty()) {
+        code = MetaServiceCode::INVALID_ARGUMENT;
+        msg = "cloud unique id not set";
+        return;
+    }
+    instance_id = get_instance_id(resource_mgr_, cloud_unique_id);
+    if (instance_id.empty()) {
+        code = MetaServiceCode::INVALID_ARGUMENT;
+        msg = "empty instance_id";
+        LOG(INFO) << msg << ", cloud_unique_id=" << cloud_unique_id;
+        return;
+    }
+
+    RPC_RATE_LIMIT(get_delete_bitmap_update_lock)
+    std::unique_ptr<Transaction> txn;
+    TxnErrorCode err = txn_kv_->create_txn(&txn);
+    if (err != TxnErrorCode::TXN_OK) {
+        code = cast_as<ErrCategory::CREATE>(err);
+        msg = "failed to init txn";
+        return;
+    }
+    auto table_id = request->table_id();
+    std::string lock_key = meta_delete_bitmap_update_lock_key({instance_id, 
table_id, -1});
+    std::string lock_val;
+    DeleteBitmapUpdateLockPB lock_info;
+    err = txn->get(lock_key, &lock_val);
+    if (err != TxnErrorCode::TXN_OK && err != TxnErrorCode::TXN_KEY_NOT_FOUND) 
{
+        ss << "failed to get delete bitmap update lock, instance_id=" << 
instance_id
+           << " table_id=" << table_id << " key=" << hex(lock_key) << " err=" 
<< err;
+        msg = ss.str();
+        code = MetaServiceCode::KV_TXN_GET_ERR;
+        return;
+    }
+    using namespace std::chrono;
+    int64_t now = 
duration_cast<seconds>(system_clock::now().time_since_epoch()).count();
+    if (err == TxnErrorCode::TXN_OK) {
+        if (!lock_info.ParseFromString(lock_val)) [[unlikely]] {
+            code = MetaServiceCode::PROTOBUF_PARSE_ERR;
+            msg = "failed to parse DeleteBitmapUpdateLockPB";
+            return;
+        }
+        if (lock_info.expiration() > 0 && lock_info.expiration() < now) {
+            LOG(INFO) << "delete bitmap lock expired, continue to process. 
lock_id="
+                      << lock_info.lock_id() << " table_id=" << table_id << " 
now=" << now;
+            lock_info.clear_initiators();
+        } else if (lock_info.lock_id() != request->lock_id()) {
+            ss << "already be locked. request lock_id=" << request->lock_id()
+               << " locked by lock_id=" << lock_info.lock_id() << " table_id=" 
<< table_id
+               << " now=" << now << " expiration=" << lock_info.expiration();
+            msg = ss.str();
+            code = MetaServiceCode::LOCK_CONFLICT;
+            return;
+        }
+    }
+
+    lock_info.set_lock_id(request->lock_id());
+    lock_info.set_expiration(now + request->expiration());
+    bool found = false;
+    for (auto initiator : lock_info.initiators()) {
+        if (request->initiator() == initiator) {
+            found = true;
+            break;
+        }
+    }
+    if (!found) {
+        lock_info.add_initiators(request->initiator());
+    }
+    lock_info.SerializeToString(&lock_val);
+    if (lock_val.empty()) {
+        code = MetaServiceCode::PROTOBUF_SERIALIZE_ERR;
+        msg = "pb serialization error";
+        return;
+    }
+    txn->put(lock_key, lock_val);
+    LOG(INFO) << "xxx put lock_key=" << hex(lock_key) << " table_id=" << 
table_id
+              << " lock_id=" << request->lock_id() << " initiator=" << 
request->initiator()
+              << " initiators_size=" << lock_info.initiators_size();
+
+    err = txn->commit();
+    if (err != TxnErrorCode::TXN_OK) {
+        code = cast_as<ErrCategory::COMMIT>(err);
+        ss << "failed to get_delete_bitmap_update_lock, err=" << err;
+        msg = ss.str();
+        return;
+    }
+
+    bool require_tablet_stats =
+            request->has_require_compaction_stats() ? 
request->require_compaction_stats() : false;
+    if (!require_tablet_stats) return;
+    // this request is from fe when it commits txn for MOW table, we send the 
compaction stats
+    // along with the GetDeleteBitmapUpdateLockResponse which will be sent to 
BE later to let
+    // BE eliminate unnecessary sync_rowsets() calls if possible
+    // 1. hold the delete bitmap update lock in MS(update lock_info.lock_id to 
current load's txn id)
+    // 2. read tablets' stats
+    // 3. check whether we still hold the delete bitmap update lock
+    // these steps can be done in different fdb txns
+
+    StopWatch read_stats_sw;
+    err = txn_kv_->create_txn(&txn);
+    if (err != TxnErrorCode::TXN_OK) {
+        code = cast_as<ErrCategory::CREATE>(err);
+        msg = "failed to init txn";
+        return;
+    }
+    for (const auto& tablet_idx : request->tablet_indexes()) {
+        // 1. get compaction cnts
+        TabletStatsPB tablet_stat;
+        std::string stats_key =
+                stats_tablet_key({instance_id, tablet_idx.table_id(), 
tablet_idx.index_id(),
+                                  tablet_idx.partition_id(), 
tablet_idx.tablet_id()});
+        std::string stats_val;
+        TxnErrorCode err = txn->get(stats_key, &stats_val);
+        
TEST_SYNC_POINT_CALLBACK("get_delete_bitmap_update_lock.get_compaction_cnts_inject_error",
+                                 &err);
+        if (err == TxnErrorCode::TXN_TOO_OLD) {
+            code = MetaServiceCode::OK;
+            err = txn_kv_->create_txn(&txn);
+            if (err != TxnErrorCode::TXN_OK) {
+                code = cast_as<ErrCategory::CREATE>(err);
+                ss << "failed to init txn when get tablet stats";
+                msg = ss.str();
+                return;
+            }
+            err = txn->get(stats_key, &stats_val);
+        }
+        if (err != TxnErrorCode::TXN_OK) {
+            code = cast_as<ErrCategory::READ>(err);
+            msg = fmt::format("failed to get tablet stats, err={} 
tablet_id={}", err,
+                              tablet_idx.tablet_id());
+            return;
+        }
+        if (!tablet_stat.ParseFromArray(stats_val.data(), stats_val.size())) {
+            code = MetaServiceCode::PROTOBUF_PARSE_ERR;
+            msg = fmt::format("marformed tablet stats value, key={}", 
hex(stats_key));
+            return;
+        }
+        response->add_base_compaction_cnts(tablet_stat.base_compaction_cnt());
+        
response->add_cumulative_compaction_cnts(tablet_stat.cumulative_compaction_cnt());
+        response->add_cumulative_points(tablet_stat.cumulative_point());
+        // 2. get tablet states
+        std::string tablet_meta_key =
+                meta_tablet_key({instance_id, tablet_idx.table_id(), 
tablet_idx.index_id(),
+                                 tablet_idx.partition_id(), 
tablet_idx.tablet_id()});
+        std::string tablet_meta_val;
+        err = txn->get(tablet_meta_key, &tablet_meta_val);
+        if (err != TxnErrorCode::TXN_OK) {
+            ss << "failed to get tablet meta"
+               << (err == TxnErrorCode::TXN_KEY_NOT_FOUND ? " (not found)" : 
"")
+               << " instance_id=" << instance_id << " tablet_id=" << 
tablet_idx.tablet_id()
+               << " key=" << hex(tablet_meta_key) << " err=" << err;
+            msg = ss.str();
+            code = err == TxnErrorCode::TXN_KEY_NOT_FOUND ? 
MetaServiceCode::TABLET_NOT_FOUND
+                                                          : 
cast_as<ErrCategory::READ>(err);
+            return;
+        }
+        doris::TabletMetaCloudPB tablet_meta;
+        if (!tablet_meta.ParseFromString(tablet_meta_val)) {
+            code = MetaServiceCode::PROTOBUF_PARSE_ERR;
+            msg = "malformed tablet meta";
+            return;
+        }
+        response->add_tablet_states(
+                
static_cast<std::underlying_type_t<TabletStatePB>>(tablet_meta.tablet_state()));
+    }
+    read_stats_sw.pause();
+    LOG(INFO) << fmt::format(
+            "tablet_idxes.size()={}, read tablet compaction cnts and tablet 
states cost={} ms",
+            request->tablet_indexes().size(), read_stats_sw.elapsed_us() / 
1000);
+
+    DeleteBitmapUpdateLockPB lock_info_tmp;
+    if (!check_delete_bitmap_lock(code, msg, ss, txn, instance_id, table_id, 
request->lock_id(),
+                                  request->initiator(), lock_key, 
lock_info_tmp, "v1")) {
+        LOG(WARNING) << "failed to check delete bitmap lock after get tablet 
stats and tablet "
+                        "states, table_id="
+                     << table_id << " request lock_id=" << request->lock_id()
+                     << " request initiator=" << request->initiator() << " 
code=" << code
+                     << " msg=" << msg;
+    }
+}
+
+void MetaServiceImpl::remove_delete_bitmap_update_lock_v2(
         google::protobuf::RpcController* controller,
         const RemoveDeleteBitmapUpdateLockRequest* request,
         RemoveDeleteBitmapUpdateLockResponse* response, 
::google::protobuf::Closure* done) {
+    VLOG_DEBUG << "remove delete bitmap update lock in v2 for table=" << 
request->table_id()
+               << ",lock id=" << request->lock_id() << ",initiator=" << 
request->initiator();
     RPC_PREPROCESS(remove_delete_bitmap_update_lock);
     std::string cloud_unique_id = request->has_cloud_unique_id() ? 
request->cloud_unique_id() : "";
     if (cloud_unique_id.empty()) {
@@ -2855,7 +3062,7 @@ void MetaServiceImpl::remove_delete_bitmap_update_lock(
         DeleteBitmapUpdateLockPB lock_info;
         if (!check_delete_bitmap_lock(code, msg, ss, txn, instance_id, 
request->table_id(),
                                       request->lock_id(), 
request->initiator(), lock_key, lock_info,
-                                      ", remove lock")) {
+                                      "v2", ", remove lock")) {
             LOG(WARNING) << "failed to check delete bitmap tablet lock"
                          << " table_id=" << request->table_id()
                          << " tablet_id=" << request->tablet_id()
@@ -2903,6 +3110,116 @@ void MetaServiceImpl::remove_delete_bitmap_update_lock(
     }
 }
 
+void MetaServiceImpl::remove_delete_bitmap_update_lock_v1(
+        google::protobuf::RpcController* controller,
+        const RemoveDeleteBitmapUpdateLockRequest* request,
+        RemoveDeleteBitmapUpdateLockResponse* response, 
::google::protobuf::Closure* done) {
+    VLOG_DEBUG << "remove delete bitmap update lock in v1 for table=" << 
request->table_id()
+               << ",lock id=" << request->lock_id() << ",initiator=" << 
request->initiator();
+    RPC_PREPROCESS(remove_delete_bitmap_update_lock);
+    std::string cloud_unique_id = request->has_cloud_unique_id() ? 
request->cloud_unique_id() : "";
+    if (cloud_unique_id.empty()) {
+        code = MetaServiceCode::INVALID_ARGUMENT;
+        msg = "cloud unique id not set";
+        return;
+    }
+    instance_id = get_instance_id(resource_mgr_, cloud_unique_id);
+    if (instance_id.empty()) {
+        code = MetaServiceCode::INVALID_ARGUMENT;
+        msg = "empty instance_id";
+        LOG(INFO) << msg << ", cloud_unique_id=" << cloud_unique_id;
+        return;
+    }
+    RPC_RATE_LIMIT(remove_delete_bitmap_update_lock)
+    std::unique_ptr<Transaction> txn;
+    TxnErrorCode err = txn_kv_->create_txn(&txn);
+    if (err != TxnErrorCode::TXN_OK) {
+        code = cast_as<ErrCategory::CREATE>(err);
+        msg = "failed to init txn";
+        return;
+    }
+    std::string lock_key =
+            meta_delete_bitmap_update_lock_key({instance_id, 
request->table_id(), -1});
+    std::string lock_val;
+    DeleteBitmapUpdateLockPB lock_info;
+    if (!check_delete_bitmap_lock(code, msg, ss, txn, instance_id, 
request->table_id(),
+                                  request->lock_id(), request->initiator(), 
lock_key, lock_info,
+                                  "v1")) {
+        LOG(WARNING) << "failed to check delete bitmap tablet lock"
+                     << " table_id=" << request->table_id() << " tablet_id=" 
<< request->tablet_id()
+                     << " request lock_id=" << request->lock_id()
+                     << " request initiator=" << request->initiator() << " msg 
" << msg;
+        return;
+    }
+    bool modify_initiators = false;
+    auto initiators = lock_info.mutable_initiators();
+    for (auto iter = initiators->begin(); iter != initiators->end(); iter++) {
+        if (*iter == request->initiator()) {
+            initiators->erase(iter);
+            modify_initiators = true;
+            break;
+        }
+    }
+    if (!modify_initiators) {
+        LOG(INFO) << "initiators don't have initiator=" << request->initiator()
+                  << ",initiators_size=" << lock_info.initiators_size() << 
",just return";
+        return;
+    } else if (initiators->empty()) {
+        LOG(INFO) << "remove delete bitmap lock, table_id=" << 
request->table_id()
+                  << " lock_id=" << request->lock_id() << " key=" << 
hex(lock_key);
+        txn->remove(lock_key);
+    } else {
+        lock_info.SerializeToString(&lock_val);
+        if (lock_val.empty()) {
+            LOG(WARNING) << "failed to seiralize lock_info, table_id=" << 
request->table_id()
+                         << " key=" << hex(lock_key);
+            return;
+        }
+        LOG(INFO) << "remove delete bitmap lock initiator, table_id=" << 
request->table_id()
+                  << ", key=" << hex(lock_key) << " lock_id=" << 
request->lock_id()
+                  << " initiator=" << request->initiator()
+                  << " initiators_size=" << lock_info.initiators_size();
+        txn->put(lock_key, lock_val);
+    }
+    err = txn->commit();
+    if (err != TxnErrorCode::TXN_OK) {
+        code = cast_as<ErrCategory::COMMIT>(err);
+        ss << "failed to remove delete bitmap tablet lock , err=" << err;
+        msg = ss.str();
+        return;
+    }
+}
+
+void 
MetaServiceImpl::get_delete_bitmap_update_lock(google::protobuf::RpcController* 
controller,
+                                                    const 
GetDeleteBitmapUpdateLockRequest* request,
+                                                    
GetDeleteBitmapUpdateLockResponse* response,
+                                                    
::google::protobuf::Closure* done) {
+    std::string use_version = config::use_delete_bitmap_lock_version;
+    if (config::use_delete_bitmap_lock_random_version && 
!use_new_version_random()) {
+        use_version = "v1";
+    }
+    if (use_version == "v2") {
+        get_delete_bitmap_update_lock_v2(controller, request, response, done);
+    } else {
+        get_delete_bitmap_update_lock_v1(controller, request, response, done);
+    }
+}
+
+void MetaServiceImpl::remove_delete_bitmap_update_lock(
+        google::protobuf::RpcController* controller,
+        const RemoveDeleteBitmapUpdateLockRequest* request,
+        RemoveDeleteBitmapUpdateLockResponse* response, 
::google::protobuf::Closure* done) {
+    std::string use_version = config::use_delete_bitmap_lock_version;
+    if (config::use_delete_bitmap_lock_random_version && 
!use_new_version_random()) {
+        use_version = "v1";
+    }
+    if (use_version == "v2") {
+        remove_delete_bitmap_update_lock_v2(controller, request, response, 
done);
+    } else {
+        remove_delete_bitmap_update_lock_v1(controller, request, response, 
done);
+    }
+}
+
 void MetaServiceImpl::remove_delete_bitmap(google::protobuf::RpcController* 
controller,
                                            const RemoveDeleteBitmapRequest* 
request,
                                            RemoveDeleteBitmapResponse* 
response,
diff --git a/cloud/src/meta-service/meta_service.h 
b/cloud/src/meta-service/meta_service.h
index 57f88d51dfe..ae2dc2997ad 100644
--- a/cloud/src/meta-service/meta_service.h
+++ b/cloud/src/meta-service/meta_service.h
@@ -321,6 +321,26 @@ private:
             const AlterInstanceRequest* request,
             std::function<std::pair<MetaServiceCode, 
std::string>(InstanceInfoPB*)> action);
 
+    void get_delete_bitmap_update_lock_v2(google::protobuf::RpcController* 
controller,
+                                          const 
GetDeleteBitmapUpdateLockRequest* request,
+                                          GetDeleteBitmapUpdateLockResponse* 
response,
+                                          ::google::protobuf::Closure* done);
+
+    void get_delete_bitmap_update_lock_v1(google::protobuf::RpcController* 
controller,
+                                          const 
GetDeleteBitmapUpdateLockRequest* request,
+                                          GetDeleteBitmapUpdateLockResponse* 
response,
+                                          ::google::protobuf::Closure* done);
+
+    void remove_delete_bitmap_update_lock_v2(google::protobuf::RpcController* 
controller,
+                                             const 
RemoveDeleteBitmapUpdateLockRequest* request,
+                                             
RemoveDeleteBitmapUpdateLockResponse* response,
+                                             ::google::protobuf::Closure* 
done);
+
+    void remove_delete_bitmap_update_lock_v1(google::protobuf::RpcController* 
controller,
+                                             const 
RemoveDeleteBitmapUpdateLockRequest* request,
+                                             
RemoveDeleteBitmapUpdateLockResponse* response,
+                                             ::google::protobuf::Closure* 
done);
+
     std::shared_ptr<TxnKv> txn_kv_;
     std::shared_ptr<ResourceManager> resource_mgr_;
     std::shared_ptr<RateLimiter> rate_limiter_;
diff --git a/cloud/src/meta-service/meta_service_job.cpp 
b/cloud/src/meta-service/meta_service_job.cpp
index 627479bc19a..f4897b6ed44 100644
--- a/cloud/src/meta-service/meta_service_job.cpp
+++ b/cloud/src/meta-service/meta_service_job.cpp
@@ -476,12 +476,13 @@ void 
MetaServiceImpl::start_tablet_job(::google::protobuf::RpcController* contro
     }
 }
 
-static bool check_and_remove_delete_bitmap_update_lock(MetaServiceCode& code, 
std::string& msg,
-                                                       std::stringstream& ss,
-                                                       
std::unique_ptr<Transaction>& txn,
-                                                       std::string& 
instance_id, int64_t table_id,
-                                                       int64_t tablet_id, 
int64_t lock_id,
-                                                       int64_t lock_initiator) 
{
+static bool check_and_remove_delete_bitmap_update_lock(
+        MetaServiceCode& code, std::string& msg, std::stringstream& ss,
+        std::unique_ptr<Transaction>& txn, std::string& instance_id, int64_t 
table_id,
+        int64_t tablet_id, int64_t lock_id, int64_t lock_initiator, 
std::string use_version) {
+    VLOG_DEBUG << "check_and_remove_delete_bitmap_update_lock table_id=" << 
table_id
+               << " tablet_id=" << tablet_id << " lock_id=" << lock_id
+               << " initiator=" << lock_initiator << " use_version=" << 
use_version;
     std::string lock_key = meta_delete_bitmap_update_lock_key({instance_id, 
table_id, -1});
     std::string lock_val;
     TxnErrorCode err = txn->get(lock_key, &lock_val);
@@ -507,7 +508,7 @@ static bool 
check_and_remove_delete_bitmap_update_lock(MetaServiceCode& code, st
         code = MetaServiceCode::LOCK_EXPIRED;
         return false;
     }
-    if (lock_id == COMPACTION_DELETE_BITMAP_LOCK_ID) {
+    if (use_version == "v2" && lock_id == COMPACTION_DELETE_BITMAP_LOCK_ID) {
         // when upgrade ms, prevent old ms get delete bitmap update lock
         if (lock_info.initiators_size() > 0) {
             ss << "compaction lock has " << lock_info.initiators_size() << " 
initiators";
@@ -579,79 +580,107 @@ static bool 
check_and_remove_delete_bitmap_update_lock(MetaServiceCode& code, st
     return true;
 }
 
+static void remove_delete_bitmap_update_lock_v1(std::unique_ptr<Transaction>& 
txn,
+                                                const std::string& 
instance_id, int64_t table_id,
+                                                int64_t tablet_id, int64_t 
lock_id,
+                                                int64_t lock_initiator) {
+    std::string lock_key = meta_delete_bitmap_update_lock_key({instance_id, 
table_id, -1});
+    std::string lock_val;
+    TxnErrorCode err = txn->get(lock_key, &lock_val);
+    LOG(INFO) << "get remove delete bitmap update lock info, table_id=" << 
table_id
+              << " key=" << hex(lock_key) << " err=" << err;
+    if (err != TxnErrorCode::TXN_OK) {
+        LOG(WARNING) << "failed to get delete bitmap update lock key, 
instance_id=" << instance_id
+                     << " table_id=" << table_id << " key=" << hex(lock_key) 
<< " err=" << err;
+        return;
+    }
+    DeleteBitmapUpdateLockPB lock_info;
+    if (!lock_info.ParseFromString(lock_val)) [[unlikely]] {
+        LOG(WARNING) << "failed to parse DeleteBitmapUpdateLockPB, 
instance_id=" << instance_id
+                     << " table_id=" << table_id << " key=" << hex(lock_key);
+        return;
+    }
+    if (lock_info.lock_id() != lock_id) {
+        return;
+    }
+    bool found = false;
+    auto initiators = lock_info.mutable_initiators();
+    for (auto iter = initiators->begin(); iter != initiators->end(); iter++) {
+        if (*iter == lock_initiator) {
+            initiators->erase(iter);
+            found = true;
+            break;
+        }
+    }
+    if (!found) {
+        INSTANCE_LOG(WARNING) << "failed to find lock_initiator, table_id=" << 
table_id
+                              << " tablet_id=" << tablet_id << " lock_id=" << 
lock_id
+                              << " initiator=" << lock_initiator << " key=" << 
hex(lock_key);
+        return;
+    }
+    if (initiators->empty()) {
+        INSTANCE_LOG(INFO) << "remove delete bitmap lock, table_id=" << 
table_id
+                           << " tablet_id=" << tablet_id << " lock_id=" << 
lock_id
+                           << " initiator=" << lock_initiator << " key=" << 
hex(lock_key);
+        txn->remove(lock_key);
+        return;
+    }
+    lock_info.SerializeToString(&lock_val);
+    if (lock_val.empty()) {
+        INSTANCE_LOG(WARNING) << "failed to seiralize lock_info, table_id=" << 
table_id
+                              << " key=" << hex(lock_key);
+        return;
+    }
+    INSTANCE_LOG(INFO) << "remove delete bitmap lock initiator, table_id=" << 
table_id
+                       << " tablet_id=" << tablet_id << " key=" << 
hex(lock_key)
+                       << " lock_id=" << lock_id << " initiator=" << 
lock_initiator
+                       << " initiators_size=" << lock_info.initiators_size();
+    txn->put(lock_key, lock_val);
+}
+
 static void remove_delete_bitmap_update_lock(std::unique_ptr<Transaction>& txn,
                                              const std::string& instance_id, 
int64_t table_id,
                                              int64_t tablet_id, int64_t 
lock_id,
-                                             int64_t lock_initiator) {
-    if (lock_id == COMPACTION_DELETE_BITMAP_LOCK_ID) {
+                                             int64_t lock_initiator, 
std::string use_version) {
+    VLOG_DEBUG << "remove_delete_bitmap_update_lock table_id=" << table_id
+               << " initiator=" << lock_initiator << " tablet_id=" << tablet_id
+               << " lock_id=" << lock_id << " use_version=" << use_version;
+    if (use_version == "v2" && lock_id == COMPACTION_DELETE_BITMAP_LOCK_ID) {
         std::string tablet_compaction_key =
                 mow_tablet_compaction_key({instance_id, table_id, 
lock_initiator});
         std::string tablet_compaction_val;
         TxnErrorCode err = txn->get(tablet_compaction_key, 
&tablet_compaction_val);
-        if (err != TxnErrorCode::TXN_OK) {
-            LOG(WARNING) << "failed to get tablet compaction key, 
instance_id=" << instance_id
-                         << " table_id=" << table_id << " initiator=" << 
lock_initiator
-                         << " key=" << hex(tablet_compaction_key) << " err=" 
<< err;
+        if (err == TxnErrorCode::TXN_KEY_NOT_FOUND) {
+            remove_delete_bitmap_update_lock_v1(txn, instance_id, table_id, 
tablet_id, lock_id,
+                                                lock_initiator);
+        } else if (err != TxnErrorCode::TXN_OK) {
+            INSTANCE_LOG(WARNING) << "failed to get tablet compaction key, 
instance_id="
+                                  << instance_id << " table_id=" << table_id
+                                  << " initiator=" << lock_initiator
+                                  << " key=" << hex(tablet_compaction_key) << 
" err=" << err;
             return;
+        } else {
+            txn->remove(tablet_compaction_key);
+            INSTANCE_LOG(INFO) << "remove tablet compaction key, table_id=" << 
table_id
+                               << ", key=" << hex(tablet_compaction_key)
+                               << " initiator=" << lock_initiator;
         }
-        txn->remove(tablet_compaction_key);
-        INSTANCE_LOG(INFO) << "remove tablet compaction key, table_id=" << 
table_id
-                           << ", key=" << hex(tablet_compaction_key)
-                           << " initiator=" << lock_initiator;
     } else {
-        std::string lock_key = 
meta_delete_bitmap_update_lock_key({instance_id, table_id, -1});
-        std::string lock_val;
-        TxnErrorCode err = txn->get(lock_key, &lock_val);
-        LOG(INFO) << "get remove delete bitmap update lock info, table_id=" << 
table_id
-                  << " key=" << hex(lock_key) << " err=" << err;
-        if (err != TxnErrorCode::TXN_OK) {
-            LOG(WARNING) << "failed to get delete bitmap update lock key, 
instance_id="
-                         << instance_id << " table_id=" << table_id << " key=" 
<< hex(lock_key)
-                         << " err=" << err;
-            return;
-        }
-        DeleteBitmapUpdateLockPB lock_info;
-        if (!lock_info.ParseFromString(lock_val)) [[unlikely]] {
-            LOG(WARNING) << "failed to parse DeleteBitmapUpdateLockPB, 
instance_id=" << instance_id
-                         << " table_id=" << table_id << " key=" << 
hex(lock_key);
-            return;
-        }
-        if (lock_info.lock_id() != lock_id) {
-            return;
-        }
-        bool found = false;
-        auto initiators = lock_info.mutable_initiators();
-        for (auto iter = initiators->begin(); iter != initiators->end(); 
iter++) {
-            if (*iter == lock_initiator) {
-                initiators->erase(iter);
-                found = true;
-                break;
-            }
-        }
-        if (!found) {
-            return;
-        }
-        if (initiators->empty()) {
-            INSTANCE_LOG(INFO) << "remove delete bitmap lock, table_id=" << 
table_id
-                               << " tablet_id=" << tablet_id << " lock_id=" << 
lock_id
-                               << " initiator=" << lock_initiator << " key=" 
<< hex(lock_key);
-            txn->remove(lock_key);
-            return;
-        }
-        lock_info.SerializeToString(&lock_val);
-        if (lock_val.empty()) {
-            INSTANCE_LOG(WARNING) << "failed to seiralize lock_info, 
table_id=" << table_id
-                                  << " key=" << hex(lock_key);
-            return;
-        }
-        INSTANCE_LOG(INFO) << "remove delete bitmap lock initiator, table_id=" 
<< table_id
-                           << " tablet_id=" << tablet_id << " key=" << 
hex(lock_key)
-                           << " lock_id=" << lock_id << " initiator=" << 
lock_initiator
-                           << " initiators_size=" << 
lock_info.initiators_size();
-        txn->put(lock_key, lock_val);
+        remove_delete_bitmap_update_lock_v1(txn, instance_id, table_id, 
tablet_id, lock_id,
+                                            lock_initiator);
     }
 }
 
+static bool use_new_version_random() {
+    std::mt19937 gen {std::random_device {}()};
+    auto p = 0.5;
+    std::bernoulli_distribution inject_fault {p};
+    if (inject_fault(gen)) {
+        return true;
+    }
+    return false;
+}
+
 void process_compaction_job(MetaServiceCode& code, std::string& msg, 
std::stringstream& ss,
                             std::unique_ptr<Transaction>& txn,
                             const FinishTabletJobRequest* request,
@@ -727,9 +756,13 @@ void process_compaction_job(MetaServiceCode& code, 
std::string& msg, std::string
         INSTANCE_LOG(INFO) << "abort tablet compaction job, tablet_id=" << 
tablet_id
                            << " key=" << hex(job_key);
         if (compaction.has_delete_bitmap_lock_initiator()) {
-            remove_delete_bitmap_update_lock(txn, instance_id, table_id, 
tablet_id,
-                                             COMPACTION_DELETE_BITMAP_LOCK_ID,
-                                             
compaction.delete_bitmap_lock_initiator());
+            std::string use_version = config::use_delete_bitmap_lock_version;
+            if (config::use_delete_bitmap_lock_random_version && 
!use_new_version_random()) {
+                use_version = "v1";
+            }
+            remove_delete_bitmap_update_lock(
+                    txn, instance_id, table_id, tablet_id, 
COMPACTION_DELETE_BITMAP_LOCK_ID,
+                    compaction.delete_bitmap_lock_initiator(), use_version);
         }
         need_commit = true;
         return;
@@ -879,9 +912,14 @@ void process_compaction_job(MetaServiceCode& code, 
std::string& msg, std::string
 
     // remove delete bitmap update lock for MoW table
     if (compaction.has_delete_bitmap_lock_initiator()) {
+        std::string use_version = config::use_delete_bitmap_lock_version;
+        if (config::use_delete_bitmap_lock_random_version && 
!use_new_version_random()) {
+            use_version = "v1";
+        }
         bool success = check_and_remove_delete_bitmap_update_lock(
                 code, msg, ss, txn, instance_id, table_id, tablet_id,
-                COMPACTION_DELETE_BITMAP_LOCK_ID, 
compaction.delete_bitmap_lock_initiator());
+                COMPACTION_DELETE_BITMAP_LOCK_ID, 
compaction.delete_bitmap_lock_initiator(),
+                use_version);
         if (!success) {
             return;
         }
@@ -1378,9 +1416,14 @@ void process_schema_change_job(MetaServiceCode& code, 
std::string& msg, std::str
 
     // process mow table, check lock
     if (new_tablet_meta.enable_unique_key_merge_on_write()) {
+        std::string use_version = config::use_delete_bitmap_lock_version;
+        if (config::use_delete_bitmap_lock_random_version && 
!use_new_version_random()) {
+            use_version = "v1";
+        }
         bool success = check_and_remove_delete_bitmap_update_lock(
                 code, msg, ss, txn, instance_id, new_table_id, new_tablet_id,
-                SCHEMA_CHANGE_DELETE_BITMAP_LOCK_ID, 
schema_change.delete_bitmap_lock_initiator());
+                SCHEMA_CHANGE_DELETE_BITMAP_LOCK_ID, 
schema_change.delete_bitmap_lock_initiator(),
+                use_version);
         if (!success) {
             return;
         }
diff --git a/cloud/src/recycler/checker.cpp b/cloud/src/recycler/checker.cpp
index 60b6b7fc5ee..513d1685b2f 100644
--- a/cloud/src/recycler/checker.cpp
+++ b/cloud/src/recycler/checker.cpp
@@ -193,6 +193,12 @@ int Checker::start() {
                 }
             }
 
+            if (config::enable_mow_compaction_key_check) {
+                if (int ret = checker->do_mow_compaction_key_check(); ret != 
0) {
+                    success = false;
+                }
+            }
+
             // If instance checker has been aborted, don't finish this job
             if (!checker->stopped()) {
                 finish_instance_recycle_job(txn_kv_.get(), check_job_key, 
instance.instance_id(),
@@ -1189,4 +1195,76 @@ int 
InstanceChecker::do_delete_bitmap_storage_optimize_check() {
     return (failed_tablets_num > 0) ? 1 : 0;
 }
 
+int InstanceChecker::do_mow_compaction_key_check() {
+    std::unique_ptr<RangeGetIterator> it;
+    std::string begin = mow_tablet_compaction_key({instance_id_, 0, 0});
+    std::string end = mow_tablet_compaction_key({instance_id_, INT64_MAX, 0});
+    MowTabletCompactionPB mow_tablet_compaction;
+    do {
+        std::unique_ptr<Transaction> txn;
+        TxnErrorCode err = txn_kv_->create_txn(&txn);
+        if (err != TxnErrorCode::TXN_OK) {
+            LOG(WARNING) << "failed to create txn";
+            return -1;
+        }
+        err = txn->get(begin, end, &it);
+        if (err != TxnErrorCode::TXN_OK) {
+            LOG(WARNING) << "failed to get mow tablet compaction key, err=" << 
err;
+            return -1;
+        }
+        int64_t now = duration_cast<std::chrono::seconds>(
+                              
std::chrono::system_clock::now().time_since_epoch())
+                              .count();
+        while (it->has_next() && !stopped()) {
+            auto [k, v] = it->next();
+            std::string_view k1 = k;
+            k1.remove_prefix(1);
+            std::vector<std::tuple<std::variant<int64_t, std::string>, int, 
int>> out;
+            decode_key(&k1, &out);
+            // 0x01 "meta" ${instance_id} "mow_tablet_comp" ${table_id} 
${initiator}
+            auto table_id = std::get<int64_t>(std::get<0>(out[3]));
+            auto initiator = std::get<int64_t>(std::get<0>(out[4]));
+            if (!mow_tablet_compaction.ParseFromArray(v.data(), v.size())) 
[[unlikely]] {
+                LOG(WARNING) << "failed to parse MowTabletCompactionPB";
+                return -1;
+            }
+            int64_t expiration = mow_tablet_compaction.expiration();
+            //check compaction key failed should meet both following two 
condition:
+            //1.compaction key is expired
+            //2.table lock key is not found or key is not expired
+            if (expiration < now - 
config::compaction_key_check_expiration_diff_seconds) {
+                std::string lock_key =
+                        meta_delete_bitmap_update_lock_key({instance_id_, 
table_id, -1});
+                std::string lock_val;
+                err = txn->get(lock_key, &lock_val);
+                std::string reason = "";
+                if (err == TxnErrorCode::TXN_KEY_NOT_FOUND) {
+                    reason = "table lock key not found";
+
+                } else {
+                    DeleteBitmapUpdateLockPB lock_info;
+                    if (!lock_info.ParseFromString(lock_val)) [[unlikely]] {
+                        LOG(WARNING) << "failed to parse 
DeleteBitmapUpdateLockPB";
+                        return -1;
+                    }
+                    if (lock_info.expiration() > now || lock_info.lock_id() != 
-1) {
+                        reason = "table lock is not expired,lock_id=" +
+                                 std::to_string(lock_info.lock_id());
+                    }
+                }
+                if (reason != "") {
+                    LOG(WARNING) << fmt::format(
+                            "[compaction key check fails] compaction key check 
fail for "
+                            "instance_id={}, table_id={}, initiator={}, 
expiration={}, now={}, "
+                            "reason={}",
+                            instance_id_, table_id, initiator, expiration, 
now, reason);
+                    return -1;
+                }
+            }
+        }
+        begin = it->next_begin_key(); // Update to next smallest key for 
iteration
+    } while (it->more() && !stopped());
+    return 0;
+}
+
 } // namespace doris::cloud
diff --git a/cloud/src/recycler/checker.h b/cloud/src/recycler/checker.h
index 7f87e90f7cb..7dd7d06fe6c 100644
--- a/cloud/src/recycler/checker.h
+++ b/cloud/src/recycler/checker.h
@@ -103,6 +103,8 @@ public:
     // which will not be cleared.
     int do_delete_bitmap_storage_optimize_check();
 
+    int do_mow_compaction_key_check();
+
     // If there are multiple buckets, return the minimum lifecycle; if there 
are no buckets (i.e.
     // all accessors are HdfsAccessor), return INT64_MAX.
     // Return 0 if success, otherwise error
diff --git a/cloud/test/meta_service_job_test.cpp 
b/cloud/test/meta_service_job_test.cpp
index 0eb43660c29..048295d8643 100644
--- a/cloud/test/meta_service_job_test.cpp
+++ b/cloud/test/meta_service_job_test.cpp
@@ -1115,6 +1115,909 @@ TEST(MetaServiceJobTest, CompactionJobTest) {
     ASSERT_NO_FATAL_FAILURE(test_abort_compaction_job(1, 2, 3, 7));
 }
 
+TEST(MetaServiceJobTest, DeleteBitmapUpdateLockCompatibilityTest) {
+    auto meta_service = get_meta_service();
+    auto sp = SyncPoint::get_instance();
+    std::unique_ptr<int, std::function<void(int*)>> defer(
+            (int*)0x01, [](int*) { 
SyncPoint::get_instance()->clear_all_call_backs(); });
+    sp->set_call_back("get_instance_id", [&](auto&& args) {
+        auto* ret = try_any_cast_ret<std::string>(args);
+        ret->first = instance_id;
+        ret->second = true;
+    });
+    sp->enable_processing();
+
+    brpc::Controller cntl;
+
+    auto test_start_compaction_job = [&](int64_t table_id, int64_t index_id, 
int64_t partition_id,
+                                         int64_t tablet_id,
+                                         TabletCompactionJobPB::CompactionType 
type,
+                                         std::string job_id = "job_id123") {
+        StartTabletJobResponse res;
+
+        auto index_key = meta_tablet_idx_key({instance_id, tablet_id});
+        TabletIndexPB idx_pb;
+        idx_pb.set_table_id(table_id);
+        idx_pb.set_index_id(index_id);
+        idx_pb.set_partition_id(partition_id);
+        idx_pb.set_tablet_id(tablet_id);
+        std::string idx_val = idx_pb.SerializeAsString();
+        std::unique_ptr<Transaction> txn;
+        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), 
TxnErrorCode::TXN_OK);
+        txn->put(index_key, idx_val);
+        std::string stats_key =
+                stats_tablet_key({instance_id, table_id, index_id, 
partition_id, tablet_id});
+        TabletStatsPB stats;
+        stats.set_base_compaction_cnt(9);
+        stats.set_cumulative_compaction_cnt(19);
+        txn->put(stats_key, stats.SerializeAsString());
+        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
+        start_compaction_job(meta_service.get(), tablet_id, job_id, "ip:port", 
9, 19, type, res);
+        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
+    };
+    FinishTabletJobResponse res;
+    auto test_commit_compaction_job = [&](int64_t table_id, int64_t index_id, 
int64_t partition_id,
+                                          int64_t tablet_id,
+                                          
TabletCompactionJobPB::CompactionType type,
+                                          int64_t initiator = 12345,
+                                          std::string job_id = "job_id123") {
+        FinishTabletJobRequest req;
+
+        auto compaction = req.mutable_job()->add_compaction();
+        compaction->set_id(job_id);
+        compaction->set_initiator("ip:port");
+        compaction->set_base_compaction_cnt(10);
+        compaction->set_cumulative_compaction_cnt(20);
+        compaction->set_delete_bitmap_lock_initiator(initiator);
+        req.mutable_job()->mutable_idx()->set_table_id(table_id);
+        req.mutable_job()->mutable_idx()->set_index_id(index_id);
+        req.mutable_job()->mutable_idx()->set_partition_id(partition_id);
+        req.mutable_job()->mutable_idx()->set_tablet_id(tablet_id);
+        req.set_action(FinishTabletJobRequest::COMMIT);
+        req.set_cloud_unique_id("test_cloud_unique_id");
+
+        auto tablet_meta_key =
+                meta_tablet_key({instance_id, table_id, index_id, 
partition_id, tablet_id});
+        std::unique_ptr<Transaction> txn;
+        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), 
TxnErrorCode::TXN_OK);
+        doris::TabletMetaCloudPB tablet_meta_pb;
+        tablet_meta_pb.set_table_id(table_id);
+        tablet_meta_pb.set_index_id(index_id);
+        tablet_meta_pb.set_partition_id(partition_id);
+        tablet_meta_pb.set_tablet_id(tablet_id);
+        tablet_meta_pb.set_cumulative_layer_point(50);
+        std::string tablet_meta_val = tablet_meta_pb.SerializeAsString();
+        ASSERT_FALSE(tablet_meta_val.empty());
+        txn->put(tablet_meta_key, tablet_meta_val);
+        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
+
+        // Create tablet stats, compaction job will update stats
+        auto tablet_stats_key =
+                stats_tablet_key({instance_id, table_id, index_id, 
partition_id, tablet_id});
+        TabletStatsPB tablet_stats_pb;
+        tablet_stats_pb.mutable_idx()->set_table_id(table_id);
+        tablet_stats_pb.mutable_idx()->set_index_id(index_id);
+        tablet_stats_pb.mutable_idx()->set_partition_id(partition_id);
+        tablet_stats_pb.mutable_idx()->set_tablet_id(tablet_id);
+
+        std::mt19937 
rng(std::chrono::system_clock::now().time_since_epoch().count());
+        std::uniform_int_distribution<int> dist(1, 10000); // Positive numbers
+
+        
compaction->set_output_cumulative_point(tablet_stats_pb.cumulative_point() + 
dist(rng));
+        compaction->set_num_output_rows(dist(rng));
+        compaction->set_num_output_rowsets(dist(rng));
+        compaction->set_num_output_segments(dist(rng));
+        compaction->set_num_input_rows(dist(rng));
+        compaction->set_num_input_rowsets(dist(rng));
+        compaction->set_num_input_segments(dist(rng));
+        compaction->set_size_input_rowsets(dist(rng));
+        compaction->set_size_output_rowsets(dist(rng));
+        compaction->set_type(type);
+
+        tablet_stats_pb.set_cumulative_compaction_cnt(dist(rng));
+        tablet_stats_pb.set_base_compaction_cnt(dist(rng));
+        
tablet_stats_pb.set_cumulative_point(tablet_meta_pb.cumulative_layer_point());
+        // MUST let data stats be larger than input data size
+        tablet_stats_pb.set_num_rows(dist(rng) + compaction->num_input_rows());
+        tablet_stats_pb.set_data_size(dist(rng) + 
compaction->size_input_rowsets());
+        tablet_stats_pb.set_num_rowsets(dist(rng) + 
compaction->num_input_rowsets());
+        tablet_stats_pb.set_num_segments(dist(rng) + 
compaction->num_input_segments());
+        tablet_stats_pb.set_index_size(dist(rng) + 
compaction->index_size_input_rowsets());
+        tablet_stats_pb.set_segment_size(dist(rng) + 
compaction->segment_size_input_rowsets());
+
+        std::string tablet_stats_val = tablet_stats_pb.SerializeAsString();
+        ASSERT_FALSE(tablet_stats_val.empty());
+        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), 
TxnErrorCode::TXN_OK);
+        txn->put(tablet_stats_key, tablet_stats_val);
+        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
+
+        // Provide input and output rowset info
+        int64_t input_version_start = dist(rng);
+        int64_t input_version_end = input_version_start + 100;
+        compaction->add_input_versions(input_version_start);
+        compaction->add_input_versions(input_version_end);
+        compaction->add_output_versions(input_version_end);
+        compaction->add_output_rowset_ids("output rowset id");
+
+        // Provide input rowset KVs, boundary test, 5 input rowsets
+        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), 
TxnErrorCode::TXN_OK);
+        // clang-format off
+        std::vector<std::string> input_rowset_keys = {
+                meta_rowset_key({instance_id, tablet_id, input_version_start - 
1}),
+                meta_rowset_key({instance_id, tablet_id, input_version_start}),
+                meta_rowset_key({instance_id, tablet_id, input_version_start + 
1}),
+                meta_rowset_key({instance_id, tablet_id, (input_version_start 
+ input_version_end) / 2}),
+                meta_rowset_key({instance_id, tablet_id, input_version_end - 
1}),
+                meta_rowset_key({instance_id, tablet_id, input_version_end}),
+                meta_rowset_key({instance_id, tablet_id, input_version_end + 
1}),
+        };
+        // clang-format on
+        std::vector<std::unique_ptr<std::string>> input_rowset_vals;
+        for (auto& i : input_rowset_keys) {
+            doris::RowsetMetaCloudPB rs_pb;
+            rs_pb.set_rowset_id(0);
+            rs_pb.set_rowset_id_v2(hex(i));
+            input_rowset_vals.emplace_back(new 
std::string(rs_pb.SerializeAsString()));
+            txn->put(i, *input_rowset_vals.back());
+        }
+        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
+
+        int64_t txn_id = dist(rng);
+        compaction->add_txn_id(txn_id);
+
+        // Provide output rowset meta
+        auto tmp_rowset_key = meta_rowset_tmp_key({instance_id, txn_id, 
tablet_id});
+        doris::RowsetMetaCloudPB tmp_rs_pb;
+        tmp_rs_pb.set_rowset_id(0);
+        tmp_rs_pb.set_txn_id(10086);
+        auto tmp_rowset_val = tmp_rs_pb.SerializeAsString();
+        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), 
TxnErrorCode::TXN_OK);
+        txn->put(tmp_rowset_key, tmp_rowset_val);
+        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
+
+        
meta_service->finish_tablet_job(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
+                                        &req, &res, nullptr);
+    };
+
+    auto test_abort_compaction_job = [&](int64_t table_id, int64_t index_id, 
int64_t partition_id,
+                                         int64_t tablet_id, int64_t initiator 
= 12345,
+                                         std::string job_id = "job_id123") {
+        FinishTabletJobRequest req;
+        FinishTabletJobResponse res;
+
+        auto compaction = req.mutable_job()->add_compaction();
+        compaction->set_id(job_id);
+        compaction->set_initiator("ip:port");
+        compaction->set_delete_bitmap_lock_initiator(initiator);
+        req.mutable_job()->mutable_idx()->set_tablet_id(tablet_id);
+        req.set_action(FinishTabletJobRequest::ABORT);
+        
meta_service->finish_tablet_job(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
+                                        &req, &res, nullptr);
+
+        std::unique_ptr<Transaction> txn;
+        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), 
TxnErrorCode::TXN_OK);
+        auto job_key = job_tablet_key({instance_id, table_id, index_id, 
partition_id, tablet_id});
+        std::string job_val;
+        ASSERT_EQ(txn->get(job_key, &job_val), TxnErrorCode::TXN_OK);
+        TabletJobInfoPB job_pb;
+        ASSERT_TRUE(job_pb.ParseFromString(job_val));
+        ASSERT_TRUE(job_pb.compaction().empty());
+    };
+
+    auto clear_rowsets = [&](int64_t tablet_id) {
+        std::unique_ptr<Transaction> txn;
+        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), 
TxnErrorCode::TXN_OK);
+        std::string key1 = meta_rowset_key({instance_id, tablet_id, 1});
+        std::string key2 = meta_rowset_key({instance_id, tablet_id, 10001});
+        txn->remove(key1, key2);
+        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
+    };
+
+    config::use_delete_bitmap_lock_random_version = false;
+    int64_t table_id = 111;
+    remove_delete_bitmap_lock(meta_service.get(), table_id);
+
+    // case 1: lock key does not exist, get and remove load lock in new way, 
success
+    config::use_delete_bitmap_lock_version = "v2";
+    auto res_code = get_delete_bitmap_lock(meta_service.get(), table_id, 123, 
-1);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    res_code = remove_delete_bitmap_lock(meta_service.get(), table_id, 123, 
-1);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+
+    // case 2: lock key does not exist, get and remove load lock in old way, 
success
+    config::use_delete_bitmap_lock_version = "v1";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, 123, -1);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    res_code = remove_delete_bitmap_lock(meta_service.get(), table_id, 123, 
-1);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+
+    // case 3: lock key does not exist, get and remove compaction lock in new 
way, success
+    config::use_delete_bitmap_lock_version = "v2";
+    test_start_compaction_job(table_id, 2, 3, 5, TabletCompactionJobPB::BASE);
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 12345);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    res_code = update_delete_bitmap(meta_service.get(), table_id, 3, 5, -1, 
12345);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    test_commit_compaction_job(table_id, 2, 3, 5, TabletCompactionJobPB::BASE);
+    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
+    clear_rowsets(5);
+
+    // case 4: lock key does not exist, get and remove compaction lock in old 
way, success
+    config::use_delete_bitmap_lock_version = "v1";
+    test_start_compaction_job(table_id, 2, 3, 5, TabletCompactionJobPB::BASE);
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 12345);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    res_code = update_delete_bitmap(meta_service.get(), table_id, 3, 5, -1, 
12345);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    test_commit_compaction_job(table_id, 2, 3, 5, TabletCompactionJobPB::BASE);
+    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
+    clear_rowsets(5);
+
+    // case 5:
+    // 5.1 lock key does not exist
+    remove_delete_bitmap_lock(meta_service.get(), table_id);
+    clear_rowsets(table_id);
+    // 5.2 load get lock in new way
+    config::use_delete_bitmap_lock_version = "v2";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, 222, -1);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 5.3 compaction get lock in new way, failed
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 111);
+    ASSERT_EQ(res_code, MetaServiceCode::LOCK_CONFLICT);
+    // 5.4 load remove lock in old way, success
+    config::use_delete_bitmap_lock_version = "v1";
+    res_code = remove_delete_bitmap_lock(meta_service.get(), table_id, 222, 
-1);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+
+    // case 6:
+    // 6.1 lock key does not exist
+    remove_delete_bitmap_lock(meta_service.get(), table_id);
+    clear_rowsets(table_id);
+    // 6.2 load get lock in old way
+    config::use_delete_bitmap_lock_version = "v1";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, 222, -1);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 6.3 compaction get lock in old way, failed
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 111);
+    ASSERT_EQ(res_code, MetaServiceCode::LOCK_CONFLICT);
+    // 6.4 load remove lock in new way, success
+    config::use_delete_bitmap_lock_version = "v2";
+    res_code = remove_delete_bitmap_lock(meta_service.get(), table_id, 222, 
-1);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+
+    // case 7:
+    // 7.1 lock key does not exist
+    remove_delete_bitmap_lock(meta_service.get(), table_id);
+    clear_rowsets(table_id);
+    // 7.2 compaction get lock in new way
+    remove_delete_bitmap_lock(meta_service.get(), table_id);
+    config::use_delete_bitmap_lock_version = "v2";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 777);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 7.3 load get lock in new way
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, 123, -1);
+    ASSERT_EQ(res_code, MetaServiceCode::LOCK_CONFLICT);
+    // 7.4 compaction update delete bitmap in old way failed, abort compaction 
job
+    config::use_delete_bitmap_lock_version = "v1";
+    test_start_compaction_job(table_id, 2, 3, 5, TabletCompactionJobPB::BASE);
+    res_code = update_delete_bitmap(meta_service.get(), table_id, 3, 5, -1, 
777);
+    ASSERT_EQ(res_code, MetaServiceCode::LOCK_EXPIRED);
+    test_abort_compaction_job(table_id, 2, 3, 5, 777);
+    clear_rowsets(5);
+
+    // case 8:
+    // 8.1 lock key does not exist
+    remove_delete_bitmap_lock(meta_service.get(), table_id);
+    clear_rowsets(table_id);
+    // 8.2 compaction get lock in old way
+    config::use_delete_bitmap_lock_version = "v1";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 888);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 8.3 load get lock in old way
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, 124, -1);
+    ASSERT_EQ(res_code, MetaServiceCode::LOCK_CONFLICT);
+    // 8.4 compaction update delete bitmap in new way failed, abort compaction 
job
+    config::use_delete_bitmap_lock_version = "v2";
+    test_start_compaction_job(table_id, 2, 3, 5, TabletCompactionJobPB::BASE);
+    res_code = update_delete_bitmap(meta_service.get(), table_id, 3, 5, -1, 
888);
+    ASSERT_EQ(res_code, MetaServiceCode::LOCK_EXPIRED);
+    test_abort_compaction_job(table_id, 2, 3, 5, 888);
+    clear_rowsets(5);
+
+    // case 9:
+    // 9.1 lock key does not exist
+    remove_delete_bitmap_lock(meta_service.get(), table_id);
+    clear_rowsets(table_id);
+    // 9.2 compaction1 get lock in new way
+    config::use_delete_bitmap_lock_version = "v2";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 901);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 9.3 compaction2 get and remove lock in old way
+    config::use_delete_bitmap_lock_version = "v1";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 902);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    test_start_compaction_job(table_id, 2, 3, 5, TabletCompactionJobPB::BASE);
+    res_code = update_delete_bitmap(meta_service.get(), table_id, 3, 5, -1, 
902);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    test_commit_compaction_job(table_id, 2, 3, 5, TabletCompactionJobPB::BASE, 
902);
+    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
+    clear_rowsets(5);
+    // 9.4 load get and remove lock in old way
+    config::use_delete_bitmap_lock_version = "v1";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, 199, -1);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    res_code = remove_delete_bitmap_lock(meta_service.get(), table_id, 199, 
-1);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 9.5 compaction3 get lock in new way
+    config::use_delete_bitmap_lock_version = "v2";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 903);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 9.6 compaction1 update delete bitmap in new way failed, abort job
+    test_start_compaction_job(table_id, 2, 3, 5, TabletCompactionJobPB::BASE);
+    res_code = update_delete_bitmap(meta_service.get(), table_id, 3, 5, -1, 
901);
+    ASSERT_EQ(res_code, MetaServiceCode::LOCK_EXPIRED);
+    test_abort_compaction_job(table_id, 2, 3, 5, 901);
+    clear_rowsets(5);
+
+    // case 10:
+    // 10.1 lock key does not exist
+    remove_delete_bitmap_lock(meta_service.get(), table_id);
+    clear_rowsets(table_id);
+    // 10.2 compaction1 get lock in new way
+    config::use_delete_bitmap_lock_version = "v2";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 1001);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 10.3 compaction2 get and remove lock in old way
+    config::use_delete_bitmap_lock_version = "v1";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 1002);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    test_start_compaction_job(table_id, 2, 3, 5, TabletCompactionJobPB::BASE);
+    res_code = update_delete_bitmap(meta_service.get(), table_id, 3, 5, -1, 
1002);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    test_commit_compaction_job(table_id, 2, 3, 5, TabletCompactionJobPB::BASE, 
1002);
+    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
+    clear_rowsets(5);
+    // 10.4 load get and remove lock in old way
+    config::use_delete_bitmap_lock_version = "v1";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, 1910, -1);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    res_code = remove_delete_bitmap_lock(meta_service.get(), table_id, 1910, 
-1);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 10.5 compaction3 get lock in old way
+    config::use_delete_bitmap_lock_version = "v1";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 1003);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 10.6 compaction1 update delete bitmap in new way success, commit job 
failed
+    config::use_delete_bitmap_lock_version = "v2";
+    test_start_compaction_job(table_id, 2, 3, 5, TabletCompactionJobPB::BASE);
+    res_code = update_delete_bitmap(meta_service.get(), table_id, 3, 5, -1, 
1001);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    test_commit_compaction_job(table_id, 2, 3, 5, TabletCompactionJobPB::BASE, 
1001);
+    ASSERT_EQ(res.status().code(), MetaServiceCode::LOCK_EXPIRED);
+    clear_rowsets(5);
+
+    // case 11:
+    // 11.1 lock key does not exist
+    remove_delete_bitmap_lock(meta_service.get(), table_id);
+    clear_rowsets(table_id);
+    // 11.2 compaction1 get lock in new way
+    config::use_delete_bitmap_lock_version = "v2";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 1101);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 11.3 compaction2 get and remove lock in old way
+    config::use_delete_bitmap_lock_version = "v1";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 1102);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    test_start_compaction_job(table_id, 2, 3, 5, TabletCompactionJobPB::BASE);
+    res_code = update_delete_bitmap(meta_service.get(), table_id, 3, 5, -1, 
1102);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    test_commit_compaction_job(table_id, 2, 3, 5, TabletCompactionJobPB::BASE, 
1102);
+    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
+    clear_rowsets(5);
+    // 11.4 sc get and remove lock in old way
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -2, -1);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    res_code = remove_delete_bitmap_lock(meta_service.get(), table_id, -2, -1);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 11.5 compaction3 get lock in new way
+    config::use_delete_bitmap_lock_version = "v2";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 1103);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 11.6 compaction1 update delete bitmap in new way failed, abort job
+    config::use_delete_bitmap_lock_version = "v2";
+    test_start_compaction_job(table_id, 2, 3, 5, TabletCompactionJobPB::BASE);
+    res_code = update_delete_bitmap(meta_service.get(), table_id, 3, 5, -1, 
1101);
+    ASSERT_EQ(res_code, MetaServiceCode::LOCK_EXPIRED);
+    test_abort_compaction_job(table_id, 2, 3, 5, 1101);
+    clear_rowsets(5);
+
+    // case 12:
+    // 12.1 lock key does not exist
+    remove_delete_bitmap_lock(meta_service.get(), table_id);
+    clear_rowsets(table_id);
+    // 12.2 compaction1 get lock in new way
+    config::use_delete_bitmap_lock_version = "v2";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 1201);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 12.3 compaction2 get and remove lock in old way
+    config::use_delete_bitmap_lock_version = "v1";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 1202);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    test_start_compaction_job(table_id, 2, 3, 5, TabletCompactionJobPB::BASE);
+    res_code = update_delete_bitmap(meta_service.get(), table_id, 3, 5, -1, 
1202);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    test_commit_compaction_job(table_id, 2, 3, 5, TabletCompactionJobPB::BASE, 
1202);
+    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
+    clear_rowsets(5);
+    // 12.4 sc get and remove lock in old way
+    config::use_delete_bitmap_lock_version = "v1";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -2, -1);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    res_code = remove_delete_bitmap_lock(meta_service.get(), table_id, -2, -1);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 12.5 compaction3 get lock in old way
+    config::use_delete_bitmap_lock_version = "v1";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 1203);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 12.6 compaction1 update delete bitmap in new way success, commit job 
failed
+    config::use_delete_bitmap_lock_version = "v2";
+    test_start_compaction_job(table_id, 2, 3, 5, TabletCompactionJobPB::BASE);
+    res_code = update_delete_bitmap(meta_service.get(), table_id, 3, 5, -1, 
1201);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    test_commit_compaction_job(table_id, 2, 3, 5, TabletCompactionJobPB::BASE, 
1201);
+    ASSERT_EQ(res.status().code(), MetaServiceCode::LOCK_EXPIRED);
+    clear_rowsets(5);
+
+    // case 13:
+    // 13.1 lock key does not exist
+    remove_delete_bitmap_lock(meta_service.get(), table_id);
+    clear_rowsets(table_id);
+    // 13.2 compaction1 get lock in new way
+    config::use_delete_bitmap_lock_version = "v2";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 1301);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 13.3 compaction2 get and remove lock in old way
+    config::use_delete_bitmap_lock_version = "v1";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 1302);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    test_start_compaction_job(table_id, 2, 3, 5, TabletCompactionJobPB::BASE);
+    res_code = update_delete_bitmap(meta_service.get(), table_id, 3, 5, -1, 
1302);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    test_commit_compaction_job(table_id, 2, 3, 5, TabletCompactionJobPB::BASE, 
1302);
+    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
+    clear_rowsets(5);
+    // 13.4 load get and remove lock in old way
+    config::use_delete_bitmap_lock_version = "v1";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, 1390, -1);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    res_code = remove_delete_bitmap_lock(meta_service.get(), table_id, 1390, 
-1);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 13.5 compaction3 get lock in new way
+    config::use_delete_bitmap_lock_version = "v2";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 1303);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 13.6 compaction1 update delete bitmap in new way failed, abort job
+    config::use_delete_bitmap_lock_version = "v2";
+    test_start_compaction_job(table_id, 2, 3, 5, TabletCompactionJobPB::BASE);
+    res_code = update_delete_bitmap(meta_service.get(), table_id, 3, 5, -1, 
1301);
+    ASSERT_EQ(res_code, MetaServiceCode::LOCK_EXPIRED);
+    test_abort_compaction_job(table_id, 2, 3, 5, 1301);
+    clear_rowsets(5);
+
+    // case 14:
+    // 14.1 lock key does not exist
+    remove_delete_bitmap_lock(meta_service.get(), table_id);
+    clear_rowsets(table_id);
+    // 14.2 compaction1 get lock in new way
+    config::use_delete_bitmap_lock_version = "v2";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 1401);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 14.3 compaction2 get and remove lock in old way
+    config::use_delete_bitmap_lock_version = "v1";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 1402);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    test_start_compaction_job(table_id, 2, 3, 5, TabletCompactionJobPB::BASE);
+    res_code = update_delete_bitmap(meta_service.get(), table_id, 3, 5, -1, 
1402);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    test_commit_compaction_job(table_id, 2, 3, 5, TabletCompactionJobPB::BASE, 
1402);
+    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
+    clear_rowsets(5);
+    // 14.4 load get and remove lock in old way
+    config::use_delete_bitmap_lock_version = "v1";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, 1490, -1);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    res_code = remove_delete_bitmap_lock(meta_service.get(), table_id, 1490, 
-1);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 14.5 compaction3 get lock in old way
+    config::use_delete_bitmap_lock_version = "v1";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 1403);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 14.6 compaction1 update delete bitmap in old way failed, abort job
+    config::use_delete_bitmap_lock_version = "v1";
+    test_start_compaction_job(table_id, 2, 3, 5, TabletCompactionJobPB::BASE);
+    res_code = update_delete_bitmap(meta_service.get(), table_id, 3, 5, -1, 
1401);
+    ASSERT_EQ(res_code, MetaServiceCode::LOCK_EXPIRED);
+    test_abort_compaction_job(table_id, 2, 3, 5, 1401);
+    clear_rowsets(5);
+
+    // case 15:
+    // 15.1 lock key does not exist
+    remove_delete_bitmap_lock(meta_service.get(), table_id);
+    clear_rowsets(table_id);
+    // 15.2 compaction1 get lock in new way
+    config::use_delete_bitmap_lock_version = "v2";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 1501);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 15.3 compaction2 get and remove lock in old way
+    config::use_delete_bitmap_lock_version = "v1";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 1502);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    test_start_compaction_job(table_id, 2, 3, 5, TabletCompactionJobPB::BASE);
+    res_code = update_delete_bitmap(meta_service.get(), table_id, 3, 5, -1, 
1502);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    test_commit_compaction_job(table_id, 2, 3, 5, TabletCompactionJobPB::BASE, 
1502);
+    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
+    clear_rowsets(5);
+    // 15.4 sc get and remove lock in old way
+    config::use_delete_bitmap_lock_version = "v1";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -2, -1);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    res_code = remove_delete_bitmap_lock(meta_service.get(), table_id, -2, -1);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 15.5 compaction3 get lock in new way
+    config::use_delete_bitmap_lock_version = "v2";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 1503);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 15.6 compaction1 update delete bitmap in old way failed, abort job
+    config::use_delete_bitmap_lock_version = "v1";
+    test_start_compaction_job(table_id, 2, 3, 5, TabletCompactionJobPB::BASE);
+    res_code = update_delete_bitmap(meta_service.get(), table_id, 3, 5, -1, 
1501);
+    ASSERT_EQ(res_code, MetaServiceCode::LOCK_EXPIRED);
+    test_abort_compaction_job(table_id, 2, 3, 5, 1501);
+    clear_rowsets(5);
+
+    // case 16:
+    // 16.1 lock key does not exist
+    remove_delete_bitmap_lock(meta_service.get(), table_id);
+    clear_rowsets(table_id);
+    // 16.2 compaction1 get lock in new way
+    config::use_delete_bitmap_lock_version = "v2";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 1601);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 16.3 compaction2 get and remove lock in old way
+    config::use_delete_bitmap_lock_version = "v1";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 1602);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    test_start_compaction_job(table_id, 2, 3, 5, TabletCompactionJobPB::BASE);
+    res_code = update_delete_bitmap(meta_service.get(), table_id, 3, 5, -1, 
1602);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    test_commit_compaction_job(table_id, 2, 3, 5, TabletCompactionJobPB::BASE, 
1602);
+    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
+    clear_rowsets(5);
+    // 16.4 sc get and remove lock in old way
+    config::use_delete_bitmap_lock_version = "v1";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -2, -1);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    res_code = remove_delete_bitmap_lock(meta_service.get(), table_id, -2, -1);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 16.5 compaction3 get lock in old way
+    config::use_delete_bitmap_lock_version = "v1";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 1603);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 16.6 compaction1 update delete bitmap in old way failed, abort job
+    config::use_delete_bitmap_lock_version = "v1";
+    test_start_compaction_job(table_id, 2, 3, 5, TabletCompactionJobPB::BASE);
+    res_code = update_delete_bitmap(meta_service.get(), table_id, 3, 5, -1, 
1601);
+    ASSERT_EQ(res_code, MetaServiceCode::LOCK_EXPIRED);
+    test_abort_compaction_job(table_id, 2, 3, 5, 1601);
+    clear_rowsets(5);
+
+    // case 17:
+    // 17.1 lock key does not exist
+    remove_delete_bitmap_lock(meta_service.get(), table_id);
+    clear_rowsets(table_id);
+    // 17.2 compaction1 get lock in old way
+    config::use_delete_bitmap_lock_version = "v1";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 1701);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 17.3 load get and remove lock in new way
+    config::use_delete_bitmap_lock_version = "v2";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, 1793, -1);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    res_code = remove_delete_bitmap_lock(meta_service.get(), table_id, 1793, 
-1);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 17.4 compaction2 get lock in new way
+    config::use_delete_bitmap_lock_version = "v2";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 1702);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 17.5 compaction1 update delete bitmap in new way failed, abort job
+    config::use_delete_bitmap_lock_version = "v2";
+    test_start_compaction_job(table_id, 2, 3, 5, TabletCompactionJobPB::BASE);
+    res_code = update_delete_bitmap(meta_service.get(), table_id, 3, 5, -1, 
1701);
+    ASSERT_EQ(res_code, MetaServiceCode::LOCK_EXPIRED);
+    test_abort_compaction_job(table_id, 2, 3, 5, 1701);
+    clear_rowsets(5);
+
+    // case 18:
+    // 18.1 lock key does not exist
+    remove_delete_bitmap_lock(meta_service.get(), table_id);
+    clear_rowsets(table_id);
+    // 18.2 compaction1 get lock in old way
+    config::use_delete_bitmap_lock_version = "v1";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 1801);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 18.3 load get and remove lock in new way
+    config::use_delete_bitmap_lock_version = "v2";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, 1893, -1);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    res_code = remove_delete_bitmap_lock(meta_service.get(), table_id, 1893, 
-1);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 18.4 compaction2 get lock in old way
+    config::use_delete_bitmap_lock_version = "v1";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 1802);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 18.5 compaction1 update delete bitmap in new way failed, abort job
+    config::use_delete_bitmap_lock_version = "v2";
+    test_start_compaction_job(table_id, 2, 3, 5, TabletCompactionJobPB::BASE);
+    res_code = update_delete_bitmap(meta_service.get(), table_id, 3, 5, -1, 
1801);
+    ASSERT_EQ(res_code, MetaServiceCode::LOCK_EXPIRED);
+    test_abort_compaction_job(table_id, 2, 3, 5, 1801);
+    clear_rowsets(5);
+
+    // case 19:
+    // 19.1 lock key does not exist
+    remove_delete_bitmap_lock(meta_service.get(), table_id);
+    clear_rowsets(table_id);
+    // 19.2 compaction1 get lock in old way
+    config::use_delete_bitmap_lock_version = "v1";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 1901);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 19.3 sc get and remove lock in new way
+    config::use_delete_bitmap_lock_version = "v2";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -2, -1);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    res_code = remove_delete_bitmap_lock(meta_service.get(), table_id, -2, -1);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 19.4 compaction2 get lock in new way
+    config::use_delete_bitmap_lock_version = "v2";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 1902);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 19.5 compaction1 update delete bitmap in new way failed, abort job
+    config::use_delete_bitmap_lock_version = "v2";
+    test_start_compaction_job(table_id, 2, 3, 5, TabletCompactionJobPB::BASE);
+    res_code = update_delete_bitmap(meta_service.get(), table_id, 3, 5, -1, 
1901);
+    ASSERT_EQ(res_code, MetaServiceCode::LOCK_EXPIRED);
+    test_abort_compaction_job(table_id, 2, 3, 5, 1901);
+    clear_rowsets(5);
+
+    // case 20:
+    // 20.1 lock key does not exist
+    remove_delete_bitmap_lock(meta_service.get(), table_id);
+    clear_rowsets(table_id);
+    // 20.2 compaction1 get lock in old way
+    config::use_delete_bitmap_lock_version = "v1";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 2001);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 20.3 sc get and remove lock in new way
+    config::use_delete_bitmap_lock_version = "v2";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -2, -1);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    res_code = remove_delete_bitmap_lock(meta_service.get(), table_id, -2, -1);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 20.4 compaction2 get lock in old way
+    config::use_delete_bitmap_lock_version = "v1";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 2002);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 20.5 compaction1 update delete bitmap in new way failed, abort job
+    config::use_delete_bitmap_lock_version = "v2";
+    test_start_compaction_job(table_id, 2, 3, 5, TabletCompactionJobPB::BASE);
+    res_code = update_delete_bitmap(meta_service.get(), table_id, 3, 5, -1, 
2001);
+    ASSERT_EQ(res_code, MetaServiceCode::LOCK_EXPIRED);
+    test_abort_compaction_job(table_id, 2, 3, 5, 2001);
+    clear_rowsets(5);
+
+    // case 21:
+    // 21.1 lock key does not exist
+    remove_delete_bitmap_lock(meta_service.get(), table_id);
+    clear_rowsets(table_id);
+    // 21.2 compaction1 get lock in old way
+    config::use_delete_bitmap_lock_version = "v1";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 2101);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 21.3 load get and remove lock in new way
+    config::use_delete_bitmap_lock_version = "v2";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, 2190, -1);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    res_code = remove_delete_bitmap_lock(meta_service.get(), table_id, 2190, 
-1);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 21.4 compaction2 get lock in new way
+    config::use_delete_bitmap_lock_version = "v2";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 2102);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 21.5 compaction1 update delete bitmap in old way failed, abort job
+    config::use_delete_bitmap_lock_version = "v1";
+    test_start_compaction_job(table_id, 2, 3, 5, TabletCompactionJobPB::BASE);
+    res_code = update_delete_bitmap(meta_service.get(), table_id, 3, 5, -1, 
2101);
+    ASSERT_EQ(res_code, MetaServiceCode::LOCK_EXPIRED);
+    test_abort_compaction_job(table_id, 2, 3, 5, 2101);
+    clear_rowsets(5);
+
+    // case 22:
+    // 22.1 lock key does not exist
+    remove_delete_bitmap_lock(meta_service.get(), table_id);
+    clear_rowsets(table_id);
+    // 22.2 compaction1 get lock in old way
+    config::use_delete_bitmap_lock_version = "v1";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 2201);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 22.3 load get and remove lock in new way
+    config::use_delete_bitmap_lock_version = "v2";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, 2290, -1);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    res_code = remove_delete_bitmap_lock(meta_service.get(), table_id, 2290, 
-1);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 22.4 compaction2 get lock in old way
+    config::use_delete_bitmap_lock_version = "v1";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 2202);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 22.5 compaction1 update delete bitmap in old way failed, abort job
+    config::use_delete_bitmap_lock_version = "v1";
+    test_start_compaction_job(table_id, 2, 3, 5, TabletCompactionJobPB::BASE);
+    res_code = update_delete_bitmap(meta_service.get(), table_id, 3, 5, -1, 
2201);
+    ASSERT_EQ(res_code, MetaServiceCode::LOCK_EXPIRED);
+    test_abort_compaction_job(table_id, 2, 3, 5, 2201);
+    clear_rowsets(5);
+
+    // case 23:
+    // 23.1 lock key does not exist
+    remove_delete_bitmap_lock(meta_service.get(), table_id);
+    clear_rowsets(table_id);
+    // 23.2 compaction1 get lock in old way
+    config::use_delete_bitmap_lock_version = "v1";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 2301);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 23.3 sc get and remove lock in new way
+    config::use_delete_bitmap_lock_version = "v2";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, 2390, -1);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    res_code = remove_delete_bitmap_lock(meta_service.get(), table_id, 2390, 
-1);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 23.4 compaction2 get lock in new way
+    config::use_delete_bitmap_lock_version = "v2";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 2302);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 23.5 compaction1 update delete bitmap in old way failed, abort job
+    config::use_delete_bitmap_lock_version = "v1";
+    test_start_compaction_job(table_id, 2, 3, 5, TabletCompactionJobPB::BASE);
+    res_code = update_delete_bitmap(meta_service.get(), table_id, 3, 5, -1, 
2301);
+    ASSERT_EQ(res_code, MetaServiceCode::LOCK_EXPIRED);
+    test_abort_compaction_job(table_id, 2, 3, 5, 2301);
+    clear_rowsets(5);
+
+    // case 24:
+    // 24.1 lock key does not exist
+    remove_delete_bitmap_lock(meta_service.get(), table_id);
+    clear_rowsets(table_id);
+    // 24.2 compaction1 get lock in old way
+    config::use_delete_bitmap_lock_version = "v1";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 2401);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 24.3 sc get and remove lock in new way
+    config::use_delete_bitmap_lock_version = "v2";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -2, -1);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    res_code = remove_delete_bitmap_lock(meta_service.get(), table_id, -2, -1);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 24.4 compaction2 get lock in old way
+    config::use_delete_bitmap_lock_version = "v1";
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 2402);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    // 24.5 compaction1 update delete bitmap in old way failed, abort job
+    config::use_delete_bitmap_lock_version = "v1";
+    test_start_compaction_job(table_id, 2, 3, 5, TabletCompactionJobPB::BASE);
+    res_code = update_delete_bitmap(meta_service.get(), table_id, 3, 5, -1, 
2401);
+    ASSERT_EQ(res_code, MetaServiceCode::LOCK_EXPIRED);
+    test_abort_compaction_job(table_id, 2, 3, 5, 2401);
+    clear_rowsets(5);
+
+    // fuzzy case 1:
+    // 1.1 lock key does not exist
+    // 1.2 compaction1 get lock in old way
+    // 1.3 sc、load、compaction get and remove lock in new or old way
+    // 1.4 compaction2 get lock in old way
+    // 1.5 if sc or load succeed,compaction1 remove lock in old way failed
+
+    // fuzzy case 2:
+    // 2.1 lock key does not exist
+    // 2.2 compaction1 get lock in new way
+    // 2.3 sc、load、compaction get and remove lock in new or old way
+    // 2.4 compaction2 get lock in new way
+    // 2.5 if sc or load succeed,compaction1 remove lock in new way failed
+    table_id = 222;
+    for (int i = 1; i <= 2; i++) {
+        std::string lock_version = "v1";
+        if (i == 1) {
+            lock_version = "v1";
+        } else {
+            lock_version = "v2";
+        }
+        // 1 lock key does not exist
+        remove_delete_bitmap_lock(meta_service.get(), table_id);
+        clear_rowsets(table_id);
+        // 2 compaction1 get lock in old/new way
+        config::use_delete_bitmap_lock_version = lock_version;
+        res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 
2501);
+        ASSERT_EQ(res_code, MetaServiceCode::OK);
+        // 3 sc、load、compaction get and remove lock in new or old way
+        bool load_or_sc_succeed = false;
+        bool compaction_succeed = false;
+        std::srand(std::time(0));
+        for (int i = 0; i < 10; i++) {
+            int num = std::rand() % 3;
+            std::string use_version = (std::rand() % 2 == 0 ? "v2" : "v1");
+            config::use_delete_bitmap_lock_version = use_version;
+            LOG(INFO) << "i=" << i << ",num=" << num << ",use_version=" << 
use_version;
+            switch (num) {
+            case 0: {
+                res_code = get_delete_bitmap_lock(meta_service.get(), 
table_id, 2590, -1);
+                if (res_code == MetaServiceCode::OK) {
+                    res_code = remove_delete_bitmap_lock(meta_service.get(), 
table_id, 2590, -1);
+                    if (res_code == MetaServiceCode::OK) {
+                        load_or_sc_succeed = true;
+                    }
+                }
+                LOG(INFO) << "i=" << i << ",load_or_sc_succeed=" << 
load_or_sc_succeed
+                          << ",compaction_succeed=" << compaction_succeed;
+                break;
+            }
+            case 1: {
+                res_code = get_delete_bitmap_lock(meta_service.get(), 
table_id, -2, -1);
+                if (res_code == MetaServiceCode::OK) {
+                    res_code = remove_delete_bitmap_lock(meta_service.get(), 
table_id, -2, -1);
+                    if (res_code == MetaServiceCode::OK) {
+                        load_or_sc_succeed = true;
+                    }
+                }
+                LOG(INFO) << "i=" << i << ",load_or_sc_succeed=" << 
load_or_sc_succeed
+                          << ",compaction_succeed=" << compaction_succeed;
+                break;
+            }
+            case 2: {
+                res_code = get_delete_bitmap_lock(meta_service.get(), 
table_id, -1, 6600 + i);
+                if (res_code == MetaServiceCode::OK) {
+                    test_start_compaction_job(table_id, 2, 3, 5, 
TabletCompactionJobPB::BASE);
+                    res_code =
+                            update_delete_bitmap(meta_service.get(), table_id, 
3, 5, -1, 6600 + i);
+                    if (res.status().code() == MetaServiceCode::OK) {
+                        test_commit_compaction_job(table_id, 2, 3, 5, 
TabletCompactionJobPB::BASE,
+                                                   6600 + i);
+                        if (res.status().code() == MetaServiceCode::OK) {
+                            compaction_succeed = true;
+                        }
+                    }
+                    clear_rowsets(5);
+                }
+                LOG(INFO) << "i=" << i << ",load_or_sc_succeed=" << 
load_or_sc_succeed
+                          << ",compaction_succeed=" << compaction_succeed;
+                break;
+            }
+            }
+        }
+        // 4 compaction2 get lock in old/new way
+        config::use_delete_bitmap_lock_version = lock_version;
+        res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 
2502);
+        ASSERT_EQ(res_code, MetaServiceCode::OK);
+        // 5 if sc or load succeed,compaction1 remove lock in old/new way 
failed
+        config::use_delete_bitmap_lock_version = lock_version;
+        test_start_compaction_job(table_id, 2, 3, 5, 
TabletCompactionJobPB::BASE);
+        test_commit_compaction_job(table_id, 2, 3, 5, 
TabletCompactionJobPB::BASE, 2501);
+        if (load_or_sc_succeed) {
+            ASSERT_EQ(res.status().code(), MetaServiceCode::LOCK_EXPIRED);
+        }
+        clear_rowsets(5);
+    }
+}
+
 TEST(MetaServiceJobTest, CompactionJobWithMoWTest) {
     auto meta_service = get_meta_service();
     auto sp = SyncPoint::get_instance();
diff --git a/cloud/test/recycler_test.cpp b/cloud/test/recycler_test.cpp
index ac93e48e9be..81da3646772 100644
--- a/cloud/test/recycler_test.cpp
+++ b/cloud/test/recycler_test.cpp
@@ -3109,6 +3109,130 @@ TEST(CheckerTest, 
delete_bitmap_storage_optimize_check_abnormal) {
     ASSERT_EQ(expected_abnormal_rowsets, real_abnormal_rowsets);
 }
 
+std::unique_ptr<MetaServiceProxy> get_meta_service() {
+    int ret = 0;
+    // MemKv
+    auto txn_kv = 
std::dynamic_pointer_cast<TxnKv>(std::make_shared<MemTxnKv>());
+    if (txn_kv != nullptr) {
+        ret = txn_kv->init();
+        [&] { ASSERT_EQ(ret, 0); }();
+    }
+    [&] { ASSERT_NE(txn_kv.get(), nullptr); }();
+
+    std::unique_ptr<Transaction> txn;
+    EXPECT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
+    txn->remove("\x00", "\xfe"); // This is dangerous if the fdb is not 
correctly set
+    EXPECT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
+
+    auto rs = std::make_shared<MockResourceManager>(txn_kv);
+    auto rl = std::make_shared<RateLimiter>();
+    auto meta_service = std::make_unique<MetaServiceImpl>(txn_kv, rs, rl);
+    return std::make_unique<MetaServiceProxy>(std::move(meta_service));
+}
+
+MetaServiceCode get_delete_bitmap_lock(MetaServiceProxy* meta_service, int64_t 
table_id,
+                                       int64_t lock_id, int64_t initiator, 
int64_t expiration = 5) {
+    brpc::Controller cntl;
+    GetDeleteBitmapUpdateLockRequest req;
+    GetDeleteBitmapUpdateLockResponse res;
+    req.set_cloud_unique_id("test_cloud_unique_id");
+    req.set_table_id(table_id);
+    req.set_expiration(expiration);
+    req.set_lock_id(lock_id);
+    req.set_initiator(initiator);
+    meta_service->get_delete_bitmap_update_lock(
+            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, 
&res, nullptr);
+    return res.status().code();
+}
+
+MetaServiceCode remove_delete_bitmap_lock(MetaServiceProxy* meta_service, 
int64_t table_id,
+                                          int64_t lock_id, int64_t initiator) {
+    brpc::Controller cntl;
+    RemoveDeleteBitmapUpdateLockRequest req;
+    RemoveDeleteBitmapUpdateLockResponse res;
+    req.set_cloud_unique_id("test_cloud_unique_id");
+    req.set_table_id(table_id);
+    req.set_lock_id(lock_id);
+    req.set_initiator(initiator);
+    meta_service->remove_delete_bitmap_update_lock(
+            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, 
&res, nullptr);
+    return res.status().code();
+}
+
+void remove_delete_bitmap_lock(MetaServiceProxy* meta_service, int64_t 
table_id) {
+    std::string lock_key =
+            meta_delete_bitmap_update_lock_key({"test_check_compaction_key", 
table_id, -1});
+    std::unique_ptr<Transaction> txn;
+    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
+    txn->remove(lock_key);
+    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
+}
+
+TEST(CheckerTest, check_compaction_key) {
+    config::enable_mow_compaction_key_check = true;
+    config::compaction_key_check_expiration_diff_seconds = 0;
+    config::use_delete_bitmap_lock_version = "v2";
+    std::string instance_id = "test_check_compaction_key";
+    [[maybe_unused]] auto sp = SyncPoint::get_instance();
+    std::unique_ptr<int, std::function<void(int*)>> defer(
+            (int*)0x01, [](int*) { 
SyncPoint::get_instance()->clear_all_call_backs(); });
+    sp->set_call_back("get_instance_id", [&](auto&& args) {
+        auto* ret = try_any_cast_ret<std::string>(args);
+        ret->first = instance_id;
+        ret->second = true;
+    });
+    sp->enable_processing();
+    int64_t table_id = 2;
+
+    //test 1:
+    //1.compaction get lock and write compaction key, but not release lock
+    //2.after lock expired, load get lock, compaction key is removed
+    auto meta_service = get_meta_service();
+    auto res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 
123);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    std::this_thread::sleep_for(std::chrono::seconds(6));
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, 100, -1);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+
+    auto txn_kv = std::make_shared<MemTxnKv>();
+    ASSERT_EQ(txn_kv->init(), 0);
+
+    InstanceInfoPB instance;
+    instance.set_instance_id(instance_id);
+    auto obj_info = instance.add_obj_info();
+    obj_info->set_id("1");
+    InstanceChecker checker(meta_service->txn_kv(), instance_id);
+    ASSERT_EQ(checker.init(instance), 0);
+    ASSERT_EQ(checker.do_mow_compaction_key_check(), 0);
+    res_code = remove_delete_bitmap_lock(meta_service.get(), table_id, 100, 
-1);
+
+    //test 2:
+    //1.compaction a get lock and write compaction key, but not release lock
+    //2.compaction key is expired
+    //3.remove delete bitmap lock accidentally(it should not happen)
+    //4.load get lock
+    //5.checker found residual compaction key
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 124, 
0);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    std::this_thread::sleep_for(std::chrono::seconds(1));
+    remove_delete_bitmap_lock(meta_service.get(), table_id);
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, 101, -1);
+    ASSERT_EQ(checker.do_mow_compaction_key_check(), -1);
+    std::this_thread::sleep_for(std::chrono::seconds(6));
+
+    //test 3:
+    //1.compaction a get lock and write compaction key, but not release lock
+    //2.compaction key is expired
+    //3.remove delete bitmap lock accidentally(it should not happen)
+    //4.checker found residual compaction key
+    table_id = 3;
+    res_code = get_delete_bitmap_lock(meta_service.get(), table_id, -1, 126, 
0);
+    ASSERT_EQ(res_code, MetaServiceCode::OK);
+    std::this_thread::sleep_for(std::chrono::seconds(1));
+    remove_delete_bitmap_lock(meta_service.get(), table_id);
+    ASSERT_EQ(checker.do_mow_compaction_key_check(), -1);
+}
+
 TEST(RecyclerTest, delete_rowset_data) {
     auto txn_kv = std::make_shared<MemTxnKv>();
     ASSERT_EQ(txn_kv->init(), 0);


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to