Closed acelyc111 closed 3 years ago
code version: master
bool CompactionPermitLimiter::request(int64_t permits) {
DorisMetrics::instance()->compaction_waitting_permits->set_value(permits);
if (permits > config::total_permits_for_compaction_score) {
// when tablet's compaction score is larger than "config::total_permits_for_compaction_score",
// it's necessary to do compaction for this tablet because this tablet will not get "permits"
// anyway. otherwise, compaction task for this tablet will not be executed forever.
std::unique_lock<std::mutex> lock(_permits_mutex);
_permits_cv.wait(lock, [=] {
return _used_permits == 0 ||
_used_permits + permits <= config::total_permits_for_compaction_score;
});
} else {
if (_used_permits + permits > config::total_permits_for_compaction_score) {
std::unique_lock<std::mutex> lock(_permits_mutex);
_permits_cv.wait(lock, [=] {
return _used_permits + permits <= config::total_permits_for_compaction_score;
});
}
}
_used_permits += permits; // here _used_permits is updated out of lock, Does this have concurrency issues ?
DorisMetrics::instance()->compaction_waitting_permits->set_value(0);
DorisMetrics::instance()->compaction_used_permits->set_value(_used_permits);
return true;
}
I have a question as in the comment above.
code version: master
bool CompactionPermitLimiter::request(int64_t permits) { DorisMetrics::instance()->compaction_waitting_permits->set_value(permits); if (permits > config::total_permits_for_compaction_score) { // when tablet's compaction score is larger than "config::total_permits_for_compaction_score", // it's necessary to do compaction for this tablet because this tablet will not get "permits" // anyway. otherwise, compaction task for this tablet will not be executed forever. std::unique_lock<std::mutex> lock(_permits_mutex); _permits_cv.wait(lock, [=] { return _used_permits == 0 || _used_permits + permits <= config::total_permits_for_compaction_score; }); } else { if (_used_permits + permits > config::total_permits_for_compaction_score) { std::unique_lock<std::mutex> lock(_permits_mutex); _permits_cv.wait(lock, [=] { return _used_permits + permits <= config::total_permits_for_compaction_score; }); } } _used_permits += permits; // here _used_permits is updated out of lock, Does this have concurrency issues ? DorisMetrics::instance()->compaction_waitting_permits->set_value(0); DorisMetrics::instance()->compaction_used_permits->set_value(_used_permits); return true; }
I have a question as in the comment above.
@wangbo
_used_permits
is defined as a type of AtomicInt64
.
code version: master
bool CompactionPermitLimiter::request(int64_t permits) { DorisMetrics::instance()->compaction_waitting_permits->set_value(permits); if (permits > config::total_permits_for_compaction_score) { // when tablet's compaction score is larger than "config::total_permits_for_compaction_score", // it's necessary to do compaction for this tablet because this tablet will not get "permits" // anyway. otherwise, compaction task for this tablet will not be executed forever. std::unique_lock<std::mutex> lock(_permits_mutex); _permits_cv.wait(lock, [=] { return _used_permits == 0 || _used_permits + permits <= config::total_permits_for_compaction_score; }); } else { if (_used_permits + permits > config::total_permits_for_compaction_score) { std::unique_lock<std::mutex> lock(_permits_mutex); _permits_cv.wait(lock, [=] { return _used_permits + permits <= config::total_permits_for_compaction_score; }); } } _used_permits += permits; // here _used_permits is updated out of lock, Does this have concurrency issues ? DorisMetrics::instance()->compaction_waitting_permits->set_value(0); DorisMetrics::instance()->compaction_used_permits->set_value(_used_permits); return true; }
I have a question as in the comment above.
@wangbo
_used_permits
is defined as a type ofAtomicInt64
.
I understand.
Describe the bug I found some BE's compactiom score metric not update anymore, I doubt the compaction not works, and use
pstack
to show all threads, there is no "compaction" words except the compaction producer thread. And then usegcore
to dump the process, the producer's stack:That means the wait condition is satisfied but the cv is still wait, so there must be some multi-threads sync problems.
To Reproduce Steps to reproduce the behavior: Very occasional to happen.
Expected behavior All threads works well.