aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/clickhouse/src/Storages/MergeTree/ReplicatedMergeTreeAltersSequence.h
blob: c104109bd4cb63e15360830e49d96bee4473d316 (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
#pragma once

#include <deque>
#include <mutex>
#include <map>

namespace DB
{
/// ALTERs in StorageReplicatedMergeTree have to be executed sequentially (one
/// by one). But ReplicatedMergeTreeQueue execute all entries almost
/// concurrently. The only dependency between entries is data parts, but they are
/// not suitable in alters case.
///
/// This class stores information about current alters in
/// ReplicatedMergeTreeQueue, and control their order of execution. Actually
/// it's a part of ReplicatedMergeTreeQueue and shouldn't be used directly by
/// other classes, also methods have to be called under ReplicatedMergeTreeQueue
/// state lock.
class ReplicatedMergeTreeAltersSequence
{
private:
    /// In general case alter consist of two stages Alter data and alter
    /// metadata. First we alter storage metadata and then we can apply
    /// corresponding data changes (MUTATE_PART). After that, we can remove
    /// alter from this sequence (alter is processed).
    struct AlterState
    {
        bool metadata_finished = false;
        bool data_finished = false;
    };

    /// alter_version -> AlterState.
    std::map<int, AlterState> queue_state;

public:

    /// Add mutation for alter (alter data stage).
    void addMutationForAlter(int alter_version, std::lock_guard<std::mutex> & /*state_lock*/);

    /// Add metadata for alter (alter metadata stage).
    void addMetadataAlter(int alter_version, std::lock_guard<std::mutex> & /*state_lock*/);

    /// Finish metadata alter. If corresponding data alter finished, than we can remove
    /// alter from sequence.
    void finishMetadataAlter(int alter_version, std::unique_lock <std::mutex> & /*state_lock*/);

    /// Finish data alter. If corresponding metadata alter finished, than we can remove
    /// alter from sequence.
    void finishDataAlter(int alter_version, std::lock_guard<std::mutex> & /*state_lock*/);

    /// Check that we can execute this data alter. If it's metadata stage finished.
    bool canExecuteDataAlter(int alter_version, std::unique_lock<std::mutex> & /*state_lock*/) const;

    /// Check that we can execute metadata alter with version.
    bool canExecuteMetaAlter(int alter_version, std::unique_lock<std::mutex> & /*state_lock*/) const;

    /// Just returns smallest alter version in sequence (first entry)
    int getHeadAlterVersion(std::unique_lock<std::mutex> & /*state_lock*/) const;
};

}