| 195 | } |
| 196 | |
| 197 | void ServerAsynchronousMetrics::updateImpl(TimePoint update_time, TimePoint current_time, bool force_update, bool first_run, AsynchronousMetricValues & new_values) |
| 198 | { |
| 199 | { |
| 200 | size_t total_bytes = 0; |
| 201 | size_t max_bytes = 0; |
| 202 | size_t total_files = 0; |
| 203 | |
| 204 | for (const auto & cache_data : FileCacheFactory::instance().getUniqueInstances()) |
| 205 | { |
| 206 | total_bytes += cache_data->cache->getUsedCacheSize(); |
| 207 | max_bytes += cache_data->cache->getMaxCacheSize(); |
| 208 | total_files += cache_data->cache->getFileSegmentsNum(); |
| 209 | } |
| 210 | |
| 211 | new_values["FilesystemCacheBytes"] = { total_bytes, |
| 212 | "Total bytes in the `cache` virtual filesystem. This cache is hold on disk." }; |
| 213 | new_values["FilesystemCacheCapacity"] = { max_bytes, |
| 214 | "Total capacity in the `cache` virtual filesystem. This cache is hold on disk." }; |
| 215 | new_values["FilesystemCacheFiles"] = { total_files, |
| 216 | "Total number of cached file segments in the `cache` virtual filesystem. This cache is hold on disk." }; |
| 217 | } |
| 218 | |
| 219 | /// Experimental ReaderExecutor read-path efficiency KPI: modeled cost (ms) per MiB of |
| 220 | /// requested bytes, as a ratio of two ProfileEvents' deltas over the interval (idle -> 0). |
| 221 | { |
| 222 | const UInt64 cost_us = static_cast<UInt64>( |
| 223 | ProfileEvents::global_counters[ProfileEvents::ReaderExecutorModeledCostMicroseconds].load(std::memory_order_relaxed)); |
| 224 | const UInt64 req_bytes = static_cast<UInt64>( |
| 225 | ProfileEvents::global_counters[ProfileEvents::ReaderExecutorRequestedBytes].load(std::memory_order_relaxed)); |
| 226 | if (!first_run) |
| 227 | { |
| 228 | const UInt64 d_cost = cost_us - prev_reader_executor_cost_us; |
| 229 | const UInt64 d_req = req_bytes - prev_reader_executor_requested_bytes; |
| 230 | const double ms_per_mib = d_req > 0 |
| 231 | ? (static_cast<double>(d_cost) / 1000.0) / (static_cast<double>(d_req) / (1024.0 * 1024.0)) |
| 232 | : 0.0; |
| 233 | new_values["ReaderExecutorModeledCostMsPerRequestedMiB"] = { ms_per_mib, |
| 234 | "Experimental ReaderExecutor read-path efficiency: modeled cost (ms) per MiB of requested" |
| 235 | " bytes over the last update interval, instance-wide -- the ratio of the deltas of" |
| 236 | " ProfileEvents ReaderExecutorModeledCostMicroseconds and ReaderExecutorRequestedBytes." |
| 237 | " Lower is better: the bandwidth floor is ~20 (a clean source read), cache hits trend to 0," |
| 238 | " over-fetch and incomplete connections push it up. 0 means no executor reads in the interval." }; |
| 239 | } |
| 240 | prev_reader_executor_cost_us = cost_us; |
| 241 | prev_reader_executor_requested_bytes = req_bytes; |
| 242 | } |
| 243 | |
| 244 | if (auto page_cache = getContext()->getPageCache()) |
| 245 | { |
| 246 | new_values["PageCacheMaxBytes"] = { page_cache->maxSizeInBytes(), |
| 247 | "Current limit on the size of userspace page cache, in bytes." }; |
| 248 | } |
| 249 | |
| 250 | new_values["Uptime"] = { getContext()->getUptimeSeconds(), |
| 251 | "The server uptime in seconds. It includes the time spent for server initialization before accepting connections." }; |
| 252 | |
| 253 | #if defined(OS_LINUX) |
| 254 | try |
nothing calls this directly
no test coverage detected