From d9976abe18600719022ee121f2c196616b9301ff Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 24 Jul 2019 22:19:29 +0300 Subject: [PATCH] Added ProfileEvents for signal handler overruns --- dbms/src/Common/ProfileEvents.cpp | 3 +++ dbms/src/Common/QueryProfiler.cpp | 17 +++++++++++++---- dbms/src/Common/TraceCollector.cpp | 6 ++++-- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/dbms/src/Common/ProfileEvents.cpp b/dbms/src/Common/ProfileEvents.cpp index 7059e02d76c..277aafa9eb8 100644 --- a/dbms/src/Common/ProfileEvents.cpp +++ b/dbms/src/Common/ProfileEvents.cpp @@ -171,6 +171,9 @@ M(OSReadChars, "Number of bytes read from filesystem, including page cache.") \ M(OSWriteChars, "Number of bytes written to filesystem, including page cache.") \ M(CreatedHTTPConnections, "Total amount of created HTTP connections (closed or opened).") \ + \ + M(QueryProfilerCannotWriteTrace, "Number of stack traces dropped by query profiler because pipe is full or cannot write to pipe.") \ + M(QueryProfilerSignalOverruns, "Number of times we drop processing of a signal due to overrun plus the number of signals that OS has not delivered due to overrun.") \ namespace ProfileEvents { diff --git a/dbms/src/Common/QueryProfiler.cpp b/dbms/src/Common/QueryProfiler.cpp index d9266e9b763..ef12d14320a 100644 --- a/dbms/src/Common/QueryProfiler.cpp +++ b/dbms/src/Common/QueryProfiler.cpp @@ -13,6 +13,7 @@ namespace ProfileEvents { extern const Event QueryProfilerCannotWriteTrace; + extern const Event QueryProfilerSignalOverruns; } namespace DB @@ -63,11 +64,19 @@ namespace /// Quickly drop if signal handler is called too frequently. /// Otherwise we may end up infinitelly processing signals instead of doing any useful work. ++write_trace_iteration; - if (info - && info->si_overrun > 0 + if (info && info->si_overrun > 0) + { /// But pass with some frequency to avoid drop of all traces. - && write_trace_iteration % info->si_overrun != 0) - return; + if (write_trace_iteration % info->si_overrun == 0) + { + ProfileEvents::increment(ProfileEvents::QueryProfilerSignalOverruns, info->si_overrun); + } + else + { + ProfileEvents::increment(ProfileEvents::QueryProfilerSignalOverruns, info->si_overrun + 1); + return; + } + } constexpr size_t buf_size = sizeof(char) + // TraceCollector stop flag 8 * sizeof(char) + // maximum VarUInt length for string size diff --git a/dbms/src/Common/TraceCollector.cpp b/dbms/src/Common/TraceCollector.cpp index 680eefad5da..20e4b0a481e 100644 --- a/dbms/src/Common/TraceCollector.cpp +++ b/dbms/src/Common/TraceCollector.cpp @@ -52,8 +52,10 @@ TraceCollector::TraceCollector(std::shared_ptr & trace_log) if (-1 == pipe_size) throwFromErrno("Cannot get pipe capacity", ErrorCodes::CANNOT_FCNTL); for (errno = 0; errno != EPERM && pipe_size <= 1048576; pipe_size *= 2) - if (-1 == fcntl(trace_pipe.fds_rw[1], F_SETPIPE_SZ, pipe_size) && errno != EPERM) - throwFromErrno("Cannot increase pipe capacity to " + toString(pipe_size), ErrorCodes::CANNOT_FCNTL); + if (-1 == fcntl(trace_pipe.fds_rw[1], F_SETPIPE_SZ, pipe_size * 2) && errno != EPERM) + throwFromErrno("Cannot increase pipe capacity to " + toString(pipe_size * 2), ErrorCodes::CANNOT_FCNTL); + + LOG_TRACE(log, "Pipe capacity is " << formatReadableSizeWithBinarySuffix(pipe_size)); thread = ThreadFromGlobalPool(&TraceCollector::run, this); }