ClickHouse/src/Common/OvercommitTracker.cpp

120 lines
3.7 KiB
C++
Raw Normal View History

2021-10-22 12:56:09 +00:00
#include "OvercommitTracker.h"
2021-10-22 15:15:33 +00:00
#include <chrono>
2021-12-06 22:16:09 +00:00
#include <mutex>
2021-10-22 12:56:09 +00:00
#include <Interpreters/ProcessList.h>
2021-10-22 15:15:33 +00:00
using namespace std::chrono_literals;
OvercommitTracker::OvercommitTracker()
: max_wait_time(0us)
, picked_tracker(nullptr)
, cancelation_state(QueryCancelationState::NONE)
{}
void OvercommitTracker::setMaxWaitTime(UInt64 wait_time)
{
2022-01-18 12:21:59 +00:00
std::lock_guard guard(overcommit_m);
2021-10-22 15:15:33 +00:00
max_wait_time = wait_time * 1us;
}
2021-10-22 12:56:09 +00:00
bool OvercommitTracker::needToStopQuery(MemoryTracker * tracker)
{
std::unique_lock<std::mutex> lk(overcommit_m);
pickQueryToExclude();
assert(cancelation_state == QueryCancelationState::RUNNING);
2022-01-18 12:21:59 +00:00
// If no query was chosen we need to stop current query.
// This may happen if no soft limit is set.
if (picked_tracker == nullptr)
{
cancelation_state = QueryCancelationState::NONE;
2021-10-22 12:56:09 +00:00
return true;
}
if (picked_tracker == tracker)
return true;
2022-01-18 12:21:59 +00:00
return !cv.wait_for(lk, max_wait_time, [this]()
2021-10-22 12:56:09 +00:00
{
return cancelation_state == QueryCancelationState::NONE;
});
}
void OvercommitTracker::unsubscribe(MemoryTracker * tracker)
{
std::unique_lock<std::mutex> lk(overcommit_m);
if (picked_tracker == tracker)
{
2022-01-18 12:21:59 +00:00
LOG_DEBUG(getLogger(), "Picked query stopped");
picked_tracker = nullptr;
cancelation_state = QueryCancelationState::NONE;
cv.notify_all();
}
}
2021-10-22 12:56:09 +00:00
UserOvercommitTracker::UserOvercommitTracker(DB::ProcessListForUser * user_process_list_)
: user_process_list(user_process_list_)
{}
void UserOvercommitTracker::pickQueryToExcludeImpl()
{
2022-01-18 12:21:59 +00:00
MemoryTracker * query_tracker = nullptr;
2021-10-22 12:56:09 +00:00
OvercommitRatio current_ratio{0, 0};
2022-01-18 12:21:59 +00:00
// At this moment query list must be read only.
// BlockQueryIfMemoryLimit is used in ProcessList to guarantee this.
auto & queries = user_process_list->queries;
2021-12-06 22:06:00 +00:00
LOG_DEBUG(logger, "Trying to choose query to stop from {} queries", queries.size());
for (auto const & query : queries)
2021-10-22 12:56:09 +00:00
{
if (query.second->isKilled())
continue;
2021-10-22 12:56:09 +00:00
auto * memory_tracker = query.second->getMemoryTracker();
if (!memory_tracker)
continue;
2021-10-22 12:56:09 +00:00
auto ratio = memory_tracker->getOvercommitRatio();
2021-12-06 22:06:00 +00:00
LOG_DEBUG(logger, "Query has ratio {}/{}", ratio.committed, ratio.soft_limit);
if (ratio.soft_limit != 0 && current_ratio < ratio)
2021-10-22 12:56:09 +00:00
{
2022-01-18 12:21:59 +00:00
query_tracker = memory_tracker;
2021-10-22 12:56:09 +00:00
current_ratio = ratio;
}
}
2021-12-06 22:06:00 +00:00
LOG_DEBUG(logger, "Selected to stop query with overcommit ratio {}/{}",
current_ratio.committed, current_ratio.soft_limit);
2022-01-18 12:21:59 +00:00
picked_tracker = query_tracker;
2021-10-22 12:56:09 +00:00
}
void GlobalOvercommitTracker::pickQueryToExcludeImpl()
{
2022-01-18 12:21:59 +00:00
MemoryTracker * query_tracker = nullptr;
2021-10-22 12:56:09 +00:00
OvercommitRatio current_ratio{0, 0};
process_list->processEachQueryStatus([&](DB::QueryStatus const & query)
{
2021-12-06 22:06:00 +00:00
if (query.isKilled())
return;
Int64 user_soft_limit = 0;
if (auto const * user_process_list = query.getUserProcessList())
user_soft_limit = user_process_list->user_memory_tracker.getSoftLimit();
2021-12-06 22:06:00 +00:00
if (user_soft_limit == 0)
return;
2021-12-06 22:06:00 +00:00
auto * memory_tracker = query.getMemoryTracker();
if (!memory_tracker)
return;
auto ratio = memory_tracker->getOvercommitRatio(user_soft_limit);
2021-12-06 22:06:00 +00:00
LOG_DEBUG(logger, "Query has ratio {}/{}", ratio.committed, ratio.soft_limit);
2021-10-22 12:56:09 +00:00
if (current_ratio < ratio)
{
2022-01-18 12:21:59 +00:00
query_tracker = memory_tracker;
2021-10-22 12:56:09 +00:00
current_ratio = ratio;
}
});
2021-12-06 22:06:00 +00:00
LOG_DEBUG(logger, "Selected to stop query with overcommit ratio {}/{}",
current_ratio.committed, current_ratio.soft_limit);
2022-01-18 12:21:59 +00:00
picked_tracker = query_tracker;
2021-10-22 12:56:09 +00:00
}