fix(server): data race when accessing the db scan info (#3199)
For the data race details, refer to [GitHub Action
Logs](https://github.com/apache/kvrocks/actions/runs/17972329716/job/51119679082?pr=3196):
```
WARNING: ThreadSanitizer: data race (pid=90210)
Write of size 8 at 0x7b1c00017030 by thread T150 (mutexes: write M0):
#0 Server::AsyncScanDBSize(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::$_9::operator()() const /home/runner/work/kvrocks/kvrocks/src/server/server.cc:1636:44 (kvrocks+0x15ddb14) (BuildId: dca9d021cc579ae4)
#1 void std::__invoke_impl<void, Server::AsyncScanDBSize(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::$_9&>(std::__invoke_other, Server::AsyncScanDBSize(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::$_9&) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/invoke.h:61:14 (kvrocks+0x15ddb14)
...
Previous read of size 8 at 0x7b1c00017030 by thread T145 (mutexes: read M1):
#0 Server::GetLastScanTime(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const /home/runner/work/kvrocks/kvrocks/src/server/server.cc:1652:25 (kvrocks+0x15bc3aa) (BuildId: dca9d021cc579ae4)
#1 Server::GetKeyspaceInfo(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/runner/work/kvrocks/kvrocks/src/server/server.cc:1418:57 (kvrocks+0x15bc3aa)
#2 Server::GetInfo(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&)::$_5::operator()(Server*) const /home/runner/work/kvrocks/kvrocks/src/server/server.cc:1454:91 (kvrocks+0x15cafbc) (BuildId: dca9d021cc579ae4)
```diff --git a/src/server/server.cc b/src/server/server.cc
index 04e62fe..d16e756 100644
--- a/src/server/server.cc
+++ b/src/server/server.cc
@@ -1646,7 +1646,8 @@
}
}
-int64_t Server::GetLastScanTime(const std::string &ns) const {
+int64_t Server::GetLastScanTime(const std::string &ns) {
+ std::lock_guard<std::mutex> lg(db_job_mu_);
auto iter = db_scan_infos_.find(ns);
if (iter != db_scan_infos_.end()) {
return iter->second.last_scan_time_secs;
diff --git a/src/server/server.h b/src/server/server.h
index 7063a66..597ea00 100644
--- a/src/server/server.h
+++ b/src/server/server.h
@@ -290,7 +290,7 @@
Status AsyncPurgeOldBackups(uint32_t num_backups_to_keep, uint32_t backup_max_keep_hours);
Status AsyncScanDBSize(const std::string &ns);
void GetLatestKeyNumStats(const std::string &ns, KeyNumStats *stats);
- int64_t GetLastScanTime(const std::string &ns) const;
+ int64_t GetLastScanTime(const std::string &ns);
StatusOr<std::vector<rocksdb::BatchResult>> PollUpdates(uint64_t next_sequence, int64_t count, bool is_strict) const;
std::string GenerateCursorFromKeyName(const std::string &key_name, CursorType cursor_type, const char *prefix = "");