This is an automated email from the ASF dual-hosted git repository.
yiguolei pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new 22157077e9 [fix](memtracker) Optimize the return msg of process memory
limit exceed #12086
22157077e9 is described below
commit 22157077e97e95e8c3dd879919a103f2e8ee8369
Author: Xinyi Zou <[email protected]>
AuthorDate: Fri Aug 26 14:28:46 2022 +0800
[fix](memtracker) Optimize the return msg of process memory limit exceed
#12086
Return the real process memory information when the process exceeds mem
limit
Optimize the memory exceed limit log printing logic
process tracker does not participate in process memory limit.
---
be/src/runtime/exec_env_init.cpp | 3 +-
be/src/runtime/memory/mem_tracker_limiter.cpp | 82 +++++++++++++++++++--------
be/src/runtime/memory/mem_tracker_limiter.h | 34 ++++++-----
be/src/runtime/runtime_filter_mgr.cpp | 2 +-
4 files changed, 81 insertions(+), 40 deletions(-)
diff --git a/be/src/runtime/exec_env_init.cpp b/be/src/runtime/exec_env_init.cpp
index 22495aeaf3..0fab11f3ee 100644
--- a/be/src/runtime/exec_env_init.cpp
+++ b/be/src/runtime/exec_env_init.cpp
@@ -203,7 +203,8 @@ Status ExecEnv::_init_mem_tracker() {
<< ". Using physical memory instead";
global_memory_limit_bytes = MemInfo::physical_mem();
}
- _process_mem_tracker = std::make_shared<MemTrackerLimiter>(-1, "Process");
+ _process_mem_tracker =
+ std::make_shared<MemTrackerLimiter>(global_memory_limit_bytes,
"Process");
thread_context()->_thread_mem_tracker_mgr->init();
thread_context()->_thread_mem_tracker_mgr->set_check_attach(false);
#if defined(USE_MEM_TRACKER) && !defined(__SANITIZE_ADDRESS__) &&
!defined(ADDRESS_SANITIZER) && \
diff --git a/be/src/runtime/memory/mem_tracker_limiter.cpp
b/be/src/runtime/memory/mem_tracker_limiter.cpp
index 410ff12d19..32061c8ad9 100644
--- a/be/src/runtime/memory/mem_tracker_limiter.cpp
+++ b/be/src/runtime/memory/mem_tracker_limiter.cpp
@@ -149,8 +149,9 @@ bool MemTrackerLimiter::gc_memory(int64_t max_consumption) {
Status MemTrackerLimiter::try_gc_memory(int64_t bytes) {
if (UNLIKELY(gc_memory(_limit - bytes))) {
return Status::MemoryLimitExceeded(fmt::format(
- "need_size={}, exceeded_tracker={}, limit={}, peak_used={},
current_used={}", bytes,
- label(), _limit, _consumption->value(),
_consumption->current_value()));
+ "failed_alloc_size={}Bytes, exceeded_tracker={}, limit={}B,
peak_used={}B, "
+ "current_used={}B",
+ bytes, label(), _limit, _consumption->value(),
_consumption->current_value()));
}
VLOG_NOTICE << "GC succeeded, TryConsume bytes=" << bytes
<< " consumption=" << _consumption->current_value() << "
limit=" << _limit;
@@ -223,22 +224,26 @@ std::string MemTrackerLimiter::log_usage(int
max_recursive_depth,
return join(usage_strings, "\n");
}
-Status MemTrackerLimiter::mem_limit_exceeded_log(const std::string& msg) {
- DCHECK(_limit != -1);
+Status MemTrackerLimiter::mem_limit_exceeded_construct(const std::string& msg)
{
std::string detail = fmt::format(
- "{}, backend={} memory used={}, free memory left={}. If is query,
can change the limit "
+ "{}, backend {} process memory used {}Bytes, process limit {}B. If
is query, can "
+ "change the limit "
"by `set exec_mem_limit=xxx`, details mem usage see be.INFO.",
msg, BackendOptions::get_localhost(),
PrettyPrinter::print(PerfCounters::get_vm_rss(), TUnit::BYTES),
- PrettyPrinter::print(MemInfo::mem_limit() -
PerfCounters::get_vm_rss(), TUnit::BYTES));
- Status status = Status::MemoryLimitExceeded(detail);
+ PrettyPrinter::print(MemInfo::mem_limit(), TUnit::BYTES));
+ return Status::MemoryLimitExceeded(detail);
+}
+void MemTrackerLimiter::print_log_usage(const std::string& msg) {
+ DCHECK(_limit != -1);
// only print the tracker log_usage in be log.
+ std::string detail = msg;
if (_print_log_usage) {
if (_label == "Process") {
// Dumping the process MemTracker is expensive. Limiting the
recursive depth to two
// levels limits the level of detail to a one-line summary for
each query MemTracker.
- detail += "\n" +
ExecEnv::GetInstance()->process_mem_tracker()->log_usage(2);
+ detail += "\n" + log_usage(2);
} else {
detail += "\n" + log_usage();
}
@@ -246,37 +251,66 @@ Status MemTrackerLimiter::mem_limit_exceeded_log(const
std::string& msg) {
LOG(WARNING) << detail;
_print_log_usage = false;
}
- return status;
}
Status MemTrackerLimiter::mem_limit_exceeded(const std::string& msg,
int64_t failed_allocation_size) {
STOP_CHECK_THREAD_MEM_TRACKER_LIMIT();
DCHECK(!_limited_ancestors.empty());
- std::string detail = fmt::format("memory limit
exceeded:<consumed_tracker={}, ", _label);
+ std::string detail = fmt::format("Memory limit exceeded,
<consuming_tracker={}, ", _label);
if (failed_allocation_size != 0)
- detail += fmt::format("need_size={}, ",
+ detail += fmt::format("failed_alloc_size={}Bytes, ",
PrettyPrinter::print(failed_allocation_size,
TUnit::BYTES));
- MemTrackerLimiter* exceeded_tracker = this;
- int64_t free_size = INT_MAX;
+ MemTrackerLimiter* exceeded_tracker = nullptr;
+ MemTrackerLimiter* max_consumption_tracker = nullptr;
+ int64_t free_size = INT64_MAX;
+ // Find the tracker that exceed limit and has the least free.
for (const auto& tracker : _limited_ancestors) {
+ if (tracker->label() == "Process") continue;
int64_t max_consumption = tracker->peak_consumption() >
tracker->consumption()
? tracker->peak_consumption()
: tracker->consumption();
- if (tracker->has_limit() && tracker->limit() < max_consumption +
failed_allocation_size) {
+ if (tracker->limit() < max_consumption + failed_allocation_size) {
exceeded_tracker = tracker;
break;
}
- if (tracker->has_limit() && tracker->limit() - max_consumption <
free_size) {
+ if (tracker->limit() - max_consumption < free_size) {
free_size = tracker->limit() - max_consumption;
- exceeded_tracker = tracker;
+ max_consumption_tracker = tracker;
}
}
- detail += fmt::format(
- "exceeded_tracker={}, limit={}, peak_used={}, current_used={}>,
executing_msg:<{}>",
- exceeded_tracker->label(), exceeded_tracker->limit(),
- exceeded_tracker->peak_consumption(),
exceeded_tracker->consumption(), msg);
- return exceeded_tracker->mem_limit_exceeded_log(detail);
+
+ auto sys_exceed_st = check_sys_mem_info(failed_allocation_size);
+ MemTrackerLimiter* print_log_usage_tracker = nullptr;
+ if (exceeded_tracker != nullptr) {
+ detail += fmt::format(
+ "exceeded_tracker={}, limit={}B, peak_used={}B,
current_used={B}>, "
+ "executing_msg:<{}>",
+ exceeded_tracker->label(), exceeded_tracker->limit(),
+ exceeded_tracker->peak_consumption(),
exceeded_tracker->consumption(), msg);
+ print_log_usage_tracker = exceeded_tracker;
+ } else if (!sys_exceed_st) {
+ detail = fmt::format("Memory limit exceeded, {}, executing_msg:<{}>",
+ sys_exceed_st.get_error_msg(), msg);
+ } else if (max_consumption_tracker != nullptr) {
+ // must after check_sys_mem_info false
+ detail += fmt::format(
+ "max_consumption_tracker={}, limit={}B, peak_used={}B,
current_used={}B>, "
+ "executing_msg:<{}>",
+ max_consumption_tracker->label(),
max_consumption_tracker->limit(),
+ max_consumption_tracker->peak_consumption(),
max_consumption_tracker->consumption(),
+ msg);
+ print_log_usage_tracker = max_consumption_tracker;
+ } else {
+ // The limit of the current tracker and parents is less than 0, the
consume will not fail,
+ // and the current process memory has no excess limit.
+ detail += fmt::format("unknown exceed reason, executing_msg:<{}>",
msg);
+ print_log_usage_tracker =
ExecEnv::GetInstance()->process_mem_tracker().get();
+ }
+ auto st = MemTrackerLimiter::mem_limit_exceeded_construct(detail);
+ if (print_log_usage_tracker != nullptr)
+ print_log_usage_tracker->print_log_usage(st.get_error_msg());
+ return st;
}
Status MemTrackerLimiter::mem_limit_exceeded(const std::string& msg,
@@ -284,9 +318,11 @@ Status MemTrackerLimiter::mem_limit_exceeded(const
std::string& msg,
Status failed_try_consume_st) {
STOP_CHECK_THREAD_MEM_TRACKER_LIMIT();
std::string detail =
- fmt::format("memory limit exceeded:<consumed_tracker={}, {}>,
executing_msg:<{}>",
+ fmt::format("memory limit exceeded:<consuming_tracker={}, {}>,
executing_msg:<{}>",
_label, failed_try_consume_st.get_error_msg(), msg);
- return failed_tracker->mem_limit_exceeded_log(detail);
+ auto st = MemTrackerLimiter::mem_limit_exceeded_construct(detail);
+ failed_tracker->print_log_usage(st.get_error_msg());
+ return st;
}
Status MemTrackerLimiter::mem_limit_exceeded(RuntimeState* state, const
std::string& msg,
diff --git a/be/src/runtime/memory/mem_tracker_limiter.h
b/be/src/runtime/memory/mem_tracker_limiter.h
index 0e6bbdfd8d..3aaa9d973f 100644
--- a/be/src/runtime/memory/mem_tracker_limiter.h
+++ b/be/src/runtime/memory/mem_tracker_limiter.h
@@ -70,11 +70,12 @@ public:
// of the process malloc.
// for fast, expect MemInfo::initialized() to be true.
if (PerfCounters::get_vm_rss() + bytes >= MemInfo::mem_limit()) {
- return Status::MemoryLimitExceeded(
- "{}: TryConsume failed, bytes={} process physical memory
consumption={} and "
- "virtual memory consumption={}, mem limit={}",
- _label, bytes, PerfCounters::get_vm_rss(),
MemInfo::current_mem(),
- MemInfo::mem_limit());
+ auto st = Status::MemoryLimitExceeded(
+ "Memory limit exceeded, process memory used {}Bytes exceed
limit {}B, "
+ "consuming_tracker={}, failed_alloc_size={}",
+ PerfCounters::get_vm_rss(), MemInfo::mem_limit(), _label,
bytes);
+
ExecEnv::GetInstance()->process_mem_tracker()->print_log_usage(st.get_error_msg());
+ return st;
}
return Status::OK();
}
@@ -197,7 +198,8 @@ private:
const std::list<MemTrackerLimiter*>& trackers,
int64_t* logged_consumption);
- Status mem_limit_exceeded_log(const std::string& msg);
+ static Status mem_limit_exceeded_construct(const std::string& msg);
+ void print_log_usage(const std::string& msg);
private:
// Limit on memory consumption, in bytes. If limit_ == -1, there is no
consumption limit. Used in log_usage。
@@ -280,7 +282,9 @@ inline Status MemTrackerLimiter::try_consume(int64_t bytes)
{
// Walk the tracker tree top-down.
for (i = _all_ancestors.size() - 1; i >= 0; --i) {
MemTrackerLimiter* tracker = _all_ancestors[i];
- if (tracker->limit() < 0) {
+ // Process tracker does not participate in the process memory limit,
process tracker consumption is virtual memory,
+ // and there is a diff between the real physical memory value of the
process. It is replaced by check_sys_mem_info.
+ if (tracker->limit() < 0 || _label == "Process") {
tracker->_consumption->add(bytes); // No limit at this tracker.
} else {
// If TryConsume fails, we can try to GC, but we may need to try
several times if
@@ -309,14 +313,14 @@ inline Status MemTrackerLimiter::check_limit(int64_t
bytes) {
RETURN_IF_ERROR(check_sys_mem_info(bytes));
int i;
// Walk the tracker tree top-down.
- for (i = _all_ancestors.size() - 1; i >= 0; --i) {
- MemTrackerLimiter* tracker = _all_ancestors[i];
- if (tracker->limit() > 0) {
- while (true) {
- if (LIKELY(tracker->_consumption->current_value() + bytes <
tracker->limit()))
- break;
- RETURN_IF_ERROR(tracker->try_gc_memory(bytes));
- }
+ for (i = _limited_ancestors.size() - 1; i >= 0; --i) {
+ MemTrackerLimiter* tracker = _limited_ancestors[i];
+ // Process tracker does not participate in the process memory limit,
process tracker consumption is virtual memory,
+ // and there is a diff between the real physical memory value of the
process. It is replaced by check_sys_mem_info.
+ if (tracker->label() == "Process") continue;
+ while (true) {
+ if (LIKELY(tracker->_consumption->current_value() + bytes <
tracker->limit())) break;
+ RETURN_IF_ERROR(tracker->try_gc_memory(bytes));
}
}
return Status::OK();
diff --git a/be/src/runtime/runtime_filter_mgr.cpp
b/be/src/runtime/runtime_filter_mgr.cpp
index 85d0fab248..0134886779 100644
--- a/be/src/runtime/runtime_filter_mgr.cpp
+++ b/be/src/runtime/runtime_filter_mgr.cpp
@@ -185,7 +185,7 @@ Status RuntimeFilterMergeControllerEntity::init(UniqueId
query_id, UniqueId frag
// merge data
Status RuntimeFilterMergeControllerEntity::merge(const PMergeFilterRequest*
request,
const char* data) {
- SCOPED_CONSUME_MEM_TRACKER(_mem_tracker.get());
+ // SCOPED_CONSUME_MEM_TRACKER(_mem_tracker.get());
std::shared_ptr<RuntimeFilterCntlVal> cntVal;
int merged_size = 0;
{
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]