diff --git a/dbms/src/Common/ThreadStatus.h b/dbms/src/Common/ThreadStatus.h index 822e1931447..05994883040 100644 --- a/dbms/src/Common/ThreadStatus.h +++ b/dbms/src/Common/ThreadStatus.h @@ -144,6 +144,10 @@ protected: void initPerformanceCounters(); + void initQueryProfiler(); + + void finalizeQueryProfiler(); + void logToQueryThreadLog(QueryThreadLog & thread_log); void assertState(const std::initializer_list & permitted_states, const char * description = nullptr); @@ -165,6 +169,9 @@ protected: time_t query_start_time = 0; size_t queries_started = 0; + bool has_query_profiler = false; + timer_t query_profiler_timer_id = 0; + Poco::Logger * log = nullptr; friend class CurrentThread; diff --git a/dbms/src/Interpreters/ThreadStatusExt.cpp b/dbms/src/Interpreters/ThreadStatusExt.cpp index eac9251cdf0..ffd12572cf1 100644 --- a/dbms/src/Interpreters/ThreadStatusExt.cpp +++ b/dbms/src/Interpreters/ThreadStatusExt.cpp @@ -5,7 +5,12 @@ #include #include #include +#include +#include +#include +#include +#include /// Implement some methods of ThreadStatus and CurrentThread here to avoid extra linking dependencies in clickhouse_common_io namespace DB @@ -92,6 +97,10 @@ void ThreadStatus::attachQuery(const ThreadGroupStatusPtr & thread_group_, bool } initPerformanceCounters(); + + LOG_INFO(&Logger::get("laplab"), "Attaching"); + initQueryProfiler(); + thread_state = ThreadState::AttachedToQuery; } @@ -119,6 +128,49 @@ void ThreadStatus::finalizePerformanceCounters() } } +namespace { + void queryProfilerTimerHandler(int /* signal */) { + LOG_INFO(&Logger::get("laplab"), "Hello from handler!"); + } +} + +void ThreadStatus::initQueryProfiler() { + sigevent sev; + sev.sigev_notify = SIGEV_THREAD_ID; + sev.sigev_signo = SIGALRM; + sev._sigev_un._tid = os_thread_id; + // TODO(laplab): get clock type from settings + if (timer_create(CLOCK_REALTIME, &sev, &query_profiler_timer_id)) { + LOG_ERROR(log, "Failed to create query profiler timer"); + return; + } + + // TODO(laplab): get period from settings + timespec period{.tv_sec = 10, .tv_nsec = 0}; + itimerspec timer_spec = {.it_interval = period, .it_value = period}; + if (timer_settime(query_profiler_timer_id, 0, &timer_spec, nullptr)) { + LOG_ERROR(log, "Failed to set query profiler timer"); + return; + } + + std::signal(SIGALRM, queryProfilerTimerHandler); + + has_query_profiler = true; +} + +void ThreadStatus::finalizeQueryProfiler() { + if (!has_query_profiler) { + return; + } + + if (timer_delete(query_profiler_timer_id)) { + LOG_ERROR(log, "Failed to delete query profiler timer"); + return; + } + + has_query_profiler = false; +} + void ThreadStatus::detachQuery(bool exit_if_already_detached, bool thread_exits) { if (exit_if_already_detached && thread_state == ThreadState::DetachedFromQuery) @@ -128,6 +180,8 @@ void ThreadStatus::detachQuery(bool exit_if_already_detached, bool thread_exits) } assertState({ThreadState::AttachedToQuery}, __PRETTY_FUNCTION__); + + finalizeQueryProfiler(); finalizePerformanceCounters(); /// Detach from thread group @@ -140,6 +194,8 @@ void ThreadStatus::detachQuery(bool exit_if_already_detached, bool thread_exits) query_context = nullptr; thread_group.reset(); + LOG_INFO(&Logger::get("laplab"), "Detaching"); + thread_state = thread_exits ? ThreadState::Died : ThreadState::DetachedFromQuery; }