-
Notifications
You must be signed in to change notification settings - Fork 3.7k
[Fix](hdfs-writer) Fix hdfs file writer core with check failed: _ref_cnt == 0 in dtor of HdfsFileWriter.
#33959
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
Changes from all commits
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 |
|---|---|---|
|
|
@@ -81,7 +81,7 @@ bvar::LatencyRecorder hdfs_hsync_latency("hdfs_hsync"); | |
| void HdfsHandlerCache::_clean_invalid() { | ||
| std::vector<uint64> removed_handle; | ||
| for (auto& item : _cache) { | ||
| if (item.second->invalid() && item.second->ref_cnt() == 0) { | ||
| if (item.second.use_count() == 1 && item.second->invalid()) { | ||
| removed_handle.emplace_back(item.first); | ||
| } | ||
| } | ||
|
|
@@ -94,7 +94,7 @@ void HdfsHandlerCache::_clean_oldest() { | |
| uint64_t oldest_time = ULONG_MAX; | ||
| uint64 oldest = 0; | ||
| for (auto& item : _cache) { | ||
| if (item.second->ref_cnt() == 0 && item.second->last_access_time() < oldest_time) { | ||
| if (item.second.use_count() == 1 && item.second->last_access_time() < oldest_time) { | ||
| oldest_time = item.second->last_access_time(); | ||
| oldest = item.first; | ||
| } | ||
|
|
@@ -103,16 +103,16 @@ void HdfsHandlerCache::_clean_oldest() { | |
| } | ||
|
|
||
| Status HdfsHandlerCache::get_connection(const THdfsParams& hdfs_params, const std::string& fs_name, | ||
| HdfsHandler** fs_handle) { | ||
| std::shared_ptr<HdfsHandler>* fs_handle) { | ||
| uint64 hash_code = hdfs_hash_code(hdfs_params); | ||
| { | ||
| std::lock_guard<std::mutex> l(_lock); | ||
| auto it = _cache.find(hash_code); | ||
| if (it != _cache.end()) { | ||
| HdfsHandler* handle = it->second.get(); | ||
| std::shared_ptr<HdfsHandler> handle = it->second; | ||
| if (!handle->invalid()) { | ||
| handle->inc_ref(); | ||
| *fs_handle = handle; | ||
| handle->update_last_access_time(); | ||
| *fs_handle = std::move(handle); | ||
|
Contributor
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. why do we still have to deal with
Contributor
Author
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. It is for fs handle cache. |
||
| return Status::OK(); | ||
| } | ||
| // fs handle is invalid, erase it. | ||
|
|
@@ -129,12 +129,12 @@ Status HdfsHandlerCache::get_connection(const THdfsParams& hdfs_params, const st | |
| _clean_oldest(); | ||
| } | ||
| if (_cache.size() < MAX_CACHE_HANDLE) { | ||
| std::unique_ptr<HdfsHandler> handle = std::make_unique<HdfsHandler>(hdfs_fs, true); | ||
| handle->inc_ref(); | ||
| *fs_handle = handle.get(); | ||
| auto handle = std::make_shared<HdfsHandler>(hdfs_fs, true); | ||
| handle->update_last_access_time(); | ||
| *fs_handle = handle; | ||
| _cache[hash_code] = std::move(handle); | ||
| } else { | ||
| *fs_handle = new HdfsHandler(hdfs_fs, false); | ||
| *fs_handle = std::make_shared<HdfsHandler>(hdfs_fs, false); | ||
| } | ||
| } | ||
| return Status::OK(); | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -54,15 +54,13 @@ class HdfsHandler { | |||||
| HdfsHandler(hdfsFS fs, bool cached) | ||||||
| : hdfs_fs(fs), | ||||||
| from_cache(cached), | ||||||
| _ref_cnt(0), | ||||||
| _create_time(std::chrono::duration_cast<std::chrono::milliseconds>( | ||||||
| std::chrono::system_clock::now().time_since_epoch()) | ||||||
| .count()), | ||||||
| _last_access_time(0), | ||||||
| _invalid(false) {} | ||||||
|
|
||||||
| ~HdfsHandler() { | ||||||
| DCHECK(_ref_cnt == 0); | ||||||
| if (hdfs_fs != nullptr) { | ||||||
| // DO NOT call hdfsDisconnect(), or we will meet "Filesystem closed" | ||||||
| // even if we create a new one | ||||||
|
|
@@ -73,17 +71,14 @@ class HdfsHandler { | |||||
|
|
||||||
| int64_t last_access_time() { return _last_access_time; } | ||||||
|
|
||||||
| void inc_ref() { | ||||||
| _ref_cnt++; | ||||||
| _last_access_time = std::chrono::duration_cast<std::chrono::milliseconds>( | ||||||
| std::chrono::system_clock::now().time_since_epoch()) | ||||||
| .count(); | ||||||
| void update_last_access_time() { | ||||||
|
Contributor
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. warning: method 'update_last_access_time' can be made const [readability-make-member-function-const]
Suggested change
|
||||||
| if (from_cache) { | ||||||
| _last_access_time = std::chrono::duration_cast<std::chrono::milliseconds>( | ||||||
| std::chrono::system_clock::now().time_since_epoch()) | ||||||
| .count(); | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| void dec_ref() { _ref_cnt--; } | ||||||
|
|
||||||
| int ref_cnt() { return _ref_cnt; } | ||||||
|
|
||||||
| bool invalid() { return _invalid; } | ||||||
|
|
||||||
| void set_invalid() { _invalid = true; } | ||||||
|
|
@@ -94,8 +89,6 @@ class HdfsHandler { | |||||
| const bool from_cache; | ||||||
|
|
||||||
| private: | ||||||
| // the number of referenced client | ||||||
| std::atomic<int> _ref_cnt; | ||||||
| // For kerberos authentication, we need to save create time so that | ||||||
| // we can know if the kerberos ticket is expired. | ||||||
| std::atomic<uint64_t> _create_time; | ||||||
|
|
@@ -118,13 +111,13 @@ class HdfsHandlerCache { | |||||
|
|
||||||
| // This function is thread-safe | ||||||
| Status get_connection(const THdfsParams& hdfs_params, const std::string& fs_name, | ||||||
| HdfsHandler** fs_handle); | ||||||
| std::shared_ptr<HdfsHandler>* fs_handle); | ||||||
|
|
||||||
| private: | ||||||
| static constexpr int MAX_CACHE_HANDLE = 64; | ||||||
|
|
||||||
| std::mutex _lock; | ||||||
| std::unordered_map<uint64_t, std::unique_ptr<HdfsHandler>> _cache; | ||||||
| std::unordered_map<uint64_t, std::shared_ptr<HdfsHandler>> _cache; | ||||||
|
|
||||||
| HdfsHandlerCache() = default; | ||||||
|
|
||||||
|
|
||||||
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.
可以不用显式写 = nullptr,智能指针默认初始化都是 nullptr