Avoid code duplication by calling the same `Context::signalKeeperDispatcherShutdown`
method that `Server.cpp` uses, instead of inlining the dispatcher lookup.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
During shutdown, `KeeperTCPHandler` connections run an infinite loop
with no shutdown detection. When the server stops the Keeper TCP
listening socket, existing handler threads keep processing heartbeats
indefinitely. `KeeperDispatcher::shutdown` (which sets the shutdown
flag) is only called after waiting for connections to close, creating
a circular dependency that blocks shutdown until the external timeout
kills the server.
Add a `shutting_down` flag to `KeeperDispatcher` that is set before
waiting for connections. `KeeperTCPHandler` checks this flag after
each `poll` return and exits cleanly when set.
https://s3.amazonaws.com/clickhouse-test-reports/json.html?PR=98447&sha=79d30b439bc793fc9aa276b28aec105750847880&name_0=PR&name_1=Stateless%20tests%20%28arm_asan%2C%20azure%2C%20parallel%29
Co-Authored-By: Claude Opus 4.6 <[email protected]>
The previous implementation used `std::call_once` which fired in the
parent process during `BaseDaemon::initialize`. After the watchdog
`fork`, jemalloc state (e.g. `background_thread`) resets in the child
but the `once_flag` remains set, so the verification check saw a
mismatch and fired `chassert`.
Split `setup` and `verifySetup` into separate functions:
- `setup` always applies settings (idempotent), called in
`BaseDaemon::initialize` and re-applied after watchdog fork
- `verifySetup` checks jemalloc state matches server settings,
called from `Server::main` and `Keeper::main`
Also extract config key names into constants in `Jemalloc.h` to keep
them in sync between `BaseDaemon` and `ServerSettings`.
https://s3.amazonaws.com/clickhouse-test-reports/json.html?PR=98232&sha=b69293471789706abde22ec86f33104dbfaf0382&name_0=PR&name_1=Stateless%20tests%20%28amd_debug%2C%20parallel%29
Co-Authored-By: Claude Opus 4.6 <[email protected]>
The same `safeExit` pattern exists in `programs/keeper/Keeper.cpp`.
Apply the same `OpenSSLInitializer::cleanup` call to avoid
LeakSanitizer false positives in Keeper as well.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
- Add missing `extern` for `jemalloc_profiler_sampling_rate` in
`Keeper.cpp`, `LocalServer.cpp`, and `Server.cpp`
- Pass `jemalloc_profiler_sampling_rate` as 5th argument to
`Jemalloc::setup` in `Keeper.cpp` and `LocalServer.cpp`
- Expose `prof.lg_sample` via `system.asynchronous_metrics` as
`jemalloc.prof.lg_sample`
- Add integration test `test_jemalloc_profiler_sampling_rate`
Co-Authored-By: Claude Opus 4.6 <[email protected]>
The `replaceByLabel` calls in `Server.cpp` and `Keeper.cpp` passed
`shared = false`, which means the `AutoPtr` inside `LayeredConfiguration`
took the raw pointer without incrementing the reference count. But the
caller's `loaded_config` `AutoPtr` also holds a reference. When the
callback's `loaded_config` goes out of scope, its destructor decrements
the reference count, potentially freeing the object while the
`LayeredConfiguration` still holds a pointer to it.
Passing `shared = true` makes the `AutoPtr` constructor call `duplicate`,
properly incrementing the reference count so the `LayeredConfiguration`
has its own counted reference.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
The config reload callback in `Server.cpp` and `Keeper.cpp` was doing
`find` + `removeConfiguration` + `add` on the shared `LayeredConfiguration`
from the `ConfigReloader` thread. This is not thread-safe because concurrent
readers (calling `getString`, etc.) iterate the same internal list without
synchronization against structural modifications.
`AbstractConfiguration` already has `mutable Poco::Mutex _mutex` that all
public read methods lock. The new `replaceByLabel` method locks the same
`_mutex` and atomically swaps the config pointer within the matching list
node — no list insert/erase needed for the common case, guaranteeing mutual
exclusion with concurrent readers.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
This commit improves the help output for all ClickHouse applications:
- Add `clickhouse help` command that lists all available subcommands
- Return exit code 0 for all help messages (previously some returned 1)
- Output help messages to stdout instead of stderr
- Use "clickhouse <cmd>" format instead of argv[0] in help messages
- Add dynamic `app_name` detection for `clickhouse client` and `clickhouse local`
to show correct invocation name based on how the binary was called
- Add `--no-sudo` option for `clickhouse start` and `clickhouse restart`
for environments without sudo (e.g., Docker containers)
- Add detailed help headers and footers for client and local with usage examples
Closes#58244
Co-Authored-By: Claude Opus 4.5 <[email protected]>
Make memory worker to be able to preventilvely purge jemalloc arenas,
if the size of dirty pages exceeds pre-configured threshold ratio
(relatively to `max_server_memory_usage`), even if the process memory
is below memory tracker limit.
Co-authored-by: Azat Khuzhin <[email protected]>
While adding a chassert, I also discovered an issue with EventPtr: it
was never deduplicated, since it was always wrapped into a callback.
This has now been fixed as well.