Add replication lag and recovery time metrics#66703
Conversation
|
This is an automated comment for commit 01ca36c with description of existing statuses. It's updated for the latest CI running ❌ Click here to open a full report in a separate page
Successful checks
|
6df4b4d to
1ad9765
Compare
1ad9765 to
7fc8ee7
Compare
|
Failing CI:
|
src/Databases/DatabaseReplicated.cpp
Outdated
| UInt32 log_ptr = parse<UInt32>(zookeeper->get(fs::path(zookeeper_path) / "replicas" / full_name / "log_ptr")); | ||
| bool is_active = zookeeper->exists(fs::path(zookeeper_path) / "replicas" / full_name / "active"); |
There was a problem hiding this comment.
It will work, but it will drastically slow down selects from system.clusters (especially for clusters having a lot of replicas). For each replica, it makes 2 sequential zk requests, so it's 2 * num_of_replicas RTT for each tryGetReplicasInfo call. Let's put all paths in a vector, make one mutli-get request (exists is basically a get request + a check for the error code (ZOK/ZNONODE)), and process the list of responses/error codes
| bool DatabaseReplicatedDDLWorker::initializeMainThread() | ||
| { | ||
| initialization_duration_timer.restart(); | ||
| initializing.store(true, std::memory_order_release); |
There was a problem hiding this comment.
This is not a performance-critical part of code, so it's okay to use the default std::memory_order_seq_cst. Using anything besides std::memory_order_seq_cst and std::memory_order_relaxed usually requires a comment explaining why it will work correctly, and I would prefer not to think about this when it's not required for performance reasons
There was a problem hiding this comment.
|
|
||
| UInt64 DatabaseReplicatedDDLWorker::getCurrentInitializationDurationMs() const | ||
| { | ||
| return initializing.load(std::memory_order_acquire) ? initialization_duration_timer.elapsedMilliseconds() : 0; |
There was a problem hiding this comment.
There's still a (theoretical) race condition:
- thread X checks
initializinghere, it's true, but kernel decides to pause this thread for a few seconds for some reason - the DDLWorker thread finishes the initialization successfully, but instantly gets an unexpected error and calls
initializeMainThreadagain - thread X wakes up and reads
start_nsinsideinitialization_duration_timer.elapsedMilliseconds()at the same time when the DDLWorker thread resets it ininitialization_duration_timer.restart()
| node = cluster.add_instance( | ||
| "node", | ||
| main_configs=["configs/config.xml"], | ||
| with_zookeeper=True, |
There was a problem hiding this comment.
with_zookeeper is redundant since there's embedded Keeper enabled in the server config
| node.query("CREATE TABLE rdb.t (x UInt32) ENGINE = MergeTree ORDER BY x;") | ||
| node.exec_in_container(["bash", "-c", "rm /var/lib/clickhouse/metadata/rdb/t.sql"]) | ||
| node.restart_clickhouse() | ||
| assert node.query("SELECT any(recovery_time) FROM system.clusters;") != "0\n" |
There was a problem hiding this comment.
"NULL\n" != "0\n" is true, so the assert will not fail if all recovery times are NULL
|
Reverted. Please resubmit. |
Changelog category (leave one):
Changelog entry (a user-readable short description of the changes that goes to CHANGELOG.md):
Add replication lag and recovery time metrics
Documentation entry for user-facing changes
CI Settings (Only check the boxes if you know what you are doing):