Compare commits

...

4 Commits

Author SHA1 Message Date
copilot-swe-agent[bot]
2b9b1584ce Pass formattable object to logger instead of intermediate string
Instead of using std::function<std::string()> which creates intermediate
strings, introduce allocating_section_namer class that formats directly
to fmt::memory_buffer. This avoids string allocation overhead when
logging allocation failures.

Co-authored-by: tgrabiec <283695+tgrabiec@users.noreply.github.com>
2025-12-05 14:44:35 +00:00
copilot-swe-agent[bot]
ac695b6986 Make allocating_section name lazily constructed from table reference
Co-authored-by: tgrabiec <283695+tgrabiec@users.noreply.github.com>
2025-12-03 20:16:13 +00:00
copilot-swe-agent[bot]
f23f6c5dcd Add name field to allocating_section and update logging
Co-authored-by: tgrabiec <283695+tgrabiec@users.noreply.github.com>
2025-12-03 20:01:38 +00:00
copilot-swe-agent[bot]
bd01b669d0 Initial plan 2025-12-03 19:48:31 +00:00
3 changed files with 57 additions and 2 deletions

View File

@@ -1287,6 +1287,15 @@ row_cache::row_cache(schema_ptr s, snapshot_source src, cache_tracker& tracker,
, _partitions(dht::raw_token_less_comparator{})
, _underlying(src())
, _snapshot_source(std::move(src))
, _update_section(logalloc::allocating_section_namer([this] (fmt::memory_buffer& buf) {
fmt::format_to(std::back_inserter(buf), "{}.{}_update", _schema->ks_name(), _schema->cf_name());
}))
, _populate_section(logalloc::allocating_section_namer([this] (fmt::memory_buffer& buf) {
fmt::format_to(std::back_inserter(buf), "{}.{}_populate", _schema->ks_name(), _schema->cf_name());
}))
, _read_section(logalloc::allocating_section_namer([this] (fmt::memory_buffer& buf) {
fmt::format_to(std::back_inserter(buf), "{}.{}_read", _schema->ks_name(), _schema->cf_name());
}))
{
try {
with_allocator(_tracker.allocator(), [this, cont] {

View File

@@ -2948,10 +2948,18 @@ void allocating_section::on_alloc_failure(logalloc::region& r) {
r.allocator().invalidate_references();
if (r.get_tracker().get_impl().segment_pool().allocation_failure_flag()) {
_lsa_reserve *= 2;
llogger.info("LSA allocation failure, increasing reserve in section {} to {} segments; trace: {}", fmt::ptr(this), _lsa_reserve, current_backtrace());
if (!_namer) {
llogger.info("LSA allocation failure, increasing reserve in section {} to {} segments; trace: {}", fmt::ptr(this), _lsa_reserve, current_backtrace());
} else {
llogger.info("LSA allocation failure, increasing reserve in section {} ({}) to {} segments; trace: {}", fmt::ptr(this), _namer, _lsa_reserve, current_backtrace());
}
} else {
_std_reserve *= 2;
llogger.info("Standard allocator failure, increasing head-room in section {} to {} [B]; trace: {}", fmt::ptr(this), _std_reserve, current_backtrace());
if (!_namer) {
llogger.info("Standard allocator failure, increasing head-room in section {} to {} [B]; trace: {}", fmt::ptr(this), _std_reserve, current_backtrace());
} else {
llogger.info("Standard allocator failure, increasing head-room in section {} ({}) to {} [B]; trace: {}", fmt::ptr(this), _namer, _std_reserve, current_backtrace());
}
}
reserve(r.get_tracker().get_impl());
}

View File

@@ -9,6 +9,10 @@
#pragma once
#include <memory>
#include <string>
#include <string_view>
#include <functional>
#include <fmt/format.h>
#include <seastar/core/memory.hh>
#include <seastar/core/shard_id.hh>
#include <seastar/core/shared_ptr.hh>
@@ -20,6 +24,28 @@
namespace logalloc {
// Forward declaration for use in allocating_section_namer
class schema;
// Helper class to format allocating section names without intermediate string allocation
// This is a formattable object that can be passed directly to fmt logger
class allocating_section_namer {
std::function<void(fmt::memory_buffer&)> _formatter;
public:
allocating_section_namer() = default;
template<typename Func>
explicit allocating_section_namer(Func&& f) : _formatter(std::forward<Func>(f)) {}
void format_to(fmt::memory_buffer& buf) const {
if (_formatter) {
_formatter(buf);
}
}
explicit operator bool() const noexcept { return bool(_formatter); }
};
struct occupancy_stats;
class region;
class region_impl;
@@ -442,6 +468,7 @@ class allocating_section {
size_t _minimum_lsa_emergency_reserve = 0;
int64_t _remaining_std_bytes_until_decay = s_bytes_per_decay;
int _remaining_lsa_segments_until_decay = s_segments_per_decay;
allocating_section_namer _namer; // Optional namer for debugging
private:
struct guard {
tracker::impl& _tracker;
@@ -453,6 +480,8 @@ private:
void maybe_decay_reserve() noexcept;
void on_alloc_failure(logalloc::region&);
public:
allocating_section() = default;
explicit allocating_section(allocating_section_namer namer) : _namer(std::move(namer)) {}
void set_lsa_reserve(size_t) noexcept;
void set_std_reserve(size_t) noexcept;
@@ -542,6 +571,15 @@ future<> use_standard_allocator_segment_pool_backend(size_t available_memory);
}
template <> struct fmt::formatter<logalloc::allocating_section_namer> {
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
auto format(const logalloc::allocating_section_namer& namer, fmt::format_context& ctx) const {
fmt::memory_buffer buf;
namer.format_to(buf);
return fmt::format_to(ctx.out(), "{}", std::string_view(buf.data(), buf.size()));
}
};
template <> struct fmt::formatter<logalloc::occupancy_stats> : fmt::formatter<string_view> {
auto format(const logalloc::occupancy_stats& stats, fmt::format_context& ctx) const {
return fmt::format_to(ctx.out(), "{:.2f}%, {:d} / {:d} [B]",