blob: 82fd271ee5f692145aabb31ea178f90c58ea91bb (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
#pragma once
#include <functional>
#include <optional>
#include <vector>
#include <base/scope_guard.h>
#include <Disks/StoragePolicy.h>
#include <Storages/MergeTree/IMergeTreeDataPart.h>
#include <Storages/MergeTree/MovesList.h>
#include <Common/ActionBlocker.h>
namespace DB
{
enum class MovePartsOutcome
{
PartsMoved,
NothingToMove,
MovesAreCancelled,
MoveWasPostponedBecauseOfZeroCopy,
};
/// Active part from storage and destination reservation where it has to be moved
struct MergeTreeMoveEntry
{
std::shared_ptr<const IMergeTreeDataPart> part;
ReservationPtr reserved_space;
MergeTreeMoveEntry(const std::shared_ptr<const IMergeTreeDataPart> & part_, ReservationPtr reservation_)
: part(part_), reserved_space(std::move(reservation_))
{
}
};
using MergeTreeMovingParts = std::vector<MergeTreeMoveEntry>;
/** Can select parts for background moves, clone them to appropriate disks into
* /detached directory and replace them into active parts set
*/
class MergeTreePartsMover
{
private:
/// Callback tells that part is not participating in background process
using AllowedMovingPredicate = std::function<bool(const std::shared_ptr<const IMergeTreeDataPart> &, String * reason)>;
public:
explicit MergeTreePartsMover(MergeTreeData * data_)
: data(data_)
, log(&Poco::Logger::get("MergeTreePartsMover"))
{
}
struct TemporaryClonedPart
{
MergeTreeMutableDataPartPtr part;
scope_guard temporary_directory_lock;
};
/// Select parts for background moves according to storage_policy configuration.
/// Returns true if at least one part was selected for move.
bool selectPartsForMove(
MergeTreeMovingParts & parts_to_move,
const AllowedMovingPredicate & can_move,
const std::lock_guard<std::mutex> & moving_parts_lock);
/// Copies part to selected reservation in detached folder. Throws exception if part already exists.
TemporaryClonedPart clonePart(const MergeTreeMoveEntry & moving_part) const;
/// Replaces cloned part from detached directory into active data parts set.
/// Replacing part changes state to DeleteOnDestroy and will be removed from disk after destructor of
/// IMergeTreeDataPart called. If replacing part doesn't exists or not active (committed) than
/// cloned part will be removed and log message will be reported. It may happen in case of concurrent
/// merge or mutation.
void swapClonedPart(TemporaryClonedPart & cloned_part) const;
/// Can stop background moves and moves from queries
ActionBlocker moves_blocker;
private:
MergeTreeData * data;
Poco::Logger * log;
};
}
|