Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduced MergeTask and MutateTask #25165

Merged
merged 124 commits into from
Sep 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
124 commits
Select commit Hold shift + click to select a range
e05dd10
save
nikitamikhaylov Jun 3, 2021
aa66c7f
save
nikitamikhaylov Jun 7, 2021
5c22168
save
nikitamikhaylov Jun 7, 2021
ae82fe2
save
nikitamikhaylov Jun 9, 2021
18708e0
save
nikitamikhaylov Jun 10, 2021
27ec511
mvp
nikitamikhaylov Jun 10, 2021
6fdc94d
fix tests
nikitamikhaylov Jun 11, 2021
fb9d661
fix tests
nikitamikhaylov Jun 15, 2021
37a7e60
fix tests
nikitamikhaylov Jun 15, 2021
2923f70
fix tests
nikitamikhaylov Jun 16, 2021
6246262
add boost future
nikitamikhaylov Jun 16, 2021
ec9e9fd
better
nikitamikhaylov Jun 16, 2021
e47c53b
add contib changes
nikitamikhaylov Jun 16, 2021
8816955
get rid of priority in thread pool and fix pvs check
nikitamikhaylov Jun 17, 2021
08b7dd2
get rid of wait_time_microseconds, because it is not used anywhere
nikitamikhaylov Jun 17, 2021
3d51ee9
added PrioritizedThreadPool
nikitamikhaylov Jun 17, 2021
c82aa7f
MergeTask for merge from log entry (replicated)
nikitamikhaylov Jun 21, 2021
2fa018e
support plain merge tree
nikitamikhaylov Jun 22, 2021
573caf7
fix msan
nikitamikhaylov Jun 22, 2021
ec70a18
fix pvs check
nikitamikhaylov Jun 22, 2021
2753cc1
fix gcc build
nikitamikhaylov Jun 22, 2021
298b4ad
fix deadlock
nikitamikhaylov Jun 23, 2021
4163384
fix use after free (maybe)
nikitamikhaylov Jun 23, 2021
1d61791
a little suppression
nikitamikhaylov Jun 23, 2021
161520f
fix nullptr dereference
nikitamikhaylov Jun 23, 2021
cae874c
improve thread pool
nikitamikhaylov Jun 24, 2021
b7900fc
better
nikitamikhaylov Jun 24, 2021
ac5b5ca
remove boost
nikitamikhaylov Jun 24, 2021
a25fab4
better
nikitamikhaylov Jun 24, 2021
4943806
get rid of exceptions
nikitamikhaylov Jun 24, 2021
614b8e9
fix build
nikitamikhaylov Jul 5, 2021
10075d1
better
nikitamikhaylov Jul 12, 2021
7aa878d
fix tests
nikitamikhaylov Jul 12, 2021
5c6cad9
rebased
nikitamikhaylov Jul 13, 2021
1ae9715
better
nikitamikhaylov Jul 14, 2021
e4744d1
fix build
nikitamikhaylov Jul 14, 2021
25c7fc9
better
nikitamikhaylov Jul 14, 2021
47c7017
fix test 00721
nikitamikhaylov Jul 15, 2021
981cdc2
better
nikitamikhaylov Jul 15, 2021
d62af5c
test impl
nikitamikhaylov Jul 16, 2021
7e99527
fix
nikitamikhaylov Jul 16, 2021
50daa38
fix tests
nikitamikhaylov Jul 16, 2021
9ed3aac
better
nikitamikhaylov Jul 16, 2021
c76d6b4
fix nullptr dereference
nikitamikhaylov Jul 16, 2021
967f40b
fix tests with encrypted disk
nikitamikhaylov Jul 17, 2021
7b6910b
try fix race
nikitamikhaylov Jul 19, 2021
89ea88c
delete some code about memory tracker
nikitamikhaylov Jul 19, 2021
28a875c
try fix race
nikitamikhaylov Jul 19, 2021
ff41123
delete some files
nikitamikhaylov Jul 19, 2021
fac351f
clean up code
nikitamikhaylov Jul 20, 2021
43d2534
updated ya.make
nikitamikhaylov Jul 20, 2021
48543c4
Update 01532_execute_merges_on_single_replica.sql
nikitamikhaylov Jul 20, 2021
103b02e
Update 01532_execute_merges_on_single_replica.sql
nikitamikhaylov Jul 20, 2021
6f3eddc
execute MergeTask with BackgroundJobsExecutor
nikitamikhaylov Jul 20, 2021
786139d
add normal priorities
nikitamikhaylov Jul 20, 2021
58c6c46
add mutate task
nikitamikhaylov Jul 21, 2021
dabb7e4
added MutatePlainMergeTree task
nikitamikhaylov Jul 22, 2021
1cc8cf4
support for replicated mutate task
nikitamikhaylov Jul 23, 2021
bc54b1f
increase queue size
nikitamikhaylov Jul 23, 2021
c969faf
fix scheduleOrThrowOnError
nikitamikhaylov Jul 23, 2021
f4280d4
fix segfault
nikitamikhaylov Jul 23, 2021
1c224b0
remove extra copying of MutationCommands
nikitamikhaylov Jul 23, 2021
c3273f1
fix build
nikitamikhaylov Jul 23, 2021
6b7d2f8
fixed empty MutationCommands creation
nikitamikhaylov Jul 26, 2021
d7c248e
fix PVS check
nikitamikhaylov Jul 26, 2021
522e1ee
fix build
nikitamikhaylov Jul 26, 2021
efa7161
fix build
nikitamikhaylov Jul 26, 2021
2ac8869
added submit continuation method and fixed build
nikitamikhaylov Jul 26, 2021
4a44ea0
fix deadlock
nikitamikhaylov Jul 26, 2021
7cfd80a
add exception to a log entry
nikitamikhaylov Jul 27, 2021
9c35863
extract common code for both tasks
nikitamikhaylov Jul 27, 2021
0185a97
try to split mutations on tasks
nikitamikhaylov Jul 28, 2021
2657d64
Merge branch 'master' into merge-task-save
nikitamikhaylov Aug 6, 2021
c6ab58c
save
nikitamikhaylov Jul 30, 2021
c3c7651
save
nikitamikhaylov Aug 5, 2021
5120703
Fix build
nikitamikhaylov Aug 6, 2021
a0e87e6
finish mutations
nikitamikhaylov Aug 6, 2021
78a4e28
Merge branch 'master' of github.com:ClickHouse/ClickHouse into merge-…
nikitamikhaylov Aug 9, 2021
9fa856f
fix build
nikitamikhaylov Aug 9, 2021
47de66f
fix nullptr dereference
nikitamikhaylov Aug 9, 2021
566b34e
fix projection test
nikitamikhaylov Aug 9, 2021
1482e9f
Merge branch 'master' of github.com:ClickHouse/ClickHouse into merge-…
nikitamikhaylov Aug 10, 2021
eba2780
Merge branch 'master' of github.com:ClickHouse/ClickHouse into merge-…
nikitamikhaylov Aug 11, 2021
b1c6fc0
Merge with master
nikitamikhaylov Aug 11, 2021
7dad110
added an executor instead of thread pool
nikitamikhaylov Aug 11, 2021
ba8f98e
fix selecting task scheduling
nikitamikhaylov Aug 12, 2021
a91152c
better BackgroundJobExecutor
nikitamikhaylov Aug 12, 2021
3b9b9d1
Merge branch 'master' of github.com:ClickHouse/ClickHouse into merge-…
nikitamikhaylov Aug 12, 2021
e6ae751
fix deadlock
nikitamikhaylov Aug 12, 2021
a4dbbdb
Merge branch 'master' of github.com:ClickHouse/ClickHouse into merge-…
nikitamikhaylov Aug 13, 2021
6765777
save
nikitamikhaylov Aug 16, 2021
b09dff4
added global MergeTreeBackgroundExecutor
nikitamikhaylov Aug 16, 2021
f8d1c1b
better
nikitamikhaylov Aug 17, 2021
9c54bd9
avoid cycles of shared_ptrs
nikitamikhaylov Aug 17, 2021
458d05c
add backoff
nikitamikhaylov Aug 17, 2021
4f9dfa6
better
nikitamikhaylov Aug 17, 2021
0b1cb94
Merge branch 'master' of github.com:ClickHouse/ClickHouse into merge-…
nikitamikhaylov Aug 17, 2021
3faa509
better
nikitamikhaylov Aug 17, 2021
daf3486
better
nikitamikhaylov Aug 17, 2021
d4cb671
better
nikitamikhaylov Aug 17, 2021
c319717
Substact a number of removed tasks from global counter
nikitamikhaylov Aug 17, 2021
10663c4
fix background moves
nikitamikhaylov Aug 18, 2021
46af7cf
better
nikitamikhaylov Aug 18, 2021
7e62078
Merge upstream/master into merge-task-save (using imerge)
nikitamikhaylov Aug 26, 2021
47d13c4
Fix build
nikitamikhaylov Aug 26, 2021
32fb6d5
Merge upstream/master into merge-task-save (using imerge)
nikitamikhaylov Aug 30, 2021
592c0c3
Fix build
nikitamikhaylov Aug 30, 2021
4656b29
better
nikitamikhaylov Aug 30, 2021
ad667ed
Merge upstream/master into merge-task-save (using imerge)
nikitamikhaylov Sep 9, 2021
b5516bc
Fixes after merge
nikitamikhaylov Sep 9, 2021
353a1a9
Another fix after merge
nikitamikhaylov Sep 9, 2021
2b09472
Fix race + delete file
nikitamikhaylov Sep 9, 2021
986c248
Merge upstream/master into merge-task-save (using imerge)
nikitamikhaylov Sep 10, 2021
67bbf91
Style
nikitamikhaylov Sep 10, 2021
64d74e5
Better
nikitamikhaylov Sep 10, 2021
187e450
Merge upstream/master into merge-task-save (using imerge)
nikitamikhaylov Sep 14, 2021
7ff200f
get rid of state
nikitamikhaylov Sep 14, 2021
780714c
Save changes
nikitamikhaylov Sep 14, 2021
d1931e9
Refactor MergeTask
nikitamikhaylov Sep 14, 2021
6f6a48a
Try to fix race and fix build
nikitamikhaylov Sep 15, 2021
279c86a
Review fixes
nikitamikhaylov Sep 15, 2021
adce5eb
Fix style, build and PVS check
nikitamikhaylov Sep 15, 2021
45124a0
Better
nikitamikhaylov Sep 16, 2021
c4dfd3b
Better test
nikitamikhaylov Sep 16, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions src/AggregateFunctions/ya.make
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ SRCS(
AggregateFunctionSimpleLinearRegression.cpp
AggregateFunctionSimpleState.cpp
AggregateFunctionSingleValueOrNull.cpp
AggregateFunctionSparkbar.cpp
AggregateFunctionState.cpp
AggregateFunctionStatistics.cpp
AggregateFunctionStatisticsSimple.cpp
Expand Down
16 changes: 8 additions & 8 deletions src/Common/MemoryTracker.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,18 +162,18 @@ class MemoryTracker
struct BlockerInThread
{
private:
BlockerInThread(const BlockerInThread &) = delete;
BlockerInThread & operator=(const BlockerInThread &) = delete;

static thread_local uint64_t counter;
static thread_local VariableContext level;

VariableContext previous_level;
public:
/// level_ - block in level and above
BlockerInThread(VariableContext level_ = VariableContext::User);
explicit BlockerInThread(VariableContext level_ = VariableContext::User);
~BlockerInThread();

BlockerInThread(const BlockerInThread &) = delete;
BlockerInThread & operator=(const BlockerInThread &) = delete;

static bool isBlocked(VariableContext current_level)
{
return counter > 0 && current_level >= level;
Expand All @@ -195,9 +195,6 @@ class MemoryTracker
struct LockExceptionInThread
{
private:
LockExceptionInThread(const LockExceptionInThread &) = delete;
LockExceptionInThread & operator=(const LockExceptionInThread &) = delete;

static thread_local uint64_t counter;
static thread_local VariableContext level;
static thread_local bool block_fault_injections;
Expand All @@ -207,9 +204,12 @@ class MemoryTracker
public:
/// level_ - block in level and above
/// block_fault_injections_ - block in fault injection too
LockExceptionInThread(VariableContext level_ = VariableContext::User, bool block_fault_injections_ = true);
explicit LockExceptionInThread(VariableContext level_ = VariableContext::User, bool block_fault_injections_ = true);
~LockExceptionInThread();

LockExceptionInThread(const LockExceptionInThread &) = delete;
LockExceptionInThread & operator=(const LockExceptionInThread &) = delete;

static bool isBlocked(VariableContext current_level, bool fault_injection)
{
return counter > 0 && current_level >= level && (!fault_injection || block_fault_injections);
Expand Down
13 changes: 8 additions & 5 deletions src/Common/Stopwatch.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <common/types.h>

#include <atomic>
#include <memory>


inline UInt64 clock_gettime_ns(clockid_t clock_type = CLOCK_MONOTONIC)
Expand All @@ -22,7 +23,7 @@ class Stopwatch
/** CLOCK_MONOTONIC works relatively efficient (~15 million calls/sec) and doesn't lead to syscall.
* Pass CLOCK_MONOTONIC_COARSE, if you need better performance with acceptable cost of several milliseconds of inaccuracy.
*/
Stopwatch(clockid_t clock_type_ = CLOCK_MONOTONIC) : clock_type(clock_type_) { start(); }
explicit Stopwatch(clockid_t clock_type_ = CLOCK_MONOTONIC) : clock_type(clock_type_) { start(); }

void start() { start_ns = nanoseconds(); is_running = true; }
void stop() { stop_ns = nanoseconds(); is_running = false; }
Expand All @@ -43,11 +44,13 @@ class Stopwatch
UInt64 nanoseconds() const { return clock_gettime_ns(clock_type); }
};

using StopwatchUniquePtr = std::unique_ptr<Stopwatch>;


class AtomicStopwatch
{
public:
AtomicStopwatch(clockid_t clock_type_ = CLOCK_MONOTONIC) : clock_type(clock_type_) { restart(); }
explicit AtomicStopwatch(clockid_t clock_type_ = CLOCK_MONOTONIC) : clock_type(clock_type_) { restart(); }

void restart() { start_ns = nanoseconds(); }
UInt64 elapsed() const { return nanoseconds() - start_ns; }
Expand Down Expand Up @@ -78,11 +81,11 @@ class AtomicStopwatch
{
AtomicStopwatch * parent = nullptr;

Lock() {}
Lock() = default;

operator bool() const { return parent != nullptr; }
explicit operator bool() const { return parent != nullptr; }

Lock(AtomicStopwatch * parent_) : parent(parent_) {}
explicit Lock(AtomicStopwatch * parent_) : parent(parent_) {}

Lock(Lock &&) = default;

Expand Down
1 change: 1 addition & 0 deletions src/Common/ThreadPool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <Common/getNumberOfPhysicalCPUCores.h>

#include <cassert>
#include <iostream>
#include <type_traits>

#include <Poco/Util/Application.h>
Expand Down
1 change: 0 additions & 1 deletion src/Common/ya.make
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ SRCS(
Epoll.cpp
ErrorCodes.cpp
Exception.cpp
ExternalLoaderStatus.cpp
FieldVisitorDump.cpp
FieldVisitorHash.cpp
FieldVisitorSum.cpp
Expand Down
5 changes: 0 additions & 5 deletions src/Compression/ya.make
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,6 @@ SRCS(
CompressionFactoryAdditions.cpp
ICompressionCodec.cpp
LZ4_decompress_faster.cpp
fuzzers/compressed_buffer_fuzzer.cpp
fuzzers/delta_decompress_fuzzer.cpp
fuzzers/double_delta_decompress_fuzzer.cpp
fuzzers/encrypted_decompress_fuzzer.cpp
fuzzers/lz4_decompress_fuzzer.cpp
getCompressionCodecForFile.cpp

)
Expand Down
1 change: 1 addition & 0 deletions src/Disks/IStoragePolicy.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class IDisk;
using DiskPtr = std::shared_ptr<IDisk>;
using Disks = std::vector<DiskPtr>;
class IReservation;
using ReservationSharedPtr = std::shared_ptr<IReservation>;
using ReservationPtr = std::unique_ptr<IReservation>;
using Reservations = std::vector<ReservationPtr>;

Expand Down
1 change: 0 additions & 1 deletion src/IO/ya.make
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ SRCS(
ReadBufferFromMemory.cpp
ReadBufferFromPocoSocket.cpp
ReadHelpers.cpp
ReadSettings.cpp
SeekAvoidingReadBuffer.cpp
SynchronousReader.cpp
ThreadPoolReader.cpp
Expand Down
1 change: 1 addition & 0 deletions src/Interpreters/Context.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ class Context: public std::enable_shared_from_this<Context>
/// A flag, used to distinguish between user query and internal query to a database engine (MaterializePostgreSQL).
bool is_internal_query = false;


public:
// Top-level OpenTelemetry trace context for the query. Makes sense only for a query context.
OpenTelemetryTraceContext query_trace_context;
Expand Down
1 change: 1 addition & 0 deletions src/Interpreters/ya.make
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ SRCS(
DatabaseAndTableWithAlias.cpp
DatabaseCatalog.cpp
DictionaryReader.cpp
DuplicateOrderByVisitor.cpp
EmbeddedDictionaries.cpp
ExecuteScalarSubqueriesVisitor.cpp
ExpressionActions.cpp
Expand Down
6 changes: 4 additions & 2 deletions src/Storages/MergeTree/BackgroundProcessList.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ class BackgroundProcessListEntry
BackgroundProcessListEntry(const BackgroundProcessListEntry &) = delete;
BackgroundProcessListEntry & operator=(const BackgroundProcessListEntry &) = delete;

BackgroundProcessListEntry(BackgroundProcessListEntry &&) = default;

BackgroundProcessListEntry(BackgroundProcessList<ListElement, Info> & list_, const typename container_t::iterator it_, const CurrentMetrics::Metric & metric)
: list(list_), it{it_}, metric_increment{metric}
{
Expand Down Expand Up @@ -58,7 +60,7 @@ class BackgroundProcessList

CurrentMetrics::Metric metric;

BackgroundProcessList(const CurrentMetrics::Metric & metric_)
explicit BackgroundProcessList(const CurrentMetrics::Metric & metric_)
: metric(metric_)
{}
public:
Expand All @@ -85,7 +87,7 @@ class BackgroundProcessList

virtual void onEntryCreate(const Entry & /* entry */) {}
virtual void onEntryDestroy(const Entry & /* entry */) {}
virtual inline ~BackgroundProcessList() {}
virtual inline ~BackgroundProcessList() = default;
};

}
49 changes: 49 additions & 0 deletions src/Storages/MergeTree/ColumnSizeEstimator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#pragma once

#include "Storages/MergeTree/IMergeTreeDataPart.h"


namespace DB
{

/* Allow to compute more accurate progress statistics */
class ColumnSizeEstimator
{
using ColumnToSize = MergeTreeDataPartInMemory::ColumnToSize;
ColumnToSize map;
public:

/// Stores approximate size of columns in bytes
/// Exact values are not required since it used for relative values estimation (progress).
size_t sum_total = 0;
size_t sum_index_columns = 0;
size_t sum_ordinary_columns = 0;

ColumnSizeEstimator(ColumnToSize && map_, const Names & key_columns, const Names & ordinary_columns)
: map(std::move(map_))
{
for (const auto & name : key_columns)
if (!map.count(name)) map[name] = 0;
for (const auto & name : ordinary_columns)
if (!map.count(name)) map[name] = 0;

for (const auto & name : key_columns)
sum_index_columns += map.at(name);

for (const auto & name : ordinary_columns)
sum_ordinary_columns += map.at(name);

sum_total = std::max(static_cast<decltype(sum_index_columns)>(1), sum_index_columns + sum_ordinary_columns);
}

Float64 columnWeight(const String & column) const
{
return static_cast<Float64>(map.at(column)) / sum_total;
}

Float64 keyColumnsWeight() const
{
return static_cast<Float64>(sum_index_columns) / sum_total;
}
};
}
5 changes: 2 additions & 3 deletions src/Storages/MergeTree/DataPartsExchange.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -580,9 +580,8 @@ MergeTreeData::MutableDataPartPtr Fetcher::downloadPartToMemory(
new_projection_part->is_temp = false;
new_projection_part->setColumns(block.getNamesAndTypesList());
MergeTreePartition partition{};
IMergeTreeDataPart::MinMaxIndex minmax_idx{};
new_projection_part->partition = std::move(partition);
new_projection_part->minmax_idx = std::move(minmax_idx);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not clear why do we use shared_ptr for minmax_idx now.
Also maybe unique can do?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We use shared_ptr, because it has a copy construct which is useful for merging projections. There we construct a bunch of MergeTasks inside a MergeTask with the same MinMaxIndex object. Before this there was a reference.

new_projection_part->minmax_idx = std::make_shared<IMergeTreeDataPart::MinMaxIndex>();

MergedBlockOutputStream part_out(
new_projection_part,
Expand All @@ -608,7 +607,7 @@ MergeTreeData::MutableDataPartPtr Fetcher::downloadPartToMemory(
new_data_part->uuid = part_uuid;
new_data_part->is_temp = true;
new_data_part->setColumns(block.getNamesAndTypesList());
new_data_part->minmax_idx.update(block, data.getMinMaxColumnsNames(metadata_snapshot->getPartitionKey()));
new_data_part->minmax_idx->update(block, data.getMinMaxColumnsNames(metadata_snapshot->getPartitionKey()));
new_data_part->partition.create(metadata_snapshot, block, 0, context);

MergedBlockOutputStream part_out(
Expand Down
92 changes: 92 additions & 0 deletions src/Storages/MergeTree/FutureMergedMutatedPart.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#include "Storages/MergeTree/FutureMergedMutatedPart.h"


namespace DB
{

namespace ErrorCodes
{
extern const int LOGICAL_ERROR;
}

void FutureMergedMutatedPart::assign(MergeTreeData::DataPartsVector parts_)
{
if (parts_.empty())
return;

size_t sum_rows = 0;
size_t sum_bytes_uncompressed = 0;
MergeTreeDataPartType future_part_type = MergeTreeDataPartType::UNKNOWN;
for (const auto & part : parts_)
{
sum_rows += part->rows_count;
sum_bytes_uncompressed += part->getTotalColumnsSize().data_uncompressed;
future_part_type = std::min(future_part_type, part->getType());
}

auto chosen_type = parts_.front()->storage.choosePartTypeOnDisk(sum_bytes_uncompressed, sum_rows);
future_part_type = std::min(future_part_type, chosen_type);
assign(std::move(parts_), future_part_type);
}

void FutureMergedMutatedPart::assign(MergeTreeData::DataPartsVector parts_, MergeTreeDataPartType future_part_type)
{
if (parts_.empty())
return;

for (const MergeTreeData::DataPartPtr & part : parts_)
{
const MergeTreeData::DataPartPtr & first_part = parts_.front();

if (part->partition.value != first_part->partition.value)
throw Exception(
"Attempting to merge parts " + first_part->name + " and " + part->name + " that are in different partitions",
ErrorCodes::LOGICAL_ERROR);
}

parts = std::move(parts_);

UInt32 max_level = 0;
Int64 max_mutation = 0;
for (const auto & part : parts)
{
max_level = std::max(max_level, part->info.level);
max_mutation = std::max(max_mutation, part->info.mutation);
}

type = future_part_type;
part_info.partition_id = parts.front()->info.partition_id;
part_info.min_block = parts.front()->info.min_block;
part_info.max_block = parts.back()->info.max_block;
part_info.level = max_level + 1;
part_info.mutation = max_mutation;

if (parts.front()->storage.format_version < MERGE_TREE_DATA_MIN_FORMAT_VERSION_WITH_CUSTOM_PARTITIONING)
{
DayNum min_date = DayNum(std::numeric_limits<UInt16>::max());
DayNum max_date = DayNum(std::numeric_limits<UInt16>::min());
for (const auto & part : parts)
{
/// NOTE: getting min and max dates from part names (instead of part data) because we want
/// the merged part name be determined only by source part names.
/// It is simpler this way when the real min and max dates for the block range can change
/// (e.g. after an ALTER DELETE command).
DayNum part_min_date;
DayNum part_max_date;
MergeTreePartInfo::parseMinMaxDatesFromPartName(part->name, part_min_date, part_max_date);
min_date = std::min(min_date, part_min_date);
max_date = std::max(max_date, part_max_date);
}

name = part_info.getPartNameV0(min_date, max_date);
}
else
name = part_info.getPartName();
}

void FutureMergedMutatedPart::updatePath(const MergeTreeData & storage, const IReservation * reservation)
{
path = storage.getFullPathOnDisk(reservation->getDisk()) + name + "/";
}

}