@@ -34,7 +34,9 @@ namespace doris {
3434
3535CloudTxnDeleteBitmapCache::CloudTxnDeleteBitmapCache (size_t size_in_bytes)
3636 : LRUCachePolicy(CachePolicy::CacheType::CLOUD_TXN_DELETE_BITMAP_CACHE, size_in_bytes,
37- LRUCacheType::SIZE, 86400 , 4 ),
37+ LRUCacheType::SIZE, /* stale_sweep_time_s*/ 86400 , /* num_shards*/ 4 ,
38+ /* element_count_capacity*/ 0 , /* enable_prune*/ true ,
39+ /* is_lru_k*/ false ),
3840 _stop_latch (1 ) {}
3941
4042CloudTxnDeleteBitmapCache::~CloudTxnDeleteBitmapCache () {
@@ -229,7 +231,9 @@ void CloudTxnDeleteBitmapCache::remove_expired_tablet_txn_info() {
229231 std::unique_lock<std::shared_mutex> wlock (_rwlock);
230232 while (!_expiration_txn.empty ()) {
231233 auto iter = _expiration_txn.begin ();
232- if (_txn_map.find (iter->second ) == _txn_map.end ()) {
234+ bool in_txn_map = _txn_map.find (iter->second ) != _txn_map.end ();
235+ bool in_markers = _empty_rowset_markers.find (iter->second ) != _empty_rowset_markers.end ();
236+ if (!in_txn_map && !in_markers) {
233237 _expiration_txn.erase (iter);
234238 continue ;
235239 }
@@ -239,6 +243,7 @@ void CloudTxnDeleteBitmapCache::remove_expired_tablet_txn_info() {
239243 if (iter->first > current_time) {
240244 break ;
241245 }
246+ // Clean from _txn_map if exists
242247 auto txn_iter = _txn_map.find (iter->second );
243248 if ((txn_iter != _txn_map.end ()) && (iter->first == txn_iter->second .txn_expiration )) {
244249 LOG_INFO (" clean expired delete bitmap" )
@@ -251,6 +256,14 @@ void CloudTxnDeleteBitmapCache::remove_expired_tablet_txn_info() {
251256 erase (cache_key);
252257 _txn_map.erase (iter->second );
253258 }
259+ // Clean from _empty_rowset_markers if exists
260+ auto marker_iter = _empty_rowset_markers.find (iter->second );
261+ if (marker_iter != _empty_rowset_markers.end ()) {
262+ LOG_INFO (" clean expired empty rowset marker" )
263+ .tag (" txn_id" , iter->second .txn_id )
264+ .tag (" tablet_id" , iter->second .tablet_id );
265+ _empty_rowset_markers.erase (marker_iter);
266+ }
254267 _expiration_txn.erase (iter);
255268 }
256269}
@@ -272,6 +285,32 @@ void CloudTxnDeleteBitmapCache::remove_unused_tablet_txn_info(TTransactionId tra
272285 }
273286}
274287
288+ void CloudTxnDeleteBitmapCache::mark_empty_rowset (TTransactionId txn_id, int64_t tablet_id,
289+ int64_t txn_expiration) {
290+ int64_t txn_expiration_min =
291+ duration_cast<std::chrono::seconds>(std::chrono::system_clock::now ().time_since_epoch ())
292+ .count () +
293+ config::tablet_txn_info_min_expired_seconds;
294+ txn_expiration = std::max (txn_expiration_min, txn_expiration);
295+
296+ if (config::enable_mow_verbose_log) {
297+ LOG_INFO (" mark empty rowset" )
298+ .tag (" txn_id" , txn_id)
299+ .tag (" tablet_id" , tablet_id)
300+ .tag (" expiration" , txn_expiration);
301+ }
302+ std::unique_lock<std::shared_mutex> wlock (_rwlock);
303+ TxnKey txn_key (txn_id, tablet_id);
304+ _empty_rowset_markers.emplace (txn_key);
305+ _expiration_txn.emplace (txn_expiration, txn_key);
306+ }
307+
308+ bool CloudTxnDeleteBitmapCache::is_empty_rowset (TTransactionId txn_id, int64_t tablet_id) {
309+ std::shared_lock<std::shared_mutex> rlock (_rwlock);
310+ TxnKey txn_key (txn_id, tablet_id);
311+ return _empty_rowset_markers.contains (txn_key);
312+ }
313+
275314void CloudTxnDeleteBitmapCache::_clean_thread_callback () {
276315 do {
277316 remove_expired_tablet_txn_info ();
0 commit comments