mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-21 17:20:50 +00:00
dbms: added fault injection in memory tracker to more easily reproducing the bug [#METR-19278].
This commit is contained in:
parent
8da3abcd94
commit
d51e03da61
@ -13,6 +13,9 @@ class MemoryTracker
|
|||||||
Int64 peak = 0;
|
Int64 peak = 0;
|
||||||
Int64 limit = 0;
|
Int64 limit = 0;
|
||||||
|
|
||||||
|
/// В целях тестирования exception safety - кидать исключение при каждом выделении памяти с указанной вероятностью.
|
||||||
|
double fault_probability = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MemoryTracker(Int64 limit_) : limit(limit_) {}
|
MemoryTracker(Int64 limit_) : limit(limit_) {}
|
||||||
|
|
||||||
@ -43,6 +46,11 @@ public:
|
|||||||
{
|
{
|
||||||
return peak;
|
return peak;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setFaultProbability(double value)
|
||||||
|
{
|
||||||
|
fault_probability = value;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -48,11 +48,14 @@ struct ProcessListElement
|
|||||||
|
|
||||||
ProcessListElement(const String & query_, const String & user_,
|
ProcessListElement(const String & query_, const String & user_,
|
||||||
const String & query_id_, const Poco::Net::IPAddress & ip_address_,
|
const String & query_id_, const Poco::Net::IPAddress & ip_address_,
|
||||||
size_t max_memory_usage, QueryPriorities::Handle && priority_handle_)
|
size_t max_memory_usage, double memory_tracker_fault_probability, QueryPriorities::Handle && priority_handle_)
|
||||||
: query(query_), user(user_), query_id(query_id_), ip_address(ip_address_), memory_tracker(max_memory_usage),
|
: query(query_), user(user_), query_id(query_id_), ip_address(ip_address_), memory_tracker(max_memory_usage),
|
||||||
priority_handle(std::move(priority_handle_))
|
priority_handle(std::move(priority_handle_))
|
||||||
{
|
{
|
||||||
current_memory_tracker = &memory_tracker;
|
current_memory_tracker = &memory_tracker;
|
||||||
|
|
||||||
|
if (memory_tracker_fault_probability)
|
||||||
|
memory_tracker.setFaultProbability(memory_tracker_fault_probability);
|
||||||
}
|
}
|
||||||
|
|
||||||
~ProcessListElement()
|
~ProcessListElement()
|
||||||
|
@ -188,6 +188,9 @@ struct Settings
|
|||||||
M(SettingMilliseconds, read_backoff_min_interval_between_events_ms, 1000) \
|
M(SettingMilliseconds, read_backoff_min_interval_between_events_ms, 1000) \
|
||||||
/** Количество событий, после которого количество потоков будет уменьшено. */ \
|
/** Количество событий, после которого количество потоков будет уменьшено. */ \
|
||||||
M(SettingUInt64, read_backoff_min_events, 2) \
|
M(SettingUInt64, read_backoff_min_events, 2) \
|
||||||
|
\
|
||||||
|
/** В целях тестирования exception safety - кидать исключение при каждом выделении памяти с указанной вероятностью. */ \
|
||||||
|
M(SettingFloat, memory_tracker_fault_probability, 0.) \
|
||||||
|
|
||||||
/// Всевозможные ограничения на выполнение запроса.
|
/// Всевозможные ограничения на выполнение запроса.
|
||||||
Limits limits;
|
Limits limits;
|
||||||
|
@ -17,6 +17,16 @@ void MemoryTracker::alloc(Int64 size)
|
|||||||
{
|
{
|
||||||
Int64 will_be = __sync_add_and_fetch(&amount, size);
|
Int64 will_be = __sync_add_and_fetch(&amount, size);
|
||||||
|
|
||||||
|
/// Используется непотокобезопасный генератор случайных чисел. Совместное распределение в разных потоках не будет равномерным.
|
||||||
|
/// В данном случае, это нормально.
|
||||||
|
if (unlikely(fault_probability && drand48() < fault_probability))
|
||||||
|
{
|
||||||
|
free(size);
|
||||||
|
throw DB::Exception("Memory tracker: fault injected. Would use " + formatReadableSizeWithBinarySuffix(will_be) + ""
|
||||||
|
" (attempt to allocate chunk of " + DB::toString(size) + " bytes)"
|
||||||
|
", maximum: " + formatReadableSizeWithBinarySuffix(limit), DB::ErrorCodes::MEMORY_LIMIT_EXCEEDED);
|
||||||
|
}
|
||||||
|
|
||||||
if (unlikely(limit && will_be > limit))
|
if (unlikely(limit && will_be > limit))
|
||||||
{
|
{
|
||||||
free(size);
|
free(size);
|
||||||
|
@ -45,7 +45,9 @@ ProcessList::EntryPtr ProcessList::insert(
|
|||||||
++cur_size;
|
++cur_size;
|
||||||
|
|
||||||
res.reset(new Entry(*this, cont.emplace(cont.end(),
|
res.reset(new Entry(*this, cont.emplace(cont.end(),
|
||||||
query_, user_, query_id_, ip_address_, settings.limits.max_memory_usage, priorities.insert(settings.priority))));
|
query_, user_, query_id_, ip_address_,
|
||||||
|
settings.limits.max_memory_usage, settings.memory_tracker_fault_probability,
|
||||||
|
priorities.insert(settings.priority))));
|
||||||
|
|
||||||
if (!query_id_.empty())
|
if (!query_id_.empty())
|
||||||
user_to_queries[user_][query_id_] = &res->get();
|
user_to_queries[user_][query_id_] = &res->get();
|
||||||
|
Loading…
Reference in New Issue
Block a user