-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: db cannot resume after disk has no space #1765
Changes from all commits
8cbc610
82b2ef1
9433bf3
138269c
613f862
d2ef6ab
00f232b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -217,6 +217,22 @@ slave-priority : 100 | |
# [NOTICE]: compact-interval is prior than compact-cron. | ||
#compact-interval : | ||
|
||
# The minimum disk usage ratio for checking resume. | ||
# If the disk usage ratio is lower than min-check-resume-ratio, it will not check resume, only higher will check resume. | ||
# Its default value is 0.7. | ||
#min-check-resume-ratio : 0.7 | ||
|
||
# The minimum free disk space to trigger db resume. | ||
# If the db has a background error, only the free disk size is larger than this configuration can trigger manually resume db. | ||
# Its default value is 256MB. | ||
# [NOTICE]: least-free-disk-resume-size should not smaller than write-buffer-size! | ||
#least-free-disk-resume-size : 256M | ||
|
||
# Manually trying to resume db interval is configured by manually-resume-interval. | ||
# If db has a background error, it will try to manually call resume() to resume db if satisfy the least free disk to resume. | ||
# Its default value is 60 seconds. | ||
#manually-resume-interval : 60 | ||
|
||
# This window-size determines the amount of data that can be transmitted in a single synchronization process. | ||
# [Tip] In the scenario of high network latency. Increasing this size can improve synchronization efficiency. | ||
# Its default value is 9000. the [maximum] value is 90000. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here are some observations and suggestions for the code patch:
Remember to thoroughly test any changes made and consider seeking feedback from other developers familiar with the project for a comprehensive review. |
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -52,6 +52,7 @@ PikaServer::PikaServer() | |
: exit_(false), | ||
slot_state_(INFREE), | ||
last_check_compact_time_({0, 0}), | ||
last_check_resume_time_({0, 0}), | ||
repl_state_(PIKA_REPL_NO_CONNECT), | ||
role_(PIKA_ROLE_SINGLE) { | ||
// Init server ip host | ||
|
@@ -1295,6 +1296,8 @@ void PikaServer::PubSubNumSub(const std::vector<std::string>& channels, | |
/******************************* PRIVATE *******************************/ | ||
|
||
void PikaServer::DoTimingTask() { | ||
// Resume DB if satisfy the condition | ||
AutoResumeDB(); | ||
// Maybe schedule compactrange | ||
AutoCompactRange(); | ||
// Purge log | ||
|
@@ -1487,6 +1490,57 @@ void PikaServer::AutoKeepAliveRSync() { | |
} | ||
} | ||
|
||
void PikaServer::AutoResumeDB() { | ||
struct statfs disk_info; | ||
int ret = statfs(g_pika_conf->db_path().c_str(), &disk_info); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see it uses There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
if (ret == -1) { | ||
LOG(WARNING) << "statfs error: " << strerror(errno); | ||
return; | ||
} | ||
|
||
int64_t interval = g_pika_conf->resume_interval(); | ||
int64_t least_free_size = g_pika_conf->least_resume_free_disk_size(); | ||
double min_check_resume_ratio = g_pika_conf->min_check_resume_ratio(); | ||
uint64_t free_size = disk_info.f_bsize * disk_info.f_bfree; | ||
uint64_t total_size = disk_info.f_bsize * disk_info.f_blocks; | ||
double disk_use_ratio = 1.0 - static_cast<double>(free_size) / static_cast<double>(total_size); | ||
|
||
struct timeval now; | ||
gettimeofday(&now, nullptr); | ||
// first check or time interval between now and last check is larger than variable "interval" | ||
if (last_check_resume_time_.tv_sec == 0 || now.tv_sec - last_check_resume_time_.tv_sec >= interval) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 在这个 if 上面加上英文注释,体现 ”第一次检验 或者 距离上次 check 时间超过 interval“ 这个 condition There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 第二,我建议先检测下当前磁盘总体使用情况,整体空闲率低于某个阈值【如 30%】时,才进来执行 check 操作,以减少加锁次数 |
||
gettimeofday(&last_check_resume_time_, nullptr); | ||
if (disk_use_ratio < min_check_resume_ratio || free_size < least_free_size){ | ||
return; | ||
} | ||
|
||
std::map<std::string, uint64_t> background_errors; | ||
std::shared_lock db_rwl(g_pika_server->dbs_rw_); | ||
// loop every db | ||
for (const auto& db_item : g_pika_server->dbs_) { | ||
Mixficsol marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if (!db_item.second) { | ||
continue; | ||
} | ||
std::shared_lock slot_rwl(db_item.second->slots_rw_); | ||
// loop every slot | ||
for (const auto& slot_item : db_item.second->slots_) { | ||
Mixficsol marked this conversation as resolved.
Show resolved
Hide resolved
|
||
background_errors.clear(); | ||
slot_item.second->DbRWLockReader(); | ||
slot_item.second->db()->GetUsage(storage::PROPERTY_TYPE_ROCKSDB_BACKGROUND_ERRORS, &background_errors); | ||
slot_item.second->DbRWUnLock(); | ||
for (const auto& item : background_errors) { | ||
if (item.second != 0) { | ||
rocksdb::Status s = slot_item.second->db()->GetDBByType(item.first)->Resume(); | ||
if (!s.ok()) { | ||
LOG(WARNING) << s.ToString(); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
void PikaServer::AutoUpdateNetworkMetric() { | ||
monotime current_time = getMonotonicUs(); | ||
size_t factor = 5e6; // us, 5s | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on the provided code patch, here are some observations and suggestions:
The added configurations
least-free-disk-resume-size
andmanually-resume-interval
seem appropriate in terms of functionality. However, it's important to ensure that these values are suitable for your specific use case and environment.For the
least-free-disk-resume-size
configuration, the value of 268435456 bytes corresponds to approximately 256MB, as mentioned in the comment. If this value aligns with your requirements, there doesn't appear to be any bug or issue.Similarly, for the
manually-resume-interval
configuration, the default value of 600 seconds (10 minutes) seems reasonable. Again, make sure it suits your needs.Reviewing the rest of the code patch, there don't appear to be any bugs or risks. However, it's difficult to provide a comprehensive review without seeing the context or the surrounding code.
If you have any specific concerns or further details regarding the code, please provide them for a more thorough review.
Remember to thoroughly test the changes and monitor the system after applying the patch to ensure it behaves as expected in your specific setup.