Skip to content

Commit 55c8b0b

Browse files
committed
Update to ClickHouse v24.8.4.13-lts
1 parent ef26f9a commit 55c8b0b

File tree

2,653 files changed

+100712
-53032
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

2,653 files changed

+100712
-53032
lines changed

base/base/BorrowedObjectPool.h

+7-7
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ class BorrowedObjectPool final
8686
}
8787

8888
/// Return object into pool. Client must return same object that was borrowed.
89-
inline void returnObject(T && object_to_return)
89+
void returnObject(T && object_to_return)
9090
{
9191
{
9292
std::lock_guard lock(objects_mutex);
@@ -99,28 +99,28 @@ class BorrowedObjectPool final
9999
}
100100

101101
/// Max pool size
102-
inline size_t maxSize() const
102+
size_t maxSize() const
103103
{
104104
return max_size;
105105
}
106106

107107
/// Allocated objects size by the pool. If allocatedObjectsSize == maxSize then pool is full.
108-
inline size_t allocatedObjectsSize() const
108+
size_t allocatedObjectsSize() const
109109
{
110110
std::lock_guard lock(objects_mutex);
111111
return allocated_objects_size;
112112
}
113113

114114
/// Returns allocatedObjectsSize == maxSize
115-
inline bool isFull() const
115+
bool isFull() const
116116
{
117117
std::lock_guard lock(objects_mutex);
118118
return allocated_objects_size == max_size;
119119
}
120120

121121
/// Borrowed objects size. If borrowedObjectsSize == allocatedObjectsSize and pool is full.
122122
/// Then client will wait during borrowObject function call.
123-
inline size_t borrowedObjectsSize() const
123+
size_t borrowedObjectsSize() const
124124
{
125125
std::lock_guard lock(objects_mutex);
126126
return borrowed_objects_size;
@@ -129,15 +129,15 @@ class BorrowedObjectPool final
129129
private:
130130

131131
template <typename FactoryFunc>
132-
inline T allocateObjectForBorrowing(const std::unique_lock<std::mutex> &, FactoryFunc && func)
132+
T allocateObjectForBorrowing(const std::unique_lock<std::mutex> &, FactoryFunc && func)
133133
{
134134
++allocated_objects_size;
135135
++borrowed_objects_size;
136136

137137
return std::forward<FactoryFunc>(func)();
138138
}
139139

140-
inline T borrowFromObjects(const std::unique_lock<std::mutex> &)
140+
T borrowFromObjects(const std::unique_lock<std::mutex> &)
141141
{
142142
T dst;
143143
detail::moveOrCopyIfThrow(std::move(objects.back()), dst);

base/base/CMakeLists.txt

+6-10
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:${COVERAGE_FLAGS}>)
1+
add_compile_options("$<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:${COVERAGE_FLAGS}>")
22

33
if (USE_CLANG_TIDY)
44
set (CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_PATH}")
@@ -32,17 +32,9 @@ set (SRCS
3232
StringRef.cpp
3333
safeExit.cpp
3434
throwError.cpp
35+
Numa.cpp
3536
)
3637

37-
if (USE_DEBUG_HELPERS)
38-
get_target_property(MAGIC_ENUM_INCLUDE_DIR ch_contrib::magic_enum INTERFACE_INCLUDE_DIRECTORIES)
39-
# CMake generator expression will do insane quoting when it encounters special character like quotes, spaces, etc.
40-
# Prefixing "SHELL:" will force it to use the original text.
41-
set (INCLUDE_DEBUG_HELPERS "SHELL:-I\"${MAGIC_ENUM_INCLUDE_DIR}\" -include \"${ClickHouse_SOURCE_DIR}/base/base/iostream_debug_helpers.h\"")
42-
# Use generator expression as we don't want to pollute CMAKE_CXX_FLAGS, which will interfere with CMake check system.
43-
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:${INCLUDE_DEBUG_HELPERS}>)
44-
endif ()
45-
4638
add_library (common ${SRCS})
4739

4840
if (WITH_COVERAGE)
@@ -55,6 +47,10 @@ if (TARGET ch_contrib::crc32_s390x)
5547
target_link_libraries(common PUBLIC ch_contrib::crc32_s390x)
5648
endif()
5749

50+
if (TARGET ch_contrib::numactl)
51+
target_link_libraries(common PUBLIC ch_contrib::numactl)
52+
endif()
53+
5854
target_include_directories(common PUBLIC .. "${CMAKE_CURRENT_BINARY_DIR}/..")
5955

6056
target_link_libraries (common

base/base/Decimal_fwd.h

+4
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ concept is_over_big_int =
4444
|| std::is_same_v<T, UInt256>
4545
|| std::is_same_v<T, Decimal128>
4646
|| std::is_same_v<T, Decimal256>;
47+
48+
template <class T>
49+
concept is_over_big_decimal = is_decimal<T> && is_over_big_int<typename T::NativeType>;
50+
4751
}
4852

4953
template <> struct is_signed<DB::Decimal32> { static constexpr bool value = true; };

base/base/EnumReflection.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ constexpr void static_for(F && f)
3232
template <is_enum T>
3333
struct fmt::formatter<T> : fmt::formatter<std::string_view>
3434
{
35-
constexpr auto format(T value, auto& format_context)
35+
constexpr auto format(T value, auto& format_context) const
3636
{
3737
return formatter<string_view>::format(magic_enum::enum_name(value), format_context);
3838
}

base/base/Numa.cpp

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#include <base/Numa.h>
2+
3+
#include "config.h"
4+
5+
#if USE_NUMACTL
6+
# include <numa.h>
7+
#endif
8+
9+
namespace DB
10+
{
11+
12+
std::optional<size_t> getNumaNodesTotalMemory()
13+
{
14+
std::optional<size_t> total_memory;
15+
#if USE_NUMACTL
16+
if (numa_available() != -1)
17+
{
18+
auto * membind = numa_get_membind();
19+
if (!numa_bitmask_equal(membind, numa_all_nodes_ptr))
20+
{
21+
total_memory.emplace(0);
22+
auto max_node = numa_max_node();
23+
for (int i = 0; i <= max_node; ++i)
24+
{
25+
if (numa_bitmask_isbitset(membind, i))
26+
*total_memory += numa_node_size(i, nullptr);
27+
}
28+
}
29+
30+
numa_bitmask_free(membind);
31+
}
32+
33+
#endif
34+
return total_memory;
35+
}
36+
37+
}

base/base/Numa.h

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#pragma once
2+
3+
#include <optional>
4+
5+
namespace DB
6+
{
7+
8+
/// return total memory of NUMA nodes the process is bound to
9+
/// if NUMA is not supported or process can use all nodes, std::nullopt is returned
10+
std::optional<size_t> getNumaNodesTotalMemory();
11+
12+
}

base/base/StringRef.h

+4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#include <base/types.h>
1313
#include <base/unaligned.h>
1414
#include <base/simd.h>
15+
#include <fmt/core.h>
16+
#include <fmt/ostream.h>
1517

1618
#include <city.h>
1719

@@ -376,3 +378,5 @@ namespace PackedZeroTraits
376378

377379

378380
std::ostream & operator<<(std::ostream & os, const StringRef & str);
381+
382+
template<> struct fmt::formatter<StringRef> : fmt::ostream_formatter {};

base/base/cgroupsv2.cpp

+13-10
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
#include <base/defines.h>
44

55
#include <fstream>
6-
#include <sstream>
6+
#include <string>
77

8+
namespace fs = std::filesystem;
89

910
bool cgroupsV2Enabled()
1011
{
@@ -13,11 +14,11 @@ bool cgroupsV2Enabled()
1314
{
1415
/// This file exists iff the host has cgroups v2 enabled.
1516
auto controllers_file = default_cgroups_mount / "cgroup.controllers";
16-
if (!std::filesystem::exists(controllers_file))
17+
if (!fs::exists(controllers_file))
1718
return false;
1819
return true;
1920
}
20-
catch (const std::filesystem::filesystem_error &) /// all "underlying OS API errors", typically: permission denied
21+
catch (const fs::filesystem_error &) /// all "underlying OS API errors", typically: permission denied
2122
{
2223
return false; /// not logging the exception as most callers fall back to cgroups v1
2324
}
@@ -33,8 +34,9 @@ bool cgroupsV2MemoryControllerEnabled()
3334
/// According to https://docs.kernel.org/admin-guide/cgroup-v2.html, file "cgroup.controllers" defines which controllers are available
3435
/// for the current + child cgroups. The set of available controllers can be restricted from level to level using file
3536
/// "cgroups.subtree_control". It is therefore sufficient to check the bottom-most nested "cgroup.controllers" file.
36-
std::string cgroup = cgroupV2OfProcess();
37-
auto cgroup_dir = cgroup.empty() ? default_cgroups_mount : (default_cgroups_mount / cgroup);
37+
fs::path cgroup_dir = cgroupV2PathOfProcess();
38+
if (cgroup_dir.empty())
39+
return false;
3840
std::ifstream controllers_file(cgroup_dir / "cgroup.controllers");
3941
if (!controllers_file.is_open())
4042
return false;
@@ -46,25 +48,26 @@ bool cgroupsV2MemoryControllerEnabled()
4648
#endif
4749
}
4850

49-
std::string cgroupV2OfProcess()
51+
fs::path cgroupV2PathOfProcess()
5052
{
5153
#if defined(OS_LINUX)
5254
chassert(cgroupsV2Enabled());
5355
/// All PIDs assigned to a cgroup are in /sys/fs/cgroups/{cgroup_name}/cgroup.procs
5456
/// A simpler way to get the membership is:
5557
std::ifstream cgroup_name_file("/proc/self/cgroup");
5658
if (!cgroup_name_file.is_open())
57-
return "";
59+
return {};
5860
/// With cgroups v2, there will be a *single* line with prefix "0::/"
5961
/// (see https://docs.kernel.org/admin-guide/cgroup-v2.html)
6062
std::string cgroup;
6163
std::getline(cgroup_name_file, cgroup);
6264
static const std::string v2_prefix = "0::/";
6365
if (!cgroup.starts_with(v2_prefix))
64-
return "";
66+
return {};
6567
cgroup = cgroup.substr(v2_prefix.length());
66-
return cgroup;
68+
/// Note: The 'root' cgroup can have an empty cgroup name, this is valid
69+
return default_cgroups_mount / cgroup;
6770
#else
68-
return "";
71+
return {};
6972
#endif
7073
}

base/base/cgroupsv2.h

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#pragma once
22

33
#include <filesystem>
4-
#include <string>
54

65
#if defined(OS_LINUX)
76
/// I think it is possible to mount the cgroups hierarchy somewhere else (e.g. when in containers).
@@ -16,7 +15,7 @@ bool cgroupsV2Enabled();
1615
/// Assumes that cgroupsV2Enabled() is enabled.
1716
bool cgroupsV2MemoryControllerEnabled();
1817

19-
/// Which cgroup does the process belong to?
20-
/// Returns an empty string if the cgroup cannot be determined.
18+
/// Detects which cgroup v2 the process belongs to and returns the filesystem path to the cgroup.
19+
/// Returns an empty path the cgroup cannot be determined.
2120
/// Assumes that cgroupsV2Enabled() is enabled.
22-
std::string cgroupV2OfProcess();
21+
std::filesystem::path cgroupV2PathOfProcess();

base/base/defines.h

+8-5
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,13 @@
8787
# define ASAN_POISON_MEMORY_REGION(a, b)
8888
#endif
8989

90-
#if !defined(ABORT_ON_LOGICAL_ERROR)
91-
#if !defined(NDEBUG) || defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) || defined(MEMORY_SANITIZER) || defined(UNDEFINED_BEHAVIOR_SANITIZER)
92-
#define ABORT_ON_LOGICAL_ERROR
93-
#endif
90+
/// We used to have only ABORT_ON_LOGICAL_ERROR macro, but most of its uses were actually in places where we didn't care about logical errors
91+
/// but wanted to check exactly if the current build type is debug or with sanitizer. This new macro is introduced to fix those places.
92+
#if !defined(DEBUG_OR_SANITIZER_BUILD)
93+
# if !defined(NDEBUG) || defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) || defined(MEMORY_SANITIZER) \
94+
|| defined(UNDEFINED_BEHAVIOR_SANITIZER)
95+
# define DEBUG_OR_SANITIZER_BUILD
96+
# endif
9497
#endif
9598

9699
/// chassert(x) is similar to assert(x), but:
@@ -101,7 +104,7 @@
101104
/// Also it makes sense to call abort() instead of __builtin_unreachable() in debug builds,
102105
/// because SIGABRT is easier to debug than SIGTRAP (the second one makes gdb crazy)
103106
#if !defined(chassert)
104-
#if defined(ABORT_ON_LOGICAL_ERROR)
107+
# if defined(DEBUG_OR_SANITIZER_BUILD)
105108
// clang-format off
106109
#include <base/types.h>
107110
namespace DB

base/base/demangle.h

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#pragma once
22

3+
#include <cstdlib>
34
#include <memory>
45
#include <string>
56

base/base/extended_types.h

+16
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,14 @@ struct make_unsigned // NOLINT(readability-identifier-naming)
108108
using type = std::make_unsigned_t<T>;
109109
};
110110

111+
template <> struct make_unsigned<Int8> { using type = UInt8; };
112+
template <> struct make_unsigned<UInt8> { using type = UInt8; };
113+
template <> struct make_unsigned<Int16> { using type = UInt16; };
114+
template <> struct make_unsigned<UInt16> { using type = UInt16; };
115+
template <> struct make_unsigned<Int32> { using type = UInt32; };
116+
template <> struct make_unsigned<UInt32> { using type = UInt32; };
117+
template <> struct make_unsigned<Int64> { using type = UInt64; };
118+
template <> struct make_unsigned<UInt64> { using type = UInt64; };
111119
template <> struct make_unsigned<Int128> { using type = UInt128; };
112120
template <> struct make_unsigned<UInt128> { using type = UInt128; };
113121
template <> struct make_unsigned<Int256> { using type = UInt256; };
@@ -121,6 +129,14 @@ struct make_signed // NOLINT(readability-identifier-naming)
121129
using type = std::make_signed_t<T>;
122130
};
123131

132+
template <> struct make_signed<Int8> { using type = Int8; };
133+
template <> struct make_signed<UInt8> { using type = Int8; };
134+
template <> struct make_signed<Int16> { using type = Int16; };
135+
template <> struct make_signed<UInt16> { using type = Int16; };
136+
template <> struct make_signed<Int32> { using type = Int32; };
137+
template <> struct make_signed<UInt32> { using type = Int32; };
138+
template <> struct make_signed<Int64> { using type = Int64; };
139+
template <> struct make_signed<UInt64> { using type = Int64; };
124140
template <> struct make_signed<Int128> { using type = Int128; };
125141
template <> struct make_signed<UInt128> { using type = Int128; };
126142
template <> struct make_signed<Int256> { using type = Int256; };

base/base/getFQDNOrHostName.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ namespace
66
{
77
std::string getFQDNOrHostNameImpl()
88
{
9+
#if defined(OS_DARWIN)
10+
return Poco::Net::DNS::hostName();
11+
#else
912
try
1013
{
1114
return Poco::Net::DNS::thisHost().name();
@@ -14,6 +17,7 @@ namespace
1417
{
1518
return Poco::Net::DNS::hostName();
1619
}
20+
#endif
1721
}
1822
}
1923

base/base/getMemoryAmount.cpp

+7-4
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,14 @@
22

33
#include <base/cgroupsv2.h>
44
#include <base/getPageSize.h>
5+
#include <base/Numa.h>
56

67
#include <fstream>
7-
#include <stdexcept>
88

99
#include <unistd.h>
1010
#include <sys/types.h>
1111
#include <sys/param.h>
1212

13-
1413
namespace
1514
{
1615

@@ -23,8 +22,9 @@ std::optional<uint64_t> getCgroupsV2MemoryLimit()
2322
if (!cgroupsV2MemoryControllerEnabled())
2423
return {};
2524

26-
std::string cgroup = cgroupV2OfProcess();
27-
auto current_cgroup = cgroup.empty() ? default_cgroups_mount : (default_cgroups_mount / cgroup);
25+
std::filesystem::path current_cgroup = cgroupV2PathOfProcess();
26+
if (current_cgroup.empty())
27+
return {};
2828

2929
/// Open the bottom-most nested memory limit setting file. If there is no such file at the current
3030
/// level, try again at the parent level as memory settings are inherited.
@@ -62,6 +62,9 @@ uint64_t getMemoryAmountOrZero()
6262

6363
uint64_t memory_amount = num_pages * page_size;
6464

65+
if (auto total_numa_memory = DB::getNumaNodesTotalMemory(); total_numa_memory.has_value())
66+
memory_amount = *total_numa_memory;
67+
6568
/// Respect the memory limit set by cgroups v2.
6669
auto limit_v2 = getCgroupsV2MemoryLimit();
6770
if (limit_v2.has_value() && *limit_v2 < memory_amount)

0 commit comments

Comments
 (0)