| 1 | #pragma once |
| 2 | |
| 3 | #include <memory> |
| 4 | #include <string> |
| 5 | |
| 6 | #include <common/likely.h> |
| 7 | #include <common/StringRef.h> |
| 8 | #include <Common/ThreadStatus.h> |
| 9 | |
| 10 | |
| 11 | namespace ProfileEvents |
| 12 | { |
| 13 | class Counters; |
| 14 | } |
| 15 | |
| 16 | class MemoryTracker; |
| 17 | |
| 18 | |
| 19 | namespace DB |
| 20 | { |
| 21 | |
| 22 | class Context; |
| 23 | class QueryStatus; |
| 24 | struct Progress; |
| 25 | class InternalTextLogsQueue; |
| 26 | |
| 27 | |
| 28 | /** Collection of static methods to work with thread-local objects. |
| 29 | * Allows to attach and detach query/process (thread group) to a thread |
| 30 | * (to calculate query-related metrics and to allow to obtain query-related data from a thread). |
| 31 | * Thread will propagate it's metrics to attached query. |
| 32 | */ |
| 33 | class CurrentThread |
| 34 | { |
| 35 | public: |
| 36 | /// Return true in case of successful initializaiton |
| 37 | static bool isInitialized(); |
| 38 | |
| 39 | /// Handler to current thread |
| 40 | static ThreadStatus & get(); |
| 41 | |
| 42 | /// Group to which belongs current thread |
| 43 | static ThreadGroupStatusPtr getGroup(); |
| 44 | |
| 45 | /// A logs queue used by TCPHandler to pass logs to a client |
| 46 | static void attachInternalTextLogsQueue(const std::shared_ptr<InternalTextLogsQueue> & logs_queue, |
| 47 | LogsLevel client_logs_level); |
| 48 | static std::shared_ptr<InternalTextLogsQueue> getInternalTextLogsQueue(); |
| 49 | |
| 50 | /// Makes system calls to update ProfileEvents that contain info from rusage and taskstats |
| 51 | static void updatePerformanceCounters(); |
| 52 | |
| 53 | static ProfileEvents::Counters & getProfileEvents(); |
| 54 | static MemoryTracker * getMemoryTracker(); |
| 55 | |
| 56 | static inline Int64 & getUntrackedMemory() |
| 57 | { |
| 58 | /// It assumes that (current_thread != nullptr) is already checked with getMemoryTracker() |
| 59 | return current_thread->untracked_memory; |
| 60 | } |
| 61 | |
| 62 | /// Update read and write rows (bytes) statistics (used in system.query_thread_log) |
| 63 | static void updateProgressIn(const Progress & value); |
| 64 | static void updateProgressOut(const Progress & value); |
| 65 | |
| 66 | /// Query management: |
| 67 | |
| 68 | /// Call from master thread as soon as possible (e.g. when thread accepted connection) |
| 69 | static void initializeQuery(); |
| 70 | |
| 71 | /// Sets query_context for current thread group |
| 72 | static void attachQueryContext(Context & query_context); |
| 73 | |
| 74 | /// You must call one of these methods when create a query child thread: |
| 75 | /// Add current thread to a group associated with the thread group |
| 76 | static void attachTo(const ThreadGroupStatusPtr & thread_group); |
| 77 | /// Is useful for a ThreadPool tasks |
| 78 | static void attachToIfDetached(const ThreadGroupStatusPtr & thread_group); |
| 79 | |
| 80 | /// Update ProfileEvents and dumps info to system.query_thread_log |
| 81 | static void finalizePerformanceCounters(); |
| 82 | |
| 83 | /// Returns a non-empty string if the thread is attached to a query |
| 84 | static StringRef getQueryId() |
| 85 | { |
| 86 | if (unlikely(!current_thread)) |
| 87 | return {}; |
| 88 | return current_thread->getQueryId(); |
| 89 | } |
| 90 | |
| 91 | /// Non-master threads call this method in destructor automatically |
| 92 | static void detachQuery(); |
| 93 | static void detachQueryIfNotDetached(); |
| 94 | |
| 95 | /// Initializes query with current thread as master thread in constructor, and detaches it in destructor |
| 96 | struct QueryScope |
| 97 | { |
| 98 | explicit QueryScope(Context & query_context); |
| 99 | ~QueryScope(); |
| 100 | |
| 101 | void logPeakMemoryUsage(); |
| 102 | bool log_peak_memory_usage_in_destructor = true; |
| 103 | }; |
| 104 | |
| 105 | private: |
| 106 | static void defaultThreadDeleter(); |
| 107 | }; |
| 108 | |
| 109 | } |
| 110 | |
| 111 | |