Added ProfileEvents for signal handler overruns

This commit is contained in:
Alexey Milovidov 2019-07-24 22:19:29 +03:00
parent 63764af4fb
commit d9976abe18
3 changed files with 20 additions and 6 deletions

View File

@ -171,6 +171,9 @@
M(OSReadChars, "Number of bytes read from filesystem, including page cache.") \ M(OSReadChars, "Number of bytes read from filesystem, including page cache.") \
M(OSWriteChars, "Number of bytes written to 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(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 namespace ProfileEvents
{ {

View File

@ -13,6 +13,7 @@
namespace ProfileEvents namespace ProfileEvents
{ {
extern const Event QueryProfilerCannotWriteTrace; extern const Event QueryProfilerCannotWriteTrace;
extern const Event QueryProfilerSignalOverruns;
} }
namespace DB namespace DB
@ -63,11 +64,19 @@ namespace
/// Quickly drop if signal handler is called too frequently. /// Quickly drop if signal handler is called too frequently.
/// Otherwise we may end up infinitelly processing signals instead of doing any useful work. /// Otherwise we may end up infinitelly processing signals instead of doing any useful work.
++write_trace_iteration; ++write_trace_iteration;
if (info if (info && info->si_overrun > 0)
&& info->si_overrun > 0 {
/// But pass with some frequency to avoid drop of all traces. /// But pass with some frequency to avoid drop of all traces.
&& write_trace_iteration % info->si_overrun != 0) if (write_trace_iteration % info->si_overrun == 0)
return; {
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 constexpr size_t buf_size = sizeof(char) + // TraceCollector stop flag
8 * sizeof(char) + // maximum VarUInt length for string size 8 * sizeof(char) + // maximum VarUInt length for string size

View File

@ -52,8 +52,10 @@ TraceCollector::TraceCollector(std::shared_ptr<TraceLog> & trace_log)
if (-1 == pipe_size) if (-1 == pipe_size)
throwFromErrno("Cannot get pipe capacity", ErrorCodes::CANNOT_FCNTL); throwFromErrno("Cannot get pipe capacity", ErrorCodes::CANNOT_FCNTL);
for (errno = 0; errno != EPERM && pipe_size <= 1048576; pipe_size *= 2) 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) 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), ErrorCodes::CANNOT_FCNTL); 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); thread = ThreadFromGlobalPool(&TraceCollector::run, this);
} }