2018-08-22 00:24:55 +00:00
|
|
|
#include <sstream>
|
|
|
|
|
2018-05-29 18:14:31 +00:00
|
|
|
#include <Common/CurrentThread.h>
|
2018-06-20 17:49:52 +00:00
|
|
|
#include <Common/Exception.h>
|
|
|
|
#include <Common/ThreadProfileEvents.h>
|
2018-08-22 00:24:55 +00:00
|
|
|
#include <Common/TaskStatsInfoGetter.h>
|
|
|
|
#include <Common/ThreadStatus.h>
|
2018-05-17 16:01:41 +00:00
|
|
|
|
2018-08-22 00:24:55 +00:00
|
|
|
#include <Poco/Logger.h>
|
2018-06-06 20:57:07 +00:00
|
|
|
#include <Poco/Ext/ThreadNumber.h>
|
2018-02-01 17:55:08 +00:00
|
|
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
2018-05-29 18:14:31 +00:00
|
|
|
|
2018-02-01 17:55:08 +00:00
|
|
|
namespace ErrorCodes
|
|
|
|
{
|
|
|
|
extern const int LOGICAL_ERROR;
|
2018-03-01 16:52:24 +00:00
|
|
|
extern const int PTHREAD_ERROR;
|
2018-02-01 17:55:08 +00:00
|
|
|
}
|
|
|
|
|
2018-09-16 00:14:55 +00:00
|
|
|
|
2019-02-08 13:23:10 +00:00
|
|
|
thread_local ThreadStatus * current_thread = nullptr;
|
2019-01-13 18:51:57 +00:00
|
|
|
|
|
|
|
|
2018-05-29 18:14:31 +00:00
|
|
|
TasksStatsCounters TasksStatsCounters::current()
|
2018-03-01 16:52:24 +00:00
|
|
|
{
|
2018-05-29 18:14:31 +00:00
|
|
|
TasksStatsCounters res;
|
2019-01-13 18:51:57 +00:00
|
|
|
CurrentThread::get().taskstats_getter->getStat(res.stat, CurrentThread::get().os_thread_id);
|
2018-05-29 18:14:31 +00:00
|
|
|
return res;
|
2018-03-01 16:52:24 +00:00
|
|
|
}
|
|
|
|
|
2018-02-01 17:55:08 +00:00
|
|
|
ThreadStatus::ThreadStatus()
|
|
|
|
{
|
2018-06-04 14:16:27 +00:00
|
|
|
thread_number = Poco::ThreadNumber::get();
|
|
|
|
os_thread_id = TaskStatsInfoGetter::getCurrentTID();
|
|
|
|
|
2018-08-14 20:29:42 +00:00
|
|
|
last_rusage = std::make_unique<RUsageCounters>();
|
2018-06-04 14:16:27 +00:00
|
|
|
last_taskstats = std::make_unique<TasksStatsCounters>();
|
2018-03-01 16:52:24 +00:00
|
|
|
|
2018-06-09 15:29:08 +00:00
|
|
|
memory_tracker.setDescription("(for thread)");
|
|
|
|
log = &Poco::Logger::get("ThreadStatus");
|
|
|
|
|
2019-01-13 18:51:57 +00:00
|
|
|
current_thread = this;
|
|
|
|
|
2018-06-06 20:57:07 +00:00
|
|
|
/// NOTE: It is important not to do any non-trivial actions (like updating ProfileEvents or logging) before ThreadStatus is created
|
|
|
|
/// Otherwise it could lead to SIGSEGV due to current_thread dereferencing
|
2018-05-29 18:14:31 +00:00
|
|
|
}
|
2018-03-01 16:52:24 +00:00
|
|
|
|
2019-01-13 18:51:57 +00:00
|
|
|
ThreadStatus::~ThreadStatus()
|
2018-05-29 18:14:31 +00:00
|
|
|
{
|
2019-01-13 18:51:57 +00:00
|
|
|
if (deleter)
|
|
|
|
deleter();
|
|
|
|
current_thread = nullptr;
|
2018-02-01 17:55:08 +00:00
|
|
|
}
|
|
|
|
|
2018-06-19 20:30:35 +00:00
|
|
|
void ThreadStatus::initPerformanceCounters()
|
|
|
|
{
|
|
|
|
performance_counters_finalized = false;
|
|
|
|
|
|
|
|
/// Clear stats from previous query if a new query is started
|
|
|
|
/// TODO: make separate query_thread_performance_counters and thread_performance_counters
|
|
|
|
performance_counters.resetCounters();
|
|
|
|
memory_tracker.resetCounters();
|
|
|
|
memory_tracker.setDescription("(for thread)");
|
2018-06-01 19:39:32 +00:00
|
|
|
|
2018-05-31 15:54:08 +00:00
|
|
|
query_start_time_nanoseconds = getCurrentTimeNanoseconds();
|
|
|
|
query_start_time = time(nullptr);
|
2018-06-04 14:16:27 +00:00
|
|
|
++queries_started;
|
|
|
|
|
2018-08-14 20:29:42 +00:00
|
|
|
*last_rusage = RUsageCounters::current(query_start_time_nanoseconds);
|
2018-08-22 00:41:30 +00:00
|
|
|
|
2018-08-29 19:01:01 +00:00
|
|
|
try
|
2018-08-22 00:41:30 +00:00
|
|
|
{
|
2018-08-29 19:01:01 +00:00
|
|
|
if (TaskStatsInfoGetter::checkPermissions())
|
|
|
|
{
|
|
|
|
if (!taskstats_getter)
|
2019-01-09 17:52:25 +00:00
|
|
|
taskstats_getter = std::make_unique<TaskStatsInfoGetter>();
|
2018-09-05 21:01:43 +00:00
|
|
|
|
2018-08-29 19:01:01 +00:00
|
|
|
*last_taskstats = TasksStatsCounters::current();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
taskstats_getter.reset();
|
|
|
|
tryLogCurrentException(__PRETTY_FUNCTION__);
|
2018-08-22 00:41:30 +00:00
|
|
|
}
|
2018-02-01 17:55:08 +00:00
|
|
|
}
|
|
|
|
|
2018-06-19 20:30:35 +00:00
|
|
|
void ThreadStatus::updatePerformanceCounters()
|
2018-02-01 17:55:08 +00:00
|
|
|
{
|
2018-05-31 15:54:08 +00:00
|
|
|
try
|
|
|
|
{
|
2018-08-14 20:29:42 +00:00
|
|
|
RUsageCounters::updateProfileEvents(*last_rusage, performance_counters);
|
2018-08-22 00:41:30 +00:00
|
|
|
if (taskstats_getter)
|
2018-06-19 20:30:35 +00:00
|
|
|
TasksStatsCounters::updateProfileEvents(*last_taskstats, performance_counters);
|
2018-05-31 15:54:08 +00:00
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
tryLogCurrentException(log);
|
|
|
|
}
|
2018-06-01 19:39:32 +00:00
|
|
|
}
|
|
|
|
|
2018-06-19 20:30:35 +00:00
|
|
|
void ThreadStatus::assertState(const std::initializer_list<int> & permitted_states, const char * description)
|
2018-03-01 16:52:24 +00:00
|
|
|
{
|
2018-06-19 20:30:35 +00:00
|
|
|
for (auto permitted_state : permitted_states)
|
2018-06-01 19:39:32 +00:00
|
|
|
{
|
2018-06-19 20:30:35 +00:00
|
|
|
if (getCurrentState() == permitted_state)
|
|
|
|
return;
|
2018-06-01 19:39:32 +00:00
|
|
|
}
|
2018-05-31 15:54:08 +00:00
|
|
|
|
2018-06-19 20:30:35 +00:00
|
|
|
std::stringstream ss;
|
|
|
|
ss << "Unexpected thread state " << getCurrentState();
|
|
|
|
if (description)
|
|
|
|
ss << ": " << description;
|
|
|
|
throw Exception(ss.str(), ErrorCodes::LOGICAL_ERROR);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ThreadStatus::attachInternalTextLogsQueue(const InternalTextLogsQueuePtr & logs_queue)
|
|
|
|
{
|
|
|
|
logs_queue_ptr = logs_queue;
|
|
|
|
|
|
|
|
if (!thread_group)
|
|
|
|
return;
|
|
|
|
|
2019-02-08 13:23:10 +00:00
|
|
|
std::lock_guard lock(thread_group->mutex);
|
2018-06-19 20:30:35 +00:00
|
|
|
thread_group->logs_queue_ptr = logs_queue;
|
|
|
|
}
|
|
|
|
|
2018-02-01 17:55:08 +00:00
|
|
|
}
|