Merge pull request #30000 from ClickHouse/profile-snapshot

Make read of Counters snapshot non-atomic
This commit is contained in:
Maksim Kita 2021-10-14 13:22:44 +03:00 committed by GitHub
commit 8ed4e73705
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 37 additions and 19 deletions

View File

@ -301,11 +301,15 @@ void Counters::reset()
resetCounters(); resetCounters();
} }
Counters Counters::getPartiallyAtomicSnapshot() const Counters::Snapshot::Snapshot()
: counters_holder(new Count[num_counters] {})
{}
Counters::Snapshot Counters::getPartiallyAtomicSnapshot() const
{ {
Counters res(VariableContext::Snapshot, nullptr); Snapshot res;
for (Event i = 0; i < num_counters; ++i) for (Event i = 0; i < num_counters; ++i)
res.counters[i].store(counters[i].load(std::memory_order_relaxed), std::memory_order_relaxed); res.counters_holder[i] = counters[i].load(std::memory_order_relaxed);
return res; return res;
} }

View File

@ -59,8 +59,23 @@ namespace ProfileEvents
} while (current != nullptr); } while (current != nullptr);
} }
struct Snapshot
{
Snapshot();
const Count & operator[] (Event event) const
{
return counters_holder[event];
}
private:
std::unique_ptr<Count[]> counters_holder;
friend class Counters;
};
/// Every single value is fetched atomically, but not all values as a whole. /// Every single value is fetched atomically, but not all values as a whole.
Counters getPartiallyAtomicSnapshot() const; Snapshot getPartiallyAtomicSnapshot() const;
/// Reset all counters to zero and reset parent. /// Reset all counters to zero and reset parent.
void reset(); void reset();

View File

@ -8,5 +8,4 @@ enum class VariableContext
User, /// Group of processes User, /// Group of processes
Process, /// For example, a query or a merge Process, /// For example, a query or a merge
Thread, /// A thread of a process Thread, /// A thread of a process
Snapshot /// Does not belong to anybody
}; };

View File

@ -408,7 +408,7 @@ QueryStatusInfo QueryStatus::getInfo(bool get_thread_list, bool get_profile_even
} }
if (get_profile_events) if (get_profile_events)
res.profile_counters = std::make_shared<ProfileEvents::Counters>(thread_group->performance_counters.getPartiallyAtomicSnapshot()); res.profile_counters = std::make_shared<ProfileEvents::Counters::Snapshot>(thread_group->performance_counters.getPartiallyAtomicSnapshot());
} }
if (get_settings && getContext()) if (get_settings && getContext())
@ -446,7 +446,7 @@ ProcessListForUserInfo ProcessListForUser::getInfo(bool get_profile_events) cons
res.peak_memory_usage = user_memory_tracker.getPeak(); res.peak_memory_usage = user_memory_tracker.getPeak();
if (get_profile_events) if (get_profile_events)
res.profile_counters = std::make_shared<ProfileEvents::Counters>(user_performance_counters.getPartiallyAtomicSnapshot()); res.profile_counters = std::make_shared<ProfileEvents::Counters::Snapshot>(user_performance_counters.getPartiallyAtomicSnapshot());
return res; return res;
} }

View File

@ -66,7 +66,7 @@ struct QueryStatusInfo
/// Optional fields, filled by query /// Optional fields, filled by query
std::vector<UInt64> thread_ids; std::vector<UInt64> thread_ids;
std::shared_ptr<ProfileEvents::Counters> profile_counters; std::shared_ptr<ProfileEvents::Counters::Snapshot> profile_counters;
std::shared_ptr<Settings> query_settings; std::shared_ptr<Settings> query_settings;
std::string current_database; std::string current_database;
}; };
@ -186,7 +186,7 @@ struct ProcessListForUserInfo
Int64 peak_memory_usage; Int64 peak_memory_usage;
// Optional field, filled by request. // Optional field, filled by request.
std::shared_ptr<ProfileEvents::Counters> profile_counters; std::shared_ptr<ProfileEvents::Counters::Snapshot> profile_counters;
}; };

View File

@ -12,7 +12,7 @@ namespace ProfileEvents
{ {
/// Put implementation here to avoid extra linking dependencies for clickhouse_common_io /// Put implementation here to avoid extra linking dependencies for clickhouse_common_io
void dumpToMapColumn(const Counters & counters, DB::IColumn * column, bool nonzero_only) void dumpToMapColumn(const Counters::Snapshot & counters, DB::IColumn * column, bool nonzero_only)
{ {
auto * column_map = column ? &typeid_cast<DB::ColumnMap &>(*column) : nullptr; auto * column_map = column ? &typeid_cast<DB::ColumnMap &>(*column) : nullptr;
if (!column_map) if (!column_map)
@ -26,7 +26,7 @@ void dumpToMapColumn(const Counters & counters, DB::IColumn * column, bool nonze
size_t size = 0; size_t size = 0;
for (Event event = 0; event < Counters::num_counters; ++event) for (Event event = 0; event < Counters::num_counters; ++event)
{ {
UInt64 value = counters[event].load(std::memory_order_relaxed); UInt64 value = counters[event];
if (nonzero_only && 0 == value) if (nonzero_only && 0 == value)
continue; continue;

View File

@ -7,6 +7,6 @@ namespace ProfileEvents
{ {
/// Dumps profile events to columns Map(String, UInt64) /// Dumps profile events to columns Map(String, UInt64)
void dumpToMapColumn(const Counters & counters, DB::IColumn * column, bool nonzero_only = true); void dumpToMapColumn(const Counters::Snapshot & counters, DB::IColumn * column, bool nonzero_only = true);
} }

View File

@ -80,7 +80,7 @@ struct QueryLogElement
String log_comment; String log_comment;
std::vector<UInt64> thread_ids; std::vector<UInt64> thread_ids;
std::shared_ptr<ProfileEvents::Counters> profile_counters; std::shared_ptr<ProfileEvents::Counters::Snapshot> profile_counters;
std::shared_ptr<Settings> query_settings; std::shared_ptr<Settings> query_settings;
static std::string name() { return "QueryLog"; } static std::string name() { return "QueryLog"; }

View File

@ -45,7 +45,7 @@ struct QueryThreadLogElement
ClientInfo client_info; ClientInfo client_info;
std::shared_ptr<ProfileEvents::Counters> profile_counters; std::shared_ptr<ProfileEvents::Counters::Snapshot> profile_counters;
static std::string name() { return "QueryThreadLog"; } static std::string name() { return "QueryThreadLog"; }

View File

@ -64,7 +64,7 @@ struct QueryViewsLogElement
UInt64 written_rows{}; UInt64 written_rows{};
UInt64 written_bytes{}; UInt64 written_bytes{};
Int64 peak_memory_usage{}; Int64 peak_memory_usage{};
std::shared_ptr<ProfileEvents::Counters> profile_counters; std::shared_ptr<ProfileEvents::Counters::Snapshot> profile_counters;
ViewStatus status = ViewStatus::QUERY_START; ViewStatus status = ViewStatus::QUERY_START;
Int32 exception_code{}; Int32 exception_code{};

View File

@ -478,7 +478,7 @@ void ThreadStatus::logToQueryThreadLog(QueryThreadLog & thread_log, const String
if (query_context_ptr->getSettingsRef().log_profile_events != 0) if (query_context_ptr->getSettingsRef().log_profile_events != 0)
{ {
/// NOTE: Here we are in the same thread, so we can make memcpy() /// NOTE: Here we are in the same thread, so we can make memcpy()
elem.profile_counters = std::make_shared<ProfileEvents::Counters>(performance_counters.getPartiallyAtomicSnapshot()); elem.profile_counters = std::make_shared<ProfileEvents::Counters::Snapshot>(performance_counters.getPartiallyAtomicSnapshot());
} }
} }
@ -519,7 +519,7 @@ void ThreadStatus::logToQueryViewsLog(const ViewRuntimeData & vinfo)
element.view_query = getCleanQueryAst(vinfo.query, query_context_ptr); element.view_query = getCleanQueryAst(vinfo.query, query_context_ptr);
element.view_target = vinfo.runtime_stats->target_name; element.view_target = vinfo.runtime_stats->target_name;
auto events = std::make_shared<ProfileEvents::Counters>(performance_counters.getPartiallyAtomicSnapshot()); auto events = std::make_shared<ProfileEvents::Counters::Snapshot>(performance_counters.getPartiallyAtomicSnapshot());
element.read_rows = progress_in.read_rows.load(std::memory_order_relaxed); element.read_rows = progress_in.read_rows.load(std::memory_order_relaxed);
element.read_bytes = progress_in.read_bytes.load(std::memory_order_relaxed); element.read_bytes = progress_in.read_bytes.load(std::memory_order_relaxed);
element.written_rows = (*events)[ProfileEvents::InsertedRows]; element.written_rows = (*events)[ProfileEvents::InsertedRows];

View File

@ -843,7 +843,7 @@ namespace
struct ProfileEventsSnapshot struct ProfileEventsSnapshot
{ {
UInt64 thread_id; UInt64 thread_id;
ProfileEvents::Counters counters; ProfileEvents::Counters::Snapshot counters;
Int64 memory_usage; Int64 memory_usage;
time_t current_time; time_t current_time;
}; };
@ -861,7 +861,7 @@ namespace
auto & value_column = columns[VALUE_COLUMN_INDEX]; auto & value_column = columns[VALUE_COLUMN_INDEX];
for (ProfileEvents::Event event = 0; event < ProfileEvents::Counters::num_counters; ++event) for (ProfileEvents::Event event = 0; event < ProfileEvents::Counters::num_counters; ++event)
{ {
UInt64 value = snapshot.counters[event].load(std::memory_order_relaxed); UInt64 value = snapshot.counters[event];
if (value == 0) if (value == 0)
continue; continue;