#pragma once #include #include #include namespace DB { /// ALTERs in StorageReplicatedMergeTree have to be executed sequentially (one by one). /// But ReplicatedMergeTreeQueue execute all entries almost concurrently. The only depency 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. /// All 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; }; private: /// alter_version -> AlterState. std::map queue_state; public: /// Add mutation for alter (alter data stage). void addMutationForAlter(int alter_version, std::lock_guard & /*state_lock*/); /// Add metadata for alter (alter metadata stage). If have_mutation=true, than we expect, that /// corresponding mutation will be added. void addMetadataAlter(int alter_version, bool have_mutation, std::lock_guard & /*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 & /*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 & /*state_lock*/); /// Check that we can execute this data alter. If it's metadata stage finished. bool canExecuteDataAlter(int alter_version, std::lock_guard & /*state_lock*/) const; /// Check that we can execute metadata alter with version. bool canExecuteMetaAlter(int alter_version, std::lock_guard & /*state_lock*/) const; /// Just returns smallest alter version in sequence (first entry) int getHeadAlterVersion(std::lock_guard & /*state_lock*/) const; }; }