94.77% (145/153) Uncovered changed code (with context): ================================================================================ src/Storages/MergeTree/MergeTreeData.cpp ================================================================================ --- uncovered block 2470-2470 --- 2468 | throw Exception(ErrorCodes::LOGICAL_ERROR, 2469 | "Table contains parts with adaptive and non adaptive marks, " >> 2470 | "but `setting enable_mixed_granularity_parts` is disabled"); 2471 | 2472 | has_non_adaptive_index_granularity_parts = have_non_adaptive_parts; --- uncovered block 4114-4114 --- 4112 | else 4113 | throw; >> 4114 | } 4115 | } 4116 | --- uncovered block 5176-5176 --- 5174 | { 5175 | LOG_TRACE(log, "Adding temporary part from directory {} with name {}.", part->getDataPartStorage().getPartDirectory(), part->name); >> 5176 | if (&out_transaction.data != this) 5177 | throw Exception(ErrorCodes::LOGICAL_ERROR, "MergeTreeData::Transaction for one table cannot be used with another. It is a bug."); 5178 | --- uncovered block 5179-5180 --- 5177 | throw Exception(ErrorCodes::LOGICAL_ERROR, "MergeTreeData::Transaction for one table cannot be used with another. It is a bug."); 5178 | >> 5179 | checkPartPartition(part, lock); >> 5180 | checkPartDuplicate(part, out_transaction, lock); 5181 | 5182 | DataPartPtr covering_part; --- uncovered block 5551-5551 --- 5549 | auto lock = lockParts(); 5550 | if (part->getState() == DataPartState::Active) >> 5551 | return; 5552 | 5553 | addPartContributionToColumnAndSecondaryIndexSizes(part); --- uncovered block 7658-7659 --- 7656 | 7657 | bool MergeTreeData::hasProjection() const >> 7658 | { >> 7659 | auto lock = readLockParts(); 7660 | for (const auto & part : data_parts_by_info) 7661 | { === Lost Baseline Coverage: 100 lines === ================================================================================ src/Storages/MergeTree/MergeTreeData.cpp ================================================================================ --- lost coverage block 2695-2695 --- 2693 | has_non_adaptive_index_granularity_parts = have_non_adaptive_parts; 2694 | transactions_enabled = have_parts_with_version_metadata; >> 2695 | 2696 | auto old_parts = grabOldParts(true); 2697 | --- lost coverage block 5245-5245 --- 5243 | 5244 | /// All checks are passed. Now we can rename the part on disk. >> 5245 | /// So, we maintain invariant: if a non-temporary part in filesystem then it is in data_parts 5246 | preparePartForCommit(part, out_transaction, lock, /* need_rename= */ true, rename_in_transaction); 5247 | --- lost coverage block 5317-5317 --- 5315 | 5316 | bool was_active = part->getState() == MergeTreeDataPartState::Active; >> 5317 | 5318 | if (was_active || clear_without_timeout) 5319 | part->remove_time.store(remove_time, std::memory_order_relaxed); --- lost coverage block 5320-5321 --- 5318 | if (was_active || clear_without_timeout) 5319 | part->remove_time.store(remove_time, std::memory_order_relaxed); >> 5320 | >> 5321 | /// Transition state before decrementing counters to keep 5322 | /// `total_parts_with_lightweight_delete` monotonic for lock-free readers. 5323 | if (part->getState() != MergeTreeDataPartState::Outdated) --- lost coverage block 5591-5591 --- 5589 | bool was_active = part->getState() == DataPartState::Active; 5590 | >> 5591 | /// Transition state before decrementing counters to keep 5592 | /// `total_parts_with_lightweight_delete` monotonic for lock-free readers. 5593 | modifyPartState(it_part, DataPartState::Deleting, lock); --- lost coverage block 6000-6000 --- 5998 | LOG_TEST(log, "swapActivePart: inserting {} into data_parts_indexes", part_copy->getNameWithState()); 5999 | auto part_it = data_parts_indexes.insert(part_copy).first; >> 6000 | 6001 | /// Increment counter before activating to keep 6002 | /// `total_parts_with_lightweight_delete` monotonic for lock-free readers. --- lost coverage block 6002-6002 --- 6000 | 6001 | /// Increment counter before activating to keep >> 6002 | /// `total_parts_with_lightweight_delete` monotonic for lock-free readers. 6003 | addPartContributionToTableCounters(part_copy); 6004 | modifyPartState(part_it, DataPartState::Active, lock); --- lost coverage block 8587-8587 --- 8585 | data.removePartContributionToColumnAndSecondaryIndexSizes(covered_part); 8586 | } >> 8587 | 8588 | data.modifyPartState(part, DataPartState::Active, acquired_parts_lock); 8589 | } --- lost coverage block 8590-8590 --- 8588 | data.modifyPartState(part, DataPartState::Active, acquired_parts_lock); 8589 | } >> 8590 | 8591 | ++part_idx; 8592 | } --- lost coverage block 8597-8597 --- 8595 | }); 8596 | } >> 8597 | 8598 | clear(); 8599 | --- lost coverage block 9705-9708 --- 9703 | { 9704 | if (partIsAssignedToBackgroundOperation(part)) >> 9705 | { >> 9706 | *reason = "part already assigned to background operation."; >> 9707 | return false; >> 9708 | } 9709 | if (currently_moving_parts.contains(part)) 9710 | { --- lost coverage block 10104-10104 --- 10102 | if (part->hasLightweightDelete()) 10103 | total_parts_with_lightweight_delete.fetch_add(1); >> 10104 | 10105 | if (part->info.isPatch()) 10106 | total_uncompressed_bytes_in_patches.fetch_add(part->getBytesUncompressedOnDisk()); --- lost coverage block 10108-10109 --- 10106 | total_uncompressed_bytes_in_patches.fetch_add(part->getBytesUncompressedOnDisk()); 10107 | } >> 10108 | >> 10109 | void MergeTreeData::removePartContributionToTableCounters(const DataPartPtr & part) 10110 | { 10111 | total_active_size_bytes.fetch_sub(part->getBytesOnDisk()); --- lost coverage block 10117-10117 --- 10115 | if (part->hasLightweightDelete()) 10116 | total_parts_with_lightweight_delete.fetch_sub(1); >> 10117 | 10118 | if (part->info.isPatch()) 10119 | total_uncompressed_bytes_in_patches.fetch_sub(part->getBytesUncompressedOnDisk()); --- lost coverage block 10121-10121 --- 10119 | total_uncompressed_bytes_in_patches.fetch_sub(part->getBytesUncompressedOnDisk()); 10120 | } >> 10121 | 10122 | void MergeTreeData::resetTableCounters() 10123 | { --- lost coverage block 10131-10131 --- 10129 | } 10130 | >> 10131 | bool MergeTreeData::insertQueryIdOrThrow(const String & query_id, size_t max_queries) const 10132 | { 10133 | std::lock_guard lock(query_id_set_mutex); ================================================================================ src/Storages/StorageMergeTree.cpp ================================================================================ --- lost coverage block 900-901 --- 898 | 899 | namespace >> 900 | { >> 901 | 902 | struct PartVersionWithName 903 | { --- lost coverage block 928-928 --- 926 | /// Killed 927 | if (current_mutation_it == current_mutations_by_version.end()) >> 928 | return {}; 929 | 930 | MergeTreeMutationStatus result{.is_done = false}; ================================================================================ src/Storages/StorageReplicatedMergeTree.cpp ================================================================================ --- lost coverage block 2016-2025 --- 2014 | 2015 | if (insane && !skip_sanity_checks) >> 2016 | { >> 2017 | LOG_DEBUG(log, sanity_report_debug_fmt, fmt::join(uncovered_unexpected_parts, ", "), fmt::join(restorable_unexpected_parts, ", "), fmt::join(parts_to_fetch, ", "), >> 2018 | fmt::join(covered_unexpected_parts, ", "), fmt::join(expected_parts, ", ")); >> 2019 | throw Exception(ErrorCodes::TOO_MANY_UNEXPECTED_DATA_PARTS, sanity_report_fmt, getStorageID().getNameForLogs(), >> 2020 | formatReadableQuantity(uncovered_unexpected_parts_rows), >> 2021 | formatReadableQuantity(total_rows_on_filesystem), >> 2022 | uncovered_unexpected_parts.size(), uncovered_unexpected_parts_rows, unexpected_parts_nonnew, unexpected_parts_nonnew_rows, >> 2023 | parts_to_fetch.size(), parts_to_fetch_blocks, covered_unexpected_parts.size(), >> 2024 | unexpected_parts_rows - uncovered_unexpected_parts_rows); >> 2025 | } 2026 | 2027 | if (unexpected_parts_nonnew_rows > 0 || uncovered_unexpected_parts_rows > 0 || !restorable_unexpected_parts.empty()) --- lost coverage block 3534-3538 --- 3532 | } 3533 | else if (info.parsed_entry->type == LogEntry::GET_PART) >> 3534 | { >> 3535 | String maybe_covering_drop_range = drop_range_set.getContainingPart(info.parsed_entry->new_part_name); >> 3536 | if (maybe_covering_drop_range.empty()) >> 3537 | get_part_set.add(info.parsed_entry->new_part_name); >> 3538 | } 3539 | else 3540 | { --- lost coverage block 3659-3659 --- 3657 | /// It should not cause any issues, but it does not allow to get rid of duplicated entries and add an assertion. 3658 | if (created_gets.contains(part_name)) >> 3659 | { 3660 | /// NOTE It would be better to copy log entry instead of creating GET_PART 3661 | /// if there are GET_PART and log entry of other type with the same new_part_name. --- lost coverage block 3663-3665 --- 3661 | /// if there are GET_PART and log entry of other type with the same new_part_name. 3662 | /// But it's a bit harder to implement, because it requires full-fledged virtual_parts set. >> 3663 | LOG_TRACE(log, "{} {}: GET_PART for it is already created", log_msg_context, part_name); >> 3664 | return true; >> 3665 | } 3666 | 3667 | return false; --- lost coverage block 3756-3756 --- 3754 | 3755 | if (should_ignore_log_entry(created_get_parts, part_name, fmt::format("Not copying {} {}", entry_name, entry_type))) >> 3756 | continue; 3757 | 3758 | if (entry_info.parsed_entry->type == LogEntry::GET_PART) --- lost coverage block 6486-6486 --- 6484 | assigned = try_assign_merge(partition_id); 6485 | if (!assigned) >> 6486 | break; 6487 | } 6488 | } --- lost coverage block 7806-7806 --- 7804 | return; 7805 | >> 7806 | auto zookeeper = getZooKeeper(); 7807 | 7808 | time_t max_replicas_unprocessed_insert_time = 0; --- lost coverage block 7808-7809 --- 7806 | auto zookeeper = getZooKeeper(); 7807 | >> 7808 | time_t max_replicas_unprocessed_insert_time = 0; >> 7809 | bool have_replica_with_nothing_unprocessed = false; 7810 | 7811 | Strings replicas = zookeeper->getChildren(fs::path(zookeeper_path) / "replicas"); --- lost coverage block 7811-7813 --- 7809 | bool have_replica_with_nothing_unprocessed = false; 7810 | >> 7811 | Strings replicas = zookeeper->getChildren(fs::path(zookeeper_path) / "replicas"); >> 7812 | Strings replica_paths; >> 7813 | replica_paths.reserve(replicas.size() * 2); 7814 | 7815 | for (const auto & replica : replicas) --- lost coverage block 7815-7818 --- 7813 | replica_paths.reserve(replicas.size() * 2); 7814 | >> 7815 | for (const auto & replica : replicas) >> 7816 | { >> 7817 | if (replica == replica_name) >> 7818 | continue; 7819 | 7820 | replica_paths.push_back(fs::path(zookeeper_path) / "replicas" / replica / "is_active"); --- lost coverage block 7820-7822 --- 7818 | continue; 7819 | >> 7820 | replica_paths.push_back(fs::path(zookeeper_path) / "replicas" / replica / "is_active"); >> 7821 | replica_paths.push_back(fs::path(zookeeper_path) / "replicas" / replica / "min_unprocessed_insert_time"); >> 7822 | } 7823 | 7824 | auto replica_result = zookeeper->tryGet(replica_paths); --- lost coverage block 7824-7825 --- 7822 | } 7823 | >> 7824 | auto replica_result = zookeeper->tryGet(replica_paths); >> 7825 | auto replica_num = 0; 7826 | 7827 | for (const auto & replica : replicas) --- lost coverage block 7827-7829 --- 7825 | auto replica_num = 0; 7826 | >> 7827 | for (const auto & replica : replicas) >> 7828 | { >> 7829 | if (replica == replica_name) 7830 | continue; 7831 | --- lost coverage block 7832-7832 --- 7830 | continue; 7831 | >> 7832 | const auto & is_active_path = replica_paths[replica_num]; 7833 | 7834 | const auto & is_active = replica_result[replica_num++]; --- lost coverage block 7834-7835 --- 7832 | const auto & is_active_path = replica_paths[replica_num]; 7833 | >> 7834 | const auto & is_active = replica_result[replica_num++]; >> 7835 | const auto & min_unprocessed_insert_time = replica_result[replica_num++]; 7836 | 7837 | /// Skip dead replicas. --- lost coverage block 7838-7838 --- 7836 | 7837 | /// Skip dead replicas. >> 7838 | if (is_active.error == Coordination::Error::ZNONODE) 7839 | continue; 7840 | else if (is_active.error != Coordination::Error::ZOK) --- lost coverage block 7840-7840 --- 7838 | if (is_active.error == Coordination::Error::ZNONODE) 7839 | continue; >> 7840 | else if (is_active.error != Coordination::Error::ZOK) 7841 | throw Coordination::Exception::fromPath(is_active.error, is_active_path); 7842 | --- lost coverage block 7843-7843 --- 7841 | throw Coordination::Exception::fromPath(is_active.error, is_active_path); 7842 | >> 7843 | if (min_unprocessed_insert_time.error != Coordination::Error::ZOK) 7844 | continue; 7845 | --- lost coverage block 7846-7847 --- 7844 | continue; 7845 | >> 7846 | const auto & value = min_unprocessed_insert_time.data; >> 7847 | time_t replica_time = value.empty() ? 0 : parse(value); 7848 | 7849 | if (replica_time == 0) --- lost coverage block 7849-7850 --- 7847 | time_t replica_time = value.empty() ? 0 : parse(value); 7848 | >> 7849 | if (replica_time == 0) >> 7850 | { 7851 | /** Note 7852 | * The conclusion that the replica does not lag may be incorrect, --- lost coverage block 7859-7861 --- 7857 | */ 7858 | >> 7859 | have_replica_with_nothing_unprocessed = true; >> 7860 | break; >> 7861 | } 7862 | 7863 | max_replicas_unprocessed_insert_time = std::max(replica_time, max_replicas_unprocessed_insert_time); --- lost coverage block 7866-7867 --- 7864 | } 7865 | >> 7866 | if (have_replica_with_nothing_unprocessed) >> 7867 | out_relative_delay = out_absolute_delay; 7868 | else 7869 | { --- lost coverage block 7875-7875 --- 7873 | out_relative_delay = out_absolute_delay - min_replicas_delay; 7874 | } >> 7875 | } 7876 | 7877 | void StorageReplicatedMergeTree::fetchPartition( --- lost coverage block 8652-8654 --- 8650 | LOG_DEBUG(log, "There is no part {} in ZooKeeper, it was only in filesystem", part_names[i]); 8651 | } >> 8652 | else >> 8653 | { >> 8654 | if (parts_should_be_retried) 8655 | parts_should_be_retried->insert(part_names[i]); 8656 | --- lost coverage block 8657-8659 --- 8655 | parts_should_be_retried->insert(part_names[i]); 8656 | >> 8657 | if (!Coordination::isHardwareError(response.error)) >> 8658 | LOG_WARNING(log, "Cannot remove part {} from ZooKeeper: {}", part_names[i], Coordination::errorMessage(response.error)); >> 8659 | } 8660 | } 8661 | } --- lost coverage block 9685-9689 --- 9683 | { 9684 | if (partial_shutdown_called) >> 9685 | { >> 9686 | was_interrupted = true; >> 9687 | target_entry_event.set(); >> 9688 | return; >> 9689 | } 9690 | 9691 | if (sync_mode == SyncReplicaMode::STRICT) --- lost coverage block 9712-9712 --- 9710 | 9711 | if (was_interrupted) >> 9712 | throw Exception(ErrorCodes::ABORTED, "Shutdown is called for table"); 9713 | 9714 | return true; --- lost coverage block 11565-11565 --- 11563 | getStatus(status, /* with_zk_fields = */ false); 11564 | if (status.queue.inserts_in_queue) >> 11565 | empty = false; 11566 | } 11567 | auto backup = restorer.getBackup(); WARNING: Failed to get start time for [Print Uncovered Code] - start time and duration won't be set --- Coverage counts --- Lines : baseline 739,502/880,956 → current 739,602/880,918 (Δ +100 / -38) Functions : baseline 798,414/878,663 → current 798,390/878,640 (Δ -24 / -23) Branches : baseline 239,659/313,564 → current 239,666/313,562 (Δ +7 / -2)