diff --git a/plugin/group_replication/include/certifier.h b/plugin/group_replication/include/certifier.h index 50dc420ed25..1c4c802a790 100644 --- a/plugin/group_replication/include/certifier.h +++ b/plugin/group_replication/include/certifier.h @@ -55,7 +55,8 @@ class Gtid_set_ref : public Gtid_set { Gtid_set_ref(Sid_map *sid_map, int64 parallel_applier_sequence_number) : Gtid_set(sid_map), reference_counter(0), - parallel_applier_sequence_number(parallel_applier_sequence_number) {} + parallel_applier_sequence_number(parallel_applier_sequence_number), + gc_version(0) {} virtual ~Gtid_set_ref() = default; @@ -76,6 +77,9 @@ class Gtid_set_ref : public Gtid_set { return --reference_counter; } + void set_gc_version(uint64 ver) {gc_version = ver;} + uint64 get_gc_version() {return gc_version;} + int64 get_parallel_applier_sequence_number() const { return parallel_applier_sequence_number; } @@ -83,6 +87,7 @@ class Gtid_set_ref : public Gtid_set { private: size_t reference_counter; int64 parallel_applier_sequence_number; + uint64 gc_version; }; /** diff --git a/plugin/group_replication/src/certifier.cc b/plugin/group_replication/src/certifier.cc index 3f79d808fa5..6a46e09e596 100644 --- a/plugin/group_replication/src/certifier.cc +++ b/plugin/group_replication/src/certifier.cc @@ -1206,6 +1206,8 @@ bool Certifier::set_group_stable_transactions_set(Gtid_set *executed_gtid_set) { return false; } +static std::atomic garbage_collection_version = {1}; + void Certifier::garbage_collect() { DBUG_TRACE; /* @@ -1228,14 +1230,21 @@ void Certifier::garbage_collect() { precedes them), then "t" is stable and can be removed from the certification info. */ + uint64 curr_gc_version = garbage_collection_version.fetch_add(1, std::memory_order_relaxed); Certification_info::iterator it = certification_info.begin(); stable_gtid_set_lock->wrlock(); while (it != certification_info.end()) { - if (it->second->is_subset_not_equals(stable_gtid_set)) { + bool need_clear = it->second->get_gc_version() == UINT64_MAX || + (it->second->get_gc_version() < curr_gc_version && + it->second->is_subset_not_equals(stable_gtid_set)); + if (need_clear) { + it->second->set_gc_version(UINT64_MAX); if (it->second->unlink() == 0) delete it->second; certification_info.erase(it++); - } else + } else { + it->second->set_gc_version(curr_gc_version); ++it; + } } stable_gtid_set_lock->unlock();