66#include < Common/Exception.h>
77#include < Common/NamedCollections/NamedCollections.h>
88#include < Common/logger_useful.h>
9+ #include < Common/filesystemHelpers.h>
910#include < Storages/System/MutableColumnsAndConstraints.h>
1011#include < Interpreters/Cache/FileCache.h>
1112#include < DataTypes/DataTypeString.h>
@@ -46,7 +47,8 @@ namespace ErrorCodes
4647 DECLARE (Bool, enable_bypass_cache_with_threshold, false , " Undocumented. Not recommended for use" , 0 ) \
4748 DECLARE (UInt64, bypass_cache_threshold, FILECACHE_BYPASS_THRESHOLD, " Undocumented. Not recommended for use" , 0 ) \
4849 DECLARE (Bool, write_cache_per_user_id_directory, false , " Internal ClickHouse Cloud setting" , 0 ) \
49- DECLARE (Bool, allow_dynamic_cache_resize, false , " Allow dynamic resize of filesystem cache" , 0 )
50+ DECLARE (Bool, allow_dynamic_cache_resize, false , " Allow dynamic resize of filesystem cache" , 0 ) \
51+ DECLARE (Double, max_size_ratio_to_total_space, 0 , " Ratio of `max_size` to total disk space" , 0 ) \
5052
5153DECLARE_SETTINGS_TRAITS (FileCacheSettingsTraits, LIST_OF_FILE_CACHE_SETTINGS)
5254IMPLEMENT_SETTINGS_TRAITS (FileCacheSettingsTraits, LIST_OF_FILE_CACHE_SETTINGS)
@@ -157,7 +159,10 @@ void FileCacheSettings::dumpToSystemSettingsColumns(
157159 res_columns[i++]->insert (cache->getFileSegmentsNum ());
158160}
159161
160- void FileCacheSettings::loadFromConfig (const Poco::Util::AbstractConfiguration & config, const std::string & config_prefix, bool allow_empty_path)
162+ void FileCacheSettings::loadFromConfig (
163+ const Poco::Util::AbstractConfiguration & config,
164+ const std::string & config_prefix,
165+ const std::string & default_cache_path)
161166{
162167 if (!config.has (config_prefix))
163168 throw Exception (ErrorCodes::NO_ELEMENTS_IN_CONFIG, " There is no path '{}' in configuration file." , config_prefix);
@@ -177,7 +182,10 @@ void FileCacheSettings::loadFromConfig(const Poco::Util::AbstractConfiguration &
177182 boost::to_upper (cache_policy);
178183 (*this )[FileCacheSetting::cache_policy] = cache_policy;
179184
180- validate (allow_empty_path);
185+ if (!(*this )[FileCacheSetting::path].changed )
186+ (*this )[FileCacheSetting::path] = default_cache_path;
187+
188+ validate ();
181189}
182190
183191void FileCacheSettings::loadFromCollection (const NamedCollection & collection)
@@ -194,15 +202,37 @@ void FileCacheSettings::loadFromCollection(const NamedCollection & collection)
194202 validate ();
195203}
196204
197- void FileCacheSettings::validate (bool allow_empty_path )
205+ void FileCacheSettings::validate ()
198206{
199- auto settings = *this ;
200- if (!allow_empty_path && !settings[FileCacheSetting::path].changed )
207+ auto & settings = *this ;
208+
209+ if (!settings[FileCacheSetting::path].changed )
201210 throw Exception (ErrorCodes::BAD_ARGUMENTS, " `path` is required parameter of cache configuration" );
202- if (!settings[FileCacheSetting::max_size].changed )
203- throw Exception (ErrorCodes::BAD_ARGUMENTS, " `max_size` is required parameter of cache configuration" );
204- if (settings[FileCacheSetting::max_size] == 0 )
211+
212+ if (!settings[FileCacheSetting::max_size].changed && !settings[FileCacheSetting::max_size_ratio_to_total_space].changed )
213+ throw Exception (ErrorCodes::BAD_ARGUMENTS, " Either `max_size` or `max_size_ratio_to_total_space` must be defined in cache configuration" );
214+
215+ if (settings[FileCacheSetting::max_size].changed && settings[FileCacheSetting::max_size_ratio_to_total_space].changed )
216+ throw Exception (ErrorCodes::BAD_ARGUMENTS, " `max_size` and `max_size_ratio_to_total_space` cannot be specified at the same time" );
217+
218+ if (settings[FileCacheSetting::max_size].changed && settings[FileCacheSetting::max_size] == 0 )
205219 throw Exception (ErrorCodes::BAD_ARGUMENTS, " `max_size` cannot be 0" );
220+
221+ if (settings[FileCacheSetting::max_size_ratio_to_total_space].changed )
222+ {
223+ if (settings[FileCacheSetting::max_size_ratio_to_total_space] <= 0 || settings[FileCacheSetting::max_size_ratio_to_total_space] > 1 )
224+ throw Exception (ErrorCodes::BAD_ARGUMENTS, " `max_size_ratio_to_total_space` must be in range (0, 1]" );
225+
226+ std::filesystem::create_directories (settings[FileCacheSetting::path].value );
227+ struct statvfs stat = getStatVFS (settings[FileCacheSetting::path]);
228+ const auto total_space = stat.f_blocks * stat.f_frsize ;
229+ settings[FileCacheSetting::max_size] = static_cast <UInt64>(std::floor (settings[FileCacheSetting::max_size_ratio_to_total_space].value * total_space));
230+
231+ LOG_TRACE (
232+ getLogger (" FileCacheSettings" ),
233+ " Using max_size as ratio {} to total disk space: {} (total space: {})" ,
234+ settings[FileCacheSetting::max_size_ratio_to_total_space].value , settings[FileCacheSetting::max_size].value , total_space);
235+ }
206236}
207237
208238}
0 commit comments