diff --git a/src/Access/ContextAccess.cpp b/src/Access/ContextAccess.cpp index 04756162b468..0d28edc0a102 100644 --- a/src/Access/ContextAccess.cpp +++ b/src/Access/ContextAccess.cpp @@ -333,7 +333,7 @@ void ContextAccess::calculateAccessRights() const boost::algorithm::join(roles_info->getCurrentRolesNames(), ", "), boost::algorithm::join(roles_info->getEnabledRolesNames(), ", ")); } - LOG_TRACE(trace_log, "Settings: readonly={}, allow_ddl={}, allow_introspection_functions={}", params.readonly, params.allow_ddl, params.allow_introspection); + LOG_TRACE(trace_log, "Settings: readonly = {}, allow_ddl = {}, allow_introspection_functions = {}", params.readonly, params.allow_ddl, params.allow_introspection); LOG_TRACE(trace_log, "List of all grants: {}", access->toString()); LOG_TRACE(trace_log, "List of all grants including implicit: {}", access_with_implicit->toString()); } diff --git a/src/Core/BaseSettings.h b/src/Core/BaseSettings.h index a14cec9cc7d9..75b13304326c 100644 --- a/src/Core/BaseSettings.h +++ b/src/Core/BaseSettings.h @@ -2,6 +2,8 @@ #include #include +#include +#include #include #include #include @@ -547,14 +549,16 @@ void BaseSettings::read(ReadBuffer & in, SettingsWriteFormat format) template String BaseSettings::toString() const { - String res; - for (const auto & field : *this) + WriteBufferFromOwnString out; + bool first = true; + for (const auto & setting : *this) { - if (!res.empty()) - res += ", "; - res += field.getName() + " = " + field.getValueString(); + if (!first) + out << ", "; + out << setting.getName() << " = " << applyVisitor(FieldVisitorToString(), setting.getValue()); + first = false; } - return res; + return out.str(); } template diff --git a/src/Daemon/BaseDaemon.cpp b/src/Daemon/BaseDaemon.cpp index 4dd6809d7261..bfd5568b71d9 100644 --- a/src/Daemon/BaseDaemon.cpp +++ b/src/Daemon/BaseDaemon.cpp @@ -54,6 +54,7 @@ #include #include #include +#include #include #include @@ -80,7 +81,9 @@ namespace DB } } -DB::PipeFDs signal_pipe; +using namespace DB; + +PipeFDs signal_pipe; /** Reset signal handler to the default and send signal to itself. @@ -89,10 +92,10 @@ DB::PipeFDs signal_pipe; static void call_default_signal_handler(int sig) { if (SIG_ERR == signal(sig, SIG_DFL)) - DB::throwFromErrno("Cannot set signal handler.", DB::ErrorCodes::CANNOT_SET_SIGNAL_HANDLER); + throwFromErrno("Cannot set signal handler.", ErrorCodes::CANNOT_SET_SIGNAL_HANDLER); if (0 != raise(sig)) - DB::throwFromErrno("Cannot send signal.", DB::ErrorCodes::CANNOT_SEND_SIGNAL); + throwFromErrno("Cannot send signal.", ErrorCodes::CANNOT_SEND_SIGNAL); } static const size_t signal_pipe_buf_size = @@ -110,8 +113,8 @@ static void writeSignalIDtoSignalPipe(int sig) auto saved_errno = errno; /// We must restore previous value of errno in signal handler. char buf[signal_pipe_buf_size]; - DB::WriteBufferFromFileDescriptor out(signal_pipe.fds_rw[1], signal_pipe_buf_size, buf); - DB::writeBinary(sig, out); + WriteBufferFromFileDescriptor out(signal_pipe.fds_rw[1], signal_pipe_buf_size, buf); + writeBinary(sig, out); out.next(); errno = saved_errno; @@ -141,17 +144,17 @@ static void signalHandler(int sig, siginfo_t * info, void * context) auto saved_errno = errno; /// We must restore previous value of errno in signal handler. char buf[signal_pipe_buf_size]; - DB::WriteBufferFromFileDescriptorDiscardOnFailure out(signal_pipe.fds_rw[1], signal_pipe_buf_size, buf); + WriteBufferFromFileDescriptorDiscardOnFailure out(signal_pipe.fds_rw[1], signal_pipe_buf_size, buf); const ucontext_t * signal_context = reinterpret_cast(context); const StackTrace stack_trace(*signal_context); - DB::writeBinary(sig, out); - DB::writePODBinary(*info, out); - DB::writePODBinary(signal_context, out); - DB::writePODBinary(stack_trace, out); - DB::writeBinary(static_cast(getThreadId()), out); - DB::writePODBinary(DB::current_thread, out); + writeBinary(sig, out); + writePODBinary(*info, out); + writePODBinary(signal_context, out); + writePODBinary(stack_trace, out); + writeBinary(static_cast(getThreadId()), out); + writePODBinary(current_thread, out); out.next(); @@ -203,12 +206,12 @@ class SignalListener : public Poco::Runnable static_assert(PIPE_BUF >= 512); static_assert(signal_pipe_buf_size <= PIPE_BUF, "Only write of PIPE_BUF to pipe is atomic and the minimal known PIPE_BUF across supported platforms is 512"); char buf[signal_pipe_buf_size]; - DB::ReadBufferFromFileDescriptor in(signal_pipe.fds_rw[0], signal_pipe_buf_size, buf); + ReadBufferFromFileDescriptor in(signal_pipe.fds_rw[0], signal_pipe_buf_size, buf); while (!in.eof()) { int sig = 0; - DB::readBinary(sig, in); + readBinary(sig, in); // We may log some specific signals afterwards, with different log // levels and more info, but for completeness we log all signals // here at trace level. @@ -231,8 +234,8 @@ class SignalListener : public Poco::Runnable UInt32 thread_num; std::string message; - DB::readBinary(thread_num, in); - DB::readBinary(message, in); + readBinary(thread_num, in); + readBinary(message, in); onTerminate(message, thread_num); } @@ -248,17 +251,17 @@ class SignalListener : public Poco::Runnable ucontext_t * context{}; StackTrace stack_trace(NoCapture{}); UInt32 thread_num{}; - DB::ThreadStatus * thread_ptr{}; + ThreadStatus * thread_ptr{}; if (sig != SanitizerTrap) { - DB::readPODBinary(info, in); - DB::readPODBinary(context, in); + readPODBinary(info, in); + readPODBinary(context, in); } - DB::readPODBinary(stack_trace, in); - DB::readBinary(thread_num, in); - DB::readPODBinary(thread_ptr, in); + readPODBinary(stack_trace, in); + readBinary(thread_num, in); + readPODBinary(thread_ptr, in); /// This allows to receive more signals if failure happens inside onFault function. /// Example: segfault while symbolizing stack trace. @@ -298,9 +301,9 @@ class SignalListener : public Poco::Runnable ucontext_t * context, const StackTrace & stack_trace, UInt32 thread_num, - DB::ThreadStatus * thread_ptr) const + ThreadStatus * thread_ptr) const { - DB::ThreadStatus thread_status; + ThreadStatus thread_status; String query_id; String query; @@ -314,7 +317,7 @@ class SignalListener : public Poco::Runnable if (auto logs_queue = thread_ptr->getInternalTextLogsQueue()) { - DB::CurrentThread::attachInternalTextLogsQueue(logs_queue, DB::LogsLevel::trace); + CurrentThread::attachInternalTextLogsQueue(logs_queue, LogsLevel::trace); } } @@ -358,12 +361,12 @@ class SignalListener : public Poco::Runnable /// NOTE: This still require memory allocations and mutex lock inside logger. /// BTW we can also print it to stderr using write syscalls. - DB::WriteBufferFromOwnString bare_stacktrace; - DB::writeString("Stack trace:", bare_stacktrace); + WriteBufferFromOwnString bare_stacktrace; + writeString("Stack trace:", bare_stacktrace); for (size_t i = stack_trace.getOffset(); i < stack_trace.getSize(); ++i) { - DB::writeChar(' ', bare_stacktrace); - DB::writePointerHex(stack_trace.getFramePointers()[i], bare_stacktrace); + writeChar(' ', bare_stacktrace); + writePointerHex(stack_trace.getFramePointers()[i], bare_stacktrace); } LOG_FATAL(log, fmt::runtime(bare_stacktrace.str())); @@ -411,8 +414,48 @@ class SignalListener : public Poco::Runnable /// Send crash report to developers (if configured) if (sig != SanitizerTrap) + { SentryWriter::onFault(sig, error_message, stack_trace); + /// Advice the user to send it manually. + if constexpr (std::string_view(VERSION_OFFICIAL).contains("official build")) + { + const auto & date_lut = DateLUT::instance(); + + /// Approximate support period, upper bound. + if (time(nullptr) - date_lut.makeDate(2000 + VERSION_MAJOR, VERSION_MINOR, 1) < (365 + 30) * 86400) + { + LOG_FATAL(log, "Report this error to https://github.com/ClickHouse/ClickHouse/issues"); + } + else + { + LOG_FATAL(log, "ClickHouse version {} is old and should be upgraded to the latest version.", VERSION_STRING); + } + } + else + { + LOG_FATAL(log, "This ClickHouse version is not official and should be upgraded to the official build."); + } + } + + /// ClickHouse Keeper does not link to some part of Settings. +#ifndef CLICKHOUSE_PROGRAM_STANDALONE_BUILD + /// List changed settings. + if (!query_id.empty()) + { + ContextPtr query_context = thread_ptr->getQueryContext(); + if (query_context) + { + String changed_settings = query_context->getSettingsRef().toString(); + + if (changed_settings.empty()) + LOG_FATAL(log, "No settings were changed"); + else + LOG_FATAL(log, "Changed settings: {}", changed_settings); + } + } +#endif + /// When everything is done, we will try to send these error messages to client. if (thread_ptr) thread_ptr->onFatalError(); @@ -436,15 +479,15 @@ static DISABLE_SANITIZER_INSTRUMENTATION void sanitizerDeathCallback() /// Also need to send data via pipe. Otherwise it may lead to deadlocks or failures in printing diagnostic info. char buf[signal_pipe_buf_size]; - DB::WriteBufferFromFileDescriptorDiscardOnFailure out(signal_pipe.fds_rw[1], signal_pipe_buf_size, buf); + WriteBufferFromFileDescriptorDiscardOnFailure out(signal_pipe.fds_rw[1], signal_pipe_buf_size, buf); const StackTrace stack_trace; int sig = SignalListener::SanitizerTrap; - DB::writeBinary(sig, out); - DB::writePODBinary(stack_trace, out); - DB::writeBinary(UInt32(getThreadId()), out); - DB::writePODBinary(DB::current_thread, out); + writeBinary(sig, out); + writePODBinary(stack_trace, out); + writeBinary(UInt32(getThreadId()), out); + writePODBinary(current_thread, out); out.next(); @@ -470,7 +513,7 @@ static DISABLE_SANITIZER_INSTRUMENTATION void sanitizerDeathCallback() std::string log_message; if (std::current_exception()) - log_message = "Terminate called for uncaught exception:\n" + DB::getCurrentExceptionMessage(true); + log_message = "Terminate called for uncaught exception:\n" + getCurrentExceptionMessage(true); else log_message = "Terminate called without an active exception"; @@ -482,11 +525,11 @@ static DISABLE_SANITIZER_INSTRUMENTATION void sanitizerDeathCallback() log_message.resize(buf_size - 16); char buf[buf_size]; - DB::WriteBufferFromFileDescriptor out(signal_pipe.fds_rw[1], buf_size, buf); + WriteBufferFromFileDescriptor out(signal_pipe.fds_rw[1], buf_size, buf); - DB::writeBinary(static_cast(SignalListener::StdTerminate), out); - DB::writeBinary(static_cast(getThreadId()), out); - DB::writeBinary(log_message, out); + writeBinary(static_cast(SignalListener::StdTerminate), out); + writeBinary(static_cast(getThreadId()), out); + writeBinary(log_message, out); out.next(); abort(); @@ -512,7 +555,7 @@ static bool tryCreateDirectories(Poco::Logger * logger, const std::string & path } catch (...) { - LOG_WARNING(logger, "{}: when creating {}, {}", __PRETTY_FUNCTION__, path, DB::getCurrentExceptionMessage(true)); + LOG_WARNING(logger, "{}: when creating {}, {}", __PRETTY_FUNCTION__, path, getCurrentExceptionMessage(true)); } return false; } @@ -527,7 +570,7 @@ void BaseDaemon::reloadConfiguration() * (It's convenient to log in console when you start server without any command line parameters.) */ config_path = config().getString("config-file", getDefaultConfigFileName()); - DB::ConfigProcessor config_processor(config_path, false, true); + ConfigProcessor config_processor(config_path, false, true); config_processor.setConfigPath(fs::path(config_path).parent_path()); loaded_config = config_processor.loadConfig(/* allow_zk_includes = */ true); @@ -548,7 +591,7 @@ BaseDaemon::~BaseDaemon() /// Reset signals to SIG_DFL to avoid trying to write to the signal_pipe that will be closed after. for (int sig : handled_signals) if (SIG_ERR == signal(sig, SIG_DFL)) - DB::throwFromErrno("Cannot set signal handler.", DB::ErrorCodes::CANNOT_SET_SIGNAL_HANDLER); + throwFromErrno("Cannot set signal handler.", ErrorCodes::CANNOT_SET_SIGNAL_HANDLER); signal_pipe.close(); } @@ -592,7 +635,7 @@ void BaseDaemon::closeFDs() /// Iterate directory separately from closing fds to avoid closing iterated directory fd. std::vector fds; for (const auto & path : fs::directory_iterator(proc_path)) - fds.push_back(DB::parse(path.path().filename())); + fds.push_back(parse(path.path().filename())); for (const auto & fd : fds) { @@ -662,7 +705,7 @@ void BaseDaemon::initialize(Application & self) } umask(umask_num); - DB::ConfigProcessor(config_path).savePreprocessedConfig(loaded_config, ""); + ConfigProcessor(config_path).savePreprocessedConfig(loaded_config, ""); /// Write core dump on crash. { @@ -713,12 +756,12 @@ void BaseDaemon::initialize(Application & self) /// { /// try /// { - /// DB::SomeApp app; + /// SomeApp app; /// return app.run(argc, argv); /// } /// catch (...) /// { - /// std::cerr << DB::getCurrentExceptionMessage(true) << "\n"; + /// std::cerr << getCurrentExceptionMessage(true) << "\n"; /// return 1; /// } /// } @@ -772,7 +815,7 @@ void BaseDaemon::initialize(Application & self) /// Create pid file. if (config().has("pid")) - pid_file.emplace(config().getString("pid"), DB::StatusFile::write_pid); + pid_file.emplace(config().getString("pid"), StatusFile::write_pid); if (is_daemon) { @@ -799,7 +842,7 @@ void BaseDaemon::initialize(Application & self) initializeTerminationAndSignalProcessing(); logRevision(); - for (const auto & key : DB::getMultipleKeysFromConfig(config(), "", "graphite")) + for (const auto & key : getMultipleKeysFromConfig(config(), "", "graphite")) { graphite_writers.emplace(key, std::make_unique(key)); } @@ -887,7 +930,7 @@ void BaseDaemon::initializeTerminationAndSignalProcessing() signal_listener_thread.start(*signal_listener); #if defined(__ELF__) && !defined(OS_FREEBSD) - String build_id_hex = DB::SymbolIndex::instance()->getBuildIDHex(); + String build_id_hex = SymbolIndex::instance()->getBuildIDHex(); if (build_id_hex.empty()) build_id = ""; else @@ -902,7 +945,7 @@ void BaseDaemon::initializeTerminationAndSignalProcessing() std::string executable_path = getExecutablePath(); if (!executable_path.empty()) - stored_binary_hash = DB::Elf(executable_path).getStoredBinaryHash(); + stored_binary_hash = Elf(executable_path).getStoredBinaryHash(); #endif } @@ -963,7 +1006,7 @@ void BaseDaemon::handleSignal(int signal_id) onInterruptSignals(signal_id); } else - throw DB::Exception::createDeprecated(std::string("Unsupported signal: ") + strsignal(signal_id), 0); // NOLINT(concurrency-mt-unsafe) // it is not thread-safe but ok in this context + throw Exception::createDeprecated(std::string("Unsupported signal: ") + strsignal(signal_id), 0); // NOLINT(concurrency-mt-unsafe) // it is not thread-safe but ok in this context } void BaseDaemon::onInterruptSignals(int signal_id) @@ -1020,7 +1063,7 @@ void BaseDaemon::setupWatchdog() pid = fork(); if (-1 == pid) - DB::throwFromErrno("Cannot fork", DB::ErrorCodes::SYSTEM_ERROR); + throwFromErrno("Cannot fork", ErrorCodes::SYSTEM_ERROR); if (0 == pid) { @@ -1073,13 +1116,13 @@ void BaseDaemon::setupWatchdog() pf = new OwnJSONPatternFormatter(config()); else pf = new OwnPatternFormatter; - Poco::AutoPtr log = new DB::OwnFormattingChannel(pf, new Poco::ConsoleChannel(std::cerr)); + Poco::AutoPtr log = new OwnFormattingChannel(pf, new Poco::ConsoleChannel(std::cerr)); logger().setChannel(log); } /// Cuncurrent writing logs to the same file from two threads is questionable on its own, /// but rotating them from two threads is disastrous. - if (auto * channel = dynamic_cast(logger().getChannel())) + if (auto * channel = dynamic_cast(logger().getChannel())) { channel->setChannelProperty("log", Poco::FileChannel::PROP_ROTATION, "never"); channel->setChannelProperty("log", Poco::FileChannel::PROP_ROTATEONOPEN, "false"); @@ -1191,7 +1234,7 @@ void systemdNotify(const std::string_view & command) int s = socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (s == -1) - DB::throwFromErrno("Can't create UNIX socket for systemd notify.", DB::ErrorCodes::SYSTEM_ERROR); + throwFromErrno("Can't create UNIX socket for systemd notify.", ErrorCodes::SYSTEM_ERROR); SCOPE_EXIT({ close(s); }); @@ -1202,7 +1245,7 @@ void systemdNotify(const std::string_view & command) addr.sun_family = AF_UNIX; if (len < 2 || len > sizeof(addr.sun_path) - 1) - throw DB::Exception(DB::ErrorCodes::SYSTEM_ERROR, "NOTIFY_SOCKET env var value \"{}\" is wrong.", path); + throw Exception(ErrorCodes::SYSTEM_ERROR, "NOTIFY_SOCKET env var value \"{}\" is wrong.", path); memcpy(addr.sun_path, path, len + 1); /// write last zero as well. @@ -1214,7 +1257,7 @@ void systemdNotify(const std::string_view & command) else if (path[0] == '/') addrlen += 1; /// non-abstract-addresses should be zero terminated. else - throw DB::Exception(DB::ErrorCodes::SYSTEM_ERROR, "Wrong UNIX path \"{}\" in NOTIFY_SOCKET env var", path); + throw Exception(ErrorCodes::SYSTEM_ERROR, "Wrong UNIX path \"{}\" in NOTIFY_SOCKET env var", path); const struct sockaddr *sock_addr = reinterpret_cast (&addr); @@ -1227,7 +1270,7 @@ void systemdNotify(const std::string_view & command) if (errno == EINTR) continue; else - DB::throwFromErrno("Failed to notify systemd, sendto returned error.", DB::ErrorCodes::SYSTEM_ERROR); + throwFromErrno("Failed to notify systemd, sendto returned error.", ErrorCodes::SYSTEM_ERROR); } else sent_bytes_total += sent_bytes;