From 36af412ea170ed744479fd3618478601632b5909 Mon Sep 17 00:00:00 2001 From: Tyshawn Date: Mon, 20 Dec 2021 20:05:13 +0800 Subject: [PATCH] [BUGFIX] fix sstable double free both gc by iter and gc by queue. --- src/storage/ob_pg_sstable_garbage_collector.cpp | 13 +++++++++++++ src/storage/ob_sstable.cpp | 10 +++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/storage/ob_pg_sstable_garbage_collector.cpp b/src/storage/ob_pg_sstable_garbage_collector.cpp index 1ddb484cb..2d2fc6b11 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 162456ba9..e1ad7c67e 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; } -- GitLab