Merge pull request #64953 from ClickHouse/tomic

Disallow creating refreshable MV on Linux < 3.15
This commit is contained in:
Michael Kolupaev 2024-09-13 03:42:28 +00:00 committed by GitHub
commit e1a206c84d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 34 additions and 14 deletions

View File

@ -57,11 +57,13 @@ namespace ErrorCodes
namespace DB namespace DB
{ {
static bool supportsAtomicRenameImpl() static std::optional<std::string> supportsAtomicRenameImpl()
{ {
VersionNumber renameat2_minimal_version(3, 15, 0); VersionNumber renameat2_minimal_version(3, 15, 0);
VersionNumber linux_version(Poco::Environment::osVersion()); VersionNumber linux_version(Poco::Environment::osVersion());
return linux_version >= renameat2_minimal_version; if (linux_version >= renameat2_minimal_version)
return std::nullopt;
return fmt::format("Linux kernel 3.15+ is required, got {}", linux_version.toString());
} }
static bool renameat2(const std::string & old_path, const std::string & new_path, int flags) static bool renameat2(const std::string & old_path, const std::string & new_path, int flags)
@ -97,10 +99,14 @@ static bool renameat2(const std::string & old_path, const std::string & new_path
ErrnoException::throwFromPath(ErrorCodes::SYSTEM_ERROR, new_path, "Cannot rename {} to {}", old_path, new_path); ErrnoException::throwFromPath(ErrorCodes::SYSTEM_ERROR, new_path, "Cannot rename {} to {}", old_path, new_path);
} }
bool supportsAtomicRename() bool supportsAtomicRename(std::string * out_message)
{ {
static bool supports = supportsAtomicRenameImpl(); static auto error = supportsAtomicRenameImpl();
return supports; if (!error.has_value())
return true;
if (out_message)
*out_message = error.value();
return false;
} }
} }
@ -152,16 +158,22 @@ static bool renameat2(const std::string & old_path, const std::string & new_path
} }
static bool supportsAtomicRenameImpl() static std::optional<std::string> supportsAtomicRenameImpl()
{ {
auto fun = dlsym(RTLD_DEFAULT, "renamex_np"); auto fun = dlsym(RTLD_DEFAULT, "renamex_np");
return fun != nullptr; if (fun != nullptr)
return std::nullopt;
return "macOS 10.12 or later is required";
} }
bool supportsAtomicRename() bool supportsAtomicRename(std::string * out_message)
{ {
static bool supports = supportsAtomicRenameImpl(); static auto error = supportsAtomicRenameImpl();
return supports; if (!error.has_value())
return true;
if (out_message)
*out_message = error.value();
return false;
} }
} }
@ -179,8 +191,10 @@ static bool renameat2(const std::string &, const std::string &, int)
return false; return false;
} }
bool supportsAtomicRename() bool supportsAtomicRename(std::string * out_message)
{ {
if (out_message)
*out_message = "only Linux and macOS are supported";
return false; return false;
} }

View File

@ -6,7 +6,7 @@ namespace DB
{ {
/// Returns true, if the following functions supported by the system /// Returns true, if the following functions supported by the system
bool supportsAtomicRename(); bool supportsAtomicRename(std::string * out_message = nullptr);
/// Atomically rename old_path to new_path. If new_path exists, do not overwrite it and throw exception /// Atomically rename old_path to new_path. If new_path exists, do not overwrite it and throw exception
void renameNoReplace(const std::string & old_path, const std::string & new_path); void renameNoReplace(const std::string & old_path, const std::string & new_path);

View File

@ -197,8 +197,9 @@ void DatabaseAtomic::renameTable(ContextPtr local_context, const String & table_
throw Exception(ErrorCodes::NOT_IMPLEMENTED, "Moving tables between databases of different engines is not supported"); throw Exception(ErrorCodes::NOT_IMPLEMENTED, "Moving tables between databases of different engines is not supported");
} }
if (exchange && !supportsAtomicRename()) std::string message;
throw Exception(ErrorCodes::NOT_IMPLEMENTED, "RENAME EXCHANGE is not supported"); if (exchange && !supportsAtomicRename(&message))
throw Exception(ErrorCodes::NOT_IMPLEMENTED, "RENAME EXCHANGE is not supported because exchanging files is not supported by the OS ({})", message);
waitDatabaseStarted(); waitDatabaseStarted();

View File

@ -968,6 +968,11 @@ void InterpreterCreateQuery::validateMaterializedViewColumnsAndEngine(const ASTC
if (database && database->getEngineName() != "Atomic") if (database && database->getEngineName() != "Atomic")
throw Exception(ErrorCodes::INCORRECT_QUERY, throw Exception(ErrorCodes::INCORRECT_QUERY,
"Refreshable materialized views (except with APPEND) only support Atomic database engine, but database {} has engine {}", create.getDatabase(), database->getEngineName()); "Refreshable materialized views (except with APPEND) only support Atomic database engine, but database {} has engine {}", create.getDatabase(), database->getEngineName());
std::string message;
if (!supportsAtomicRename(&message))
throw Exception(ErrorCodes::NOT_IMPLEMENTED,
"Can't create refreshable materialized view because exchanging files is not supported by the OS ({})", message);
} }
Block input_block; Block input_block;