diff --git a/src/storage/ob_pg_sstable_garbage_collector.cpp b/src/storage/ob_pg_sstable_garbage_collector.cpp index 1ddb484cb97371b3805f072fe232917b62567004..2d2fc6b119e576e1322e883594ca7782b51a6b8e 100644 --- a/src/storage/ob_pg_sstable_garbage_collector.cpp +++ b/src/storage/ob_pg_sstable_garbage_collector.cpp @@ -103,6 +103,19 @@ int ObPGSSTableGarbageCollector::gc_free_sstable_by_pg_iter() left_recycle_cnt -= recycle_cnt; } } + if (OB_SUCC(ret)) { + while (OB_SUCC(ret) && free_sstables_queue_.size() > 0) { + ObLink *ptr = NULL; + if (OB_FAIL(free_sstables_queue_.pop(ptr))) { + LOG_WARN("fail to pop item", K(ret)); + } else if (OB_ISNULL(ptr)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error, ptr is nullptr", K(ret), KP(ptr)); + } else { + free_sstable_gc_item(static_cast(ptr)); + } + } + } } if (nullptr != partition_iter) { ObPartitionService::get_instance().revert_pg_iter(partition_iter); diff --git a/src/storage/ob_sstable.cpp b/src/storage/ob_sstable.cpp index 162456ba96543fe14c02ef6bc0d9f9c1c94d11a2..e1ad7c67ec509a899b743dbf1ab0349f03cb6011 100644 --- a/src/storage/ob_sstable.cpp +++ b/src/storage/ob_sstable.cpp @@ -3203,15 +3203,19 @@ int ObSSTable::add_macro_ref() int64_t ObSSTable::dec_ref() { - int64_t ref_cnt = ATOMIC_SAF(&ref_cnt_, 1 /* just sub 1 */); - - if (0 == ref_cnt) { + // If current ref_cnt is 1, it should be pushed into gc queue firstly. Then, decrease reference + // counts. The reason is that gc by iter may be faster than gc by queue. + if (1 == get_ref()) { int ret = OB_SUCCESS; if (OB_FAIL(ObPGSSTableGarbageCollector::get_instance().push_sstable_into_gc_queue(key_))) { LOG_WARN("fail to push sstable into gc queue", K(ret), K(key_)); } } + int64_t ref_cnt = ATOMIC_SAF(&ref_cnt_, 1 /* just sub 1 */); + if (OB_UNLIKELY(ref_cnt < 0)) { + LOG_ERROR("Unexpected ref cnt of sstable", K(ref_cnt), K(key_)); + } return ref_cnt; }