| 40 | } |
| 41 | |
| 42 | void CompactionChecker::PickCompactionFilesForCf(const engine::ColumnFamilyConfig &column_family_config) { |
| 43 | rocksdb::TablePropertiesCollection props; |
| 44 | rocksdb::ColumnFamilyHandle *cf = storage_->GetCFHandle(column_family_config.Id()); |
| 45 | auto s = storage_->GetDB()->GetPropertiesOfAllTables(cf, &props); |
| 46 | if (!s.ok()) { |
| 47 | WARN("[compaction checker] Failed to get table properties, {}", s.ToString()); |
| 48 | return; |
| 49 | } |
| 50 | // The main goal of compaction was reclaimed the disk space and removed |
| 51 | // the tombstone. It seems that compaction checker was unnecessary here when |
| 52 | // the live files was too few, Hard code to 1 here. |
| 53 | if (props.size() <= 1) return; |
| 54 | |
| 55 | size_t max_files_to_compact = 1; |
| 56 | if (props.size() / 360 > max_files_to_compact) { |
| 57 | max_files_to_compact = props.size() / 360; |
| 58 | } |
| 59 | int64_t now = util::GetTimeStamp(); |
| 60 | |
| 61 | auto force_compact_file_age = storage_->GetConfig()->force_compact_file_age; |
| 62 | auto force_compact_min_ratio = |
| 63 | static_cast<double>(storage_->GetConfig()->force_compact_file_min_deleted_percentage) / 100.0; |
| 64 | |
| 65 | std::string best_filename; |
| 66 | double best_delete_ratio = 0; |
| 67 | int64_t total_keys = 0, deleted_keys = 0; |
| 68 | rocksdb::Slice start_key, stop_key, best_start_key, best_stop_key; |
| 69 | for (const auto &iter : props) { |
| 70 | if (max_files_to_compact == 0) return; |
| 71 | |
| 72 | uint64_t file_creation_time = iter.second->file_creation_time; |
| 73 | if (file_creation_time == 0) { |
| 74 | // Fallback to the file Modification time to prevent repeatedly compacting the same file, |
| 75 | // file_creation_time is 0 which means the unknown condition in rocksdb |
| 76 | s = rocksdb::Env::Default()->GetFileModificationTime(iter.first, &file_creation_time); |
| 77 | if (!s.ok()) { |
| 78 | INFO("[compaction checker] Failed to get the file creation time: {}, err: {}", iter.first, s.ToString()); |
| 79 | continue; |
| 80 | } |
| 81 | } |
| 82 | |
| 83 | for (const auto &property_iter : iter.second->user_collected_properties) { |
| 84 | if (property_iter.first == "total_keys") { |
| 85 | auto parse_result = ParseInt<int>(property_iter.second, 10); |
| 86 | if (!parse_result) { |
| 87 | ERROR("[compaction checker] Parse total_keys error: {}", parse_result.Msg()); |
| 88 | continue; |
| 89 | } |
| 90 | total_keys = *parse_result; |
| 91 | } |
| 92 | if (property_iter.first == "deleted_keys") { |
| 93 | auto parse_result = ParseInt<int>(property_iter.second, 10); |
| 94 | if (!parse_result) { |
| 95 | ERROR("[compaction checker] Parse deleted_keys error: {}", parse_result.Msg()); |
| 96 | continue; |
| 97 | } |
| 98 | deleted_keys = *parse_result; |
| 99 | } |
no test coverage detected