mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-19 14:11:58 +00:00
Merge pull request #36133 from Algunenano/osx_atomic_exchange
Add support for atomic exchange in OSX
This commit is contained in:
commit
2e95e0db3b
@ -1,4 +1,4 @@
|
||||
#include <Common/renameat2.h>
|
||||
#include <Common/atomicRename.h>
|
||||
#include <Common/Exception.h>
|
||||
#include <Common/VersionNumber.h>
|
||||
#include <Poco/Environment.h>
|
||||
@ -55,7 +55,7 @@ namespace ErrorCodes
|
||||
namespace DB
|
||||
{
|
||||
|
||||
static bool supportsRenameat2Impl()
|
||||
static bool supportsAtomicRenameImpl()
|
||||
{
|
||||
VersionNumber renameat2_minimal_version(3, 15, 0);
|
||||
VersionNumber linux_version(Poco::Environment::osVersion());
|
||||
@ -64,7 +64,7 @@ static bool supportsRenameat2Impl()
|
||||
|
||||
static bool renameat2(const std::string & old_path, const std::string & new_path, int flags)
|
||||
{
|
||||
if (!supportsRenameat2())
|
||||
if (!supportsAtomicRename())
|
||||
return false;
|
||||
if (old_path.empty() || new_path.empty())
|
||||
throw Exception(ErrorCodes::LOGICAL_ERROR, "Cannot rename {} to {}: path is empty", old_path, new_path);
|
||||
@ -93,9 +93,69 @@ static bool renameat2(const std::string & old_path, const std::string & new_path
|
||||
throwFromErrnoWithPath(fmt::format("Cannot rename {} to {}", old_path, new_path), new_path, ErrorCodes::SYSTEM_ERROR);
|
||||
}
|
||||
|
||||
bool supportsRenameat2()
|
||||
bool supportsAtomicRename()
|
||||
{
|
||||
static bool supports = supportsRenameat2Impl();
|
||||
static bool supports = supportsAtomicRenameImpl();
|
||||
return supports;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
// Includes
|
||||
#include <dlfcn.h> // For dlsym
|
||||
#include <stdio.h> // For renamex_np
|
||||
#include <string.h> // For stderror
|
||||
|
||||
#ifndef RENAME_SWAP
|
||||
#define RENAME_SWAP 0x00000002
|
||||
#endif
|
||||
#ifndef RENAME_EXCL
|
||||
#define RENAME_EXCL 0x00000004
|
||||
#endif
|
||||
|
||||
|
||||
#define RENAME_NOREPLACE RENAME_EXCL
|
||||
#define RENAME_EXCHANGE RENAME_SWAP
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
static bool renameat2(const std::string & old_path, const std::string & new_path, int flags)
|
||||
{
|
||||
using function_type = int (*)(const char * from, const char * to, unsigned int flags);
|
||||
static function_type fun = reinterpret_cast<function_type>(dlsym(RTLD_DEFAULT, "renamex_np"));
|
||||
if (fun == nullptr)
|
||||
return false;
|
||||
|
||||
if (old_path.empty() || new_path.empty())
|
||||
throw Exception(ErrorCodes::LOGICAL_ERROR, "Cannot rename {} to {}: path is empty", old_path, new_path);
|
||||
|
||||
if (0 == (*fun)(old_path.c_str(), new_path.c_str(), flags))
|
||||
return true;
|
||||
int errnum = errno;
|
||||
|
||||
if (errnum == ENOTSUP || errnum == EINVAL)
|
||||
return false;
|
||||
if (errnum == EEXIST)
|
||||
throwFromErrno(fmt::format("Cannot rename {} to {} because the second path already exists", old_path, new_path), ErrorCodes::ATOMIC_RENAME_FAIL);
|
||||
if (errnum == ENOENT)
|
||||
throwFromErrno(fmt::format("Paths cannot be exchanged because {} or {} does not exist", old_path, new_path), ErrorCodes::ATOMIC_RENAME_FAIL);
|
||||
throwFromErrnoWithPath(
|
||||
fmt::format("Cannot rename {} to {}: {}", old_path, new_path, strerror(errnum)), new_path, ErrorCodes::SYSTEM_ERROR);
|
||||
}
|
||||
|
||||
|
||||
static bool supportsAtomicRenameImpl()
|
||||
{
|
||||
auto fun = dlsym(RTLD_DEFAULT, "renamex_np");
|
||||
return fun != nullptr;
|
||||
}
|
||||
|
||||
bool supportsAtomicRename()
|
||||
{
|
||||
static bool supports = supportsAtomicRenameImpl();
|
||||
return supports;
|
||||
}
|
||||
|
||||
@ -114,7 +174,7 @@ static bool renameat2(const std::string &, const std::string &, int)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool supportsRenameat2()
|
||||
bool supportsAtomicRename()
|
||||
{
|
||||
return false;
|
||||
}
|
@ -6,7 +6,7 @@ namespace DB
|
||||
{
|
||||
|
||||
/// Returns true, if the following functions supported by the system
|
||||
bool supportsRenameat2();
|
||||
bool supportsAtomicRename();
|
||||
|
||||
/// 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);
|
@ -4,7 +4,7 @@
|
||||
#include <IO/WriteHelpers.h>
|
||||
#include <IO/ReadBufferFromFile.h>
|
||||
#include <Parsers/formatAST.h>
|
||||
#include <Common/renameat2.h>
|
||||
#include <Common/atomicRename.h>
|
||||
#include <Storages/StorageMaterializedView.h>
|
||||
#include <Interpreters/Context.h>
|
||||
#include <Interpreters/ExternalDictionariesLoader.h>
|
||||
@ -158,7 +158,7 @@ void DatabaseAtomic::renameTable(ContextPtr local_context, const String & table_
|
||||
return;
|
||||
}
|
||||
|
||||
if (exchange && !supportsRenameat2())
|
||||
if (exchange && !supportsAtomicRename())
|
||||
throw Exception(ErrorCodes::NOT_IMPLEMENTED, "RENAME EXCHANGE is not supported");
|
||||
|
||||
auto & other_db = dynamic_cast<DatabaseAtomic &>(to_database);
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include <Interpreters/Context.h>
|
||||
#include <Common/filesystemHelpers.h>
|
||||
#include <Common/quoteString.h>
|
||||
#include <Common/renameat2.h>
|
||||
#include <Common/atomicRename.h>
|
||||
#include <Disks/IO/createReadBufferFromFileBase.h>
|
||||
|
||||
#include <fstream>
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include <Parsers/formatAST.h>
|
||||
#include <IO/ReadHelpers.h>
|
||||
#include <Poco/DirectoryIterator.h>
|
||||
#include <Common/renameat2.h>
|
||||
#include <Common/atomicRename.h>
|
||||
#include <Common/CurrentMetrics.h>
|
||||
#include <base/logger_useful.h>
|
||||
#include <Poco/Util/AbstractConfiguration.h>
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include <Common/typeid_cast.h>
|
||||
#include <Common/Macros.h>
|
||||
#include <Common/randomSeed.h>
|
||||
#include <Common/renameat2.h>
|
||||
#include <Common/atomicRename.h>
|
||||
#include <Common/hex.h>
|
||||
|
||||
#include <Core/Defines.h>
|
||||
|
Loading…
Reference in New Issue
Block a user