diff --git a/dbms/src/Storages/MergeTree/DiskSpaceMonitor.cpp b/dbms/src/Storages/MergeTree/DiskSpaceMonitor.cpp index a9a5da5fd14..b7ca1c67743 100644 --- a/dbms/src/Storages/MergeTree/DiskSpaceMonitor.cpp +++ b/dbms/src/Storages/MergeTree/DiskSpaceMonitor.cpp @@ -90,7 +90,8 @@ void DiskSelector::add(const DiskPtr & disk) disks.emplace(disk->getName(), disk); } -StoragePolicy::Volume::Volume(const Poco::Util::AbstractConfiguration & config, const std::string & config_prefix, const DiskSelector & disk_selector) +StoragePolicy::Volume::Volume(String name_, const Poco::Util::AbstractConfiguration & config, const std::string & config_prefix, const DiskSelector & disk_selector) + : name(std::move(name_)) { Poco::Util::AbstractConfiguration::Keys keys; config.keys(config_prefix, keys); @@ -208,19 +209,22 @@ UInt64 StoragePolicy::Volume::getMaxUnreservedFreeSpace() const return res; } -StoragePolicy::StoragePolicy(const String & name_, const Poco::Util::AbstractConfiguration & config, const std::string & config_prefix, - const DiskSelector & disks) : name(name_) +StoragePolicy::StoragePolicy(String name_, const Poco::Util::AbstractConfiguration & config, const std::string & config_prefix, + const DiskSelector & disks) : name(std::move(name_)) { + String volumes_prefix = config_prefix + ".volumes"; + if (!config.has(volumes_prefix)) + throw Exception("StoragePolicy must contain at least one Volume (.volumes)", ErrorCodes::EXCESSIVE_ELEMENT_IN_CONFIG); + Poco::Util::AbstractConfiguration::Keys keys; - config.keys(config_prefix, keys); + config.keys(volumes_prefix, keys); for (const auto & attr_name : keys) { - if (!startsWith(attr_name, "volume")) - throw Exception("Unknown element in config: " + config_prefix + "." + attr_name + ", must be 'volume'", - ErrorCodes::UNKNOWN_ELEMENT_IN_CONFIG); - volumes.emplace_back(config, config_prefix + "." + attr_name, disks); + volumes.emplace_back(attr_name, config, volumes_prefix + "." + attr_name, disks); + volumes_names[attr_name] = volumes.size() - 1; } + if (volumes.empty()) throw Exception("StoragePolicy must contain at least one Volume", ErrorCodes::EXCESSIVE_ELEMENT_IN_CONFIG); @@ -339,11 +343,12 @@ StoragePolicySelector::StoragePolicySelector(const Poco::Util::AbstractConfigura } constexpr auto default_storage_policy_name = "default"; + constexpr auto default_volume_name = "default"; constexpr auto default_disk_name = "default"; if (policies.find(default_storage_policy_name) == policies.end()) policies.emplace(default_storage_policy_name, std::make_shared(default_storage_policy_name, - StoragePolicy::Volumes{{std::vector{disks[default_disk_name]}, + StoragePolicy::Volumes{StoragePolicy::Volume{default_volume_name, std::vector{disks[default_disk_name]}, std::numeric_limits::max()}})); } diff --git a/dbms/src/Storages/MergeTree/DiskSpaceMonitor.h b/dbms/src/Storages/MergeTree/DiskSpaceMonitor.h index a5da5995d27..5505eeda9f8 100644 --- a/dbms/src/Storages/MergeTree/DiskSpaceMonitor.h +++ b/dbms/src/Storages/MergeTree/DiskSpaceMonitor.h @@ -303,29 +303,31 @@ public: friend class StoragePolicy; public: - Volume(std::vector disks_, UInt64 max_data_part_size_) - : max_data_part_size(max_data_part_size_), disks(std::move(disks_)) { } + Volume(String name_, std::vector disks_, UInt64 max_data_part_size_) + : max_data_part_size(max_data_part_size_), disks(std::move(disks_)), name(std::move(name_)) { } - Volume(const Poco::Util::AbstractConfiguration & config, const std::string & config_prefix, const DiskSelector & disk_selector); + Volume(String name_, const Poco::Util::AbstractConfiguration & config, const std::string & config_prefix, const DiskSelector & disk_selector); - Volume(const Volume & other) : max_data_part_size(other.max_data_part_size), disks(other.disks) { } + Volume(const Volume & other) : max_data_part_size(other.max_data_part_size), disks(other.disks), name(other.name) { } Volume & operator=(const Volume & other) { disks = other.disks; max_data_part_size = other.max_data_part_size; last_used.store(0, std::memory_order_relaxed); + name = other.name; return *this; } Volume(Volume && other) noexcept - : max_data_part_size(other.max_data_part_size), disks(std::move(other.disks)) { } + : max_data_part_size(other.max_data_part_size), disks(std::move(other.disks)), name(std::move(other.name)) { } Volume & operator=(Volume && other) noexcept { disks = std::move(other.disks); max_data_part_size = other.max_data_part_size; last_used.store(0, std::memory_order_relaxed); + name = std::move(other.name); return *this; } @@ -337,20 +339,32 @@ public: UInt64 getMaxUnreservedFreeSpace() const; + const String & getName() const { return name; } + UInt64 max_data_part_size = std::numeric_limits::max(); Disks disks; private: mutable std::atomic last_used = 0; + String name; }; using Volumes = std::vector; - StoragePolicy(const String & name_, const Poco::Util::AbstractConfiguration & config, const std::string & config_prefix, + StoragePolicy(String name_, const Poco::Util::AbstractConfiguration & config, const std::string & config_prefix, const DiskSelector & disks); - StoragePolicy(const String & name_, Volumes volumes_) : volumes(std::move(volumes_)), name(name_) { } + StoragePolicy(String name_, Volumes volumes_) : volumes(std::move(volumes_)), name(std::move(name_)) + { + if (volumes.empty()) + throw Exception("StoragePolicy must contain at least one Volume", ErrorCodes::UNKNOWN_POLICY); + + for (size_t i = 0; i != volumes.size(); ++i) + { + volumes_names[volumes[i].getName()] = i; + } + } /// Returns disks ordered by volumes priority Disks getDisks() const; @@ -390,9 +404,14 @@ public: const auto & getVolumes() const { return volumes; } + const auto & getVolume(size_t i) const { return volumes[i]; } + + const auto & getVolume(const String & volume_name) { return getVolume(volumes_names[volume_name]); } + private: Volumes volumes; String name; + std::map volumes_names; }; using StoragePolicyPtr = std::shared_ptr; diff --git a/dbms/src/Storages/System/StorageSystemStoragePolicies.cpp b/dbms/src/Storages/System/StorageSystemStoragePolicies.cpp index b8a58dadde4..39c961658bd 100644 --- a/dbms/src/Storages/System/StorageSystemStoragePolicies.cpp +++ b/dbms/src/Storages/System/StorageSystemStoragePolicies.cpp @@ -17,7 +17,8 @@ StorageSystemStoragePolicies::StorageSystemStoragePolicies(const std::string & n { setColumns(ColumnsDescription( { - {"name", std::make_shared()}, + {"policy_name", std::make_shared()}, + {"volume_name", std::make_shared()}, {"volume_priority", std::make_shared()}, {"disks", std::make_shared(std::make_shared())}, {"max_data_part_size", std::make_shared()}, @@ -34,7 +35,8 @@ BlockInputStreams StorageSystemStoragePolicies::read( { check(column_names); - MutableColumnPtr col_name_mut = ColumnString::create(); + MutableColumnPtr col_policy_name_mut = ColumnString::create(); + MutableColumnPtr col_volume_name_mut = ColumnString::create(); MutableColumnPtr col_priority_mut = ColumnUInt64::create(); MutableColumnPtr col_disks_mut = ColumnArray::create(ColumnString::create()); MutableColumnPtr col_max_part_size_mut = ColumnUInt64::create(); @@ -46,7 +48,8 @@ BlockInputStreams StorageSystemStoragePolicies::read( const auto & volumes = policy_ptr->getVolumes(); for (size_t i = 0; i != volumes.size(); ++i) { - col_name_mut->insert(name); + col_policy_name_mut->insert(name); + col_volume_name_mut->insert(volumes[i].getName()); col_priority_mut->insert(i); Array disks; disks.reserve(volumes[i].disks.size()); @@ -57,14 +60,16 @@ BlockInputStreams StorageSystemStoragePolicies::read( } } - ColumnPtr col_name = std::move(col_name_mut); + ColumnPtr col_policy_name = std::move(col_policy_name_mut); + ColumnPtr col_volume_name = std::move(col_volume_name_mut); ColumnPtr col_priority = std::move(col_priority_mut); ColumnPtr col_disks = std::move(col_disks_mut); ColumnPtr col_max_part_size = std::move(col_max_part_size_mut); Block res = getSampleBlock().cloneEmpty(); size_t col_num = 0; - res.getByPosition(col_num++).column = col_name; + res.getByPosition(col_num++).column = col_policy_name; + res.getByPosition(col_num++).column = col_volume_name; res.getByPosition(col_num++).column = col_priority; res.getByPosition(col_num++).column = col_disks; res.getByPosition(col_num++).column = col_max_part_size;