源码路径
curve-release2.2\src\chunkserver\raftlog
1.curve_segment_log_storage.cpp
2.curve_segment.cpp
在curve_segment_log_storage.cpp
文件中,定义了CurveSegmentLogStorage
类及其相关方法。以下是该文件中函数的方法分析,采用代码注释的方式进行说明:
// StoreOptForCurveSegmentLogStorage方法,设置CurveSegmentLogStorage的选项
LogStorageOptions StoreOptForCurveSegmentLogStorage(LogStorageOptions options) {
// 如果传入了walFilePool选项,保存该选项
if (nullptr != options.walFilePool) {
options_ = options;
}
// 返回保存的选项
return options_;
}
// RegisterCurveSegmentLogStorageOrDie方法,注册CurveSegmentLogStorage到braft
void RegisterCurveSegmentLogStorageOrDie() {
// 创建CurveSegmentLogStorage实例
static CurveSegmentLogStorage logStorage;
// 向braft注册该实例
braft::log_storage_extension()->RegisterOrDie("curve", &logStorage);
}
// CurveSegmentLogStorage类的初始化方法
int CurveSegmentLogStorage::init(braft::ConfigurationManager* configuration_manager) {
// 创建日志存储目录
butil::FilePath dir_path(_path);
if (!butil::CreateDirectoryAndGetError(dir_path, &e, braft::FLAGS_raft_create_parent_directories)) {
// 如果创建目录失败,记录错误并返回
LOG(ERROR) << "Fail to create " << dir_path.value << ": " << e;
return -1;
}
// 根据系统支持选择校验和类型
if (butil::crc32c::IsFastCrc32Supported()) {
_checksum_type = CHECKSUM_CRC32;
LOG_ONCE(INFO) << "Use crc32c as the checksum type of appending entries";
} else {
_checksum_type = CHECKSUM_MURMURHASH32;
LOG_ONCE(INFO) << "Use murmurhash32 as the checksum type of appending entries";
}
// 加载元数据、列出段文件、加载段文件等初始化操作
// ...
// 如果目录为空,则设置_first_log_index为1,并保存元数据
if (is_empty) {
_first_log_index.store(1);
_last_log_index.store(0);
ret = save_meta(1);
}
return ret; // 返回初始化结果
}
// 加载元数据的方法
int CurveSegmentLogStorage::load_meta() {
// 从文件系统中加载元数据
// ...
}
// 列出段文件的方法
int CurveSegmentLogStorage::list_segments(bool is_empty) {
// 列出所有段文件,并恢复段元数据
// ...
}
// 加载段文件的方法
int CurveSegmentLogStorage::load_segments(braft::ConfigurationManager* configuration_manager) {
// 为每个段文件加载数据
// ...
}
// 获取最后日志索引的方法
int64_t CurveSegmentLogStorage::last_log_index() {
// 返回最后日志索引
return _last_log_index.load(butil::memory_order_acquire);
}
// 获取日志条目的方法
braft::LogEntry* CurveSegmentLogStorage::get_entry(const int64_t index) {
// 根据索引获取日志条目
// ...
}
// 获取段的方法
int CurveSegmentLogStorage::get_segment(int64_t index, scoped_refptr<Segment>* ptr) {
// 根据索引获取段
// ...
}
// 获取任期的方法
int64_t CurveSegmentLogStorage::get_term(const int64_t index) {
// 根据索引获取任期
// ...
}
// 追加日志条目的方法
int CurveSegmentLogStorage::append_entry(const braft::LogEntry* entry) {
// 将日志条目追加到打开的段中
// ...
}
// 追加多个日志条目的方法
int CurveSegmentLogStorage::append_entries(const std::vector<braft::LogEntry>& entries) {
// 追加一系列日志条目
// ...
}
// 截断前缀的方法
int CurveSegmentLogStorage::truncate_prefix(const int64_t first_index_kept) {
// 截断保留first_index_kept及之前的日志
// ...
}
// 保存元数据的方法
int CurveSegmentLogStorage::save_meta(const int64_t log_index) {
// 将元数据保存到文件系统中
// ...
}
// 移除段的方法
void CurveSegmentLogStorage::pop_segments(const int64_t first_index_kept, std::vector<scoped_refptr<Segment>>* popped) {
// 移除保留first_index_kept及之前的段
// ...
}
// 重置日志存储的方法
int CurveSegmentLogStorage::reset(const int64_t next_log_index) {
// 重置日志存储,移除所有段并设置新的日志索引
// ...
}
// 列出所有文件的方法
void CurveSegmentLogStorage::list_files(std::vector<std::string>* seg_files) {
// 列出所有段文件和元数据文件
// ...
}
// 同步所有段的方法
void CurveSegmentLogStorage::sync() {
// 同步所有段到磁盘
// ...
}
// 创建新的日志存储实例的方法
braft::LogStorage* CurveSegmentLogStorage::new_instance(const std::string& uri) const {
// 创建并返回一个新的CurveSegmentLogStorage实例
// ...
}
// 获取打开的段的方法
scoped_refptr<Segment> CurveSegmentLogStorage::open_segment(size_t to_write) {
// 打开或创建一个新的段用于写入
// ...
}
// 获取日志存储状态的方法
LogStorageStatus CurveSegmentLogStorage::GetStatus() {
// 返回当前存储状态
// ...
}
CurveSegmentLogStorage
类是日志存储的核心组件,它负责管理日志数据的存储、检索、追加和截断等操作。通过这些方法,CurveSegmentLogStorage
类能够维护和管理日志数据的一致性和完整性,同时提供高效的数据访问和同步机制。
在curve_segment.cpp
文件中,定义了CurveSegment
类及其相关方法。以下是该文件中函数的方法分析,采用代码注释的方式进行说明:
// CurveSegment类的构造函数
CurveSegment::CurveSegment(const std::string& path, int64_t first_index,
int64_t last_index, ChecksumType checksum_type,
FilePool* walFilePool)
: _path(path),
_first_index(first_index),
_last_index(last_index),
_checksum_type(checksum_type),
_walFilePool(walFilePool),
_fd(-1),
_direct_fd(-1),
_meta(bytes, 0) { // 初始化元数据对象
// 根据校验和类型初始化校验和函数
switch (_checksum_type) {
case CHECKSUM_MURMURHASH32:
_get_checksum = &CurveSegment::get_checksum<CHECKSUM_MURMURHASH32>;
_verify_checksum = &CurveSegment::verify_checksum<CHECKSUM_MURMURHASH32>;
break;
case CHECKSUM_CRC32:
_get_checksum = &CurveSegment::get_checksum<CHECKSUM_CRC32>;
_verify_checksum = &CurveSegment::verify_checksum<CHECKSUM_CRC32>;
break;
default:
LOG(ERROR) << "Unknown checksum_type=" << _checksum_type;
break;
}
}
// 创建CurveSegment的方法
int CurveSegment::create() {
// 创建一个新的CurveSegment,并初始化元数据页
// ...
}
// CurveSegment类的析构函数
CurveSegment::~CurveSegment() {
// 清理资源,关闭文件描述符
// ...
}
// 加载CurveSegment的方法
int CurveSegment::load(braft::ConfigurationManager* configuration_manager) {
// 打开CurveSegment文件,并加载元数据页和日志条目索引
// ...
}
// 追加日志条目的方法
int CurveSegment::append(const braft::LogEntry* entry) {
// 将日志条目追加到CurveSegment中
// ...
}
// 更新元数据页的方法
int CurveSegment::_update_meta_page() {
// 将更新后的元数据页写入到文件中
// ...
}
// 获取日志条目的方法
braft::LogEntry* CurveSegment::get(const int64_t index) const {
// 根据索引获取日志条目
// ...
}
// 获取日志条目对应的任期的方法
int64_t CurveSegment::get_term(const int64_t index) const {
// 根据索引获取日志条目的任期
// ...
}
// 关闭CurveSegment的方法
int CurveSegment::close(bool will_sync) {
// 关闭CurveSegment,并根据需要同步数据到磁盘
// ...
}
// 同步CurveSegment的方法
int CurveSegment::sync(bool will_sync) {
// 同步CurveSegment中的数据到磁盘
// ...
}
// 删除CurveSegment的方法
int CurveSegment::unlink() {
// 从文件系统中删除CurveSegment
// ...
}
// 截断CurveSegment的方法
int CurveSegment::truncate(const int64_t last_index_kept) {
// 截断CurveSegment,移除保留last_index_kept及之前的日志数据
// ...
}
// 获取CurveSegment文件名的方法
std::string CurveSegment::file_name() {
// 根据CurveSegment的状态返回对应的文件名
// ...
}
// 私有方法,根据索引获取日志条目的元数据
int CurveSegment::_get_meta(int64_t index, LogMeta* meta) const {
// 获取指定索引的日志条目的元数据
// ...
}
CurveSegment
类是日志存储的基本单元,它负责管理单个日志段的创建、加载、追加、同步和截断等操作。通过这些方法,CurveSegment
类能够维护和管理日志数据的一致性和完整性,同时提供高效的数据访问和同步机制。类中还包括了一些私有辅助方法,用于内部处理和维护CurveSegment
的状态。