Segment::close_ertr::future<> BlockSegment::close()
{
- return manager.segment_close(id);
+ return manager.segment_close(id, write_pointer);
}
Segment::write_ertr::future<> BlockSegment::write(
return manager.segment_write({id, offset}, bl);
}
-Segment::close_ertr::future<> BlockSegmentManager::segment_close(segment_id_t id)
+Segment::close_ertr::future<> BlockSegmentManager::segment_close(
+ segment_id_t id, segment_off_t write_pointer)
{
assert(tracker);
tracker->set(id, segment_state_t::CLOSED);
+ ++stats.closed_segments;
+ int unused_bytes = get_segment_size() - write_pointer;
+ assert(unused_bytes >= 0);
+ stats.closed_segments_unused_bytes += unused_bytes;
+ stats.metadata_write.increment(tracker->get_size());
return tracker->write_out(device, superblock.tracker_offset);
}
addr.offset,
get_offset(addr),
bl.length());
+ stats.data_write.increment(bl.length());
return do_writev(device, get_offset(addr), std::move(bl), superblock.block_size);
}
).safe_then([=](auto p) {
device = std::move(p.first);
auto sd = p.second;
+ stats.data_read.increment(
+ ceph::encoded_sizeof_bounded<block_sm_superblock_t>());
return read_superblock(device, sd);
}).safe_then([=](auto sb) {
superblock = sb;
tracker = std::make_unique<SegmentStateTracker>(
superblock.segments,
superblock.block_size);
+ stats.data_read.increment(tracker->get_size());
return tracker->read_in(
device,
superblock.tracker_offset
tracker->set(i, segment_state_t::CLOSED);
}
}
+ stats.metadata_write.increment(tracker->get_size());
return tracker->write_out(device, superblock.tracker_offset);
});
});
device = p.first;
stat = p.second;
sb = make_superblock(meta, stat);
+ stats.metadata_write.increment(
+ ceph::encoded_sizeof_bounded<block_sm_superblock_t>());
return write_superblock(device, sb);
}).safe_then([&] {
logger().debug("BlockSegmentManager::mkfs: superblock written");
tracker.reset(new SegmentStateTracker(sb.segments, sb.block_size));
+ stats.metadata_write.increment(tracker->get_size());
return tracker->write_out(device, sb.tracker_offset);
}).finally([&] {
return device.close();
}
tracker->set(id, segment_state_t::OPEN);
+ stats.metadata_write.increment(tracker->get_size());
return tracker->write_out(device, superblock.tracker_offset
).safe_then([this, id] {
+ ++stats.opened_segments;
return open_ertr::future<SegmentRef>(
open_ertr::ready_future_marker{},
SegmentRef(new BlockSegment(*this, id)));
}
tracker->set(id, segment_state_t::EMPTY);
+ ++stats.released_segments;
+ stats.metadata_write.increment(tracker->get_size());
return tracker->write_out(device, superblock.tracker_offset);
}
return crimson::ct_error::enoent::make();
}
+ stats.data_read.increment(len);
return do_read(
device,
get_offset(addr),
out);
}
+void BlockSegmentManager::register_metrics()
+{
+ namespace sm = seastar::metrics;
+ // TODO: add label for device_id
+ stats.reset();
+ metrics.add_group(
+ "segment_manager",
+ {
+ sm::make_counter(
+ "data_read_num",
+ stats.data_read.num,
+ sm::description("total number of data read")
+ ),
+ sm::make_counter(
+ "data_read_bytes",
+ stats.data_read.bytes,
+ sm::description("total bytes of data read")
+ ),
+ sm::make_counter(
+ "data_write_num",
+ stats.data_write.num,
+ sm::description("total number of data write")
+ ),
+ sm::make_counter(
+ "data_write_bytes",
+ stats.data_write.bytes,
+ sm::description("total bytes of data write")
+ ),
+ sm::make_counter(
+ "metadata_write_num",
+ stats.metadata_write.num,
+ sm::description("total number of metadata write")
+ ),
+ sm::make_counter(
+ "metadata_write_bytes",
+ stats.metadata_write.bytes,
+ sm::description("total bytes of metadata write")
+ ),
+ sm::make_counter(
+ "opened_segments",
+ stats.opened_segments,
+ sm::description("total segments opened")
+ ),
+ sm::make_counter(
+ "closed_segments",
+ stats.closed_segments,
+ sm::description("total segments closed")
+ ),
+ sm::make_counter(
+ "closed_segments_unused_bytes",
+ stats.closed_segments_unused_bytes,
+ sm::description("total unused bytes of closed segments")
+ ),
+ sm::make_counter(
+ "released_segments",
+ stats.released_segments,
+ sm::description("total segments released")
+ ),
+ }
+ );
+}
+
}
>;
close_ertr::future<> close();
- BlockSegmentManager(const std::string &path) : device_path(path) {}
+ BlockSegmentManager(const std::string &path) : device_path(path) {
+ register_metrics();
+ }
~BlockSegmentManager();
open_ertr::future<SegmentRef> open(segment_id_t id) final;
friend class BlockSegment;
using segment_state_t = Segment::segment_state_t;
-
+ struct effort_t {
+ uint64_t num = 0;
+ uint64_t bytes = 0;
+
+ void increment(uint64_t read_bytes) {
+ ++num;
+ bytes += read_bytes;
+ }
+ };
+
+ struct {
+ effort_t data_read;
+ effort_t data_write;
+ effort_t metadata_write;
+ uint64_t opened_segments;
+ uint64_t closed_segments;
+ uint64_t closed_segments_unused_bytes;
+ uint64_t released_segments;
+
+ void reset() {
+ data_read = {};
+ data_write = {};
+ metadata_write = {};
+ opened_segments = 0;
+ closed_segments = 0;
+ closed_segments_unused_bytes = 0;
+ released_segments = 0;
+ }
+ } stats;
+
+ void register_metrics();
+ seastar::metrics::metric_group metrics;
+
std::string device_path;
std::unique_ptr<SegmentStateTracker> tracker;
block_sm_superblock_t superblock;
char *buffer = nullptr;
- Segment::close_ertr::future<> segment_close(segment_id_t id);
+ Segment::close_ertr::future<> segment_close(
+ segment_id_t id, segment_off_t write_pointer);
};
}