| 1992 | |
| 1993 | |
| 1994 | bool StorageReplicatedMergeTree::executeFetch(LogEntry & entry) |
| 1995 | { |
| 1996 | /// Looking for covering part. After that entry.actual_new_part_name may be filled. |
| 1997 | String replica = findReplicaHavingCoveringPart(entry, true); |
| 1998 | const auto storage_settings_ptr = getSettings(); |
| 1999 | auto metadata_snapshot = getInMemoryMetadataPtr(); |
| 2000 | |
| 2001 | if (storage_settings_ptr->replicated_max_parallel_fetches && |
| 2002 | total_fetches >= storage_settings_ptr->replicated_max_parallel_fetches) |
| 2003 | throw Exception(ErrorCodes::TOO_MANY_FETCHES, "Too many total fetches from replicas, maximum: {} ", |
| 2004 | storage_settings_ptr->replicated_max_parallel_fetches.toString()); |
| 2005 | |
| 2006 | ++total_fetches; |
| 2007 | SCOPE_EXIT({--total_fetches;}); |
| 2008 | |
| 2009 | if (storage_settings_ptr->replicated_max_parallel_fetches_for_table |
| 2010 | && current_table_fetches >= storage_settings_ptr->replicated_max_parallel_fetches_for_table) |
| 2011 | throw Exception(ErrorCodes::TOO_MANY_FETCHES, "Too many fetches from replicas for table, maximum: {}", |
| 2012 | storage_settings_ptr->replicated_max_parallel_fetches_for_table.toString()); |
| 2013 | |
| 2014 | ++current_table_fetches; |
| 2015 | SCOPE_EXIT({--current_table_fetches;}); |
| 2016 | |
| 2017 | try |
| 2018 | { |
| 2019 | if (replica.empty()) |
| 2020 | { |
| 2021 | /** If a part is to be written with a quorum and the quorum is not reached yet, |
| 2022 | * then (due to the fact that a part is impossible to download right now), |
| 2023 | * the quorum entry should be considered unsuccessful. |
| 2024 | * TODO Complex code, extract separately. |
| 2025 | */ |
| 2026 | if (entry.quorum) |
| 2027 | { |
| 2028 | if (entry.type != LogEntry::GET_PART) |
| 2029 | throw Exception("Logical error: log entry with quorum but type is not GET_PART", ErrorCodes::LOGICAL_ERROR); |
| 2030 | |
| 2031 | LOG_DEBUG(log, "No active replica has part {} which needs to be written with quorum. Will try to mark that quorum as failed.", entry.new_part_name); |
| 2032 | |
| 2033 | /** Atomically: |
| 2034 | * - if replicas do not become active; |
| 2035 | * - if there is a `quorum` node with this part; |
| 2036 | * - delete `quorum` node; |
| 2037 | * - add a part to the list `quorum/failed_parts`; |
| 2038 | * - if the part is not already removed from the list for deduplication `blocks/block_num`, then delete it; |
| 2039 | * |
| 2040 | * If something changes, then we will nothing - we'll get here again next time. |
| 2041 | */ |
| 2042 | |
| 2043 | /** We collect the `host` node versions from the replicas. |
| 2044 | * When the replica becomes active, it changes the value of host in the same transaction (with the creation of `is_active`). |
| 2045 | * This will ensure that the replicas do not become active. |
| 2046 | */ |
| 2047 | |
| 2048 | auto zookeeper = getZooKeeper(); |
| 2049 | |
| 2050 | Strings replicas = zookeeper->getChildren(fs::path(zookeeper_path) / "replicas"); |
| 2051 |
nothing calls this directly
no test coverage detected