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/Exception.h>
|
||||||
#include <Common/VersionNumber.h>
|
#include <Common/VersionNumber.h>
|
||||||
#include <Poco/Environment.h>
|
#include <Poco/Environment.h>
|
||||||
@ -55,7 +55,7 @@ namespace ErrorCodes
|
|||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
|
||||||
static bool supportsRenameat2Impl()
|
static bool 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());
|
||||||
@ -64,7 +64,7 @@ static bool supportsRenameat2Impl()
|
|||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
if (!supportsRenameat2())
|
if (!supportsAtomicRename())
|
||||||
return false;
|
return false;
|
||||||
if (old_path.empty() || new_path.empty())
|
if (old_path.empty() || new_path.empty())
|
||||||
throw Exception(ErrorCodes::LOGICAL_ERROR, "Cannot rename {} to {}: path is empty", old_path, new_path);
|
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);
|
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;
|
return supports;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,7 +174,7 @@ static bool renameat2(const std::string &, const std::string &, int)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool supportsRenameat2()
|
bool supportsAtomicRename()
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
@ -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 supportsRenameat2();
|
bool supportsAtomicRename();
|
||||||
|
|
||||||
/// 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);
|
@ -4,7 +4,7 @@
|
|||||||
#include <IO/WriteHelpers.h>
|
#include <IO/WriteHelpers.h>
|
||||||
#include <IO/ReadBufferFromFile.h>
|
#include <IO/ReadBufferFromFile.h>
|
||||||
#include <Parsers/formatAST.h>
|
#include <Parsers/formatAST.h>
|
||||||
#include <Common/renameat2.h>
|
#include <Common/atomicRename.h>
|
||||||
#include <Storages/StorageMaterializedView.h>
|
#include <Storages/StorageMaterializedView.h>
|
||||||
#include <Interpreters/Context.h>
|
#include <Interpreters/Context.h>
|
||||||
#include <Interpreters/ExternalDictionariesLoader.h>
|
#include <Interpreters/ExternalDictionariesLoader.h>
|
||||||
@ -158,7 +158,7 @@ void DatabaseAtomic::renameTable(ContextPtr local_context, const String & table_
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exchange && !supportsRenameat2())
|
if (exchange && !supportsAtomicRename())
|
||||||
throw Exception(ErrorCodes::NOT_IMPLEMENTED, "RENAME EXCHANGE is not supported");
|
throw Exception(ErrorCodes::NOT_IMPLEMENTED, "RENAME EXCHANGE is not supported");
|
||||||
|
|
||||||
auto & other_db = dynamic_cast<DatabaseAtomic &>(to_database);
|
auto & other_db = dynamic_cast<DatabaseAtomic &>(to_database);
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include <Interpreters/Context.h>
|
#include <Interpreters/Context.h>
|
||||||
#include <Common/filesystemHelpers.h>
|
#include <Common/filesystemHelpers.h>
|
||||||
#include <Common/quoteString.h>
|
#include <Common/quoteString.h>
|
||||||
#include <Common/renameat2.h>
|
#include <Common/atomicRename.h>
|
||||||
#include <Disks/IO/createReadBufferFromFileBase.h>
|
#include <Disks/IO/createReadBufferFromFileBase.h>
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
#include <Parsers/formatAST.h>
|
#include <Parsers/formatAST.h>
|
||||||
#include <IO/ReadHelpers.h>
|
#include <IO/ReadHelpers.h>
|
||||||
#include <Poco/DirectoryIterator.h>
|
#include <Poco/DirectoryIterator.h>
|
||||||
#include <Common/renameat2.h>
|
#include <Common/atomicRename.h>
|
||||||
#include <Common/CurrentMetrics.h>
|
#include <Common/CurrentMetrics.h>
|
||||||
#include <base/logger_useful.h>
|
#include <base/logger_useful.h>
|
||||||
#include <Poco/Util/AbstractConfiguration.h>
|
#include <Poco/Util/AbstractConfiguration.h>
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#include <Common/typeid_cast.h>
|
#include <Common/typeid_cast.h>
|
||||||
#include <Common/Macros.h>
|
#include <Common/Macros.h>
|
||||||
#include <Common/randomSeed.h>
|
#include <Common/randomSeed.h>
|
||||||
#include <Common/renameat2.h>
|
#include <Common/atomicRename.h>
|
||||||
#include <Common/hex.h>
|
#include <Common/hex.h>
|
||||||
|
|
||||||
#include <Core/Defines.h>
|
#include <Core/Defines.h>
|
||||||
|
Loading…
Reference in New Issue
Block a user