当前位置:网站首页>Leveldb source code analysis -- log file format
Leveldb source code analysis -- log file format
2022-06-24 17:23:00 【Xiao Lin Gang】
Use scenarios
- WAL Log files ;
- MANIFEST Version information file ;
Log file format
characteristic :
- log The file consists of consecutive block form , Every block The size of is fixed to 32K;
- Every block Continuous record form ;
- Because of users data May be larger than 32K, One block Cannot save , So through type Field to indicate the type of log ;
Such as :
Log operations
Read log
bool Reader::ReadRecord(Slice* record, std::string* scratch) { if (last_record_offset_ < initial_offset_) { if (!SkipToInitialBlock()) { return false; } } scratch->clear(); record->clear(); bool in_fragmented_record = false; uint64_t prospective_record_offset = 0; Slice fragment; while (true) { const unsigned int record_type = ReadPhysicalRecord(&fragment); uint64_t physical_record_offset = end_of_buffer_offset_ - buffer_.size() - kHeaderSize - fragment.size(); if (resyncing_) { if (record_type == kMiddleType) { continue; } else if (record_type == kLastType) { resyncing_ = false; continue; } else { resyncing_ = false; } } switch (record_type) { case kFullType: if (in_fragmented_record) { // Handle bug in earlier versions of log::Writer where // it could emit an empty kFirstType record at the tail end // of a block followed by a kFullType or kFirstType record // at the beginning of the next block. if (!scratch->empty()) { ReportCorruption(scratch->size(), "partial record without end(1)"); } } prospective_record_offset = physical_record_offset; scratch->clear(); *record = fragment; last_record_offset_ = prospective_record_offset; return true; case kFirstType: if (in_fragmented_record) { // Handle bug in earlier versions of log::Writer where // it could emit an empty kFirstType record at the tail end // of a block followed by a kFullType or kFirstType record // at the beginning of the next block. if (!scratch->empty()) { ReportCorruption(scratch->size(), "partial record without end(2)"); } } prospective_record_offset = physical_record_offset; scratch->assign(fragment.data(), fragment.size()); in_fragmented_record = true; break; case kMiddleType: if (!in_fragmented_record) { ReportCorruption(fragment.size(), "missing start of fragmented record(1)"); } else { scratch->append(fragment.data(), fragment.size()); } break; case kLastType: if (!in_fragmented_record) { ReportCorruption(fragment.size(), "missing start of fragmented record(2)"); } else { scratch->append(fragment.data(), fragment.size()); *record = Slice(*scratch); last_record_offset_ = prospective_record_offset; return true; } break; case kEof: if (in_fragmented_record) { // This can be caused by the writer dying immediately after // writing a physical record but before completing the next; don't // treat it as a corruption, just ignore the entire logical record. scratch->clear(); } return false; case kBadRecord: if (in_fragmented_record) { ReportCorruption(scratch->size(), "error in middle of record"); in_fragmented_record = false; scratch->clear(); } break; default: { char buf[40]; std::snprintf(buf, sizeof(buf), "unknown record type %u", record_type); ReportCorruption( (fragment.size() + (in_fragmented_record ? scratch->size() : 0)), buf); in_fragmented_record = false; scratch->clear(); break; } } } return false; } // Read a... From the disk file record Data records unsigned int Reader::ReadPhysicalRecord(Slice* result) { while (true) { if (buffer_.size() < kHeaderSize) { if (!eof_) { buffer_.clear(); // Read a... From the disk file 4K A block of data Status status = file_->Read(kBlockSize, &buffer_, backing_store_); end_of_buffer_offset_ += buffer_.size(); if (!status.ok()) { buffer_.clear(); ReportDrop(kBlockSize, status); eof_ = true; return kEof; } else if (buffer_.size() < kBlockSize) { eof_ = true; } continue; } else { buffer_.clear(); return kEof; } } // analysis record Category and length of records const char* header = buffer_.data(); const uint32_t a = static_cast<uint32_t>(header[4]) & 0xff; const uint32_t b = static_cast<uint32_t>(header[5]) & 0xff; const unsigned int type = header[6]; const uint32_t length = a | (b << 8); if (kHeaderSize + length > buffer_.size()) { size_t drop_size = buffer_.size(); buffer_.clear(); if (!eof_) { ReportCorruption(drop_size, "bad record length"); return kBadRecord; } // If the end of the file has been reached without reading |length| bytes // of payload, assume the writer died in the middle of writing the record. // Don't report a corruption. return kEof; } if (type == kZeroType && length == 0) { // Skip zero length record without reporting any drops since // such records are produced by the mmap based writing code in // env_posix.cc that preallocates file regions. buffer_.clear(); return kBadRecord; } // Check crc if (checksum_) { uint32_t expected_crc = crc32c::Unmask(DecodeFixed32(header)); uint32_t actual_crc = crc32c::Value(header + 6, 1 + length); if (actual_crc != expected_crc) { // Drop the rest of the buffer since "length" itself may have // been corrupted and if we trust it, we could find some // fragment of a real log record that just happens to look // like a valid log record. size_t drop_size = buffer_.size(); buffer_.clear(); ReportCorruption(drop_size, "checksum mismatch"); return kBadRecord; } } buffer_.remove_prefix(kHeaderSize + length); // Skip physical record that started before initial_offset_ if (end_of_buffer_offset_ - buffer_.size() - kHeaderSize - length < initial_offset_) { result->clear(); return kBadRecord; } *result = Slice(header + kHeaderSize, length); return type; } }
边栏推荐
- [leetcode108] convert an ordered array into a binary search tree (medium order traversal)
- Classic examples of C language 100
- Ramda 鲜为人知的一面
- How to troubleshoot and solve the problem that the ultra-low delay security live broadcast system webrtc client plays no audio in the browser?
- Snapshot management for elastic cloud enterprise
- 网站SEO排名越做越差是什么原因造成的?
- ClassNotFoundException v/s NoClassDefFoundError
- Sigai intelligent container damage identification products are deployed in Rizhao Port and Yingkou Port
- Try catch finally implementation mechanism
- How to learn go language happily? Let's go!
猜你喜欢
[leetcode108] convert an ordered array into a binary search tree (medium order traversal)
Using consistent hash algorithm in Presto to enhance the data cache locality of dynamic clusters
MySQL learning -- table structure of SQL test questions
Why do you develop middleware when you are young? "You can choose your own way"
Daily algorithm & interview questions, 28 days of special training in large factories - the 15th day (string)
随机推荐
Kubernetes 1.20.5 helm installation Jenkins
Ramda's little-known side
Explanation of pod DNS configuration & cases of DNS resolution failure
Several cloud products of Tencent cloud have passed IPv6 enabled cloud logo certification
Explore cloudera manager management software tuning (1)
Edit distance (linear dp+ violence matching)
FPGA systematic learning notes serialization_ Day8 [design of 4-bit multiplier and 4-bit divider]
Management system permission design
How to build RTSP test URL in Intranet Environment
How to customize the log output format of zap?
Cloud native monitoring practice (2) monitoring and collection of components outside the TKE cluster
[play with Tencent cloud] check 9 popular Tencent cloud products
Introduction to visual studio shortcut keys and advanced gameplay
Daily algorithm & interview questions, 28 days of special training in large factories - the 15th day (string)
Tencent monthly security report helps rural revitalization, releases cloud security reports, and jointly builds a joint network security laboratory
Why do you develop middleware when you are young? "You can choose your own way"
How to compile and debug go runtime source code
zblog系统如何根据用户ID获取用户相关信息的教程
Pagoda activities, team members can enjoy a lightweight server 1 core 2g5m 28 yuan for two years
How to perform concurrent stress testing on RTSP video streams distributed by audio and video streaming servers?